欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用canvas實現(xiàn)一個vue彈幕組件功能

 更新時間:2018年11月30日 08:28:14   作者:ideagay  
這篇文章主要介紹了使用canvas實現(xiàn)一個vue彈幕組件功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下

看B站時,對彈幕的實現(xiàn)產(chǎn)生了興趣,一開始想到用css3動畫去實現(xiàn),后來感覺這樣性能不是很好,查了下資料,發(fā)現(xiàn)可以用canvas實現(xiàn),于是就摸索著寫了一個簡單的彈幕。

彈幕功能

  1. 支持動態(tài)添加彈幕
  2. 彈幕不重疊
  3. 自定義彈幕顏色

效果圖

demo 

源碼地址

前端框架選了比較熟悉的vuejs

彈幕滾動的基本思路就是通過定時器不斷地改變彈幕的位置,時時重繪畫布。

實現(xiàn)步驟

先加入一個canvas標(biāo)簽,這里有個注意點,關(guān)于設(shè)備像素比對canvas的影響,會出現(xiàn)繪圖模糊。

<canvas width="600" height="600"></canvas> // 如果單純這樣寫,canvas會出現(xiàn)模糊
<canvas width="600" height="600" style="width: 300px;height: 300px">
</canvas>
//為了不出現(xiàn)模糊,需要設(shè)置canvas的css寬高為上下文寬高的1/devicePixelRatio,
本文是對于devicePixelRatio:2的設(shè)備設(shè)置的,該值可從window.devicePixelRatio取得。
<canvas ref="hiddenCanvas" width="0" height="0" style="display: none">
</canvas> 
// 后面會用到

我們先定義一個數(shù)組來存放彈幕數(shù)據(jù),一條彈幕信息,包括文本內(nèi)容,x,y坐標(biāo)位置,顏色,速度(可以是隨機或者固定,為了計算簡單,我們這里采用了固定的速度)

var dmArr = [];
var gap = 80; // 彈幕的上下間距
var hiddenCanvas = this.$refs.hiddenCanvas;
// 增加彈幕的方法
function pushDm(text, color) {
  let y = getY(); // 先確定跑道
  let x = 600; // 初始x坐標(biāo)為canvas的右邊界
  let delayWidth = 0; // 同跑道
  for (let i = 0, len = dmArr.length; i < len; i++) {
    let dm = dmArr[i];
    if (y === dm.y) { // 如果是同跑道,則往后排,設(shè)置一定的間隔,保證彈幕不會重疊;
      delayWidth += Math.floor(hiddenCanvas.getContext('2d').measureText(dm.text).width * 4 + 50);
    }  }
  dmArr.push({
    text: text,
    x: x + delayWidth,
    y: y,
    speed: 8,
    color: color || getColor()
  });
}
// 隨機獲得y坐標(biāo)
function getY() {
  let range = Math.floor(600 / gap); // 跑道數(shù)量
  return Math.floor(Math.random() * range + 1) * gap;
}
// 隨機獲得顏色
function getColor() {
  return `${Math.floor(Math.random() * 16777215).toString(16)}`;
}
// 寫一個for循環(huán),初始化30條彈幕
for (let i = 0; i < 30; i++) {
  pushDm(`It's barrage ${i}`);
}

接下來設(shè)置一個20ms的定時器,實現(xiàn)彈幕滾動效果

var timer = null;
var ctx = this.$refs.canvas.getContext('2d');
function start(){
 timer = setInterval(() => {
  ctx.clearRect(0, 0, 600, 600); // 每次需要清空畫布
  ctx.save();
  ctx.font = '30px Microsoft YaHei'; // 這里需要把字體大小設(shè)為需要顯示的css大小的2倍(devicePixelRatio為2時)
  if (!dmArr.length) stop(); // 如果沒有新彈幕了,就停止計時器
  for (let i = 0, len = this.dmArr.length; i < len; i++) {
    let dm = dmArr[i];
    let overRange = -ctx.measureText(dm.text).width * 2;
    dm.x -= dm.speed;
    if (dm.x < overRange) {
      dmArr.splice(i, 1); // 彈幕在畫布中不可見時,從數(shù)組中移除該項
      continue;
    }
    ctx.fillStyle = `#${dm.color}`;
    ctx.fillText(dm.text, dm.x, dm.y);
  }
  ctx.restore();
 }, 20);
}
function stop() {
  clearInterval(timer);
  ctx.clearRect(0, 0, 600, 600);
}

