This commit is contained in:
sunmeng 2025-08-21 09:11:09 +08:00
parent c019bc9470
commit af3d727a64
10 changed files with 172 additions and 74 deletions

View File

@ -79,7 +79,8 @@ export default {
methods: { methods: {
handleCanvasClick(e) { handleCanvasClick(e) {
if (!this.containerRect) return; if (!this.containerRect) return;
//
if (this.isMoving) return;
// dpr // dpr
const dpr = this.$refs.canvasRef.dpr || 1; const dpr = this.$refs.canvasRef.dpr || 1;
@ -260,11 +261,30 @@ export default {
// console.log(event,'handleTouchEvent') // console.log(event,'handleTouchEvent')
// //
this.touchPoints = event.touches.length; this.touchPoints = event.touches.length;
//
if (event.type === 'touchstart') {
this.lastTouchTime = Date.now();
this.touchStartPoint = {
x: event.touches[0].clientX,
y: event.touches[0].clientY
};
this.isMoving = false; //
}
else if (event.type === 'touchmove') {
//
if (this.touchStartPoint) {
const dx = Math.abs(event.touches[0].clientX - this.touchStartPoint.x);
const dy = Math.abs(event.touches[0].clientY - this.touchStartPoint.y);
if (dx > 5 || dy > 5) {
this.isMoving = true;
}
}
}
// //
if (event.type === 'touchstart') { // if (event.type === 'touchstart') {
this.gestureStatus = event.touches.length > 1 ? '双指开始' : '单指开始'; // this.gestureStatus = event.touches.length > 1 ? '' : '';
} // }
// //
this.gestureHandler?.catchEvent(event); this.gestureHandler?.catchEvent(event);

View File

@ -199,40 +199,66 @@ class GestureHandler {
} }
// 基础缩放手势处理 // 基础缩放手势处理
_handlePinch(touches) { // _handlePinch(touches) {
const point1 = touches[0]; // const point1 = touches[0];
const point2 = touches[1]; // const point2 = touches[1];
const getPoint = (touch) => ({ // const getPoint = (touch) => ({
x: touch.x || (touch.clientX - this.containerRect.left), // x: touch.x || (touch.clientX - this.containerRect.left),
y: touch.y || (t.clientY - this.containerRect.top) // y: touch.y || (t.clientY - this.containerRect.top)
}); // });
const currentPoints = [getPoint(point1), getPoint(point2)]; // const currentPoints = [getPoint(point1), getPoint(point2)];
if (this.lastPoints) { // if (this.lastPoints) {
const currentDistance = Math.sqrt( // const currentDistance = Math.sqrt(
Math.pow(currentPoints[1].x - currentPoints[0].x, 2) + // Math.pow(currentPoints[1].x - currentPoints[0].x, 2) +
Math.pow(currentPoints[1].y - currentPoints[0].y, 2) // Math.pow(currentPoints[1].y - currentPoints[0].y, 2)
); // );
const prevDistance = Math.sqrt( // const prevDistance = Math.sqrt(
Math.pow(this.lastPoints[1].x - this.lastPoints[0].x, 2) + // Math.pow(this.lastPoints[1].x - this.lastPoints[0].x, 2) +
Math.pow(this.lastPoints[1].y - this.lastPoints[0].y, 2) // Math.pow(this.lastPoints[1].y - this.lastPoints[0].y, 2)
); // );
if (prevDistance > 0 && currentDistance > 0) { // if (prevDistance > 0 && currentDistance > 0) {
const scaleChange = currentDistance / prevDistance; // const scaleChange = currentDistance / prevDistance;
const centerX = (currentPoints[0].x + currentPoints[1].x) / 2; // const centerX = (currentPoints[0].x + currentPoints[1].x) / 2;
const centerY = (currentPoints[0].y + currentPoints[1].y) / 2; // const centerY = (currentPoints[0].y + currentPoints[1].y) / 2;
this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY); // this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
} // }
} // }
this.lastPoints = currentPoints; // this.lastPoints = currentPoints;
} // }
_handlePinch(touches) {
if (touches.length < 2) return;
// 获取当前两点位置
const currentDistance = this.calculateDistance(touches);
if (this.lastPinchDistance && currentDistance) {
const scaleChange = currentDistance / this.lastPinchDistance;
// 计算中心点
const centerX = (touches[0].clientX + touches[1].clientX) / 2;
const centerY = (touches[0].clientY + touches[1].clientY) / 2;
// 应用缩放
this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
}
this.lastPinchDistance = currentDistance;
}
calculateDistance(touches) {
const dx = touches[0].clientX - touches[1].clientX;
const dy = touches[0].clientY - touches[1].clientY;
return Math.sqrt(dx * dx + dy * dy);
}
} }
export default GestureHandler; export default GestureHandler;

View File

@ -94,10 +94,20 @@ export default {
}, },
methods: { methods: {
//
invertPoint(x, y) { invertPoint(x, y) {
// 使dpr const det = this.matrix.a * this.matrix.d - this.matrix.b * this.matrix.c;
const inverted = this.matrix.invertPoint(x, y); return {
return inverted; x: (this.matrix.d * x - this.matrix.c * y -
this.matrix.d * this.matrix.tx + this.matrix.c * this.matrix.ty) / det,
y: (-this.matrix.b * x + this.matrix.a * y +
this.matrix.b * this.matrix.tx - this.matrix.a * this.matrix.ty) / det
};
},
//
shouldIgnoreClick() {
return Date.now() - this.lastTouchTime < 300;
}, },
// //

View File

@ -1 +1 @@
{"version":3,"file":"gesture-canvas-page.js","sources":["pages/index/gesture-canvas-page.vue?type=page"],"sourcesContent":["import MiniProgramPage from '/Users/sunmeng/Desktop/wx/canvas/pages/index/gesture-canvas-page.vue'\nwx.createPage(MiniProgramPage)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,WAAW,eAAe;"} {"version":3,"file":"gesture-canvas-page.js","sources":["pages/index/gesture-canvas-page.vue?type=page"],"sourcesContent":["import MiniProgramPage from '/Users/sunmeng/Desktop/wx/canvas/pages/index/gesture-canvas-page.vue'\nwx.createPage(MiniProgramPage)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,WAAW,eAAe;"}

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"version":3,"file":"transform-canvas.js","sources":["/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue?type=component"],"sourcesContent":["import Component from '/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue'\nwx.createComponent(Component)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,gBAAgB,SAAS;"} {"version":3,"file":"transform-canvas.js","sources":["/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue?type=component"],"sourcesContent":["import Component from '/Users/sunmeng/Desktop/wx/canvas/pages/index/transform-canvas.vue'\nwx.createComponent(Component)"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,GAAG,gBAAgB,SAAS;"}

View File

@ -6882,7 +6882,7 @@ function initOnError() {
function initRuntimeSocketService() { function initRuntimeSocketService() {
const hosts = "127.0.0.1,172.10.0.127"; const hosts = "127.0.0.1,172.10.0.127";
const port = "8090"; const port = "8090";
const id = "mp-weixin_05amPE"; const id = "mp-weixin_Z8uiV9";
const lazy = typeof swan !== "undefined"; const lazy = typeof swan !== "undefined";
let restoreError = lazy ? () => { let restoreError = lazy ? () => {
} : initOnError(); } : initOnError();

View File

@ -41,6 +41,8 @@ const _sfc_main = {
handleCanvasClick(e) { handleCanvasClick(e) {
if (!this.containerRect) if (!this.containerRect)
return; return;
if (this.isMoving)
return;
const dpr = this.$refs.canvasRef.dpr || 1; const dpr = this.$refs.canvasRef.dpr || 1;
const x = (e.detail.x - this.containerRect.left) * dpr; const x = (e.detail.x - this.containerRect.left) * dpr;
const y = (e.detail.y - this.containerRect.top) * dpr; const y = (e.detail.y - this.containerRect.top) * dpr;
@ -63,7 +65,7 @@ const _sfc_main = {
} else if (this.currentView === "seat") { } else if (this.currentView === "seat") {
const hitSeat = this.$refs.canvasRef.checkSeatHit(x, y); const hitSeat = this.$refs.canvasRef.checkSeatHit(x, y);
if (hitSeat) { if (hitSeat) {
common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:111", "选中座位:", hitSeat); common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:112", "选中座位:", hitSeat);
this.toggleSeatSelection(hitSeat); this.toggleSeatSelection(hitSeat);
} }
} }
@ -110,7 +112,7 @@ const _sfc_main = {
return; return;
} }
} catch (e) { } catch (e) {
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:171", "获取容器位置失败:", e); common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:172", "获取容器位置失败:", e);
} }
await new Promise((r) => setTimeout(r, 100)); await new Promise((r) => setTimeout(r, 100));
retryCount++; retryCount++;
@ -122,7 +124,7 @@ const _sfc_main = {
container: this.containerRect container: this.containerRect
}); });
} catch (e) { } catch (e) {
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:187", "手势处理器初始化失败:", e); common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:188", "手势处理器初始化失败:", e);
this.gestureHandler = { this.gestureHandler = {
catchEvent: this.createGestureFallback(), catchEvent: this.createGestureFallback(),
setScale: (scale) => { setScale: (scale) => {
@ -180,7 +182,20 @@ const _sfc_main = {
var _a; var _a;
this.touchPoints = event.touches.length; this.touchPoints = event.touches.length;
if (event.type === "touchstart") { if (event.type === "touchstart") {
this.gestureStatus = event.touches.length > 1 ? "双指开始" : "单指开始"; this.lastTouchTime = Date.now();
this.touchStartPoint = {
x: event.touches[0].clientX,
y: event.touches[0].clientY
};
this.isMoving = false;
} else if (event.type === "touchmove") {
if (this.touchStartPoint) {
const dx = Math.abs(event.touches[0].clientX - this.touchStartPoint.x);
const dy = Math.abs(event.touches[0].clientY - this.touchStartPoint.y);
if (dx > 5 || dy > 5) {
this.isMoving = true;
}
}
} }
(_a = this.gestureHandler) == null ? void 0 : _a.catchEvent(event); (_a = this.gestureHandler) == null ? void 0 : _a.catchEvent(event);
if (event.type === "touchend" || event.type === "touchcancel") { if (event.type === "touchend" || event.type === "touchcancel") {
@ -528,7 +543,7 @@ const _sfc_main = {
}; };
this.seatAreas = response.data; this.seatAreas = response.data;
} catch (e) { } catch (e) {
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:627", "加载区域数据失败:", e); common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:647", "加载区域数据失败:", e);
} }
}, },
async loadSeatData(areaCode) { async loadSeatData(areaCode) {
@ -567,7 +582,7 @@ const _sfc_main = {
} }
}); });
} catch (e) { } catch (e) {
common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:685", "加载座位数据失败:", e); common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:705", "加载座位数据失败:", e);
common_vendor.index.showToast({ title: "加载座位失败", icon: "none" }); common_vendor.index.showToast({ title: "加载座位失败", icon: "none" });
} }
} }

