Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <webdevcat@proton.me>2024-08-09 10:22:44 -0700
committerCatalin Mititiuc <webdevcat@proton.me>2024-08-09 10:22:44 -0700
commit90fe01caaf5b8e0488aef15eb5c76f1e87145797 (patch)
tree8d4bdc49898ed8a3842468b93638400496891b6e
parentca9ad3ac2a8a0b5709ae7f55dcff3a7473bb9203 (diff)
Extract programmatic pan coord calculations into gameboard module
-rw-r--r--node_modules/pan-zoom/index.js2
-rw-r--r--node_modules/pan-zoom/src/modules/pan.js82
-rw-r--r--package-lock.json13
-rw-r--r--package.json2
-rwxr-xr-xscripts/docker-run2
-rw-r--r--src/modules/gameboard.js33
-rw-r--r--src/modules/pan-zoom.js20
7 files changed, 42 insertions, 112 deletions
diff --git a/node_modules/pan-zoom/index.js b/node_modules/pan-zoom/index.js
deleted file mode 100644
index ab80f47..0000000
--- a/node_modules/pan-zoom/index.js
+++ /dev/null
@@ -1,2 +0,0 @@
-export { default as pan, manualPan } from './src/modules/pan.js';
-export { default as zoom } from './src/modules/zoom.js';
diff --git a/node_modules/pan-zoom/src/modules/pan.js b/node_modules/pan-zoom/src/modules/pan.js
deleted file mode 100644
index 98fc74b..0000000
--- a/node_modules/pan-zoom/src/modules/pan.js
+++ /dev/null
@@ -1,82 +0,0 @@
-import getComputedTransformMatrix from './utils.js';
-
-const minDistanceThreshold = 5;
-
-function distanceBetween({ x: x1, y: y1 }, { x: x2, y: y2 }) {
- return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
-}
-
-function minDistanceThresholdIsMet(startPt, endPt) {
- return distanceBetween(startPt, endPt) >= minDistanceThreshold;
-}
-
-function stopEventPropagationToChildren(el, type) {
- el.addEventListener(type, e => e.stopPropagation(), { capture: true, once: true });
-}
-
-function getTranslateMatrix(startPt, movePt) {
- const translateMatrix = new DOMMatrix();
-
- return translateMatrix.translate(movePt.x - startPt.x, movePt.y - startPt.y);
-}
-
-export function manualPan(gb, counter) {
- const mtx = getComputedTransformMatrix(gb),
- inverseScreenCTM = gb.getScreenCTM().inverse();
-
- const counterRect = counter.getBoundingClientRect();
- const mapRect = document.querySelector('object').getBoundingClientRect();
-
- let startPt = new DOMPoint(counterRect.x + counterRect.width / 2, counterRect.y + counterRect.height / 2);
- let movePt = new DOMPoint(mapRect.width / 2, mapRect.height / 2);
-
- startPt = startPt.matrixTransform(inverseScreenCTM);
- movePt = movePt.matrixTransform(inverseScreenCTM);
-
- gb.style.transition = 'transform 0.5s';
- gb.style.transform = mtx.multiply(getTranslateMatrix(startPt, movePt));
- gb.addEventListener('transitionend', () => gb.style.transition = '', { once: true });
-}
-
-export default function (svg, el, e) {
- e.preventDefault();
-
- const mtx = getComputedTransformMatrix(el),
- inverseScreenCTM = el.getScreenCTM().inverse();
-
- let startPt = new DOMPoint(e.clientX, e.clientY),
- movePt = new DOMPoint(),
- isPanning = false;
-
- function pointerMove(e) {
- movePt.x = e.clientX;
- movePt.y = e.clientY;
-
- if (!isPanning && minDistanceThresholdIsMet(startPt, movePt)) {
- isPanning = true;
- //e.target.setPointerCapture(e.pointerId);
-
- startPt.x = e.clientX;
- startPt.y = e.clientY;
- startPt = startPt.matrixTransform(inverseScreenCTM);
-
- stopEventPropagationToChildren(el, 'click');
- }
-
- if (isPanning) {
- movePt.x = e.clientX;
- movePt.y = e.clientY;
- movePt = movePt.matrixTransform(inverseScreenCTM);
-
- el.style.transform = mtx.multiply(getTranslateMatrix(startPt, movePt));
- }
- }
-
- svg.addEventListener('pointermove', pointerMove);
-
- svg.addEventListener(
- 'pointerup',
- () => svg.removeEventListener('pointermove', pointerMove),
- { once: true }
- );
-}
diff --git a/package-lock.json b/package-lock.json
index c66ac96..b7e3a65 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -5,7 +5,7 @@
"packages": {
"": {
"dependencies": {
- "pan-zoom": "github:webdevcat-me/pan-zoom"
+ "pan-zoom": "file:../pan-zoom"
},
"devDependencies": {
"esbuild": "^0.20.2",
@@ -16,6 +16,13 @@
"selenium-webdriver": "^4.19.0"
}
},
+ "../pan-zoom": {
+ "version": "0.2.0",
+ "devDependencies": {
+ "esbuild": "^0.20.2",
+ "esbuild-server": "^0.3.0"
+ }
+ },
"node_modules/@ampproject/remapping": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
@@ -3819,8 +3826,8 @@
"dev": true
},
"node_modules/pan-zoom": {
- "version": "0.2.0",
- "resolved": "git+ssh://git@github.com/webdevcat-me/pan-zoom.git#9c34e15c47cf3578adeff41693a62061a25fdcde"
+ "resolved": "../pan-zoom",
+ "link": true
},
"node_modules/parent-module": {
"version": "1.0.1",
diff --git a/package.json b/package.json
index e72df9b..805fd31 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"type": "module",
"dependencies": {
- "pan-zoom": "github:webdevcat-me/pan-zoom"
+ "pan-zoom": "file:../pan-zoom"
},
"devDependencies": {
"esbuild": "^0.20.2",
diff --git a/scripts/docker-run b/scripts/docker-run
index a11ce87..42af014 100755
--- a/scripts/docker-run
+++ b/scripts/docker-run
@@ -10,4 +10,4 @@ else
port=8080
fi
-docker run --rm --init -it -v $PWD:/usr/src/app -u $user_id:$user_id -p $port:$port $image $@
+docker run --rm --init -it -v $PWD:/usr/src/app -v $PWD/../pan-zoom:/usr/src/pan-zoom -u $user_id:$user_id -p $port:$port $image $@
diff --git a/src/modules/gameboard.js b/src/modules/gameboard.js
index 4218833..4407577 100644
--- a/src/modules/gameboard.js
+++ b/src/modules/gameboard.js
@@ -2,15 +2,13 @@ import * as firingArc from './game/firing_arc.js';
import * as sightLine from './game/sight_line.js';
import * as soldier from './game/soldier.js';
import { Observable } from './observable';
+import { programmaticPan } from 'pan-zoom';
-
-import { manualPan } from 'pan-zoom';
+const frontmostStore = new Map();
let svg,
placing = [];
-const frontmostStore = new Map();
-
function getCellContents(cell) {
return cell.querySelectorAll('*:not(use[href="#hex"])');
}
@@ -184,6 +182,27 @@ function selectOffBoard() {
Observable.notify('select', this, { revealRecord: true });
}
+function panMapToCounter(counter) {
+ const gb = svg.querySelector('.gameboard');
+
+ if (gb.contains(counter)) {
+ const counterRect = counter.getBoundingClientRect();
+ const mapRect = svg.parentNode.defaultView.frameElement.getBoundingClientRect();
+
+ const counterCoords = {
+ clientX: counterRect.x + counterRect.width / 2,
+ clientY: counterRect.y + counterRect.height / 2
+ };
+
+ const mapViewportCenterCoords = {
+ clientX: mapRect.width / 2,
+ clientY: mapRect.height / 2
+ };
+
+ programmaticPan(gb, counterCoords, mapViewportCenterCoords);
+ }
+}
+
function select(data, opts) {
const counter = data && (soldier.getCounter(svg, data) || soldier.createCounter(data));
const isSelected = data && data.classList && data.classList.contains('selected');
@@ -192,10 +211,8 @@ function select(data, opts) {
if (isSelected || !data) return;
- if (opts?.revealCounter && document.querySelector('#auto-center-map').checked) {
- const gb = svg.querySelector('.gameboard');
- if (gb.contains(counter)) manualPan(gb, counter);
- }
+ if (opts?.revealCounter && document.querySelector('#auto-center-map').checked)
+ panMapToCounter(counter);
counter.classList.add(soldier.getSelectedClass());
firingArc.get(svg, counter).forEach(el => el.removeAttribute('clip-path'));
diff --git a/src/modules/pan-zoom.js b/src/modules/pan-zoom.js
index 5e224e8..76c77f6 100644
--- a/src/modules/pan-zoom.js
+++ b/src/modules/pan-zoom.js
@@ -1,27 +1,17 @@
import { pan, zoom } from 'pan-zoom';
-const storageKey = 'pan-zoom',
- zoomFactor = 0.25;
+const storageKey = 'pan-zoom';
+const zoomFactor = 0.25;
function restorePanZoomVal(el) {
const storedPanZoomVal = localStorage.getItem(storageKey);
- if (storedPanZoomVal) {
- el.style.transform = storedPanZoomVal;
- }
+ if (storedPanZoomVal) el.style.transform = storedPanZoomVal;
}
function addEventListeners(svg, el) {
- svg.addEventListener('wheel', e => zoom(el, e, zoomFactor), { passive: false });
- svg.addEventListener('pointerdown', e => {
- if (e.button === 0) {
- e.target.setPointerCapture(e.pointerId);
- pan(svg, el, e), { passive: false };
- }
- });
- svg.addEventListener('pointermove', e => {
- console.log('clientX,clientY', `${e.clientX},${e.clientY}`);
- });
+ svg.addEventListener('wheel', zoom(el, zoomFactor), { passive: false });
+ svg.addEventListener('pointerdown', pan(el), { passive: false });
}
function storePanZoomVal(transformMatrix) {