亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁(yè) > 編程 > HTML > 正文

基于Canvas+Vue的彈幕組件的實(shí)現(xiàn)

2024-08-26 00:21:34
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

最近由于項(xiàng)目需要定制化一個(gè)彈幕功能,所以嘗試使用canvas來(lái)開(kāi)發(fā)組件。經(jīng)過(guò)測(cè)試在一些低端機(jī)的效果也沒(méi)有明顯的卡頓,和大家交流一下

彈幕效果

 

 
Canvas,Vue,彈幕

 

 功能介紹

  • 支持循環(huán)彈幕
  • 彈幕不重疊
  • 支持選擇軌道數(shù)
  • 支持彈幕發(fā)送

使用

npm i vue-barrage

參數(shù)配置 

 

name type default desc
barrageList Array [] 彈幕數(shù)據(jù)
speed Number 4 彈幕滾動(dòng)速度
loop Boolean true 是否循環(huán)滾動(dòng)
channels Number 2 彈幕軌道數(shù)

 

功能實(shí)現(xiàn)

html樣式

<template>    <div class="barrage-container">        <div            class="container"            :style="{height: barrageHeight/2+'px'}">            <canvas                id="canvas"                ref="canvas"                :width="barrageWidth"                :height="barrageHeight"                :style="{'width': barrageWidth/2 + 'px','height': barrageHeight/2 + 'px'}"/>        </div>    </div></template>

js實(shí)現(xiàn)

監(jiān)聽(tīng)數(shù)據(jù)源

