新建组件 Canvas.vue
。
// @/components/Canvas.vue
<template>
<div :style="{ height: waveAllHeight 'px', background: bgColor }" class="wave">
<canvas id="wave1"></canvas>
<canvas id="wave2"></canvas>
<canvas id="wave3"></canvas>
</div>
</template>
<script>
export default {
name: "Canvas",
props: {
bgColor: {
default: "none",
}, // 背景色
waveAllHeight: { default: 160 }, // 波浪的整体高度
waveCount: { default: 2 }, // 波峰个数
waveHeight: { default: 50 }, // 波浪起伏高度
// 波浪颜色
waveColor: {
default () {
return [
"#f3f3f3",
"#f3f3f3",
"#f3f3f3",
];
},
},
// 波浪速率
waveTime: {
default () {
return [4000, 4000, 4000];
},
},
},
data () {
return {};
},
mounted () {
this.wavePlay("wave1", 140, this.waveColor[0], this.waveTime[0]);
this.wavePlay("wave2", 140, this.waveColor[1], this.waveTime[1]);
this.wavePlay("wave3", 140, this.waveColor[2], this.waveTime[2]);
},
methods: {
wavePlay ($canvasID, $progress, $maveColor, $time) {
const that = this;
let waveWidth = 3300, // 波浪长度
offset = 0,
waveHeight = that.waveHeight, // 波浪起伏高度
waveCount = that.waveCount, // 波浪个数
startX = -1200,
startY = 212, // canvas 高度
progress = $progress, // 波浪位置高度
d2 = waveWidth / waveCount, // 单个波浪的宽度
d = d2 / 2,
hd = d / 2,
c = document.getElementById($canvasID),
ctx = c.getContext("2d");
c.width = 1920; // 画布宽度
c.height = that.waveAllHeight; // 画布高度
function move () {
offset -= 5;
if (-1 * offset === d2) {
offset = 0;
}
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillStyle = $maveColor; // 画布填充色
ctx.beginPath();
let offsetY = startY - progress;
// 绘制贝塞尔曲线
ctx.moveTo(startX - offset, offsetY); // 开始点
for (let i = 0; i < waveCount; i ) {
let dx = i * d2;
let offsetX = dx startX - offset;
ctx.quadraticCurveTo(
offsetX hd,
offsetY waveHeight,
offsetX d,
offsetY
);
ctx.quadraticCurveTo(
offsetX hd d,
offsetY - waveHeight,
offsetX d2,
offsetY
);
}
ctx.lineTo(startX waveWidth, 3000);
ctx.lineTo(startX, 0);
ctx.fill();
setTimeout(move, $time / 60); // 速度
}
move();
},
},
};
</script>
<style scoped lang="scss">
.wave {
width: 100%;
height: 100%;
position: relative;
top: 0;
left: 0;
margin-top: -8%;
canvas {
width: 100%;
opacity: 1;
position: absolute;
top: 0;
left: 0;
}
}
@media (max-width: 900px) {
.wave {
display: none;
}
}
</style>