我們還需要一個輸入框,來實現(xiàn)手動添加彈幕功能

<input type="text" @keyup.enter="sent" v-model="dmInput" maxlength="20">

<button type="button" @click="sent">發(fā)表</button>
var dmInput = '';
var color = ''; // 可自定義彈幕的顏色
function sent() {
  if (!dmInput) return;
  stop();
  pushDm(dmInput, color);
  start();
  dmInput = '';
}

有待改進的地方和疑問?速度不恒定時,怎么保持彈幕不重疊視頻彈幕是根據(jù)彈幕發(fā)送時間點來定位到視頻的每一幀?如何實現(xiàn)?

總結(jié)

以上所述是小編給大家介紹的使用canvas實現(xiàn)一個vue彈幕組件功能,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關(guān)文章

  • 淺談vue中慎用style的scoped屬性

    淺談vue中慎用style的scoped屬性

    本篇文章主要介紹了淺談vue中慎用style的scoped屬性,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Vue中textarea自適應(yīng)高度方案的實現(xiàn)

    Vue中textarea自適應(yīng)高度方案的實現(xiàn)

    本文主要介紹了Vue中textarea自適應(yīng)高度方案的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • vue如何判斷安卓還是IOS

    vue如何判斷安卓還是IOS

    這篇文章主要介紹了vue如何判斷安卓還是IOS,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • 沒有搭建腳手架時vue組件的使用方式

    沒有搭建腳手架時vue組件的使用方式

    這篇文章主要介紹了沒有搭建腳手架時vue組件的使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue3組件更新中的DOM?diff算法示例詳解

    Vue3組件更新中的DOM?diff算法示例詳解

    虛擬dom是當(dāng)前前端最流行的兩個框架(vue和react)都用到的一種技術(shù),都說他能幫助vue和react提升渲染性能,提升用戶體驗,下面這篇文章主要給大家介紹了關(guān)于Vue3組件更新中的DOM?diff算法的相關(guān)資料,需要的朋友可以參考下
    2022-04-04
  • vue3中的watch和watchEffect實例詳解

    vue3中的watch和watchEffect實例詳解

    watch和watchEffect都是監(jiān)聽器,但在寫法和使用上有所區(qū)別,下面這篇文章主要給大家介紹了關(guān)于vue3中watch和watchEffect的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • 從零寫vue日歷組件

    從零寫vue日歷組件

    最近做項目遇到一個需求,需要制作一個定制化的日歷組件,本文主要介紹了從零寫vue日歷組件,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 在項目中封裝axios的實戰(zhàn)過程

    在項目中封裝axios的實戰(zhàn)過程

    這篇文章主要給大家介紹了關(guān)于如何在項目中封裝axios的相關(guān)資料,axios 請求的封裝,無非是為了方便代碼管理,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • iview+vue實現(xiàn)導(dǎo)入EXCEL預(yù)覽功能

    iview+vue實現(xiàn)導(dǎo)入EXCEL預(yù)覽功能

    這篇文章主要為大家詳細介紹了iview+vue實現(xiàn)導(dǎo)入EXCEL預(yù)覽功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • vue3移動端嵌入pdf的多種方法小結(jié)

    vue3移動端嵌入pdf的多種方法小結(jié)

    這篇文章主要介紹了vue3移動端嵌入pdf的多種方法小結(jié),使用embed嵌入有好處也有缺點,本文給大家講解的非常詳細,需要的朋友可以參考下
    2023-10-10

最新評論