前言
跟着视频稍微过了一遍Canvas,收获挺大的
弹幕
大概就是文字的横向移动,明白原理的话其实也挺简单的
至于实现思路的话,大概是这样的
canvas中要发送一条弹幕需要这些值
文字内容 文字宽度 文字大小 颜色 x轴位置 y轴位置 速度 弹幕发送时间
这里除x轴位置以外,其它值均需要进行保存
文字宽度在发送时通过 ctx.measureText(text).width
获取并保存
(这样操作是为了省去加载弹幕宽度的步骤
- 弹幕发送时间
这里可以根据定时器对播放时间进行累加,再根据 累加值
& 累加值 + 运行间隔
来查出该区间需要发送的弹幕
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
body {
margin: 0;
}
#canvas {
height: 600px;
width: 600px;
}
</style>
</head>
<body>
<canvas id="canvas" height="600" width="600" style="border: 1px solid"></canvas>
<video id="video" controls="controls" autoplay="autoplay" src="http://tdwh-oss.oss-cn-qingdao.aliyuncs.com/video/2022022218172286075.mp4"></video>
</body>
<script>
let canvas = document.querySelector("#canvas");
let canvasH = canvas.clientHeight;
let ctx = canvas.getContext("2d");
video();
/* 视频 + 弹幕实现 */
function video() {
let videoDom = document.querySelector("#video");
ctx.font = "20px 微软雅黑"
let interval;
let danMuKu = [
{
text: "233333",
height: 50,
speed: 1,
width: 0,
color: "aqua"
},
{
text: "233333333333",
height: 70,
speed: 2,
width: 0,
color: "white"
},
{
text: "emmmmmm",
height: 50,
speed: 3,
width: 0,
color: "azure"
},
]
// 这里循环取文字宽度
for (let i = 0; i <= danMuKu.length - 1; i++) {
danMuKu[i].width = ctx.measureText(danMuKu[i].text).width;
}
let canvasW = canvas.clientWidth;
videoDom.onplay = () => {
interval = setInterval(() => {
ctx.clearRect(0, 0, 600, 600)
ctx.fillStyle = "black"
ctx.fillRect(0, 0, 600, 600);
ctx.drawImage(videoDom, 0, 131.25, 600, 337.5);
danMuKu.forEach(v => {
// 初始化起始位置
if (v.initX == null) v.initX = canvasW;
v.initX -= v.speed;
ctx.fillStyle = v.color;
ctx.fillText(v.text, v.initX, v.height);
if (v.initX <= -1 * v.width) v.initX = canvasW
})
}, 10)
}
videoDom.onpause = () => {
clearInterval(interval)
}
}
</script>
</html>
雪花
雪花的运动方向自然是从上往下,稍微复杂的点大致在运动轨迹了
// 这里根据正负值(大小)初始化运动方向, 左/右
if (v.path == null) v.path = randomNum(-.5, .5);
// 这里得出第一个x值, v.x为雪花的初始x轴位置, +path 则表示雪花会往那个方向飘动
let num1 = v.x + v.path;
// 这里得出第二个x值, 这里用num1而不是用v.x的原因是因为 v.x运动轨迹可能会变成波浪线/接近笔直的一条线,num1则会保持原运动轨迹
let num2 = num1 + (v.path < 0 ? -.5 : .5);
// 再从num1和num2中取出一个随机数
v.x = randomNum(num1, num2)
// 获取n & m之间的随机数(小数/负数)
function randomNum(n, m) {
return Math.random() * (m - n) + n;
}
创意工坊
加上了canvas后顺便也上传了新的视频壁纸到创意工坊

Comments | NOTHING