canvas/pages/index/transform-canvas.vue

154 lines
3.6 KiB
Vue

<template>
<canvas
canvas-id="gestureCanvas"
:style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }"
/>
</template>
<script>
export default {
props: {
width: Number,
height: Number,
matrix: Object
},
data() {
return {
ctx: null,
canvasWidth: this.width,
canvasHeight: this.height
};
},
mounted() {
this.initCanvas();
},
methods: {
initCanvas() {
this.ctx = uni.createCanvasContext('gestureCanvas', this);
const pixelRatio = uni.getSystemInfoSync().pixelRatio;
this.ctx.scale(pixelRatio, pixelRatio);
},
applyTransform(matrix) {
if (!matrix) return;
// 核心修复:考虑像素比的转换
const pixelRatio = uni.getSystemInfoSync().pixelRatio;
const tx = matrix.tx * pixelRatio;
const ty = matrix.ty * pixelRatio;
// 直接设置完整的变换矩阵
this.ctx.setTransform(
matrix.a,
matrix.b,
matrix.c,
matrix.d,
tx,
ty
);
},
// 调试网格
// 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) {
console.warn('Canvas上下文未初始化');
return;
}
// 1. 清除Canvas
this.clearCanvas();
// 2. 应用当前变换
this.applyTransform(this.matrix);
// 3. 绘制内容
this.drawContent();
},
clearCanvas() {
const pixelRatio = uni.getSystemInfoSync().pixelRatio;
const width = this.canvasWidth * pixelRatio;
const height = this.canvasHeight * pixelRatio;
// 重置变换
this.ctx.setTransform(1, 0, 0, 1, 0, 0);
this.ctx.clearRect(0, 0, width, height);
},
drawContent() {
// 绘制一个矩形和圆形
this.ctx.fillStyle = '#3498db';
this.ctx.fillRect(50, 50, 100, 100);
this.ctx.fillStyle = '#e74c3c';
this.ctx.beginPath();
this.ctx.arc(150, 150, 50, 0, 2 * Math.PI);
this.ctx.fill();
// 绘制一个文字
this.ctx.fillStyle = '#2c3e50';
this.ctx.font = '20px sans-serif';
this.ctx.fillText('手势Canvas', 50, 250);
// 执行绘制
this.ctx.draw();
}
}
};
</script>