|
|
|
@ -1,11 +1,13 @@
@@ -1,11 +1,13 @@
|
|
|
|
|
function init_listeners(state, context) { |
|
|
|
|
window.addEventListener('keydown', (e) => keydown(e, state, context)); |
|
|
|
|
window.addEventListener('keyup', (e) => keyup(e, state, context)); |
|
|
|
|
window.addEventListener('paste', (e) => paste(e, state, context)); |
|
|
|
|
|
|
|
|
|
context.canvas.addEventListener('mousedown', (e) => mousedown(e, state, context)); |
|
|
|
|
context.canvas.addEventListener('mousemove', (e) => mousemove(e, state, context)); |
|
|
|
|
context.canvas.addEventListener('mouseup', (e) => mouseup(e, state, context)); |
|
|
|
|
context.canvas.addEventListener('mouseleave', (e) => mouseup(e, state, context)); |
|
|
|
|
context.canvas.addEventListener('contextmenu', cancel); |
|
|
|
|
context.canvas.addEventListener('wheel', (e) => wheel(e, state, context)); |
|
|
|
|
|
|
|
|
|
context.canvas.addEventListener('touchstart', (e) => touchstart(e, state, context)); |
|
|
|
@ -27,6 +29,16 @@ function zenmode() {
@@ -27,6 +29,16 @@ function zenmode() {
|
|
|
|
|
document.querySelector('.sizer-wrapper').classList.toggle('hidden'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
async function paste(e, state, context) { |
|
|
|
|
const items = (e.clipboardData || e.originalEvent.clipboardData).items; |
|
|
|
|
for (const item of items) { |
|
|
|
|
if (item.kind === 'file') { |
|
|
|
|
const file = item.getAsFile(); |
|
|
|
|
await insert_image(state, context, file); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function keydown(e, state, context) { |
|
|
|
|
if (e.code === 'Space' && !state.drawing) { |
|
|
|
|
state.spacedown = true; |
|
|
|
@ -46,22 +58,48 @@ function keyup(e, state, context) {
@@ -46,22 +58,48 @@ function keyup(e, state, context) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function mousedown(e, state, context) { |
|
|
|
|
const screenp = {'x': window.devicePixelRatio * e.clientX, 'y': window.devicePixelRatio * e.clientY}; |
|
|
|
|
const canvasp = screen_to_canvas(state, screenp); |
|
|
|
|
|
|
|
|
|
if (e.button === 2) { |
|
|
|
|
// Right click on image to select it
|
|
|
|
|
const image_event = image_at(state, canvasp.x, canvasp.y); |
|
|
|
|
|
|
|
|
|
if (image_event) { |
|
|
|
|
context.active_image = image_event.image_id; |
|
|
|
|
} else { |
|
|
|
|
context.active_image = null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
schedule_draw(state, context); |
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (e.button !== 0) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (context.active_image) { |
|
|
|
|
// Move selected image with left click
|
|
|
|
|
const image_event = image_at(state, canvasp.x, canvasp.y); |
|
|
|
|
if (image_event && image_event.image_id === context.active_image) { |
|
|
|
|
state.moving_image = image_event; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (state.spacedown) { |
|
|
|
|
state.moving = true; |
|
|
|
|
context.canvas.classList.add('moving'); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const screenp = {'x': window.devicePixelRatio * e.clientX, 'y': window.devicePixelRatio * e.clientY}; |
|
|
|
|
const canvasp = screen_to_canvas(state, screenp); |
|
|
|
|
|
|
|
|
|
clear_dynamic_stroke(state, context, state.me); |
|
|
|
|
update_dynamic_stroke(state, context, state.me, canvasp); |
|
|
|
|
|
|
|
|
|
state.drawing = true; |
|
|
|
|
context.active_image = null; |
|
|
|
|
|
|
|
|
|
schedule_draw(state, context); |
|
|
|
|
} |
|
|
|
@ -77,6 +115,13 @@ function mousemove(e, state, context) {
@@ -77,6 +115,13 @@ function mousemove(e, state, context) {
|
|
|
|
|
do_draw = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (state.moving_image) { |
|
|
|
|
state.moving_image.x += e.movementX / state.canvas.zoom; |
|
|
|
|
state.moving_image.y += e.movementY / state.canvas.zoom; |
|
|
|
|
move_image(context, state.moving_image); |
|
|
|
|
do_draw = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const screenp = {'x': window.devicePixelRatio * e.clientX, 'y': window.devicePixelRatio * e.clientY}; |
|
|
|
|
const canvasp = screen_to_canvas(state, screenp); |
|
|
|
|
|
|
|
|
@ -100,6 +145,13 @@ function mouseup(e, state, context) {
@@ -100,6 +145,13 @@ function mouseup(e, state, context) {
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (state.moving_image) { |
|
|
|
|
schedule_draw(state, context); |
|
|
|
|
queue_event(state, image_move_event(context.active_image, state.moving_image.x, state.moving_image.y)); |
|
|
|
|
state.moving_image = null; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (state.moving) { |
|
|
|
|
state.moving = false; |
|
|
|
|
context.canvas.classList.remove('moving'); |
|
|
|
@ -354,29 +406,7 @@ async function on_drop(e, state, context) {
@@ -354,29 +406,7 @@ async function on_drop(e, state, context) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const file = e.dataTransfer.files[0]; |
|
|
|
|
const bitmap = await createImageBitmap(file); |
|
|
|
|
|
|
|
|
|
const p = { 'x': state.cursor.x, 'y': state.cursor.y }; |
|
|
|
|
const canvasp = screen_to_canvas(state, p); |
|
|
|
|
|
|
|
|
|
canvasp.x -= bitmap.width / 2; |
|
|
|
|
canvasp.y -= bitmap.height / 2; |
|
|
|
|
|
|
|
|
|
add_image(context, bitmap, canvasp); |
|
|
|
|
|
|
|
|
|
const form_data = new FormData(); |
|
|
|
|
form_data.append('file', file); |
|
|
|
|
|
|
|
|
|
const resp = await fetch(`/api/image?deskId=${state.desk_id}`, { |
|
|
|
|
method: 'post', |
|
|
|
|
body: form_data, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if (resp.ok) { |
|
|
|
|
const image_id = await resp.text(); |
|
|
|
|
const event = image_event(image_id, canvasp.x, canvasp.y); |
|
|
|
|
await queue_event(state, event); |
|
|
|
|
} |
|
|
|
|
await insert_image(state, context, file); |
|
|
|
|
|
|
|
|
|
schedule_draw(state, context); |
|
|
|
|
|
|
|
|
|