最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

彈幕功能

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

效果圖

demo 

源碼地址

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

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

實(shí)現(xiàn)步驟

先加入一個(gè)canvas標(biāo)簽,這里有個(gè)注意點(diǎn),關(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> 
// 后面會用到

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

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()
  });
}
// 隨機(jī)獲得y坐標(biāo)
function getY() {
  let range = Math.floor(600 / gap); // 跑道數(shù)量
  return Math.floor(Math.random() * range + 1) * gap;
}
// 隨機(jī)獲得顏色
function getColor() {
  return `${Math.floor(Math.random() * 16777215).toString(16)}`;
}
// 寫一個(gè)for循環(huán),初始化30條彈幕
for (let i = 0; i < 30; i++) {
  pushDm(`It's barrage ${i}`);
}

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

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時(shí))
  if (!dmArr.length) stop(); // 如果沒有新彈幕了,就停止計(jì)時(shí)器
  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í),從數(shù)組中移除該項(xiàng)
      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);
}

我們還需要一個(gè)輸入框,來實(shí)現(xiàn)手動(dòng)添加彈幕功能

<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ìn)的地方和疑問?速度不恒定時(shí),怎么保持彈幕不重疊視頻彈幕是根據(jù)彈幕發(fā)送時(shí)間點(diǎn)來定位到視頻的每一幀?如何實(shí)現(xiàn)?

總結(jié)

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

相關(guān)文章

  • 手寫vue無限滾動(dòng)指令的詳細(xì)過程

    手寫vue無限滾動(dòng)指令的詳細(xì)過程

    今天在移動(dòng)端項(xiàng)目中遇見一個(gè)需求,需要數(shù)據(jù)無限滾動(dòng),所以下面這篇文章主要給大家介紹了關(guān)于手寫vue無限滾動(dòng)指令的詳細(xì)過程,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • vue中想要mock數(shù)據(jù)在線上環(huán)境生效如何操作

    vue中想要mock數(shù)據(jù)在線上環(huán)境生效如何操作

    本文主要介紹了在配置了mock數(shù)據(jù)之后在線上環(huán)境使用,主要通過在main.ts文件中注冊和vite.config.ts文件夾中配置插件來實(shí)現(xiàn),感興趣的可以了解一下
    2025-01-01
  • Vue多組件倉庫開發(fā)與發(fā)布詳解

    Vue多組件倉庫開發(fā)與發(fā)布詳解

    這篇文章主要介紹了Vue多組件倉庫開發(fā)與發(fā)布詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02
  • vue如何截取字符串

    vue如何截取字符串

    這篇文章主要介紹了vue如何截取字符串,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Vue3中引入、封裝和使用svg矢量圖的實(shí)現(xiàn)示例

    Vue3中引入、封裝和使用svg矢量圖的實(shí)現(xiàn)示例

    SVG全稱Scalable Vector Graphics,它是網(wǎng)絡(luò)上使用最廣泛的矢量圖格式,在項(xiàng)目開發(fā)過程中,我們經(jīng)常會用到svg矢量圖,而且我們使用svg以后,頁面上加載的不再是圖片資源,本文將給大家介紹Vue3中引入、封裝和使用svg矢量圖的實(shí)現(xiàn)示例,需要的朋友可以參考下
    2024-07-07
  • vue 擴(kuò)展現(xiàn)有組件的操作

    vue 擴(kuò)展現(xiàn)有組件的操作

    這篇文章主要介紹了vue 擴(kuò)展現(xiàn)有組件的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Vue中獲取圖片高度的兩種方法

    Vue中獲取圖片高度的兩種方法

    在使用Vue2開發(fā)移動(dòng)端頁面的時(shí)候,需要做一個(gè)效果,實(shí)現(xiàn)的方案是背景漸變,但是想要實(shí)現(xiàn)這個(gè)效果就必須進(jìn)行定位,我的背景高度需要在一個(gè)十分恰當(dāng)?shù)奈恢?但是我的圖片會隨著移動(dòng)端頁面的變化而發(fā)生高度的變化,為什么會變化?所以本文介紹了Vue中獲取圖片高度的方法
    2024-08-08
  • Vue el使用el-checkbox-group復(fù)選框進(jìn)行單選框方式

    Vue el使用el-checkbox-group復(fù)選框進(jìn)行單選框方式

    這篇文章主要介紹了Vue el使用el-checkbox-group復(fù)選框進(jìn)行單選框方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10
  • Vue實(shí)現(xiàn)簡單網(wǎng)頁計(jì)算器

    Vue實(shí)現(xiàn)簡單網(wǎng)頁計(jì)算器

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)簡單網(wǎng)頁計(jì)算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • Vue自動(dòng)生成組件示例總結(jié)

    Vue自動(dòng)生成組件示例總結(jié)

    在Vue中,我們可以使用unplugin-generate-component-name插件自動(dòng)基于目錄名稱生成組件名稱,這個(gè)插件使得在大型代碼庫中找到和管理組件更加容易和直觀,這篇文章主要介紹了Vue自動(dòng)生成組件示例總結(jié),需要的朋友可以參考下
    2023-12-12

最新評論

揭西县| 唐山市| 门头沟区| 灌南县| 遵义县| 颍上县| 永寿县| 和硕县| 栾城县| 本溪市| 任丘市| 花莲县| 景东| 湖州市| 清丰县| 句容市| 万年县| 偏关县| 斗六市| 安丘市| 繁峙县| 阜康市| 德保县| 浦北县| 微山县| 明光市| 泽库县| 武穴市| 靖江市| 松潘县| 吴桥县| 连云港市| 梁河县| 田林县| 永平县| 崇明县| 浪卡子县| 大余县| 桐柏县| 增城市| 科技|