canvas中实现画布内元素的拖拽(下)
2023-12-14 17:37:25
在上篇实现基础上,实现仅能在画布区域内移动
const canvas = document.createElement('canvas')
canvas.width = 400
canvas.height = 400
canvas.id = 'canvas'
document.body.appendChild(canvas)
let ctx = canvas.getContext('2d') //画笔
// 状态标志
const statusConfig = {
IDLE: 0, //
DRAGSTART: 1, //鼠标按下
DRAGGING: 2 //托拽中
}
// 画布信息
const canvasInfo = {
status: statusConfig.IDLE, //状态
dragTarget: null, //拖拽对象
lastEvtPos: { //前一位置
x: null,
y: null
},
offsetEvtPos: { //前一偏移
x: null,
y: null
}
}
let circles = [] //存储画的圆
// 画圆
const drawCircle = (ctx, cx, cy, r) => {
ctx.save()
ctx.beginPath() //开始画
ctx.arc(cx, cy, r, 0, Math.PI * 2)
ctx.strokeStyle = 'pink'
ctx.fillStyle = 'pink'
ctx.stroke() //描边模式
ctx.fill()
ctx.closePath() //结束
ctx.restore()
}
drawCircle(ctx, 100, 100, 10)
// 存储圆的位置
circles.push({
x: 100,
y: 100,
r: 10
})
drawCircle(ctx, 200, 150, 20)
circles.push({
x: 200,
y: 150,
r: 20
})
// 元素拖拽 鼠标的画布坐标
const getCanvasPostion = e => {
return {
x: e.offsetX, //鼠标在页面中的位置的同时减去canvas元素本身的偏移量
y: e.offsetY,
}
}
// 两点之间的距离
const getInstance = (p1, p2) => {
// 指数运算符 **,它们分别对 (p1.x - p2.x) 和 (p1.y - p2.y) 进行自乘。
return Math.sqrt((p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2)
// Math.pow 函数,它用于计算指定数字的指定次方。
// return Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2))
}
// 判断是否在圆内
const ifInCirlce = (pos) => {
for (let i = 0; i < circles.length; i++) {
if (getInstance(circles[i], pos) < circles[i].r) {
return circles[i]
}
}
return false
}
// 鼠标按下监听
canvas.addEventListener('mousedown', e => {
const canvasPostion = getCanvasPostion(e)
const circleRef = ifInCirlce(canvasPostion)
if (circleRef) {
console.log(circleRef);
canvasInfo.dragTarget = circleRef //拖拽对象
canvasInfo.status = statusConfig.DRAGSTART
canvasInfo.lastEvtPos = canvasPostion
canvasInfo.offsetEvtPos = canvasPostion
}
})
// 鼠标移动
canvas.addEventListener('mousemove', e => {
const canvasPostion = getCanvasPostion(e)
const {dragTarget} = canvasInfo
if (ifInCirlce(canvasPostion)) {
canvas.style.cursor = 'all-scroll'
}else {
canvas.style.cursor = ''
}
if (!dragTarget) return
if (canvasInfo.status === statusConfig.DRAGSTART && getInstance(canvasPostion, canvasInfo.lastEvtPos) > 5) {
console.log('try to drag');
canvasInfo.status = statusConfig.DRAGGING
canvasInfo.offsetEvtPos = canvasPostion
}else if(canvasInfo.status === statusConfig.DRAGGING){
console.log('draging');
dragTarget.x += (canvasPostion.x - canvasInfo.offsetEvtPos.x)
dragTarget.y += (canvasPostion.y - canvasInfo.offsetEvtPos.y) //基于偏移
// 新增控制在区域内拖动代码----开始
if (dragTarget.x - dragTarget.r < 0) {
dragTarget.x = 0 + dragTarget.r
}else if (dragTarget.x + dragTarget.r > canvas.width) {
dragTarget.x = canvas.width - dragTarget.r
}
if (dragTarget.y - dragTarget.r < 0) {
dragTarget.y = 0 + dragTarget.r
}else if (dragTarget.y + dragTarget.r > canvas.height) {
dragTarget.y = canvas.height - dragTarget.r
}
// 新增控制在区域内拖动代码----结束
ctx.clearRect(0,0, canvas.width, canvas.height) //清空画布
circles.forEach(c => drawCircle(ctx, c.x, c.y, c.r))
canvasInfo.offsetEvtPos = canvasPostion
}
})
canvas.addEventListener('mouseup', e => {
canvasInfo.status = statusConfig.IDLE
})
canvas.addEventListener('mouseleave', e => {
canvasInfo.status = statusConfig.IDLE
canvas.style.cursor = ''
})
canvas中实现画布内元素的拖拽(不可拖拽出画布区域)
至此,现现画布内元素的拖拽就完结了。
文章来源:https://blog.csdn.net/qq_45290368/article/details/134998820
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!