Browse Source

Merge scale and move local history, fixing undo for image move/scale

sdf
A.Olokhtonov 2 months ago
parent
commit
fea2874004
  1. 14
      README.txt
  2. 24
      client/client_recv.js
  3. 53
      client/undo.js
  4. 8
      client/webgl_geometry.js
  5. 2
      client/webgl_listeners.js

14
README.txt

@ -16,8 +16,9 @@ Release:
+ Stroke previews get connected when drawn without panning on touch devices + Stroke previews get connected when drawn without panning on touch devices
+ Redraw HTML (cursors) on local canvas moves + Redraw HTML (cursors) on local canvas moves
+ New strokes dissapear on the HMH desk + New strokes dissapear on the HMH desk
+ Undo history of moving and scaling images seems messed up
- Nothing get's drawn if we enable snapping and draw a curve where first and last point match - Nothing get's drawn if we enable snapping and draw a curve where first and last point match
- Undo history of moving and scaling images seems messed up - Weird clipping on HMH desk full zoomout after running "benchmark"
- Debug - Debug
- Restore ability to limit event range - Restore ability to limit event range
* Listeners/events/multiplayer * Listeners/events/multiplayer
@ -30,6 +31,7 @@ Release:
+ Be able to have multiple "current" strokes per player. In case of bad internet this can happen! + Be able to have multiple "current" strokes per player. In case of bad internet this can happen!
- Do NOT use session id as player id LUL - Do NOT use session id as player id LUL
- Save events to indexeddb (as some kind of a blob), restore on reconnect and page reload - Save events to indexeddb (as some kind of a blob), restore on reconnect and page reload
- Handle out of space
- Local prediction for tools! - Local prediction for tools!
- Immediately commit a stroke to the canvas, change order if earlier strokes arrive - Immediately commit a stroke to the canvas, change order if earlier strokes arrive
- Show my own image immediately, show placeholders while images are loading (add bitmap size to event) - Show my own image immediately, show placeholders while images are loading (add bitmap size to event)
@ -52,12 +54,17 @@ Release:
- Redo - Redo
+ Snapping to grid + Snapping to grid
- Snapping to other points? - Snapping to other points?
- Color picker should work for ruler
- Show previous color in color picker preview
- Stick picker preview to cursor
* Polish * Polish
+ Use typedvector where appropriate + Use typedvector where appropriate
- Show what's happening while the desk is loading (downloading, processing, uploading to gpu) - Show what's happening while the desk is loading (downloading, processing, uploading to gpu)
- Settings panel for config values (including the setting for "offline mode") - Settings panel for config values (including the setting for "offline mode")
- Set up VAOs - Set up VAOs
- We are calling "geometry_prepare_stroke" twice for some reason - We are calling "geometry_prepare_stroke" twice for some reason
- Replace "geometry_add_dummy_stroke" with something not [so] cursed
- Automatically extract locations from shaders (see nitka project for code examples)
- Presentation / "marketing" - Presentation / "marketing"
- Title (InfiNotes? MegaDesk?) - Title (InfiNotes? MegaDesk?)
- Icon - Icon
@ -80,6 +87,11 @@ Bonus:
+ Dots pattern + Dots pattern
+ Grid pattern + Grid pattern
- Menu option - Menu option
- Offline mode
- Only one user
- No server, everything applied immediately
- Allow export to file
- Save to browser storage (probaby indexed db + recent events in localstorage)
Bonus-bonus: Bonus-bonus:
- Actually infinite canvas (replace floats with something, some kind of fixed point scheme? chunks? multilevel scheme?) - Actually infinite canvas (replace floats with something, some kind of fixed point scheme? chunks? multilevel scheme?)

24
client/client_recv.js

