思路:
1、用canvas绘制一个小球
2、判断鼠标的位置是否在小球上(坐标已经转换成相对canvas的坐标)
3、如果在,就开启一个mousemove事件,重新根据鼠标的位置来绘制小球
4、如果松开鼠标,就添加一个mouseup事件,将mousemove很本身的mouseup事件移除
代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script>
//获取canvas
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
//小球类
class Ball{
constructor(x,y,r,color){
this.x = x;
this.y = y;
this.r = r;
this.color = color;
}
render(ctx){
ctx.save();
ctx.beginPath();
ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false);
ctx.fillStyle = this.color;
ctx.fill();
ctx.restore();
}
//判断鼠标是否在小范围内
isInside(x,y){
//将鼠标坐标转换为相对的canvas坐标
const rect=canvas.getBoundingClientRect();
const mouseX=x-rect.left;
const mouseY=y-rect.top;
//鼠标与圆中心点的距离
const distance=Math.sqrt((mouseX-this.x)**2+(mouseY-this.y)**2);
if(distance<=this.r){
return true;
}else{
return false;
}
}
}
const X=canvas.width/2;
const Y=canvas.height/2;
//将鼠标坐标转换为相对的canvas坐标
function getMousePos(event){
const rect=canvas.getBoundingClientRect();
const mouseX=event.clientX-rect.left;
const mouseY=event.clientY-rect.top;
return{
x:mouseX,
y:mouseY
}
}
//实现小球
let ball = new Ball(X,Y,50,'pink');
ball.render(ctx);
//初始化小球的坐标位置分别与鼠标坐标的差值
let dx=0;
let dy=0;
//鼠标按下不放事件
canvas.addEventListener('mousedown',function(event){
//判断鼠标点击的位置是否在小球内
if(ball.isInside(event.clientX,event.clientY)){
const {x,y}=getMousePos(event);//获取鼠标相对canvas的坐标位置
dx=x-ball.x;//获取鼠标x坐标与小球中心点x坐标的差值
dy=y-ball.y;//获取鼠标y坐标与小球中心点y坐标的差值
canvas.addEventListener('mousemove',moveBallFn);//添加mousemove事件监听
canvas.addEventListener('mouseup',upBallFn);//添加mouseup事件监听
}
});
//获取鼠标的位置,更新小球的位置
function moveBallFn(e){
const {x,y}=getMousePos(e);
ball.x = x-dx;
ball.y = y-dy;
}
//鼠标松开事件
function upBallFn(e){//移除mousemove和mouseup事件监听
canvas.removeEventListener('mousemove',moveBallFn);
canvas.removeEventListener('mouseup',upBallFn);
}
//不断重绘
(function move(){//函数自执行
window.requestAnimationFrame(move);//动画帧
//重新获取鼠标位置,然后清除画布,重新绘制小球
ctx.clearRect(0,0,canvas.width,canvas.height);//每一帧都清除画布
ball.render(ctx);//重新绘制小球
})();
</script>
</body>
</html>