From 1dd4377b03d7a4b07ae411a53c6289face7e9c67 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 22 Aug 2023 20:37:44 +0400 Subject: [PATCH] Update onWheel --- src/canvas/view/CanvasView.ts | 46 +++++++++++++++++++++++--------- src/canvas/view/FrameView.ts | 4 +-- src/canvas/view/FrameWrapView.ts | 14 ++++++++-- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/canvas/view/CanvasView.ts b/src/canvas/view/CanvasView.ts index 09ef000e0..01b1b390a 100644 --- a/src/canvas/view/CanvasView.ts +++ b/src/canvas/view/CanvasView.ts @@ -154,29 +154,38 @@ export default class CanvasView extends ModuleView { } screenToWorld(x: number, y: number): Coordinates { - const { left, top } = this.getCanvasOffset(); - const coords = this.module.getCoords(); + const { module } = this; + const coords = module.getCoords(); + const zoom = module.getZoomMultiplier(); const vwDelta = this.getViewportDelta(); return { - x: x - left - coords.x - vwDelta.x, - y: y - top - coords.y - vwDelta.y, + x: (x - coords.x - vwDelta.x) * zoom, + y: (y - coords.y - vwDelta.y) * zoom, }; } onPointer(ev: PointerEvent) { if (!this.config.infiniteCanvas) return; - const coords: Coordinates = { x: ev.clientX, y: ev.clientY }; + const canvasRect = this.getCanvasOffset(); + const screenCoords: Coordinates = { + x: ev.clientX - canvasRect.left, + y: ev.clientY - canvasRect.top, + }; if ((ev as any)._parentEvent) { // with _parentEvent means was triggered from the iframe - const { top, left } = (ev.target as HTMLElement).getBoundingClientRect(); - coords.y += top; - coords.x += left; + const frameRect = (ev.target as HTMLElement).getBoundingClientRect(); + const zoom = this.module.getZoomDecimal(); + screenCoords.x = frameRect.left - canvasRect.left + ev.clientX * zoom; + screenCoords.y = frameRect.top - canvasRect.top + ev.clientY * zoom; } - this.model.set({ pointer: this.screenToWorld(coords.x, coords.y) }); + this.model.set({ + pointerScreen: screenCoords, + pointer: this.screenToWorld(screenCoords.x, screenCoords.y), + }); } onKeyPress(ev: KeyboardEvent) { @@ -192,17 +201,27 @@ export default class CanvasView extends ModuleView { onWheel(ev: WheelEvent) { const { module, config } = this; if (config.infiniteCanvas) { + this.preventDefault(ev); const { deltaX, deltaY } = ev; const zoom = module.getZoomDecimal(); const isZooming = hasModifierKey(ev); - this.preventDefault(ev); + const coords = module.getCoords(); if (isZooming) { const newZoom = zoom - deltaY * zoom * 0.01; module.setZoom(newZoom * 100); + + // Update coordinates based on pointer + const pointer = this.model.get('pointerScreen'); + const canvasRect = this.getCanvasOffset(); + const pointerX = pointer.x - canvasRect.width / 2; + const pointerY = pointer.y - canvasRect.height / 2; + const zoomDelta = newZoom / zoom; + const x = pointerX - (pointerX - coords.x) * zoomDelta; + const y = pointerY - (pointerY - coords.y) * zoomDelta; + module.setCoords(x, y); } else { - const { x, y } = module.getCoords(); - module.setCoords(x - deltaX, y - deltaY); + module.setCoords(coords.x - deltaX, coords.y - deltaY); } } } @@ -233,6 +252,7 @@ export default class CanvasView extends ModuleView { const zoomDc = module.getZoomDecimal(); framesArea.style.transform = `scale(${zoomDc}) translate(${x * mpl}px, ${y * mpl}px)`; + // framesArea.style.transformOrigin = 'top left'; } if (cvStyle) { @@ -391,7 +411,7 @@ export default class CanvasView extends ModuleView { } } - getViewportDelta(): Coordinates { + getViewportDelta(opts: { withZoom?: number } = {}): Coordinates { const zoom = this.module.getZoomMultiplier(); const { width, height } = this.getCanvasOffset(); const worldWidth = width * zoom; diff --git a/src/canvas/view/FrameView.ts b/src/canvas/view/FrameView.ts index ad2290fc2..67556f7fc 100644 --- a/src/canvas/view/FrameView.ts +++ b/src/canvas/view/FrameView.ts @@ -476,10 +476,10 @@ export default class FrameView extends ModuleView { { event: 'keydown keyup keypress', class: 'KeyboardEvent' }, { event: 'mousedown mousemove mouseup', class: 'MouseEvent' }, { event: 'pointerdown pointermove pointerup', class: 'PointerEvent' }, - { event: 'wheel', class: 'WheelEvent' }, + { event: 'wheel', class: 'WheelEvent', opts: { passive: !config.infiniteCanvas } }, ].forEach(obj => obj.event.split(' ').forEach(event => { - doc.addEventListener(event, ev => this.el.dispatchEvent(createCustomEvent(ev, obj.class))); + doc.addEventListener(event, ev => this.el.dispatchEvent(createCustomEvent(ev, obj.class)), obj.opts); }) ); diff --git a/src/canvas/view/FrameWrapView.ts b/src/canvas/view/FrameWrapView.ts index 2d7049176..bedfb8f47 100644 --- a/src/canvas/view/FrameWrapView.ts +++ b/src/canvas/view/FrameWrapView.ts @@ -22,7 +22,6 @@ export default class FrameWrapView extends ModuleView { constructor(model: Frame, canvasView: CanvasView) { super({ model }); bindAll(this, 'onScroll', 'frameLoaded', 'updateOffset', 'remove', 'startDrag'); - //console.log(model.module) const config = { ...model.config, frameWrapView: this, @@ -143,9 +142,20 @@ export default class FrameWrapView extends ModuleView { } frameLoaded() { - const { frame } = this; + const { frame, config } = this; frame.getWindow().onscroll = this.onScroll; this.updateDim(); + + if (this.config.infiniteCanvas) { + // const iframe = this.frame.el; + // console.log('frameEl', iframe.contentDocument) + // const observer = new ResizeObserver(() => { + // // console.log('height', iframe.contentDocument!.body.scrollHeight) + // this.el.style.height = `${iframe.contentDocument!.body.scrollHeight}px`; + // }) + // observer.observe(iframe.contentDocument!.body); + // TODO: disable min-height: 100vh; + } } __handleSize() {