日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端学习(2879)歌谣学习篇原生js和canvas实现弹幕功能

發布時間:2023/12/9 HTML 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端学习(2879)歌谣学习篇原生js和canvas实现弹幕功能 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

我是歌謠 放棄很難 堅持一定很酷
2021繼續加油

目錄結構

文件地址
源碼地址后面可見

源碼文件

index.css

body {
margin: 0;
}

.container {
width: 1000px;
margin: 0 auto;
}

.video-wrapper {
position: relative;
}

.video-wrapper video {
width: 100%;
}

.video-wrapper canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 563px;
}

.video-wrapper .tool-box {
height: 38px;
}

.video-wrapper input,
.video-wrapper button {
height: 100%;
margin-right: 15px;
vertical-align: middle;
outline: none;
border: none;
box-sizing: border-box;
border-radius: 5px;
}

.video-wrapper .danmu-input {
width: 300px;
border: 1px solid #ccc;
}

.video-wrapper .danmu-btn {
color: #fff;
background-color: orange;
}

danmu.js

import { getTextWidth, getTextPosition } from ‘./utils’;

class Danmu {
constructor (danmu, fCtx) {
this.content = danmu.content;
this.runTime = danmu.runTime;
this.danmu = danmu;
this.ctx = fCtx;
}

initialize () {
this.color = this.danmu.color || this.ctx.color;
this.speed = this.danmu.speed || this.ctx.speed;
this.fontSize = 30;
this.width = getTextWidth(this.content, this.fontSize);
getTextPosition(this.ctx.canvas, this.fontSize, this);
}

render () {
this.ctx.canvasCtx.font = this.fontSize + ‘px Microsoft Yahei’;
this.ctx.canvasCtx.fillStyle = this.color;
this.ctx.canvasCtx.fillText(this.content, this.X, this.Y);
}
}

export default Danmu;

index.js

import { isObject, isArray } from ‘./utils’;
import Danmu from ‘./Danmu’;

class VideoDanmu {
constructor (video, canvas, options) {
if (!video || !canvas || !options || !isObject(options)) return;
if (!options.danmuData || !isArray(options.danmuData)) return;

this.video = video; this.canvas = canvas; this.canvasCtx = canvas.getContext('2d'); this.canvas.width = video.offsetWidth; this.canvas.height = video.offsetHeight;this.danmuPaused = true;Object.assign(this, options, {speed: 2,runTime: 0,color: '#fff' });this.danmuPool = this.createDanmuPool(); this.render();

}

createDanmuPool () {
return this.danmuData.map(dm => new Danmu(dm, this));
}

render () {
this.clearRect();
this.renderDanmu();
!this.danmuPaused && requestAnimationFrame(this.render.bind(this));
}

renderDanmu () {
let currentTime = this.video.currentTime;

this.danmuPool.map((danmu) => {if (!danmu.stopRender && currentTime >= danmu.runTime) {if (!danmu.isInitialized) {danmu.initialize();danmu.isInitialized = true;}danmu.X -= danmu.speed;danmu.render();if (danmu.X <= danmu.width * -1) {danmu.stopRender = true;}} })

}

reset () {
this.clearRect();
let currentTime = this.video.currentTime;

this.danmuPool.map((danmu) => {danmu.stopRender = false;if (currentTime <= danmu.runTime) {danmu.isInitialized = false;} else {danmu.stopRender = true;} })

}

add (data) {
this.danmuPool.push(new Danmu(data, this));
}

clearRect () {
this.canvasCtx.clearRect(0, 0, this.canvas.width, this.canvas.height);
}
}

export default VideoDanmu;

util.js

function isObject (value) {
const type = Object.prototype.toString.call(value);
return type === ‘[object Object]’;
}

function isArray (value) {
return Array.isArray(value);
}

function getTextWidth (content, fontSize) {
const _span = document.createElement(‘span’);
_span.innerText = content;
_span.style.fontSize = fontSize + ‘px’;
_span.style.position = ‘absolute’;
document.body.appendChild(_span);
let width = _span.offsetWidth;
document.body.removeChild(_span);
return width;
}

function getTextPosition (wrapper, fontSize, ctx) {
const X = wrapper.width;
let Y = wrapper.height * Math.random();

Y < fontSize && (Y = fontSize);
Y > wrapper.height - fontSize && (Y = wrapper.height - fontSize);

ctx.X = X;
ctx.Y = Y;
}

export {
isObject,
isArray,
getTextWidth,
getTextPosition
}

index.js

import VideoDanmu from ‘./danmu’;

const danmuData = [
{
content: ‘我真的好喜歡這首鋼琴曲’,
runTime: 10,
speed: 2,
color: ‘red’
},
{
content: ‘這首鋼琴曲是紅豬里的一去不復返的時光’,
runTime: 0,
speed: 4,
color: ‘orange’
},
{
content: ‘久石讓是我最崇拜的音樂家之一’,
runTime: 15,
speed: 4,
color: ‘green’
}
]

😭(doc) => {

const oDanmuVideo = doc.getElementById(‘J_danmuVideo’),
oDanmuCanvas = doc.getElementById(‘J_danmuCanvas’),
oDanmuBtn = doc.getElementsByClassName(‘danmu-btn’)[0],
oDanmuInput = doc.getElementsByClassName(‘danmu-input’)[0],
oColorInput = doc.getElementsByClassName(‘color-input’)[0];

const init = () => {
window.videoDanmu = new VideoDanmu(
oDanmuVideo,
oDanmuCanvas,
{
danmuData
}
)
bindEvent();
}

function bindEvent () {
oDanmuVideo.addEventListener(‘play’, handleVideoPlay, false);
oDanmuVideo.addEventListener(‘pause’, handleVideoPause, false);
oDanmuVideo.addEventListener(‘seeked’, handleVideoSeek, false);
oDanmuBtn.addEventListener(‘click’, handleToolClick, false);
}

function handleVideoPlay () {
videoDanmu.danmuPaused = false;
videoDanmu.render();
}

function handleVideoPause () {
videoDanmu.danmuPaused = true;
}

function handleVideoSeek () {
videoDanmu.reset();
}

function handleToolClick () {
if (videoDanmu.danmuPaused) return;

const inputValue = oDanmuInput.value.trim();if (!inputValue.length) return;const colorValue = oColorInput.value,runTime = oDanmuVideo.currentTime;const _data = {content: inputValue,color: colorValue,runTime }videoDanmu.add(_data); oDanmuInput.value = '';

}

init();

})(document);

## 主文件 Document 發送彈幕 ## 運行結果 ![在這里插入圖片描述](https://img-blog.csdnimg.cn/2021021714473891.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzM5MjQ4OQ==,size_16,color_FFFFFF,t_70)## 源碼地址 [源碼地址](https://gitee.com/geyaoisgeyao/small-cases-of-daily-learning/tree/master/)

總結

以上是生活随笔為你收集整理的前端学习(2879)歌谣学习篇原生js和canvas实现弹幕功能的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。