diff --git a/pages/index/gesture-canvas-page.vue b/pages/index/gesture-canvas-page.vue
index f40dab5..31f4694 100644
--- a/pages/index/gesture-canvas-page.vue
+++ b/pages/index/gesture-canvas-page.vue
@@ -25,7 +25,6 @@
-
@@ -69,30 +68,35 @@ export default {
methods: {
// 独立的手势初始化方法
initGestureHandler() {
- try {
- this.gestureHandler = new GestureHandler(this, this.transformMatrix, {
- container: this.containerRect
- });
- } catch (e) {
- console.error('手势处理器初始化失败:', e);
- // 创建降级方案
- this.gestureHandler = {
- catchEvent: (event) => {
- // 基本手势处理
- const touches = event.touches || [];
- if (touches.length > 0) {
- const point = touches[0];
- const x = point.clientX - this.containerRect.left;
- const y = point.clientY - this.containerRect.top;
-
- // 简单移动逻辑
- this.transformMatrix.tx = x - 50;
- this.transformMatrix.ty = y - 50;
- this.updateCanvas();
- }
- }
- }
- }
+ try {
+ this.gestureHandler = new GestureHandler(this, this.transformMatrix, {
+ container: this.containerRect
+ });
+ } catch (e) {
+ console.error('手势处理器初始化失败:', e);
+ // 简化降级方案
+ this.gestureHandler = {
+ catchEvent: (event) => {
+ // 只处理最基本的行为
+ if (event.touches.length > 0) {
+ const firstTouch = event.touches[0];
+ const x = firstTouch.clientX - this.containerRect.left;
+ const y = firstTouch.clientY - this.containerRect.top;
+
+ // 仅更新调试信息显示
+ this.gestureStatus = "降级模式: 单指拖动";
+ this.touchPoints = event.touches.length;
+
+ // 简单变换
+ if (event.type === 'touchmove') {
+ this.transformMatrix.tx = x;
+ this.transformMatrix.ty = y;
+ this.updateCanvas();
+ }
+ }
+ }
+ }
+ }
},
async getContainerPosition() {
@@ -130,18 +134,35 @@ export default {
console.error(`容器位置获取失败,已重试${maxRetries}次`);
},
- // 事件处理(完整修复)
+ // 事件处理
async handleTouchEvent(event) {
- // 修复点1:确保处理器就绪的防护代码
+
if (!this.gestureHandler || !this.containerRect) {
console.warn('手势处理器未就绪,尝试重新初始化...');
await this.getContainerPosition();
this.initGestureHandler();
-
+ if (event.type === 'touchend' || event.type === 'touchcancel') {
+ this.lastPoint = null;
+ this.lastPoints = null;
+ this.gestureStatus = '结束';
+
+ // 更新一次画面
+ this.updateCanvas();
+ return;
+ }
// 重新处理当前事件
if (this.gestureHandler) {
return this.handleTouchEvent(event);
}
+ // 如果是简单处理器,使用下面优化的基础处理方法
+ if (!this.at) {
+ // 使用优化后的基础处理方法
+ if (correctedEvent.touches.length === 1) {
+ this.handlePan(correctedEvent.touches[0]);
+ } else if (correctedEvent.touches.length > 1) {
+ this.handlePinch(correctedEvent.touches);
+ }
+ }
return;
}
@@ -230,14 +251,6 @@ export default {
this.updateCanvas();
},
- // 调试输出
- logMatrix() {
- console.log('当前变换矩阵:', this.transformMatrix.toArray());
- console.log('容器位置:', this.containerRect);
- if (this.$refs.canvasRef) {
- this.$refs.canvasRef.drawDebugGrid();
- }
- }
}
};
diff --git a/pages/index/gesture-handler.js b/pages/index/gesture-handler.js
index d35e706..c2e267c 100644
--- a/pages/index/gesture-handler.js
+++ b/pages/index/gesture-handler.js
@@ -4,6 +4,8 @@ class GestureHandler {
constructor(context, transformMatrix, { container }) {
this.transformMatrix = transformMatrix;
this.containerRect = container;
+ this.panThreshold = 5; // 移动5像素以上才认为是拖动
+ this.panStarted = false;
// 小程序环境兼容处理
const atOptions = {
@@ -49,10 +51,10 @@ class GestureHandler {
if (touches.length === 1) {
// 单指移动
- this.handlePan(touches[0]);
+ this._handlePan(touches[0]);
} else if (touches.length > 1) {
// 双指缩放
- this.handlePinch(touches);
+ this._handlePinch(touches);
}
}
};
@@ -63,9 +65,23 @@ class GestureHandler {
this.at.on('pan', (event) => {
if (event.type === 'panstart') {
console.log('panstart', event);
+ // 重置移动开始状态
+ this.panStarted = false;
}
else if (event.type === 'panmove') {
- // 关键修复:基于当前缩放比例修正移动量
+ // 检查是否超过阈值
+ const distance = Math.sqrt(event.deltaX**2 + event.deltaY**2);
+
+ if (!this.panStarted && distance < this.panThreshold) {
+ return; // 小于阈值不处理
+ }
+
+ if (!this.panStarted) {
+ console.log('拖动手势开始');
+ this.panStarted = true;
+ }
+
+ // 基于当前缩放比例修正移动量
const currentScale = Math.sqrt(
this.transformMatrix.a * this.transformMatrix.a +
this.transformMatrix.b * this.transformMatrix.b
@@ -75,9 +91,12 @@ class GestureHandler {
const dx = event.deltaX / currentScale;
const dy = event.deltaY / currentScale;
+
console.log(`平移: deltaX=${event.deltaX}, deltaY=${event.deltaY} | 修正后: dx=${dx}, dy=${dy}`);
this.transformMatrix.translate(dx, dy);
+ } else if (event.type === 'panend') {
+ this.panStarted = false;
}
});
@@ -114,77 +133,92 @@ class GestureHandler {
}
- catchEvent(event) {
- try {
- if (this.at) {
- this.at.run(event);
- } else if (this.handleGesture) {
- this.handleGesture.run(event);
- }
- } catch (e) {
- console.error('手势处理错误:', e);
- // 降级处理
- const touches = event.touches || [];
- if (touches.length > 0) {
- this.handlePan(touches[0]);
+ // 公共接口保持不变
+ catchEvent(event) {
+ try {
+ if (this.at) {
+ this.at.run(event);
+ } else {
+ // 内部处理降级方案
+ const touches = event.touches || [];
+ const eventType = event.type;
+
+ // 在事件开始时重置状态
+ if (eventType === 'touchstart') {
+ this.lastPoint = null;
+ this.lastPoints = null;
+ this.lastDistance = null;
+ }
+
+ // 处理不同数量的手指
+ if (touches.length === 1) {
+ this._handlePan(touches[0]);
+ } else if (touches.length > 1) {
+ this._handlePinch(touches);
+ }
+ }
+ } catch (e) {
+ console.error('手势处理错误:', e);
}
}
- }
-
// 基础平移手势处理
- handlePan(touch) {
- if (this.lastPoint) {
- const dx = touch.clientX - this.lastPoint.x;
- const dy = touch.clientY - this.lastPoint.y;
-
- // 根据当前缩放比例修正移动量
- const currentScale = Math.sqrt(
- this.transformMatrix.a * this.transformMatrix.a +
- this.transformMatrix.b * this.transformMatrix.b
- );
-
- const correctedDx = dx / currentScale;
- const correctedDy = dy / currentScale;
-
- this.transformMatrix.translate(correctedDx, correctedDy);
- }
- this.lastPoint = {x: touch.clientX, y: touch.clientY};
+ _handlePan(touch) {
+ const pointX = touch.x || (touch.clientX - this.containerRect.left);
+ const pointY = touch.y || (touch.clientY - this.containerRect.top);
+
+ if (this.lastPoint) {
+ // 基于容器坐标系的增量计算
+ const dx = pointX - this.lastPoint.x;
+ const dy = pointY - this.lastPoint.y;
+
+ // 使用真实增量,不需要缩放修正
+ this.transformMatrix.translate(dx, dy);
+ }
+
+ // 存储当前点 (容器坐标系)
+ this.lastPoint = {x: pointX, y: pointY};
}
// 基础缩放手势处理
- handlePinch(touches) {
+ _handlePinch(touches) {
const point1 = touches[0];
- const point2 = touches[1];
-
- if (this.lastPoints) {
- // 计算当前距离
- const currentDistance = Math.sqrt(
- Math.pow(point2.clientX - point1.clientX, 2) +
- Math.pow(point2.clientY - point1.clientY, 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) {
- const scaleChange = currentDistance / prevDistance;
-
- // 计算中心点
- const centerX = (point1.clientX + point2.clientX) / 2 - this.containerRect.left;
- const centerY = (point1.clientY + point2.clientY) / 2 - this.containerRect.top;
-
- this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
- }
- }
-
- this.lastPoints = [
- {x: point1.clientX, y: point1.clientY},
- {x: point2.clientX, y: point2.clientY}
- ];
+ const point2 = touches[1];
+
+ // 获取容器坐标系坐标
+ const getPoint = (touch) => ({
+ x: touch.x || (touch.clientX - this.containerRect.left),
+ y: touch.y || (touch.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;
}
}
diff --git a/pages/index/transform-canvas.vue b/pages/index/transform-canvas.vue
index 2723c4c..5a281a5 100644
--- a/pages/index/transform-canvas.vue
+++ b/pages/index/transform-canvas.vue
@@ -52,57 +52,57 @@ export default {
},
// 调试网格
- drawDebugGrid() {
- if (!this.ctx) return;
+ // drawDebugGrid() {
+ // if (!this.ctx) return;
- const pixelRatio = uni.getSystemInfoSync().pixelRatio;
- const width = this.canvasWidth * pixelRatio;
- const height = this.canvasHeight * pixelRatio;
+ // const pixelRatio = uni.getSystemInfoSync().pixelRatio;
+ // const width = this.canvasWidth * pixelRatio;
+ // const height = this.canvasHeight * pixelRatio;
- // 保存当前状态
- this.ctx.save();
+ // // 保存当前状态
+ // this.ctx.save();
- // 重置变换
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
+ // // 重置变换
+ // this.ctx.setTransform(1, 0, 0, 1, 0, 0);
- // 绘制网格
- this.ctx.strokeStyle = 'rgba(200, 200, 200, 0.3)';
- this.ctx.lineWidth = 1;
+ // // 绘制网格
+ // this.ctx.strokeStyle = 'rgba(200, 200, 200, 0.3)';
+ // this.ctx.lineWidth = 1;
- // 横向线
- for (let y = 0; y <= height; y += 50) {
- this.ctx.beginPath();
- this.ctx.moveTo(0, y);
- this.ctx.lineTo(width, y);
- this.ctx.stroke();
- }
+ // // 横向线
+ // for (let y = 0; y <= height; y += 50) {
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(0, y);
+ // this.ctx.lineTo(width, y);
+ // this.ctx.stroke();
+ // }
- // 纵向线
- for (let x = 0; x <= width; x += 50) {
- this.ctx.beginPath();
- this.ctx.moveTo(x, 0);
- this.ctx.lineTo(x, height);
- this.ctx.stroke();
- }
+ // // 纵向线
+ // for (let x = 0; x <= width; x += 50) {
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(x, 0);
+ // this.ctx.lineTo(x, height);
+ // this.ctx.stroke();
+ // }
- // 绘制坐标轴
- this.ctx.strokeStyle = '#ff0000';
- this.ctx.lineWidth = 2;
- this.ctx.beginPath();
- this.ctx.moveTo(0, 0);
- this.ctx.lineTo(width, 0);
- this.ctx.stroke();
+ // // 绘制坐标轴
+ // this.ctx.strokeStyle = '#ff0000';
+ // this.ctx.lineWidth = 2;
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(0, 0);
+ // this.ctx.lineTo(width, 0);
+ // this.ctx.stroke();
- this.ctx.beginPath();
- this.ctx.moveTo(0, 0);
- this.ctx.lineTo(0, height);
- this.ctx.stroke();
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(0, 0);
+ // this.ctx.lineTo(0, height);
+ // this.ctx.stroke();
- // 恢复之前的状态
- this.ctx.restore();
+ // // 恢复之前的状态
+ // this.ctx.restore();
- this.ctx.draw();
- },
+ // this.ctx.draw();
+ // },
// 绘制主内容
draw() {
diff --git a/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-canvas-page.js.map b/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-canvas-page.js.map
index aa8200a..7c78ca3 100644
--- a/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-canvas-page.js.map
+++ b/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-canvas-page.js.map
@@ -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;"}
\ No newline at end of file
+{"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;"}
\ No newline at end of file
diff --git a/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-handler.js.map b/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-handler.js.map
index 39c7d67..30e4872 100644
--- a/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-handler.js.map
+++ b/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/gesture-handler.js.map
@@ -1 +1 @@
-{"version":3,"file":"gesture-handler.js","sources":["pages/index/gesture-handler.js"],"sourcesContent":["import AnyTouch from 'any-touch'\n\nclass GestureHandler {\n constructor(context, transformMatrix, { container }) {\n this.transformMatrix = transformMatrix;\n this.containerRect = container;\n \n // 小程序环境兼容处理\n const atOptions = {\n getPoint: touch => ({\n x: touch.clientX - this.containerRect.left,\n y: touch.clientY - this.containerRect.top\n }),\n preventDefault: false\n };\n \n // 小程序特化处理 - 跳过DOM相关操作\n if (typeof window === 'undefined' || typeof HTMLElement === 'undefined') {\n // 小程序环境下不需要设置DOM属性\n atOptions._element = { \n style: {},\n addEventListener: () => {},\n removeEventListener: () => {}\n };\n }\n \n try {\n this.at = new AnyTouch(atOptions);\n } catch (e) {\n console.error('AnyTouch初始化失败:', e);\n // 降级方案:在小程序环境实现基本手势\n this.handleGesture = this.createSimpleGestureHandler();\n }\n \n if (this.at) {\n this.setupGestures();\n console.log('AnyTouch手势处理器已初始化');\n } else {\n console.warn('使用简化手势处理器');\n }\n }\n \n // 创建小程序专用的简化手势处理器\n createSimpleGestureHandler() {\n return {\n run: (event) => {\n // 小程序环境下的基本手势实现\n const touches = event.touches || [];\n \n if (touches.length === 1) {\n // 单指移动\n this.handlePan(touches[0]);\n } else if (touches.length > 1) {\n // 双指缩放\n this.handlePinch(touches);\n }\n }\n };\n }\n \n setupGestures() {\n // 平移手势 - 修复版本\n this.at.on('pan', (event) => {\n if (event.type === 'panstart') {\n console.log('panstart', event);\n }\n else if (event.type === 'panmove') {\n // 关键修复:基于当前缩放比例修正移动量\n const currentScale = Math.sqrt(\n this.transformMatrix.a * this.transformMatrix.a +\n this.transformMatrix.b * this.transformMatrix.b\n );\n \n // 逆缩放移动量\n const dx = event.deltaX / currentScale;\n const dy = event.deltaY / currentScale;\n \n console.log(`平移: deltaX=${event.deltaX}, deltaY=${event.deltaY} | 修正后: dx=${dx}, dy=${dy}`);\n \n this.transformMatrix.translate(dx, dy);\n }\n });\n \n // 缩放手势 - 修复版本\n this.at.on('pinch', (event) => {\n if (event.type === 'pinchstart') {\n this.lastScale = 1;\n }\n else if (event.type === 'pinchmove') {\n // 计算缩放变化量\n const scaleChange = event.scale / this.lastScale;\n this.lastScale = event.scale;\n \n // 使用两指中心点\n const centerX = event.center.x;\n const centerY = event.center.y;\n \n console.log(`缩放: scale=${event.scale} | 变化=${scaleChange} | 中心点: (${centerX}, ${centerY})`);\n \n // 应用缩放\n this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);\n }\n });\n \n // 点击手势\n this.at.on('tap', (event) => {\n console.log('点击事件', event);\n });\n \n // 长按手势\n this.at.on('press', (event) => {\n console.log('长按事件', event);\n });\n }\n \n \n catchEvent(event) {\n try {\n if (this.at) {\n this.at.run(event);\n } else if (this.handleGesture) {\n this.handleGesture.run(event);\n }\n } catch (e) {\n console.error('手势处理错误:', e);\n // 降级处理\n const touches = event.touches || [];\n if (touches.length > 0) {\n this.handlePan(touches[0]);\n }\n }\n }\n \n // 基础平移手势处理\n handlePan(touch) {\n if (this.lastPoint) {\n const dx = touch.clientX - this.lastPoint.x;\n const dy = touch.clientY - this.lastPoint.y;\n \n // 根据当前缩放比例修正移动量\n const currentScale = Math.sqrt(\n this.transformMatrix.a * this.transformMatrix.a +\n this.transformMatrix.b * this.transformMatrix.b\n );\n \n const correctedDx = dx / currentScale;\n const correctedDy = dy / currentScale;\n \n this.transformMatrix.translate(correctedDx, correctedDy);\n }\n this.lastPoint = {x: touch.clientX, y: touch.clientY};\n }\n \n // 基础缩放手势处理\n handlePinch(touches) {\n const point1 = touches[0];\n const point2 = touches[1];\n \n if (this.lastPoints) {\n // 计算当前距离\n const currentDistance = Math.sqrt(\n Math.pow(point2.clientX - point1.clientX, 2) + \n Math.pow(point2.clientY - point1.clientY, 2)\n );\n \n // 上次距离\n const prevDistance = Math.sqrt(\n Math.pow(this.lastPoints[1].x - this.lastPoints[0].x, 2) + \n Math.pow(this.lastPoints[1].y - this.lastPoints[0].y, 2)\n );\n \n // 缩放比例\n if (prevDistance > 0) {\n const scaleChange = currentDistance / prevDistance;\n \n // 计算中心点\n const centerX = (point1.clientX + point2.clientX) / 2 - this.containerRect.left;\n const centerY = (point1.clientY + point2.clientY) / 2 - this.containerRect.top;\n \n this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);\n }\n }\n \n this.lastPoints = [\n {x: point1.clientX, y: point1.clientY},\n {x: point2.clientX, y: point2.clientY}\n ];\n }\n}\n\nexport default GestureHandler;"],"names":["AnyTouch","uni"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"gesture-handler.js","sources":["pages/index/gesture-handler.js"],"sourcesContent":["import AnyTouch from 'any-touch'\n\nclass GestureHandler {\n constructor(context, transformMatrix, { container }) {\n this.transformMatrix = transformMatrix;\n this.containerRect = container;\n\t\tthis.panThreshold = 5; // 移动5像素以上才认为是拖动\n\t\tthis.panStarted = false;\n \n // 小程序环境兼容处理\n const atOptions = {\n getPoint: touch => ({\n x: touch.clientX - this.containerRect.left,\n y: touch.clientY - this.containerRect.top\n }),\n preventDefault: false\n };\n \n // 小程序特化处理 - 跳过DOM相关操作\n if (typeof window === 'undefined' || typeof HTMLElement === 'undefined') {\n // 小程序环境下不需要设置DOM属性\n atOptions._element = { \n style: {},\n addEventListener: () => {},\n removeEventListener: () => {}\n };\n }\n \n try {\n this.at = new AnyTouch(atOptions);\n } catch (e) {\n console.error('AnyTouch初始化失败:', e);\n // 降级方案:在小程序环境实现基本手势\n this.handleGesture = this.createSimpleGestureHandler();\n }\n \n if (this.at) {\n this.setupGestures();\n console.log('AnyTouch手势处理器已初始化');\n } else {\n console.warn('使用简化手势处理器');\n }\n }\n \n // 创建小程序专用的简化手势处理器\n createSimpleGestureHandler() {\n return {\n run: (event) => {\n // 小程序环境下的基本手势实现\n const touches = event.touches || [];\n \n if (touches.length === 1) {\n // 单指移动\n this._handlePan(touches[0]);\n } else if (touches.length > 1) {\n // 双指缩放\n this._handlePinch(touches);\n }\n }\n };\n }\n \n setupGestures() {\n // 平移手势 - 修复版本\n this.at.on('pan', (event) => {\n if (event.type === 'panstart') {\n console.log('panstart', event);\n\t\t\t\t// 重置移动开始状态\n\t\t\t\tthis.panStarted = false;\n }\n else if (event.type === 'panmove') {\n\t\t\t\t// 检查是否超过阈值\n\t\t\t\tconst distance = Math.sqrt(event.deltaX**2 + event.deltaY**2);\n\t\t\t\t\n\t\t\t\tif (!this.panStarted && distance < this.panThreshold) {\n\t\t\t\t\treturn; // 小于阈值不处理\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (!this.panStarted) {\n\t\t\t\t\tconsole.log('拖动手势开始');\n\t\t\t\t\tthis.panStarted = true;\n\t\t\t\t}\n\t\t\t\t\n // 基于当前缩放比例修正移动量\n const currentScale = Math.sqrt(\n this.transformMatrix.a * this.transformMatrix.a +\n this.transformMatrix.b * this.transformMatrix.b\n );\n \n // 逆缩放移动量\n const dx = event.deltaX / currentScale;\n const dy = event.deltaY / currentScale;\n \n\t\t\t\t\n console.log(`平移: deltaX=${event.deltaX}, deltaY=${event.deltaY} | 修正后: dx=${dx}, dy=${dy}`);\n \n this.transformMatrix.translate(dx, dy);\n } else if (event.type === 'panend') {\n this.panStarted = false;\n }\n });\n \n // 缩放手势 - 修复版本\n this.at.on('pinch', (event) => {\n if (event.type === 'pinchstart') {\n this.lastScale = 1;\n }\n else if (event.type === 'pinchmove') {\n // 计算缩放变化量\n const scaleChange = event.scale / this.lastScale;\n this.lastScale = event.scale;\n \n // 使用两指中心点\n const centerX = event.center.x;\n const centerY = event.center.y;\n \n console.log(`缩放: scale=${event.scale} | 变化=${scaleChange} | 中心点: (${centerX}, ${centerY})`);\n \n // 应用缩放\n this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);\n }\n });\n \n // 点击手势\n this.at.on('tap', (event) => {\n console.log('点击事件', event);\n });\n \n // 长按手势\n this.at.on('press', (event) => {\n console.log('长按事件', event);\n });\n }\n \n \n // 公共接口保持不变\n catchEvent(event) {\n try {\n if (this.at) {\n this.at.run(event);\n } else {\n // 内部处理降级方案\n const touches = event.touches || [];\n const eventType = event.type;\n \n // 在事件开始时重置状态\n if (eventType === 'touchstart') {\n this.lastPoint = null;\n this.lastPoints = null;\n this.lastDistance = null;\n }\n \n // 处理不同数量的手指\n if (touches.length === 1) {\n this._handlePan(touches[0]);\n } else if (touches.length > 1) {\n this._handlePinch(touches);\n }\n }\n } catch (e) {\n console.error('手势处理错误:', e);\n }\n }\n // 基础平移手势处理\n _handlePan(touch) {\n const pointX = touch.x || (touch.clientX - this.containerRect.left);\n\t\tconst pointY = touch.y || (touch.clientY - this.containerRect.top);\n\t\n\t\tif (this.lastPoint) {\n\t\t\t// 基于容器坐标系的增量计算\n\t\t\tconst dx = pointX - this.lastPoint.x;\n\t\t\tconst dy = pointY - this.lastPoint.y;\n\t\t\t\n\t\t\t// 使用真实增量,不需要缩放修正\n\t\t\tthis.transformMatrix.translate(dx, dy);\n\t\t}\n\t\t\n\t\t// 存储当前点 (容器坐标系)\n\t\tthis.lastPoint = {x: pointX, y: pointY};\n }\n \n // 基础缩放手势处理\n _handlePinch(touches) {\n const point1 = touches[0];\n\t\tconst point2 = touches[1];\n\t\t\n\t\t// 获取容器坐标系坐标\n\t\tconst getPoint = (touch) => ({\n\t\t\tx: touch.x || (touch.clientX - this.containerRect.left),\n\t\t\ty: touch.y || (touch.clientY - this.containerRect.top)\n\t\t});\n\t\t\n\t\tconst currentPoints = [getPoint(point1), getPoint(point2)];\n\t\t\n\t\tif (this.lastPoints) {\n\t\t\t// 计算当前距离 (容器坐标系)\n\t\t\tconst currentDistance = Math.sqrt(\n\t\t\t\tMath.pow(currentPoints[1].x - currentPoints[0].x, 2) + \n\t\t\t\tMath.pow(currentPoints[1].y - currentPoints[0].y, 2)\n\t\t\t);\n\t\t\t\n\t\t\t// 上次距离 (容器坐标系)\n\t\t\tconst prevDistance = Math.sqrt(\n\t\t\t\tMath.pow(this.lastPoints[1].x - this.lastPoints[0].x, 2) + \n\t\t\t\tMath.pow(this.lastPoints[1].y - this.lastPoints[0].y, 2)\n\t\t\t);\n\t\t\t\n\t\t\t// 缩放比例\n\t\t\tif (prevDistance > 0 && currentDistance > 0) {\n\t\t\t\tconst scaleChange = currentDistance / prevDistance;\n\t\t\t\t\n\t\t\t\t// 计算中心点 (容器坐标系)\n\t\t\t\tconst centerX = (currentPoints[0].x + currentPoints[1].x) / 2;\n\t\t\t\tconst centerY = (currentPoints[0].y + currentPoints[1].y) / 2;\n\t\t\t\t\n\t\t\t\tthis.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// 存储当前点\n\t\tthis.lastPoints = currentPoints;\n }\n}\n\nexport default GestureHandler;"],"names":["AnyTouch","uni"],"mappings":"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"}
\ No newline at end of file
diff --git a/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/transform-canvas.js.map b/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/transform-canvas.js.map
index 45ceeef..3a41822 100644
--- a/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/transform-canvas.js.map
+++ b/unpackage/dist/dev/.sourcemap/mp-weixin/pages/index/transform-canvas.js.map
@@ -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;"}
\ No newline at end of file
+{"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;"}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/common/vendor.js b/unpackage/dist/dev/mp-weixin/common/vendor.js
index 1d49d33..def1e28 100644
--- a/unpackage/dist/dev/mp-weixin/common/vendor.js
+++ b/unpackage/dist/dev/mp-weixin/common/vendor.js
@@ -6882,7 +6882,7 @@ function initOnError() {
function initRuntimeSocketService() {
const hosts = "127.0.0.1,172.10.0.205";
const port = "8090";
- const id = "mp-weixin_j4oiF-";
+ const id = "mp-weixin_aMdMwA";
const lazy = typeof swan !== "undefined";
let restoreError = lazy ? () => {
} : initOnError();
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.js b/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.js
index 91dea19..af6efec 100644
--- a/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.js
+++ b/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.js
@@ -35,17 +35,20 @@ const _sfc_main = {
container: this.containerRect
});
} catch (e) {
- common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:77", "手势处理器初始化失败:", e);
+ common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:76", "手势处理器初始化失败:", e);
this.gestureHandler = {
catchEvent: (event) => {
- const touches = event.touches || [];
- if (touches.length > 0) {
- const point = touches[0];
- const x = point.clientX - this.containerRect.left;
- const y = point.clientY - this.containerRect.top;
- this.transformMatrix.tx = x - 50;
- this.transformMatrix.ty = y - 50;
- this.updateCanvas();
+ if (event.touches.length > 0) {
+ const firstTouch = event.touches[0];
+ const x = firstTouch.clientX - this.containerRect.left;
+ const y = firstTouch.clientY - this.containerRect.top;
+ this.gestureStatus = "降级模式: 单指拖动";
+ this.touchPoints = event.touches.length;
+ if (event.type === "touchmove") {
+ this.transformMatrix.tx = x;
+ this.transformMatrix.ty = y;
+ this.updateCanvas();
+ }
}
}
};
@@ -69,26 +72,40 @@ const _sfc_main = {
width: rect.width,
height: rect.height
};
- common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:119", "成功获取容器位置:", this.containerRect);
+ common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:123", "成功获取容器位置:", this.containerRect);
return;
}
} catch (e) {
- common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:123", "获取容器位置失败:", e);
+ common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:127", "获取容器位置失败:", e);
}
await new Promise((r) => setTimeout(r, 100));
retryCount++;
}
- common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:131", `容器位置获取失败,已重试${maxRetries}次`);
+ common_vendor.index.__f__("error", "at pages/index/gesture-canvas-page.vue:135", `容器位置获取失败,已重试${maxRetries}次`);
},
- // 事件处理(完整修复)
+ // 事件处理
async handleTouchEvent(event) {
if (!this.gestureHandler || !this.containerRect) {
- common_vendor.index.__f__("warn", "at pages/index/gesture-canvas-page.vue:137", "手势处理器未就绪,尝试重新初始化...");
+ common_vendor.index.__f__("warn", "at pages/index/gesture-canvas-page.vue:141", "手势处理器未就绪,尝试重新初始化...");
await this.getContainerPosition();
this.initGestureHandler();
+ if (event.type === "touchend" || event.type === "touchcancel") {
+ this.lastPoint = null;
+ this.lastPoints = null;
+ this.gestureStatus = "结束";
+ this.updateCanvas();
+ return;
+ }
if (this.gestureHandler) {
return this.handleTouchEvent(event);
}
+ if (!this.at) {
+ if (correctedEvent.touches.length === 1) {
+ this.handlePan(correctedEvent.touches[0]);
+ } else if (correctedEvent.touches.length > 1) {
+ this.handlePinch(correctedEvent.touches);
+ }
+ }
return;
}
const currentTime = Date.now();
@@ -96,7 +113,7 @@ const _sfc_main = {
const correctedTouches = Array.from(event.touches).map((touch) => {
const x = touch.clientX - this.containerRect.left;
const y = touch.clientY - this.containerRect.top;
- common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:160", `原始坐标: (${touch.clientX}, ${touch.clientY}) 修正后: (${x}, ${y})`);
+ common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:181", `原始坐标: (${touch.clientX}, ${touch.clientY}) 修正后: (${x}, ${y})`);
return {
...touch,
x,
@@ -149,14 +166,6 @@ const _sfc_main = {
zoomOut() {
this.transformMatrix.scale(0.8, 0.8, this.canvasWidth / 2, this.canvasHeight / 2);
this.updateCanvas();
- },
- // 调试输出
- logMatrix() {
- common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:235", "当前变换矩阵:", this.transformMatrix.toArray());
- common_vendor.index.__f__("log", "at pages/index/gesture-canvas-page.vue:236", "容器位置:", this.containerRect);
- if (this.$refs.canvasRef) {
- this.$refs.canvasRef.drawDebugGrid();
- }
}
}
};
@@ -183,8 +192,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
k: common_vendor.o((...args) => $options.handleTouchEvent && $options.handleTouchEvent(...args)),
l: common_vendor.o((...args) => $options.resetCanvas && $options.resetCanvas(...args)),
m: common_vendor.o((...args) => $options.zoomIn && $options.zoomIn(...args)),
- n: common_vendor.o((...args) => $options.zoomOut && $options.zoomOut(...args)),
- o: common_vendor.o((...args) => $options.logMatrix && $options.logMatrix(...args))
+ n: common_vendor.o((...args) => $options.zoomOut && $options.zoomOut(...args))
};
}
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-2e633000"]]);
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.wxml b/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.wxml
index 6d4fa6d..f0ddf49 100644
--- a/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.wxml
+++ b/unpackage/dist/dev/mp-weixin/pages/index/gesture-canvas-page.wxml
@@ -1 +1 @@
-缩放: {{a}} | X: {{b}} | Y: {{c}}手势: {{d}}触点: {{e}}
\ No newline at end of file
+缩放: {{a}} | X: {{b}} | Y: {{c}}手势: {{d}}触点: {{e}}
\ No newline at end of file
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/gesture-handler.js b/unpackage/dist/dev/mp-weixin/pages/index/gesture-handler.js
index c5990e3..1615762 100644
--- a/unpackage/dist/dev/mp-weixin/pages/index/gesture-handler.js
+++ b/unpackage/dist/dev/mp-weixin/pages/index/gesture-handler.js
@@ -4,6 +4,8 @@ class GestureHandler {
constructor(context, transformMatrix, { container }) {
this.transformMatrix = transformMatrix;
this.containerRect = container;
+ this.panThreshold = 5;
+ this.panStarted = false;
const atOptions = {
getPoint: (touch) => ({
x: touch.clientX - this.containerRect.left,
@@ -23,14 +25,14 @@ class GestureHandler {
try {
this.at = new common_vendor.i(atOptions);
} catch (e) {
- common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:30", "AnyTouch初始化失败:", e);
+ common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:32", "AnyTouch初始化失败:", e);
this.handleGesture = this.createSimpleGestureHandler();
}
if (this.at) {
this.setupGestures();
- common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:37", "AnyTouch手势处理器已初始化");
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:39", "AnyTouch手势处理器已初始化");
} else {
- common_vendor.index.__f__("warn", "at pages/index/gesture-handler.js:39", "使用简化手势处理器");
+ common_vendor.index.__f__("warn", "at pages/index/gesture-handler.js:41", "使用简化手势处理器");
}
}
// 创建小程序专用的简化手势处理器
@@ -39,9 +41,9 @@ class GestureHandler {
run: (event) => {
const touches = event.touches || [];
if (touches.length === 1) {
- this.handlePan(touches[0]);
+ this._handlePan(touches[0]);
} else if (touches.length > 1) {
- this.handlePinch(touches);
+ this._handlePinch(touches);
}
}
};
@@ -49,15 +51,26 @@ class GestureHandler {
setupGestures() {
this.at.on("pan", (event) => {
if (event.type === "panstart") {
- common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:65", "panstart", event);
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:67", "panstart", event);
+ this.panStarted = false;
} else if (event.type === "panmove") {
+ const distance = Math.sqrt(event.deltaX ** 2 + event.deltaY ** 2);
+ if (!this.panStarted && distance < this.panThreshold) {
+ return;
+ }
+ if (!this.panStarted) {
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:80", "拖动手势开始");
+ this.panStarted = true;
+ }
const currentScale = Math.sqrt(
this.transformMatrix.a * this.transformMatrix.a + this.transformMatrix.b * this.transformMatrix.b
);
const dx = event.deltaX / currentScale;
const dy = event.deltaY / currentScale;
- common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:78", `平移: deltaX=${event.deltaX}, deltaY=${event.deltaY} | 修正后: dx=${dx}, dy=${dy}`);
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:95", `平移: deltaX=${event.deltaX}, deltaY=${event.deltaY} | 修正后: dx=${dx}, dy=${dy}`);
this.transformMatrix.translate(dx, dy);
+ } else if (event.type === "panend") {
+ this.panStarted = false;
}
});
this.at.on("pinch", (event) => {
@@ -68,68 +81,75 @@ class GestureHandler {
this.lastScale = event.scale;
const centerX = event.center.x;
const centerY = event.center.y;
- common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:98", `缩放: scale=${event.scale} | 变化=${scaleChange} | 中心点: (${centerX}, ${centerY})`);
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:117", `缩放: scale=${event.scale} | 变化=${scaleChange} | 中心点: (${centerX}, ${centerY})`);
this.transformMatrix.scale(scaleChange, scaleChange, centerX, centerY);
}
});
this.at.on("tap", (event) => {
- common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:107", "点击事件", event);
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:126", "点击事件", event);
});
this.at.on("press", (event) => {
- common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:112", "长按事件", event);
+ common_vendor.index.__f__("log", "at pages/index/gesture-handler.js:131", "长按事件", event);
});
}
+ // 公共接口保持不变
catchEvent(event) {
try {
if (this.at) {
this.at.run(event);
- } else if (this.handleGesture) {
- this.handleGesture.run(event);
+ } else {
+ const touches = event.touches || [];
+ const eventType = event.type;
+ if (eventType === "touchstart") {
+ this.lastPoint = null;
+ this.lastPoints = null;
+ this.lastDistance = null;
+ }
+ if (touches.length === 1) {
+ this._handlePan(touches[0]);
+ } else if (touches.length > 1) {
+ this._handlePinch(touches);
+ }
}
} catch (e) {
- common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:125", "手势处理错误:", e);
- const touches = event.touches || [];
- if (touches.length > 0) {
- this.handlePan(touches[0]);
- }
+ common_vendor.index.__f__("error", "at pages/index/gesture-handler.js:161", "手势处理错误:", e);
}
}
// 基础平移手势处理
- handlePan(touch) {
+ _handlePan(touch) {
+ const pointX = touch.x || touch.clientX - this.containerRect.left;
+ const pointY = touch.y || touch.clientY - this.containerRect.top;
if (this.lastPoint) {
- const dx = touch.clientX - this.lastPoint.x;
- const dy = touch.clientY - this.lastPoint.y;
- const currentScale = Math.sqrt(
- this.transformMatrix.a * this.transformMatrix.a + this.transformMatrix.b * this.transformMatrix.b
- );
- const correctedDx = dx / currentScale;
- const correctedDy = dy / currentScale;
- this.transformMatrix.translate(correctedDx, correctedDy);
+ const dx = pointX - this.lastPoint.x;
+ const dy = pointY - this.lastPoint.y;
+ this.transformMatrix.translate(dx, dy);
}
- this.lastPoint = { x: touch.clientX, y: touch.clientY };
+ this.lastPoint = { x: pointX, y: pointY };
}
// 基础缩放手势处理
- handlePinch(touches) {
+ _handlePinch(touches) {
const point1 = touches[0];
const point2 = touches[1];
+ const getPoint = (touch) => ({
+ x: touch.x || touch.clientX - this.containerRect.left,
+ y: touch.y || touch.clientY - this.containerRect.top
+ });
+ const currentPoints = [getPoint(point1), getPoint(point2)];
if (this.lastPoints) {
const currentDistance = Math.sqrt(
- Math.pow(point2.clientX - point1.clientX, 2) + Math.pow(point2.clientY - point1.clientY, 2)
+ 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) {
+ if (prevDistance > 0 && currentDistance > 0) {
const scaleChange = currentDistance / prevDistance;
- const centerX = (point1.clientX + point2.clientX) / 2 - this.containerRect.left;
- const centerY = (point1.clientY + point2.clientY) / 2 - this.containerRect.top;
+ 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 = [
- { x: point1.clientX, y: point1.clientY },
- { x: point2.clientX, y: point2.clientY }
- ];
+ this.lastPoints = currentPoints;
}
}
exports.GestureHandler = GestureHandler;
diff --git a/unpackage/dist/dev/mp-weixin/pages/index/transform-canvas.js b/unpackage/dist/dev/mp-weixin/pages/index/transform-canvas.js
index 52b6961..778f5c0 100644
--- a/unpackage/dist/dev/mp-weixin/pages/index/transform-canvas.js
+++ b/unpackage/dist/dev/mp-weixin/pages/index/transform-canvas.js
@@ -38,41 +38,47 @@ const _sfc_main = {
);
},
// 调试网格
- drawDebugGrid() {
- if (!this.ctx)
- return;
- const pixelRatio = common_vendor.index.getSystemInfoSync().pixelRatio;
- const width = this.canvasWidth * pixelRatio;
- const height = this.canvasHeight * pixelRatio;
- this.ctx.save();
- this.ctx.setTransform(1, 0, 0, 1, 0, 0);
- this.ctx.strokeStyle = "rgba(200, 200, 200, 0.3)";
- this.ctx.lineWidth = 1;
- for (let y = 0; y <= height; y += 50) {
- this.ctx.beginPath();
- this.ctx.moveTo(0, y);
- this.ctx.lineTo(width, y);
- this.ctx.stroke();
- }
- for (let x = 0; x <= width; x += 50) {
- this.ctx.beginPath();
- this.ctx.moveTo(x, 0);
- this.ctx.lineTo(x, height);
- this.ctx.stroke();
- }
- this.ctx.strokeStyle = "#ff0000";
- this.ctx.lineWidth = 2;
- this.ctx.beginPath();
- this.ctx.moveTo(0, 0);
- this.ctx.lineTo(width, 0);
- this.ctx.stroke();
- this.ctx.beginPath();
- this.ctx.moveTo(0, 0);
- this.ctx.lineTo(0, height);
- this.ctx.stroke();
- this.ctx.restore();
- this.ctx.draw();
- },
+ // drawDebugGrid() {
+ // if (!this.ctx) return;
+ // const pixelRatio = uni.getSystemInfoSync().pixelRatio;
+ // const width = this.canvasWidth * pixelRatio;
+ // const height = this.canvasHeight * pixelRatio;
+ // // 保存当前状态
+ // this.ctx.save();
+ // // 重置变换
+ // this.ctx.setTransform(1, 0, 0, 1, 0, 0);
+ // // 绘制网格
+ // this.ctx.strokeStyle = 'rgba(200, 200, 200, 0.3)';
+ // this.ctx.lineWidth = 1;
+ // // 横向线
+ // for (let y = 0; y <= height; y += 50) {
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(0, y);
+ // this.ctx.lineTo(width, y);
+ // this.ctx.stroke();
+ // }
+ // // 纵向线
+ // for (let x = 0; x <= width; x += 50) {
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(x, 0);
+ // this.ctx.lineTo(x, height);
+ // this.ctx.stroke();
+ // }
+ // // 绘制坐标轴
+ // this.ctx.strokeStyle = '#ff0000';
+ // this.ctx.lineWidth = 2;
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(0, 0);
+ // this.ctx.lineTo(width, 0);
+ // this.ctx.stroke();
+ // this.ctx.beginPath();
+ // this.ctx.moveTo(0, 0);
+ // this.ctx.lineTo(0, height);
+ // this.ctx.stroke();
+ // // 恢复之前的状态
+ // this.ctx.restore();
+ // this.ctx.draw();
+ // },
// 绘制主内容
draw() {
if (!this.ctx) {