uniapp中canvas实现拖拽
时间: 2025-06-06 17:39:45 浏览: 22
### 实现 UniApp 中 Canvas 的拖拽功能
在 UniApp 中实现 Canvas 上元素的拖拽效果涉及多个方面,包括触摸事件监听、坐标转换以及状态管理。以下是详细的实现方案:
#### 1. 初始化 Canvas 和上下文对象
为了能够在 Canvas 上绘制图形并对其进行操作,首先要获取到 Canvas 组件及其对应的绘图上下文。
```javascript
const query = uni.createSelectorQuery();
let canvasContext;
query.select('#myCanvas').fields({ node: true, size: true }).exec((res) => {
const canvas = res[0].node;
canvas.width = res[0].width * (750 / uni.getSystemInfoSync().windowWidth);
canvas.height = res[0].height * (750 / uni.getSystemInfoSync().windowHeight);
canvasContext = canvas.getContext('2d');
});
```
此部分代码用于初始化 Canvas 并设置其尺寸以适应屏幕比例[^2]。
#### 2. 定义触控交互逻辑
通过绑定 `touchstart`、`touchmove` 及 `touchend` 三个主要事件来捕捉用户的输入行为,并据此更新被选中物体的位置属性。
```html
<template>
<view @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd">
<!-- ... -->
</view>
</template>
<script>
export default {
data() {
return {
draggingItemIndex: null,
startX: 0,
startY: 0,
currentX: 0,
currentY: 0,
itemsPosition: []
};
},
methods: {
handleTouchStart(event){
let touchPoint = event.touches[0];
this.startX = touchPoint.clientX;
this.startY = touchPoint.clientY;
// 判断点击位置是否位于某个 item 内部
for(let i=items.length-1; i>=0 ;i--){
if(isInside(touchPoint.clientX,touchPoint.clientY,i)){
this.draggingItemIndex=i;
break;
}
}
},
handleTouchMove(event){
if(this.draggingItemIndex !== null){
let movedPoint=event.changedTouches[0];
this.currentX=movedPoint.clientX-this.startX+this.itemsPosition[this.draggingItemIndex][0];
this.currentY=movedPoint.clientY-this.startY+this.itemsPosition[this.draggingItemIndex][1];
drawItems(); // 更新画布显示
this.startX=movedPoint.clientX;
this.startY=movedPoint.clientY;
updatePositions(); // 记录新的位置数据
}
},
handleTouchEnd(){
this.draggingItemIndex=null;
}
}
</script>
```
上述 JavaScript 方法实现了基本的手势识别机制,当检测到有效接触点时启动拖曳过程,在移动过程中不断调整目标物品的新坐标直至释放手指结束整个流程[^3]。
#### 3. 坐标系变换与边界检查
考虑到设备差异可能导致的不同分辨率影响,需确保所有计算均基于标准化后的视窗空间内完成;同时为了避免越界情况发生,还需加入必要的范围限定措施。
```javascript
function normalizeCoordinate(rawCoord){
var systemInfo = wx.getSystemInfoSync();
return rawCoord*(750/systemInfo.windowWidth);
}
// 应用于每次修改 position 后...
if(normalizedNewPos>maxAllowedValue || normalizedNewPos<minAllowedValue){
// 调整至合法区间内
}
```
这里展示了如何将原始触摸坐标映射回统一的标准单位下进行后续运算,同时也给出了简单的溢出保护策略作为参考[^1]。
阅读全文
相关推荐


















