我想实现一个带箭头的线段从起点出发,沿着设定的几个坐标运动该如何实现哎,线段可以改宽度渐变色,

可以使用Vue 3中的<canvas>元素和requestAnimationFrame()方法,实现带箭头的线段从一个坐标点开始,并沿指定路径运动。
requestAnimationFrame()方法循环调用绘制函数,以使线段动起来。下面是Vue 3中的示例代码,可以根据需要修改坐标点数组:
<template>
<canvas ref="canvas" style="width:100%; height:100%;" />
</template>
<script>
export default {
mounted() {
this.ctx = this.$refs.canvas.getContext('2d');
this.width = this.$refs.canvas.width;
this.height = this.$refs.canvas.height;
// 定义坐标点
this.points = [
{ x: 100, y: 100 },
{ x: 200, y: 200 },
{ x: 300, y: 100 },
{ x: 400, y: 200 },
{ x: 300, y: 300 },
{ x: 200, y: 200 },
{ x: 100, y: 300 },
];
// 定义线段样式
this.lineWidth = 6;
this.gradient = this.ctx.createLinearGradient(0, 0, this.width, 0);
this.gradient.addColorStop(0, '#00ff00');
this.gradient.addColorStop(1, '#0000ff');
// 绘制
this.animate();
},
methods: {
animate() {
// 绘制函数
const draw = (t) => {
this.ctx.clearRect(0, 0, this.width, this.height);
// 设置线段样式
this.ctx.lineWidth = this.lineWidth;
this.ctx.strokeStyle = this.gradient;
this.ctx.lineCap = 'round';
this.ctx.lineJoin = 'round';
this.ctx.setLineDash([]);
// 开始绘制
this.ctx.beginPath();
this.ctx.moveTo(this.points[0].x, this.points[0].y);
for (let i = 1; i < this.points.length; i++) {
const dx = this.points[i].x - this.points[i - 1].x;
const dy = this.points[i].y - this.points[i - 1].y;
// 计算箭头角度和长度
const angle = Math.atan2(dy, dx);
const len = Math.sqrt(dx * dx + dy * dy);
const arrowLen = Math.min(20, len / 3);
// 计算箭头坐标
const arrowX = this.points[i - 1].x + dx - arrowLen * Math.cos(angle);
const arrowY = this.points[i - 1].y + dy - arrowLen * Math.sin(angle);
// 连接线段
this.ctx.lineTo(this.points[i].x, this.points[i].y);
if (i == this.points.length - 1) {
// 最后一段线段时绘制箭头
this.ctx.moveTo(arrowX, arrowY);
this.ctx.lineTo(this.points[i - 1].x + dx, this.points[i - 1].y + dy);
this.ctx.lineTo(this.points[i - 1].x + dx - arrowLen * Math.cos(angle - Math.PI / 6), this.points[i - 1].y + dy - arrowLen * Math.sin(angle - Math.PI / 6));
this.ctx.lineTo(this.points[i - 1].x + dx - arrowLen * Math.cos(angle + Math.PI / 6), this.points[i - 1].y + dy - arrowLen * Math.sin(angle + Math.PI / 6));
this.ctx.lineTo(arrowX, arrowY);
}
}
this.ctx.stroke();
requestAnimationFrame(draw);
};
requestAnimationFrame(draw);
},
},
};
</script>
该代码中,requestAnimationFrame方法会传递一个时间戳参数t。在实现动画过程中,我们可以根据这个值,计算出运动过程中的每个样式值,实现更丰富的动画效果。