拖动矩形可移动位置,拖动右下角正方形可改变矩形大小,效果如下:

完整的代码:
点击查看
我们以uniapp为例,uniapp可以导出小程序
<template>
<view>
<canvas canvas-id="myCanvas" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" style="width: 100%; height: 300px;"></canvas>
</view>
</template>
<script>
export default {
data() {
return {
ctx: null,
rect: {
x: 50,
y: 50,
width: 100,
height: 80
},
isDragging: false,
isResizing: false,
lastX: 0,
lastY: 0,
resizeHandleSize: 20, // 增大调整大小的触控范围
}
},
onReady() {
this.ctx = uni.createCanvasContext('myCanvas')
this.drawRect()
},
methods: {
drawRect() {
this.ctx.clearRect(0, 0, 300, 150)
// 绘制主矩形
this.ctx.beginPath()
this.ctx.rect(this.rect.x, this.rect.y, this.rect.width, this.rect.height)
this.ctx.stroke()
// 绘制右下角的调整大小标识
this.drawResizeHandle()
this.ctx.draw()
},
drawResizeHandle() {
const x = this.rect.x + this.rect.width
const y = this.rect.y + this.rect.height
// 绘制一个小正方形作为调整大小的标识
this.ctx.fillStyle = 'blue'
this.ctx.fillRect(x - 10, y - 10, 10, 10)
// 绘制两条线来增强视觉效果
this.ctx.beginPath()
this.ctx.moveTo(x - 15, y)
this.ctx.lineTo(x, y)
this.ctx.moveTo(x, y - 15)
this.ctx.lineTo(x, y)
this.ctx.strokeStyle = 'blue'
this.ctx.stroke()
},
touchStart(e) {
const touch = e.touches[0]
this.lastX = touch.x
this.lastY = touch.y
// 检查是否在右下角的调整大小区域
if (this.isInResizeHandle(touch.x, touch.y)) {
this.isResizing = true
}
// 检查是否在矩形内部
else if (this.isInRect(touch.x, touch.y)) {
this.isDragging = true
}
},
touchMove(e) {
const touch = e.touches[0]
const dx = touch.x - this.lastX
const dy = touch.y - this.lastY
if (this.isDragging) {
this.rect.x += dx
this.rect.y += dy
} else if (this.isResizing) {
this.rect.width += dx
this.rect.height += dy
// 确保矩形不会变得太小
if (this.rect.width < 20) this.rect.width = 20
if (this.rect.height < 20) this.rect.height = 20
}
this.lastX = touch.x
this.lastY = touch.y
this.drawRect()
},
touchEnd() {
this.isDragging = false
this.isResizing = false
},
isInResizeHandle(x, y) {
const handleX = this.rect.x + this.rect.width
const handleY = this.rect.y + this.rect.height
return (x >= handleX - this.resizeHandleSize && x <= handleX &&
y >= handleY - this.resizeHandleSize && y <= handleY)
},
isInRect(x, y) {
return (x >= this.rect.x && x <= this.rect.x + this.rect.width &&
y >= this.rect.y && y <= this.rect.y + this.rect.height)
}
}
}
</script> 网友回复
如何破解绕开seedance2.0真人照片生成视频 限制?
python有哪些算法可以将视频中的每个帧图片去除指定区域水印合成新的视频?
iphone的激光雷达数据能否实时传输到three三维空间中?
豆包sora等ai视频生成大模型生成的视频水印如何去除?
python如何实现在电脑上拨号打电话给手机?
具身机器人与人形机器人区别?
nodejs如何将一个完整的js代码文件切割成不同的部分混淆后动态加载进入html运行?
为啥windows.onerror捕获js错误是这样的{"message":"Script error.","source":"","lineno":0,"colno":0,"stack":null,
2026年ai将全面接管编程?
WebMCP是干啥的?