@ -407,16 +407,7 @@ function handle_event(state, context, event, options = {}) {
if (image) { if (image) {
// if (config.debug_print) console.debug('move image', image_id, 'to', image_event.x, image_event.y); // if (config.debug_print) console.debug('move image', image_id, 'to', image_event.x, image_event.y);
if (image.move_head < image.move_history.length) { push_image_move(image, event.x, event.y);
image.move_history[image.move_head] = event.x;
image.move_history[image.move_head + 1] = event.y;
} else {
image.move_history.push(event.x, event.y);
}
image.move_head += 2;
image.at.x = event.x;
image.at.y = event.y;
need_draw = true; need_draw = true;
} }
@ -429,18 +420,7 @@ function handle_event(state, context, event, options = {}) {
const image = get_image(context, image_id); const image = get_image(context, image_id);
if (image !== null) { if (image !== null) {
if (image.scale_head < image.scale_history.length) { push_image_scale(image, event.corner, event.x, event.y);
image.scale_history[image.scale_head] = image.at.x;
image.scale_history[image.scale_head + 1] = image.at.y;
image.scale_history[image.scale_head + 2] = image.width;
image.scale_history[image.scale_head + 3] = image.height;
} else {
image.scale_history.push(image.at.x, image.at.y, image.width, image.height);
}
image.scale_head += 4;
scale_image(context, image, event.corner, {'x': event.x, 'y': event.y});
need_draw = true; need_draw = true;
} }

53
client/undo.js

@ -42,9 +42,7 @@ function undo(state, context, event, options) {
other_event.deleted = true; other_event.deleted = true;
const image = get_image(context, other_event.image_id); const image = get_image(context, other_event.image_id);
if (image !== null) { if (image !== null) {
image.move_head -= 2; pop_image_transform(image);
image.at.x = image.move_history[image.move_head - 2];
image.at.y = image.move_history[image.move_head - 1];
need_draw = true; need_draw = true;
} else { } else {
console.warning('Undo image move for a non-existent image'); console.warning('Undo image move for a non-existent image');
@ -56,15 +54,7 @@ function undo(state, context, event, options) {
other_event.deleted = true; other_event.deleted = true;
const image = get_image(context, other_event.image_id); const image = get_image(context, other_event.image_id);
if (image !== null) { if (image !== null) {
image.scale_head -= 4; pop_image_transform(image);
// NEXT: merge move and scale. Otherwise we can't know
// that there have been move events inbetween scale
image.at.x = image.scale_history[image.scale_head - 4];
image.at.y = image.scale_history[image.scale_head - 3];
image.width = image.scale_history[image.scale_head - 2];
image.height = image.scale_history[image.scale_head - 1];
need_draw = true; need_draw = true;
} else { } else {
console.warning('Undo image scale for a non-existent image'); console.warning('Undo image scale for a non-existent image');
@ -101,3 +91,42 @@ function undo(state, context, event, options) {
function redo() { function redo() {
console.log('TODO'); console.log('TODO');
} }
function push_image_move(image, x, y) {
if (image.transform_head < image.transform_history.length) {
image.transform_history[image.transform_head] = image.at.x;
image.transform_history[image.transform_head + 1] = image.at.y;
image.transform_history[image.transform_head + 2] = image.width;
image.transform_history[image.transform_head + 3] = image.height;
} else {
image.transform_history.push(image.at.x, image.at.y, image.width, image.height);
}
image.at.x = x;
image.at.y = y;
image.transform_head += 4;
}
function push_image_scale(image, corner, x, y) {
if (image.transform_head < image.transform_history.length) {
image.transform_history[image.transform_head] = image.at.x;
image.transform_history[image.transform_head + 1] = image.at.y;
image.transform_history[image.transform_head + 2] = image.width;
image.transform_history[image.transform_head + 3] = image.height;
} else {
image.transform_history.push(image.at.x, image.at.y, image.width, image.height);
}
scale_image(image, corner, {'x': x, 'y': y});
image.transform_head += 4;
}
function pop_image_transform(image, corner, x, y) {
image.transform_head -= 4;
image.at.x = image.transform_history[image.transform_head - 4];
image.at.y = image.transform_history[image.transform_head - 3];
image.width = image.transform_history[image.transform_head - 2];
image.height = image.transform_history[image.transform_head - 1];
}

8
client/webgl_geometry.js

@ -209,10 +209,8 @@ function add_image(context, image_id, bitmap, p, width, height) {
'raw_at': {...p}, 'raw_at': {...p},
'width': width, 'width': width,
'height': height, 'height': height,
'move_history': [ p.x, p.y ], 'transform_history': [ p.x, p.y, width, height ],
'scale_history': [ p.x, p.y, width, height ], 'transform_head': 4,
'move_head': 2,
'scale_head': 4,
}; };
context.images.push(entry); context.images.push(entry);
@ -234,7 +232,7 @@ function add_image(context, image_id, bitmap, p, width, height) {
} }
} }
function scale_image(context, image, corner, canvasp) { function scale_image(image, corner, canvasp) {
let new_width, new_height; let new_width, new_height;
const old_x2 = image.at.x + image.width; const old_x2 = image.at.x + image.width;

2
client/webgl_listeners.js

@ -386,7 +386,7 @@ function mousemove(e, state, context) {
if (state.imagescaling) { if (state.imagescaling) {
const image = get_image(context, state.active_image); const image = get_image(context, state.active_image);
scale_image(context, image, state.scaling_corner, canvasp); scale_image(image, state.scaling_corner, canvasp);
do_draw = true; do_draw = true;
} }

Loading…
Cancel
Save