箭头跟随动效,这个很有意思的动效,看起来无从下手,实则还真有点难度,难在如下几个知识点
- 怎么确认箭头方向
- 怎么画确定方向的箭头
- 怎么让箭头跟随鼠标方向移动
1、 怎么确认箭头方向?
一个点在另一个点那个方向这个在Math对象有个Math.atan2(y,x)函数可以做到,其定义:Math.atan2 返回从原点(0,0)到(x,y)点的线段与x轴正方向之间的平面角度(弧度值),也就是Math.atan2(y,x);
Math.atan2( -0, -0 ) // -3.141592653589793
Math.atan2( 0, -0 ) // +3.141592653589793
2、 怎么画确定方向的箭头?
这里可能下意识想着上一次箭头方向和现在箭头方向的角度是多少,这样想下去,基本无解,canvas动画和上次的状态是无关的,只要画出现在想要的样子就可以了,每一个当前状态连在一起变成了动画,所以先画出静态的箭头,最简单应该是角度为0的箭头,很快画应该就画完成,再画一个随机角度的箭头,动手起来要点时间,通过sin,cos,tan,和相关箭头的各个点位进行一翻计算后也能画出来,可能如下: 但这样的方式有点繁琐,所以有了这种方式:画一个为角度0的箭头,再旋转对应的角度
3、 怎么让箭头跟随鼠标方向移动?
可以理解为怎么让一个箭头沿着一个方向移动,首先这个速度肯定是自定的,所以箭头移动的速度是知道,并且还知道方向(箭头方向),这样就可以直接将速度分解成水平和垂直两个速度,sin、cos很容易就可以得到
x += v * Math.cos(angle)
y += v * Math.sin(angle)
4、完整实现
<template>
<div id="app">
<canvas id="canvas"></canvas>
</div>
</template>
<script>
class Arrow {
constructor(x, y, color, angle) {
//箭头中心x坐标,默认值为0
this.x = x || 0;
//箭头中心y坐标,默认值为0
this.y = y || 0;
//颜色,默认值为“#FF0099”
this.color = color || "blue";
//旋转角度,默认值为0
this.angle = angle || 0;
}
stroke(cxt) {
cxt.save();
// 将画布的左上角移至箭头的中心点 从而可旋转使自己不会偏移位置
cxt.translate(this.x, this.y);
cxt.rotate(this.angle);
cxt.strokeStyle = this.color;
cxt.beginPath();
cxt.moveTo(-20, -10);
cxt.lineTo(0, -10);
cxt.lineTo(0, -20);
cxt.lineTo(20, 0);
cxt.lineTo(0, 20);
cxt.lineTo(0, 10);
cxt.lineTo(-20, 10);
cxt.closePath();
cxt.stroke();
cxt.restore();
}
}
export default {
name: "App",
mounted() {
const eleCvas = document.getElementById("canvas");
const mouse = { x: 0, y: 0 };
const arrow = new Arrow(150, 75);
eleCvas.addEventListener("mousemove", event => {
mouse.x = event.pageX - canvas.offsetLeft;
mouse.y = event.pageY - canvas.offsetTop;
});
const cxt = eleCvas.getContext("2d");
cxt.fillStyle = "red";
let v = 2;
let mousex = 0;
let mousey = 0;
(function drawFrame() {
cxt.clearRect(0, 0, eleCvas.width, eleCvas.height);
window.requestAnimationFrame(drawFrame);
if (mouse.x !== mousex || mouse.y !== mousey) {
mousex = mouse.x;
mousey = mouse.y;
arrow.angle = Math.atan2(mouse.y - arrow.y, mouse.x - arrow.x);
}
const vx = Math.cos(arrow.angle) * v;
const vy = Math.sin(arrow.angle) * v;
arrow.x += vx;
arrow.y += vy;
arrow.stroke(cxt);
})();
}
};
</script>
<style>
#app {
text-align: center;
}
canvas {
border: 1px solid red;
}
</style>
代码地址
相关
- canvas动画 (一)
- canvas动画 (二)
- canvas 入门
- canvas入门应了解的初高中知识
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!