HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 请将页面title修改为你的姓名 -->
<title>lp</title>
<style>
canvas {
border: 3px solid black;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="600" height="400"></canvas>
<script src="todo.js"></script>
<video id ='myvedio' src="video" controls loop hidden width="600" height="300"></video>
</body>
</html>
JS:
/*
Functions :代码题-视频弹幕
Author :周二班-lp
Build_Date:2022.11.1
Version :1.0
要求:补充代码来实现demo效果
1、初始化时显示TXT
2、鼠标点击开始播放视频
3、随着视频播放在canvas上逐帧绘制视频内容
4、播放过程中,按回车键出现弹幕(内容、位置随机)
说明:
1、原则上不能大幅修改提供的程序段
2、在上方Author区注明完成者中文姓名和教学班级,例如“周二班-张三”
*/
//=========================================================================
//=========================变量定义区=======================================
// 此块内容如非必要,请勿修改,可增加或使用该区域变量
let canvas = document.getElementById("myCanvas"),
context = canvas.getContext('2d');
let video = document.createElement('video');
const W = canvas.width,
H = canvas.height; // canvas的大小
const TXT = 'Click to Start'; // 初始化时显示的文本
const FPS = 24; // 视频fps
const TXT2 = ['Good', 'Nice', 'Bad', 'Wow']; // 弹幕文字数组
// let danmu = {
// show: false,
// txt: '',
// x0: 0,
// y0: 0
// }; // 当前弹幕的文字及位置
let playing = true;
let dArray = []; //弹幕池
//=========================变量定义区 end=======================================
//=========================函数定义区=======================================
//============待完成的代码区域======================
// 请编写函数,绘制每一帧的绘制内容
function drawInterval() {
// 清屏
context.clearRect(0, 0, W, H);
// 绘制视频帧
//context.drawImage(video, 0, 0, W, H);
context.save(); //先在底层放图片
context.globalAlpha = 0.2;
context.drawImage(video, 0, 0, W, H); //对于视频元素,是一帧一帧取的
context.restore();
context.save();
//要剪辑的区域形状
context.beginPath();
context.arc(W / 2, H / 2, 50, Math.PI / 180 * 0, Math.PI / 180 * 360);
//剪辑
context.clip();
context.drawImage(video, 0, 0, W, H); //这里对原先的覆盖只会是剪辑的区域进行覆盖
context.restore();
// if (danmu.show) {
// x -= 20;
// context.fillText(danmu.txt, x,danmu.y0);
// }
//每播放一帧,就显示之前的全部弹幕
for (i = 0; i < dArray.length; ++i) //这里不懂
{
temp = dArray[i];
temp.x -= temp.dx;
//当danmu.show为真是,绘制弹幕
if (temp.show)
context.fillText(temp.txt, temp.x, temp.y0);
}
}
// 请编写函数,开始播放视频并在canvas上逐帧绘制视频
function startAnimation() {
console.log('播放'); // 此句不要删
// 开始播放视频
video.play(); //播放视频之前先写一个play
// 开始逐帧绘制
interval = setInterval(drawInterval, 1000 / FPS); //播放动画
}
function pauseAnimation()
{
video.pause(); //要暂停视频之前先pause一下video
clearInterval(interval); //停止动画
}
// 请编写函数,初始化时显示文本
function showTxt() {
context.save();
context.fillStyle='black';
context.lineWidth=2;
context.strokeText(TXT, W / 2,H / 2);
context.restore();
}
// ------ 事件响应函数 ------
// 请编写函数,鼠标点击后开始动画, 鼠标再次点击暂停
canvas.onmousedown = function () {
playing = !playing;
if (!playing)
startAnimation();
else
pauseAnimation();
}
// 请补全函数,键盘按回车键发送弹幕
window.addEventListener("keydown", function (e) {
if (e.key == "Enter") {
console.log("回车键!");
//设置当前弹幕的文本和位置
var danmu = {
show: false,
txt: '',
x0: 0,
y0: 0,
dx: 20,
x: 0
}; // 当前弹幕的文字及位置
danmu.show = true; //显示为true
idx = Math.floor(Math.random() * TXT2.length); // 随机从弹幕文本数组中选取一个下标
// 请补全代码,设置当前弹幕的文本和位置
danmu.txt=TXT2[idx];
danmu.x0=Math.random() * W;
danmu.y0=Math.random() * H;
danmu.x = danmu.x0;
//填充弹幕池
dArray.push(danmu);
}
});
//============待完成的代码区域 end ====================
//============初始化 ====================
// init,如非必要,请勿修改
function init() {
console.log('初始化');
context.font = '60px sans-serif';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillStyle = 'red';
video.src = 'video.mp4';
video.loop = true;
showTxt(); //先显示文本
}
//=========================函数定义区 end=======================================
init();