watch: {    barrageList (val) {        if (val.length !== 0) {            this.initData() // 數(shù)據(jù)初始化            this.render() // 開(kāi)始渲染        }    }}

數(shù)據(jù)初始化

barrageArray 是存儲(chǔ)彈幕數(shù)據(jù)用的,包括默認(rèn)彈幕列表和新增彈幕項(xiàng)

/** * 數(shù)據(jù)初始化 */initData () {    for (let i = 0; i < this.barrageList.length; i++) { // 此處處理只顯示40個(gè)字符        let content = this.barrageList[i].content.length > 40 ? `${this.barrageList[i].content.substring(0, 40)}...` : this.barrageList[i].content        this.pushMessage(content, this.barrageList[i].color)    }},/** * 增加數(shù)據(jù) * @param content * @param color */pushMessage (content, color) {    let position = this.getPosition() // 確定跑道位置    let x = this.barrageWidth // 初始位置    let offsetWidth = 0    for (let i = 0, len = this.barrageArray.length; i < len; i++) {        let item = this.barrageArray[i]        if (position === item.position) { // 如果同跑道,則往后排            offsetWidth += Math.floor(this.ctx.measureText(item.content).width * 3 + 60)        }    }    this.barrageArray.push({        content: content, // 彈幕內(nèi)容        x: x + offsetWidth, // 確定每一條彈幕的初始位置        originX: x + offsetWidth, // 存儲(chǔ)當(dāng)前彈幕的位置,以便在循環(huán)的時(shí)候使用        position: position,        width: this.ctx.measureText(content).width * 3, // canvas繪制內(nèi)容寬度        color: color || this.getColor() // 自定義顏色    })},

初始化數(shù)據(jù)需要處理的就是計(jì)算當(dāng)前彈幕的軌道、位置、寬度,以便在 canvas 繪制的時(shí)候使用

繪制 canvas

/** * 渲染 */render () {    this.ctx.clearRect(0, 0, this.barrageWidth, this.barrageHeight)    this.ctx.font = '30px Microsoft YaHei'    this.draw()    window.requestAnimationFrame(this.render) // 每隔16.6毫秒渲染一次,如果使用setInterval的話在低端機(jī)型會(huì)有點(diǎn)卡頓},/** * 開(kāi)始繪制 文字和背景 */draw () {    for (let i = 0, len = this.barrageArray.length; i < len; i++) {        let barrage = this.barrageArray[i]        try {            barrage.x -= this.speed            if (barrage.x < -barrage.width - 100) { // 此處判斷彈幕消失時(shí)機(jī)                if (i === this.barrageArray.length - 1) { // 最后一條消失時(shí)的判斷邏輯                    if (!this.loop) { //如果不是循環(huán)彈幕的話就取消繪制 判斷是否循環(huán),不循環(huán)執(zhí)行cancelAnimationFrame                        cancelAnimationFrame(this.render)                        return                    }                    if (this.addArray.length !== 0) { // 此處判斷增加彈幕的邏輯                        this.barrageArray = this.barrageArray.concat(this.addArray)                        this.addArray = []                    }                    for (let j = 0; j < this.barrageArray.length; j++) { // 給每條彈幕的x初始值                        this.barrageArray[j].x = this.barrageArray[j].originX                    }                }            }            if (barrage.x <= 2 * document.body.clientWidth + barrage.width) { // 判斷什么時(shí)候開(kāi)始繪制,如果不判斷的話會(huì)導(dǎo)致彈幕滾動(dòng)卡頓                // 繪制背景                this.drawRoundRect(this.ctx, barrage.x - 15, barrage.position - 30, barrage.width + 30, 40, 20, `rgba(0,0,0,0.75)`)                // 繪制文字                this.ctx.fillStyle = `${barrage.color}`                this.ctx.fillText(barrage.content, barrage.x, barrage.position)            }        } catch (e) {            console.log(e)        }    }},

此處判斷繪制邏輯,包括什么時(shí)候取消,彈幕開(kāi)始繪制判斷,彈幕消失判斷

其他函數(shù)

/** * 獲取文字位置 * 使用pathWayIndex來(lái)確認(rèn)每一條彈幕所在的軌道 * 返回距離頂部的距離 * @TODO此處還可以優(yōu)化,根據(jù)每條軌道的距離來(lái)判斷下一條彈幕出現(xiàn)位置  */getPosition () {    let range = this.channels    let top = (this.pathWayIndex % range) * 50 + 40    this.pathWayIndex++    return top},/** * 獲取隨機(jī)顏色 */getColor () {    return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);},/** * 繪畫(huà)圓角矩形 * @param context * @param x * @param y * @param width * @param height * @param radius * @param color */drawRoundRect (context, x, y, width, height, radius, color) {    context.beginPath()    context.fillStyle = color    context.arc(x + radius, y + radius, radius, Math.PI, Math.PI * 3 / 2)    context.lineTo(width - radius + x, y)    context.arc(width - radius + x, radius + y, radius, Math.PI * 3 / 2, Math.PI * 2)    context.lineTo(width + x, height + y - radius)    context.arc(width - radius + x, height - radius + y, radius, 0, Math.PI / 2)    context.lineTo(radius + x, height + y)    context.arc(radius + x, height - radius + y, radius, Math.PI / 2, Math.PI)    context.fill()    context.closePath()}

此處為彈幕服務(wù)函數(shù)

使用

<barrage    ref="barrage"    class="barrage"    :barrage-list="barrageList"    :speed="speed"    :loop="loop"    :channels="channels"/>    import Barrage from 'vue-barrage'// 彈幕數(shù)據(jù)初始化  this.barrageList = [{    content: '試數(shù)據(jù)測(cè)試數(shù)測(cè)試數(shù)據(jù)數(shù)測(cè)試數(shù)據(jù)',    color: 'white'}]// 新增彈幕this.$refs.barrage.add({    content: '增加一條新的彈幕增加一條新的彈幕', color: 'white'})

結(jié)語(yǔ)

總的來(lái)說(shuō)這個(gè)組件還有可優(yōu)化的空間,后續(xù)我會(huì)繼續(xù)改進(jìn)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持VeVb武林網(wǎng)。


注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到HTML教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
国产精品久久久久久婷婷天堂| 97在线日本国产| 国产亚洲精品美女| 国产亚洲精品v| 99久久国产综合精品色伊| 国产伦精品一区| 久久久国产精品黄毛片| 丁香花在线高清完整版视频| 中文字幕久精品免费视频| 免费大秀视频在线播放| 精人妻一区二区三区| **三级三级97片毛片| 久久综合五月婷婷| 午夜精品三级久久久有码| 搞黄视频在线观看| 精品人妻无码中文字幕18禁| 成人网免费看| 国产呦精品一区二区三区网站| 日日躁夜夜躁人人揉av五月天| 午夜不卡av在线| 在线观看操人| 国产乱人伦真实精品视频| 福利网站在线观看| 波多野结衣乳巨码无在线| 天堂成人在线| 精品伦精品一区二区三区视频密桃| 欧美日韩一区在线观看| www三级免费| 国内精品免费| 中文字幕久热在线精品| 亚洲精品一级二级| 精品国产亚洲一区二区三区| 中文字幕精品一区日韩| 国产成人无码精品久久久性色| 无码免费一区二区三区| 姑娘第5集在线观看免费好剧| 欧美一区二区三区视频免费| 久久久精品人妻无码专区| 国产高清在线一区| 国产精品一区=区| 免费国偷自产拍精品视频| 久久99精品久久久久久噜噜| 好男人中文字幕官网| 黄色免费av| 午夜成人免费影院| 亚洲激情视频在线播放| 欧美福利一区二区三区| 污污在线观看| 日本成在线观看| 日本在线人成| аⅴ成人天堂中文在线| 久久精品国产亚洲AV无码男同| 久久香蕉国产线看观看av| 国产精品久久久久久久久久东京| 日本中文字幕不卡免费| 亚洲黄网站在线观看| 欧美精品丝袜久久久中文字幕| 日韩欧美国产中文字幕| 99国产精品久久久久久| 国产一二三四在线视频| brazzers欧美最新版视频| 日韩中文字幕观看| 久久久久久久久国产一区| 五月婷婷之综合激情| 日本一二三四高清不卡| 国产免费a视频| 国产精品入口麻豆免费看| 你懂的网站在线播放| 精品一区二区三区四区五区六区| 日韩在线第七页| 国产一级视频在线播放| 日本毛片在线观看| 久久久精品三级| 福利在线免费| 一级黄色片在线| 亚洲色欲色欲www| 天堂在线视频网站| 韩国三级hd中文字幕有哪些| 亚洲精品aaa| 在线日韩一区| 原千岁中文字幕| 黄色网页在线观看| 欧美美女一区二区| 国产精品人人爽人人做我的可爱| 欧美大香线蕉线伊人久久| 亚洲一区二区三区视频在线播放| 国产99久久久国产精品成人免费| 青青草视频在线免费直播| 精品大片一区二区| 先锋av资源色| 国产日本欧美在线| 亚洲成人av片在线观看| 天堂网在线观看视频| 深夜福利视频一区二区| 一区二区三区一级片| 在线观看制服搞黄视频| 麻豆视频久久| 国产区视频在线| 91.com在线观看| 色婷婷亚洲精品| 手机看片日韩国产| 免费一级特黄特色毛片久久看| 狠狠色狠狠色综合日日tαg| 中文字幕乱码亚洲精品一区| 国产农村一级特黄α**毛片| 麻豆国产精品一区| 中文字幕免费高清在线观看| 久久亚洲免费视频| 国产美女视频免费观看下载软件| 大荫蒂性生交片| 在线免费观看麻豆| 亚州成人在线电影| 一本一道久久a久久综合蜜桃| 精品一区二区成人免费视频| 久久久一区二区三区捆绑**| 亚洲区 欧美区| 亚洲欧美激情精品一区二区| 91精品国产综合久久香蕉922| 青青草原播放器| 又大又黄又粗| 久久久亚洲网站| 欧美日韩精品一区二区| 91在线视频成人| 婷婷激情图片久久| 成人h动漫精品一区二区下载| 国产乱子伦农村叉叉叉| 桥本有菜亚洲精品av在线| 日韩网址在线观看| 69堂成人精品免费视频| 椎名由奈av一区二区三区| 久久婷婷激情| 丝袜美腿玉足3d专区一区| 人成在线视频| 中文字幕二区三区| 精精国产xxxx视频在线播放| 青青青手机在线视频观看| 日韩免费在线观看| 日本黄网免费一区二区精品| 国产美女免费网站| 久草青青在线观看| 第一区免费在线观看| 草莓视频一区二区三区| 日韩一区二区免费视频| 亚洲日本一区二区三区| 大地资源高清在线视频观看| 456亚洲影院| 97人妻天天摸天天爽天天| 欧美精品偷拍| 欧美激情一区二区视频| 中国毛片直接看| 制服丝袜中文字幕亚洲| 美女精品在线| 免费成人看片| 欧美成人vr18sexvr| 丝袜老师办公室里做好紧好爽| 亚洲精品综合一区二区三区| 91国内免费在线视频| 成人美女视频| 亚洲国产岛国毛片在线| 久久久国产精品久久久| 日韩精品免费一区二区夜夜嗨| 538在线观看| 黄视频网站在线观看| 色天使综合视频| 综合av色偷偷网| 精品成人av一区| 国产精品极品美女在线观看免费| 久久综合精品国产一区二区三区| 人妻aⅴ无码一区二区三区| 国产视频每日更新| 欧美国产激情视频| 麻豆精品国产| 国产精品特级毛片一区二区三区| 欧洲亚洲精品视频| a毛片毛片av永久免费| 在线播放av片| 久久精视频免费在线久久完整在线看| 日韩精品一区二区三区四| 黄网视频午夜青春| 少女频道在线观看免费播放电视剧| 狠狠操视频网站| 99久久精品国产一区二区三区| 国产精品视频一区二区图片| 色婷婷综合五月| 国产精品电影在线观看| 国产精品黄色大片| 亚洲人成在线免费观看| 偷偷色噜狠狠狠狠的777米奇| 在线免费看污| 男人靠女人免费视频网站| 古装做爰无遮挡三级聊斋艳谭| 999www人成免费视频| 黄色性视频网站| 91香蕉视频网址| 小鲜肉gaygays免费动漫| 国产精品麻豆一区| 国产一区免费在线| av高清一区二区| 国产又粗又长又硬| 一本综合精品| 伊人色在线观看| 天天骑天天干| 男人的天堂av网| sm一区二区三区| 日本精品久久久久久久| 黄网站视频在线观看| 亚洲国产精品成人无久久精品| 国产精品视频白浆免费视频| 77导航福利在线| 国产在线一区二区三区| 僵尸再翻生在线观看免费国语| 国产精品videossex| 欧美日韩伦理一区二区| 亚洲色欲综合一区二区三区| 美女免费视频网站| 欧美性猛交xxxx乱| 麻豆一区二区在线观看| 亚洲专区欧美专区| 亚洲精品中文字幕有码专区| 青春娱乐分类视频精品2动漫| 久久久噜噜噜久久中文字幕色伊伊| 亚洲人体在线| 国产精品原创巨作av| 亚洲综合色在线观看| 香蕉视频在线观看黄| 亚洲人被黑人高潮完整版| 九九热国产精品视频| 欧美黑人精品一区二区不卡| 亚洲欧美清纯在线制服| 日韩写真在线| 日韩久久免费av| 91久久在线观看| 高潮毛片7777777毛片| 亚洲国产成人精品电影| 91网站最新地址| 欧美日本在线播放| 中文字幕精品www乱入免费视频| 久久精品盗摄| 日本大片在线看黄a∨免费| 国产精品69久久久久水密桃| 亚洲精华国产欧美| 欧美成人免费va影院高清| 欧美日韩一区二区三区在线| 在线黄色免费观看| 中文字幕日本最新乱码视频| 久久天天躁狠狠躁夜夜躁| 日韩毛片在线免费看| 日韩欧美视频一区| 人与牲动交xxxxbbbb高清| 欧美日韩不卡中文字幕在线| 国产卡一卡二卡三| 高清无码视频直接看| 黑粗硬大欧美视频| 爱情岛论坛亚洲自拍| 爱搞国产精品| 欧美大胆视频| 日本不卡高清视频一区| 日韩久久久久久久久久久| 国产一级不卡视频| 黄色电影免费在线观看| 欧美性一二三区| 欧美精品hd| 激情都市亚洲| 草草视频在线观看| 好吊色一区二区三区| 色av一区二区| 麻豆av一区二区三区| 久久精品人人做人人爽电影| 99热这里只有精品1| 亚洲国模精品私拍| 亚洲小说区图片区情欲小说| 不卡的看片网站| 国产精品一区二区3区| 日本欧美精品久久久| 在线免费观看羞羞视频一区二区| 欧美人动性xxxxz0oz| 自拍偷拍视频在线| 国产日韩欧美a| 欧美三级华人主播| 国产成人97精品免费看片| 色香色香欲天天天影视综合网| 国产成a人亚洲精v品| 国产亚洲xxx| 日韩欧美激情一区| 日本不卡一二区| 久久狠狠婷婷| 亚洲国产一区二区久久久777| 欧美电视剧在线看免费| 日韩女同互慰一区二区| 粉嫩av懂色av蜜臀av分享| 在线观看毛片av| 九色视频网站| 无码av天堂一区二区三区| 麻豆网站在线观看| 性欧美69xoxoxoxo| av在线加勒比| 国产成人精品免费看在线播放| 国产欧美午夜| 欧美日韩国产欧| 91精品啪在线观看国产18| 亚洲欧美丝袜中文综合| 男人天堂a在线| 夜色福利刺激| 久久精子c满五个校花| 国产精品三区www17con| 婷婷综合在线| 欧美在线视频a| 116极品美女午夜一级| 九九99久久精品在免费线bt| 欧美激情精品久久久久久| 久久久夜色精品亚洲| 亚洲深夜福利在线观看| 9797在线看片亚洲精品| 色噜噜色狠狠狠狠狠综合色一| 裸体av在线| 福利片在线看| 国产日韩欧美精品一区二区三区| 美女又爽又黄视频毛茸茸| 国产一区二区三区蝌蚪| 欧美在线播放一区二区| 好吊视频在线观看| 石原莉奈在线亚洲二区| 久久久天堂av| 日韩精品欧美在线| 91精东传媒理伦片在线观看| 欧美一区二区久久久| 国产一区二区免费电影| 好久没做在线观看|