View File

@ -54,9 +54,9 @@ class GestureHandler {
return (event) => { return (event) => {
const touches = event.touches || []; const touches = event.touches || [];
if (touches.length === 1) { if (touches.length === 1) {
const getPoint = (t2) => ({ const getPoint = (t) => ({
x: t2.x || t2.clientX - this.containerRect.left, x: t.x || t.clientX - this.containerRect.left,
y: t2.y || t2.clientY - this.containerRect.top y: t.y || t.clientY - this.containerRect.top
}); });
const currentPoint = getPoint(touches[0]); const currentPoint = getPoint(touches[0]);
if (!startPoint) { if (!startPoint) {
@ -141,9 +141,9 @@ class GestureHandler {
} }
// 基础平移手势处理 // 基础平移手势处理
_handlePan(touch) { _handlePan(touch) {
const getPoint = (t2) => ({ const getPoint = (t) => ({
x: t2.x || t2.clientX - this.containerRect.left, x: t.x || t.clientX - this.containerRect.left,
y: t2.y || t2.clientY - this.containerRect.top y: t.y || t.clientY - this.containerRect.top
}); });
const currentPoint = getPoint(touch); const currentPoint = getPoint(touch);
if (this.lastPoint) { if (this.lastPoint) {
@ -155,29 +155,48 @@ class GestureHandler {
this.lastPoint = currentPoint; this.lastPoint = currentPoint;
} }
// 基础缩放手势处理 // 基础缩放手势处理
// _handlePinch(touches) {
// const point1 = touches[0];
// const point2 = touches[1];
// const getPoint = (touch) => ({
// x: touch.x || (touch.clientX - this.containerRect.left),
// y: touch.y || (t.clientY - this.containerRect.top)
// });
// const currentPoints = [getPoint(point1), getPoint(point2)];
// if (this.lastPoints) {
// const currentDistance = Math.sqrt(
// Math.pow(currentPoints[1].x - currentPoints[0].x, 2) +
// Math.pow(currentPoints[1].y - currentPoints[0].y, 2)
// );
// const prevDistance = Math.sqrt(
// Math.pow(this.lastPoints[1].x - this.lastPoints[0].x, 2) +
// Math.pow(this.lastPoints[1].y - this.lastPoints[0].y, 2)
// );
// if (prevDistance > 0 && currentDistance > 0) {
// const scaleChange = currentDistance / prevDistance;
// const centerX = (currentPoints[0].x + currentPoints[1].x) / 2;
// const centerY = (currentPoints[0].y + currentPoints[1].y) / 2;
// this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
// }
// }
// this.lastPoints = currentPoints;
// }
_handlePinch(touches) { _handlePinch(touches) {
const point1 = touches[0]; if (touches.length < 2)
const point2 = touches[1]; return;
const getPoint = (touch) => ({ const currentDistance = this.calculateDistance(touches);
x: touch.x || touch.clientX - this.containerRect.left, if (this.lastPinchDistance && currentDistance) {
y: touch.y || t.clientY - this.containerRect.top const scaleChange = currentDistance / this.lastPinchDistance;
}); const centerX = (touches[0].clientX + touches[1].clientX) / 2;
const currentPoints = [getPoint(point1), getPoint(point2)]; const centerY = (touches[0].clientY + touches[1].clientY) / 2;
if (this.lastPoints) { this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
const currentDistance = Math.sqrt(
Math.pow(currentPoints[1].x - currentPoints[0].x, 2) + Math.pow(currentPoints[1].y - currentPoints[0].y, 2)
);
const prevDistance = Math.sqrt(
Math.pow(this.lastPoints[1].x - this.lastPoints[0].x, 2) + Math.pow(this.lastPoints[1].y - this.lastPoints[0].y, 2)
);
if (prevDistance > 0 && currentDistance > 0) {
const scaleChange = currentDistance / prevDistance;
const centerX = (currentPoints[0].x + currentPoints[1].x) / 2;
const centerY = (currentPoints[0].y + currentPoints[1].y) / 2;
this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
}
} }
this.lastPoints = currentPoints; this.lastPinchDistance = currentDistance;
}
calculateDistance(touches) {
const dx = touches[0].clientX - touches[1].clientX;
const dy = touches[0].clientY - touches[1].clientY;
return Math.sqrt(dx * dx + dy * dy);
} }
} }
exports.GestureHandler = GestureHandler; exports.GestureHandler = GestureHandler;

View File

@ -91,9 +91,17 @@ const _sfc_main = {
this.initCanvas(); this.initCanvas();
}, },
methods: { methods: {
// 修正坐标转换方法
invertPoint(x, y) { invertPoint(x, y) {
const inverted = this.matrix.invertPoint(x, y); const det = this.matrix.a * this.matrix.d - this.matrix.b * this.matrix.c;
return inverted; return {
x: (this.matrix.d * x - this.matrix.c * y - this.matrix.d * this.matrix.tx + this.matrix.c * this.matrix.ty) / det,
y: (-this.matrix.b * x + this.matrix.a * y + this.matrix.b * this.matrix.tx - this.matrix.a * this.matrix.ty) / det
};
},
// 添加移动速度检查
shouldIgnoreClick() {
return Date.now() - this.lastTouchTime < 300;
}, },
// 添加点击检测方法 // 添加点击检测方法
checkHitArea(x, y) { checkHitArea(x, y) {
@ -186,7 +194,7 @@ const _sfc_main = {
}); });
this.redraw(); this.redraw();
} catch (e) { } catch (e) {
common_vendor.index.__f__("error", "at pages/index/transform-canvas.vue:240", "图片加载失败:", e); common_vendor.index.__f__("error", "at pages/index/transform-canvas.vue:250", "图片加载失败:", e);
this.image = null; this.image = null;
} }
}, },