Skip to content

Commit 2988ef5

Browse files
authored
Merge pull request #122 from node-projects/copilot/fix-overlay-rectangle-calculation
Fix miniature view viewport rect calculation and add click-to-navigate
2 parents 7d5f16a + 79b60eb commit 2988ef5

File tree

1 file changed

+55
-6
lines changed

1 file changed

+55
-6
lines changed

src/miniature-view.ts

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
import { BaseCustomWebComponentConstructorAppend, css, html, Disposable } from "@node-projects/base-custom-webcomponent";
22
import { DesignerCanvas, IMiniatureView, InstanceServiceContainer } from "@node-projects/web-component-designer";
33

4-
//TODO: with click on miniature view move main view to the position of the click
5-
//use: this._instanceServiceContainer.designerCanvas.canvasOffset = {x: ..., y: ... }
6-
74
export class MiniatureView extends BaseCustomWebComponentConstructorAppend implements IMiniatureView {
85

96
static override readonly style = css`
@@ -32,6 +29,7 @@ export class MiniatureView extends BaseCustomWebComponentConstructorAppend imple
3229
height: 100%;
3330
pointer-events: auto;
3431
background: transparent;
32+
cursor: pointer;
3533
}
3634
#viewRect {
3735
position: absolute;
@@ -40,6 +38,7 @@ export class MiniatureView extends BaseCustomWebComponentConstructorAppend imple
4038
width: 100%;
4139
height: 100%;
4240
border: 1px solid black;
41+
pointer-events: none;
4342
}`;
4443

4544
static override readonly template = html`
@@ -52,6 +51,7 @@ export class MiniatureView extends BaseCustomWebComponentConstructorAppend imple
5251

5352
private _innerDiv: HTMLDivElement;
5453
private _outerDiv: HTMLDivElement;
54+
private _above: HTMLDivElement;
5555
private _instanceServiceContainer: InstanceServiceContainer;
5656
private _contentChangedHandler: Disposable;
5757
private _maxX = 0;
@@ -63,7 +63,9 @@ export class MiniatureView extends BaseCustomWebComponentConstructorAppend imple
6363
private _minatureScaleX = 1;
6464
private _minatureScaleY = 1;
6565
private _reRenderFlag = false;
66-
//private _cachedMiniatureViews = new WeakMap<InstanceServiceContainer, HTMLDivElement>();
66+
private _isDragging = false;
67+
private _boundMouseMove: (e: MouseEvent) => void;
68+
private _boundMouseUp: (e: MouseEvent) => void;
6769

6870
constructor() {
6971
super();
@@ -72,8 +74,14 @@ export class MiniatureView extends BaseCustomWebComponentConstructorAppend imple
7274
this._outerDiv = this._getDomElement<HTMLDivElement>('outerDiv');
7375
this._innerDiv = this._getDomElement<HTMLDivElement>('innerDiv');
7476
this._viewRect = this._getDomElement<HTMLDivElement>('viewRect');
77+
this._above = this._getDomElement<HTMLDivElement>('above');
7578
this._innerShadow = this._innerDiv.attachShadow({ mode: 'open' });
7679

80+
this._boundMouseMove = this._onMouseMove.bind(this);
81+
this._boundMouseUp = this._onMouseUp.bind(this);
82+
83+
this._above.addEventListener('mousedown', (e) => this._onMouseDown(e));
84+
7785
this._resizeObserver = new ResizeObserver(() => {
7886
this._reSize();
7987
});
@@ -121,12 +129,53 @@ export class MiniatureView extends BaseCustomWebComponentConstructorAppend imple
121129
const offset = designerCanvas.canvasOffset;
122130
const zoom = designerCanvas.zoomFactor;
123131

124-
this._viewRect.style.left = (offset.x / this._maxX * 100) + '%';
125-
this._viewRect.style.top = (offset.y / this._maxY * 100) + '%';
132+
this._viewRect.style.left = (-offset.x / this._maxX * 100) + '%';
133+
this._viewRect.style.top = (-offset.y / this._maxY * 100) + '%';
126134
this._viewRect.style.width = (designerCanvas.clientWidth / zoom / this._maxX * 100) + '%';
127135
this._viewRect.style.height = (designerCanvas.clientHeight / zoom / this._maxY * 100) + '%';
128136
}
129137

138+
private _onMouseDown(e: MouseEvent) {
139+
if (!this._instanceServiceContainer) return;
140+
this._isDragging = true;
141+
this._moveCanvasToMousePosition(e);
142+
window.addEventListener('mousemove', this._boundMouseMove);
143+
window.addEventListener('mouseup', this._boundMouseUp);
144+
e.preventDefault();
145+
}
146+
147+
private _onMouseMove(e: MouseEvent) {
148+
if (!this._isDragging) return;
149+
this._moveCanvasToMousePosition(e);
150+
e.preventDefault();
151+
}
152+
153+
private _onMouseUp(e: MouseEvent) {
154+
this._isDragging = false;
155+
window.removeEventListener('mousemove', this._boundMouseMove);
156+
window.removeEventListener('mouseup', this._boundMouseUp);
157+
}
158+
159+
private _moveCanvasToMousePosition(e: MouseEvent) {
160+
const designerCanvas = this._instanceServiceContainer.designerCanvas;
161+
const zoom = designerCanvas.zoomFactor;
162+
const aboveRect = this._above.getBoundingClientRect();
163+
164+
const mouseX = e.clientX - aboveRect.left;
165+
const mouseY = e.clientY - aboveRect.top;
166+
167+
const contentX = (mouseX / aboveRect.width) * this._maxX;
168+
const contentY = (mouseY / aboveRect.height) * this._maxY;
169+
170+
const halfViewW = designerCanvas.clientWidth / zoom / 2;
171+
const halfViewH = designerCanvas.clientHeight / zoom / 2;
172+
173+
designerCanvas.canvasOffset = {
174+
x: -(contentX - halfViewW),
175+
y: -(contentY - halfViewH)
176+
};
177+
}
178+
130179
public set instanceServiceContainer(value: InstanceServiceContainer) {
131180
this._contentChangedHandler?.dispose()
132181
this._zoomFactorChangedHandler?.dispose();

0 commit comments

Comments
 (0)