Browse Source

Correct Ctrl+Z with image support

master
A.Olokhtonov 1 year ago
parent
commit
2b01730749
  1. 12
      client/cursor.js
  2. 6
      client/default.css
  3. 24
      client/draw.js
  4. 3
      client/index.html
  5. 3
      client/index.js
  6. 44
      client/recv.js

12
client/cursor.js

@ -1,6 +1,5 @@ @@ -1,6 +1,5 @@
function on_down(e) {
if (e.button === 1) {
elements.cursor.classList.add('dhide');
elements.canvas0.classList.add('moving');
storage.state.moving = true;
storage.state.mousedown = true;
@ -76,7 +75,6 @@ async function on_up(e) { @@ -76,7 +75,6 @@ async function on_up(e) {
if (storage.state.moving && (e.button === 1 || e.button === 0)) {
storage.state.mousedown = false;
if (!storage.state.spacedown) {
elements.cursor.classList.remove('dhide');
elements.canvas0.classList.remove('moving');
storage.state.moving = false;
return;
@ -94,16 +92,21 @@ async function on_up(e) { @@ -94,16 +92,21 @@ async function on_up(e) {
function on_keydown(e) {
if (e.code === 'Space' && !storage.state.drawing) {
elements.cursor.classList.add('dhide');
elements.canvas0.classList.add('moving');
storage.state.moving = true;
storage.state.spacedown = true;
return;
}
if (e.code === 'KeyZ' && e.ctrlKey) {
const event = undo_event();
queue_event(event);
return;
}
}
function on_keyup(e) {
if (e.code === 'Space' && storage.state.moving) {
elements.cursor.classList.remove('dhide');
elements.canvas0.classList.remove('moving');
storage.state.moving = false;
storage.state.spacedown = false;
@ -112,7 +115,6 @@ function on_keyup(e) { @@ -112,7 +115,6 @@ function on_keyup(e) {
function on_leave(e) {
if (storage.state.moving) {
elements.cursor.classList.remove('dhide');
elements.canvas0.classList.remove('moving');
storage.state.moving = false;
storage.state.holding = false;

6
client/default.css

@ -13,6 +13,12 @@ html, body { @@ -13,6 +13,12 @@ html, body {
position: absolute;
top: 0;
left: 0;
opacity: 1;
transition: opacity .2s;
}
.canvas.white {
opacity: 0;
}
.canvas.moving {

24
client/draw.js

@ -38,4 +38,28 @@ function predraw_user(user_id, event) { @@ -38,4 +38,28 @@ function predraw_user(user_id, event) {
storage.ctx1.stroke();
storage.predraw[user_id].push({ 'x': event.x, 'y': event.y });
}
function redraw_region(bbox) {
storage.ctx0.save();
storage.ctx0.clearRect(bbox.xmin, bbox.ymin, bbox.xmax - bbox.xmin, bbox.ymax - bbox.ymin);
storage.ctx0.beginPath();
storage.ctx0.rect(bbox.xmin, bbox.ymin, bbox.xmax - bbox.xmin, bbox.ymax - bbox.ymin);
storage.ctx0.clip();
for (const event of storage.events) {
if (event.type === EVENT.STROKE && !event.deleted) {
if (stroke_intersects_region(event.points, bbox)) {
draw_stroke(event);
}
} else if (event.type === EVENT.IMAGE && !event.deleted) {
const image_bbox = bitmap_bbox(event);
if (rectangles_intersect(image_bbox, bbox)) {
storage.ctx0.drawImage(event.bitmap, image_bbox.xmin, image_bbox.ymin);
}
}
}
storage.ctx0.restore();
}

3
client/index.html

@ -14,8 +14,7 @@ @@ -14,8 +14,7 @@
<script type="text/javascript" src="draw.js"></script>
</head>
<body>
<div class="cursor" id="cursor"></div>
<canvas class="canvas" id="canvas0"></canvas>
<canvas class="canvas white" id="canvas0"></canvas>
<canvas class="canvas" id="canvas1"></canvas>
</body>
</html>

3
client/index.js

@ -141,9 +141,6 @@ function main() { @@ -141,9 +141,6 @@ function main() {
elements.canvas0 = document.getElementById('canvas0');
elements.canvas1 = document.getElementById('canvas1');
elements.cursor = document.getElementById('cursor');
elements.cursor.style.width = storage.cursor.width + 'px';
elements.cursor.style.height = storage.cursor.width + 'px';
storage.canvas.offset_x = window.scrollX;
storage.canvas.offset_y = window.scrollY;

44
client/recv.js

@ -86,23 +86,18 @@ function des_event(d) { @@ -86,23 +86,18 @@ function des_event(d) {
return event;
}
function redraw_region(bbox) {
storage.ctx0.save();
storage.ctx0.clearRect(bbox.xmin, bbox.ymin, bbox.xmax - bbox.xmin, bbox.ymax - bbox.ymin);
storage.ctx0.beginPath();
storage.ctx0.rect(bbox.xmin, bbox.ymin, bbox.xmax - bbox.xmin, bbox.ymax - bbox.ymin);
storage.ctx0.clip();
for (const event of storage.events) {
if (event.type === EVENT.STROKE && !event.deleted) {
if (stroke_intersects_region(event.points, bbox)) {
draw_stroke(event);
}
}
}
function bitmap_bbox(event) {
const x = (event.x <= storage.canvas.width ? event.x : event.x - 65536);
const y = (event.y <= storage.canvas.height ? event.y : event.y - 65536);
const bbox = {
'xmin': x,
'xmax': x + event.bitmap.width,
'ymin': y,
'ymax': y + event.bitmap.height
};
storage.ctx0.restore();
return bbox;
}
async function handle_event(event) {
@ -123,11 +118,17 @@ async function handle_event(event) { @@ -123,11 +118,17 @@ async function handle_event(event) {
case EVENT.UNDO: {
for (let i = storage.events.length - 1; i >=0; --i) {
const other_event = storage.events[i];
if (other_event.type === EVENT.STROKE && other_event.user_id === event.user_id && !other_event.deleted) {
other_event.deleted = true;
const stats = stroke_stats(other_event.points, storage.cursor.width);
redraw_region(stats.bbox);
break;
} else if (other_event.type === EVENT.IMAGE && other_event.user_id === event.user_id && !other_event.deleted) {
other_event.deleted = true;
const bbox = bitmap_bbox(other_event);
redraw_region(bbox);
break;
}
}
@ -139,11 +140,11 @@ async function handle_event(event) { @@ -139,11 +140,11 @@ async function handle_event(event) {
const blob = await r.blob();
const bitmap = await createImageBitmap(blob);
event.bitmap = bitmap;
const x = (event.x <= storage.canvas.width ? event.x : event.x - 65536);
const y = (event.y <= storage.canvas.height ? event.y : event.y - 65536);
const bbox = bitmap_bbox(event);
storage.ctx0.drawImage(bitmap, bbox.xmin, bbox.ymin);
storage.ctx0.drawImage(bitmap, x, y);
break;
}
@ -176,7 +177,6 @@ async function handle_message(d) { @@ -176,7 +177,6 @@ async function handle_message(d) {
console.debug('init in');
}
const event_count = des_u32(d);
console.debug(`${event_count} events in init`);
@ -184,10 +184,12 @@ async function handle_message(d) { @@ -184,10 +184,12 @@ async function handle_message(d) {
for (let i = 0; i < event_count; ++i) {
const event = des_event(d);
handle_event(event);
await handle_event(event);
storage.events.push(event);
}
elements.canvas0.classList.remove('white');
send_ack(event_count);
sync_queue();

Loading…
Cancel
Save