uni-app中canvas的拖动事件是否存在bug?
uni-app中canvas的拖动事件是否存在bug?
代码如上,一个简单的canvas拖动图片的demo,在uniapp内置浏览器中点击图片,出现了2个奇怪的现象
- 没有拖动,也调用拖动的函数(如图1)
- 明明点击的位置在图片上,而图片的高度是100,得到的clientY=129,明显不对。(如图2)
该代码运行到微信小程序开发者工具,没有上面两个问题。运行改成PC模式也没有上面两个问题
图片
代码示例
<template>
<view class="container">
<canvas canvas-id="puzzleCanvas" @touchstart="handleStart" @touchmove="handleMove" @touchend="handleEnd"
@mousedown="handleStart" @mousemove="handleMove" @mouseup="handleEnd"></canvas>
</view>
</template>
<script>
export default {
data() {
return {
ctx: null,
pieces: [
{ x: 0, y: 0, width: 100, height: 100, image: '/static/p1.png' },
{ x: 100, y: 0, width: 100, height: 100, image: '/static/p2.png' },
// 更多拼块
],
currentPiece: null,
offsetX: 0,
offsetY: 0,
isDragging: false
};
},
mounted() {
const canvas = uni.createCanvasContext('puzzleCanvas', this);
this.ctx = canvas;
this.drawPieces();
},
methods: {
drawPieces() {
this.pieces.forEach(piece => {
const img = piece.image;
// 根据路径绘制图片
this.ctx.drawImage(img, piece.x, piece.y, piece.width, piece.height);
});
this.ctx.draw();
},
handleStart(event) {
this.$showlog("点击开始")
const point = this.getPoint(event);
this.currentPiece = this.pieces.find(piece => this.isPointInPiece(point, piece));
this.$showlog("currentPiece",this.currentPiece)
if (this.currentPiece) {
this.offsetX = point.x - this.currentPiece.x;
this.offsetY = point.y - this.currentPiece.y;
this.isDragging = true;
}
},
handleMove(event) {
this.$showlog("点击拖动")
if (this.isDragging && this.currentPiece) {
const point = this.getPoint(event);
this.currentPiece.x = point.x - this.offsetX;
this.currentPiece.y = point.y - this.offsetY;
this.redrawCanvas();
}
},
handleEnd(event) {
this.$showlog("点击结束")
this.isDragging = false;
this.currentPiece = null;
},
getPoint(event) {
this.$showlog("getPoint",event)
const touch = event.touches ? event.touches[0] : event;
return { x: touch.clientX, y: touch.clientY };
},
isPointInPiece(point, piece) {
return (
point.x > piece.x &&
point.x < piece.x + piece.width &&
point.y > piece.y &&
point.y < piece.y + piece.height
);
},
redrawCanvas() {
this.ctx.clearRect(0, 0, 750, 750); // 清空画布,750是canvas的宽度和高度
this.drawPieces();
}
}
}
</script>
<style>
.container {
/* position: relative; */
width: 750rpx;
height: 450rpx;
}
canvas {
width: 750rpx;
height: 450rpx;
background-color: #335566;
}
</style>
1 回复
在uni-app中,关于canvas的拖动事件是否存在bug,这通常取决于具体的实现方式和平台差异。为了帮助你更好地理解和排查可能的问题,下面提供一个基本的canvas拖动事件实现的代码案例。如果你遇到特定的问题,可以根据这个基础代码进行调整和测试。
首先,确保你的uni-app项目已经正确配置了canvas组件。以下是一个简单的canvas拖动事件的实现示例:
<template>
<view class="container">
<canvas
canvas-id="myCanvas"
style="width: 300px; height: 300px; border: 1px solid #000;"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@touchend="onTouchEnd"
></canvas>
</view>
</template>
<script>
export default {
data() {
return {
lastX: 0,
lastY: 0,
offsetX: 0,
offsetY: 0,
isDragging: false,
};
},
methods: {
onTouchStart(e) {
const touch = e.touches[0];
this.lastX = touch.clientX - this.offsetX;
this.lastY = touch.clientY - this.offsetY;
this.isDragging = true;
},
onTouchMove(e) {
if (!this.isDragging) return;
const touch = e.touches[0];
this.offsetX = touch.clientX - this.lastX;
this.offsetY = touch.clientY - this.lastY;
// 假设我们有一个矩形要拖动,这里更新它的位置
const ctx = uni.createCanvasContext('myCanvas');
ctx.clearRect(0, 0, 300, 300); // 清除画布
ctx.setFillStyle('red');
ctx.fillRect(this.offsetX, this.offsetY, 50, 50); // 绘制矩形
ctx.draw();
},
onTouchEnd() {
this.isDragging = false;
},
},
};
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
</style>
在这个示例中,我们使用了touchstart
、touchmove
和touchend
事件来处理canvas上的拖动操作。onTouchStart
方法记录触摸开始的位置,onTouchMove
方法根据触摸移动的位置更新canvas上的图形(在这个例子中是一个矩形),onTouchEnd
方法停止拖动。
请注意,这个示例假设你正在绘制一个简单的矩形,并且这个矩形可以拖动。如果你在实际应用中遇到更复杂的情况(比如多个图形的拖动、复杂的碰撞检测等),你可能需要更复杂的逻辑来处理。
如果你发现具体的bug或问题,建议查看uni-app的官方文档或社区论坛,看看是否有其他开发者遇到并解决了类似的问题。同时,确保你的uni-app和依赖库都是最新版本,以利用最新的功能和修复。