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

基于Vue設(shè)計實現(xiàn)一個彈幕組件

 更新時間:2023年06月13日 11:15:19   作者:前端小張同學(xué)  
這篇文章主要給大家分享一個開發(fā)中常見的需求,接下來將為大家詳細介紹彈幕的實現(xiàn)以及設(shè)計思路一步一步描述出來,希望大家能夠喜歡

1.關(guān)于彈幕設(shè)計思想

1.1業(yè)務(wù)層 | 視圖層(全局組件)

從業(yè)務(wù)角度來說,如果你設(shè)計的是全局彈幕組件,你要考慮以下幾點。

  • 容器的高度?
  • 容器層次結(jié)構(gòu)劃分?
  • 渲染彈幕的方式,使用組件的人應(yīng)該傳遞什么數(shù)據(jù)?
  • 是否支持全屏彈幕?
  • 是否支持彈幕關(guān)閉和開啟?
  • 是否需要重置彈幕?
  • 是否支持暫停彈幕?
  • 是否需要集成發(fā)送功能?

設(shè)計方案考慮完整了以后,你將可以開始考慮 數(shù)據(jù)層的設(shè)計

1.2數(shù)據(jù)層

從數(shù)據(jù)角度來說每一條彈幕無非是一個element,然后把彈幕內(nèi)容放到這個element元素中,并且給 element 添加動畫,那接下來,你應(yīng)該這樣考慮。

  • 彈幕是JS對象?它的屬性有哪些?
  • 誰去管理這些彈幕?如何讓他能夠支持暫停和關(guān)閉?
  • 你如何把后臺的數(shù)據(jù),與你前臺的一些靜態(tài)數(shù)據(jù)進行合并,創(chuàng)造出一個完整對象?
  • 你怎么去渲染這些彈幕?
  • 你想要幾秒創(chuàng)建一次彈幕并在容器內(nèi)顯示和運行?
  • 彈幕具備哪些靈活的屬性?運行動畫時間 , 用戶自己發(fā)布的彈幕樣式定制? 又或者,彈幕需要幾條彈道內(nèi)運行等等這些你都需要考慮。

數(shù)據(jù)設(shè)計方案考慮完整了以后,你將可以開始考慮 數(shù)據(jù)管理層的設(shè)計

1.3數(shù)據(jù)管理層

從管理的角度來說,外界調(diào)用某些方法,你即可快速的響應(yīng)操作,例如外界調(diào)用 open 方法,你就播放彈幕,調(diào)用Stop方法,你就關(guān)閉彈幕 接下來,你應(yīng)該考慮以下幾點。

  • 面向?qū)ο笤O(shè)計,應(yīng)該提供哪些方法,具備哪些功能?
  • 調(diào)用了指定的方法,應(yīng)該怎么對數(shù)據(jù)進行操作。
  • 如何對彈幕做性能優(yōu)化?

到這里 , 我們設(shè)計方案基本完成,接下來我們可以開始編寫代碼。

2.代碼實現(xiàn)

2.1數(shù)據(jù)層設(shè)計方案實現(xiàn)

我們需要構(gòu)建一個 Barrage 類 ,我們每次去創(chuàng)建一個彈幕的時候都會 new Barrage,讓他幫助我們生成一些彈幕屬性。

export class Barrage {
  constructor(obj) {
  // 每次 new Barrage()  傳入一個 后臺返回的數(shù)據(jù)對象 obj
    const { barrageId, speed, level, top, jumpUrl, barrageContent, animationPlayState, ...args } = obj
    this.barrageId = barrageId; // id : 每條彈幕的唯一id
    this.speed = speed; // speed : 彈幕運行的速度,由外界控制 
    this.level = level; // level : 彈幕的層級 --> 彈幕可分為設(shè)計可分為 上下 1 , 1 兩個層級 ,可決定彈幕的顯示是全屏還是半屏顯示
    this.top = top; //  top :彈幕生成的位置相對于 level 的層級 決定 ,相對于 Level 層級 盒子距離頂部的位置
    this.jumpUrl = jumpUrl; //  jumpUrl :點擊彈幕需要跳轉(zhuǎn)的鏈接
    this.barrageContent = barrageContent; // barrageContent : 彈幕的內(nèi)容
    this.animationPlayState = ''; // 設(shè)計彈幕 是否可 點擊暫停功能
    this.color = '#FFF' // 彈幕顏色
    this.args = args // 除去Barrage類之外的一些數(shù)據(jù)屬性全部丟到這里,例如后臺返回的數(shù)據(jù)
  }
}

2.2數(shù)據(jù)管理層設(shè)計方案實現(xiàn)

我們在這里實現(xiàn)了 , 彈幕的 增加,刪除,初始化,重置,關(guān)閉 , 開啟功能

1.實現(xiàn)彈幕開啟功能

BarrageManager.js

export class BarrageManager {
constructor(barrageVue) {
    this.barrages = []; // 填彈幕的數(shù)組
    this.barragesIds = [] // 批量刪除彈幕的數(shù)組id
    this.sourceBarrages = [] // 源彈幕數(shù)據(jù)
    this.timer = null //控制彈幕的開啟和關(guān)
    this.barrageVue = barrageVue // 彈幕組件實例
    this.deleteCount = 0, // 銷毀彈幕的總數(shù)
    this.lastDeleteCount = 0, // 最后可銷毀的數(shù)量
    this.row = 0,
    this.count = 0
  }
  init(barrages) {
    this.sourceBarrages = barrages
    this.deleteCount = parseInt(this.sourceBarrages.length / deleteQuantity.FIFTY) // 計算可刪除數(shù)量 
    this.lastDeleteCount = this.sourceBarrages.length % deleteQuantity.FIFTY // 計算 最后一次可刪除數(shù)量
  }
   /**
   * 
   * @param {*} barrages 接收一個彈幕數(shù)組數(shù)據(jù) 
   * @description 循環(huán)創(chuàng)建 彈幕對象 ,將后臺數(shù)據(jù)與 創(chuàng)建彈幕的屬性結(jié)合 存入彈幕數(shù)組
   */
  loopCreateBarrage(barrages) {
    const { rows, createTime, crearteBarrageObject } = this.barrageVue
    let maxRows = rows / 2 // 最大的彈幕行數(shù)
    this.timer = setInterval(() => {
      for (let i = 0; i < 1; i++) {
        let barrageItem = barrages[this.count]
        if (this.row >= maxRows) { this.row = 0 } // 如果當(dāng)前已經(jīng)到了 最大的彈幕行數(shù)臨界點則 回到第0 行彈道繼續(xù) 創(chuàng)建
        if (!barrageItem) return clearInterval(this.timer) // 如果取不到了則證明沒數(shù)據(jù)了 , 結(jié)束彈幕展示
        const item = crearteBarrageObject({ row: this.row, ...barrageItem }) // 添加對象到 彈幕數(shù)組中
        this.addBarrage(item)
        this.count++ // 用于取值 ,取了多少條
        this.row++ // 用于彈道
      }
    }, createTime * 1000);
  }
   /**
   * @param {*} barrages 傳入一個彈幕數(shù)組數(shù)據(jù) 
   * @returns 無返回值
   * @description 調(diào)用 該方法 開始播放彈幕
   */
  open(barrages) {
    if (barrages.length === 0) return
    this.init(barrages)
    this.loopCreateBarrage(this.sourceBarrages)
    }
}

在這里我們初始化了一個 open 方法,并接收一個數(shù)組 ,并調(diào)用了 init 方法 去做初始化操作,并調(diào)用了 循環(huán)創(chuàng)建的方法,沒 createTime 秒創(chuàng)建一條彈幕,加入到彈幕數(shù)組中。

2.連接視圖層

2.3視圖層 | 業(yè)務(wù)層設(shè)計方案實現(xiàn)

index.vue

<template>
  <div class="barrage">
    <div class="barrage-container" ref="barrageContainer">
      <div class="barrage-half-screen" ref="halfScreenContainer">
        <template v-for="item in barrageFiltering.level1">
          <barrage-item 
            :item="item" :class="{pausedAnimation : paused }" 
            :options='barrageTypeCallback(item)' 
            @destory="destoryBraageItem" :key="item.barrageId">
          </barrage-item>
        </template>
      </div>
      <div class="barrage-full-screen" v-if="fullScreen">
        <template v-for="item in barrageFiltering.level2">
          <barrage-item 
            :item="item" :class="{pausedAnimation : paused }"
            :options='barrageTypeCallback(item)'
            @destory="destoryBraageItem" :key="item.barrageId">
          </barrage-item>
        </template>
      </div>
    </div>
    <user-input ref="publishBarrage" v-if="openPublishBarrage" @onBlur="handleBlur">
      <template #user-operatio-right>
        <!-- 處理兼容性問題 ios 和 安卓 觸發(fā)點擊事件 -->
        <div class="send" @click="sendBarrage($event)" v-if="IOS">
          <slot name="rightRegion"></slot>
        </div>
        <div class="send" @mousedown="sendBarrage($event)" v-else>
          <slot name="rightRegion"></slot>
        </div>
      </template>
    </user-input>
  </div>
</template>
export default {
  created () {
    this.barrageManager = new BarrageManager(this)
  },
  mounted() {
    // 初始化彈幕渲染數(shù)據(jù)
    this.initBarrageRenderData();
  },
  data() {
    return {
      barrageManager : null,
      isClickSend: false,
      paused : false
    };
  },
  methods : {
    initBarrageRenderData() {
      this.barrageManager.open(this.barrages);
    },
  },
  computed : {
   barrageFiltering() {
      return {
        level1:
          this.barrageManager.barrages.filter(
            item => item.level === barrageLevel.LEVEL1
          ) || [],
        level2:
          this.barrageManager.barrages.filter(
            item => item.level === barrageLevel.LEVEL2
          ) || []
      };
    },
  }
}

視圖層知識點回顧

在這里我們在彈幕組件創(chuàng)建的時候去創(chuàng)建了一個 彈幕管理對象,并且在掛載的時候去初始化了以下 彈幕渲染的數(shù)據(jù),于是我們調(diào)用了 彈幕管理類open方法,這樣當(dāng)組件掛載時,就會去渲染 barrageFiltering 數(shù)據(jù),這里我們是在管理類中拿到了管理類中循環(huán)創(chuàng)建的數(shù)據(jù)。

open 方法實現(xiàn)

到這里我們的彈幕的開啟基本上已經(jīng)完成了,可以看得出,如果你是這樣設(shè)計的,你只需要在組件中調(diào)用管理類的一些方法,它就能幫你完成一些功能。

3.實現(xiàn)彈幕關(guān)閉功能

barrageManager.js

 class BarrageManager {
 constructor(barrageVue) {
    this.barrages = []; // 填彈幕的數(shù)組
    this.barragesIds = [] // 批量刪除彈幕的數(shù)組id
    this.sourceBarrages = [] // 源彈幕數(shù)據(jù)
    this.timer = null //控制彈幕的開啟和關(guān)
    this.barrageVue = barrageVue // 彈幕組件實例
    this.deleteCount = 0, // 銷毀彈幕的總數(shù)
    this.lastDeleteCount = 0, // 最后可銷毀的數(shù)量
    this.row = 0,
    this.count = 0
  }
 /**
   * @return 無返回值 
   * @description 調(diào)用close 方法 關(guān)閉彈幕
   */
  close() {
    clearInterval(this.timer)
    this.removeAllBarrage()
  }
   /**
   * @description 刪除全部的彈幕數(shù)據(jù)
   */
  removeAllBarrage() {
    this.barrages = []
  }
 }

關(guān)閉功能知識點回顧

在這里我們可以看到,關(guān)閉彈幕的功能其實很簡單,你只需要把開啟彈幕時的定時器關(guān)閉,并且把彈幕數(shù)組數(shù)據(jù)清空就可以了

4.實現(xiàn)彈幕添加功能

index.vue

  addBarrage(barrageContent) {
      // 獲取當(dāng)前 定時器正在創(chuàng)建的 一行
      let currentRow = this.barrageManager.getRow();
      let row = currentRow === this.rows / 2 ? 0 : currentRow + 1;
      if (row === this.rows / 2) {
        row = 0;
      }
      let myBarrage = {
        row,
        barrageId: '1686292223004',
        barrageContent,
        style: this.style,
        type: "mySelf", // 用戶自己發(fā)布的彈幕類型
        barrageCategory: this.userBarrageType
      };
      const item = this.crearteBarrageObject(myBarrage);
      this.barrageManager.addBarrage(item); // 數(shù)據(jù)準(zhǔn)備好了 調(diào)用添加方法
      console.info("發(fā)送成功")
      this.barrageManager.setRow(row + 1);
    },

barrageManager.js

 class BarrageManager {
 constructor(barrageVue) {
    this.barrages = []; // 填彈幕的數(shù)組
    this.barragesIds = [] // 批量刪除彈幕的數(shù)組id
    this.sourceBarrages = [] // 源彈幕數(shù)據(jù)
    this.timer = null //控制彈幕的開啟和關(guān)
    this.barrageVue = barrageVue // 彈幕組件實例
    this.deleteCount = 0, // 銷毀彈幕的總數(shù)
    this.lastDeleteCount = 0, // 最后可銷毀的數(shù)量
    this.row = 0,
    this.count = 0
  }
   /**
   * 
   * @param {*} obj  合并完整的的彈幕對象
   * @param  {...any} args 開發(fā)者以后可能需要傳遞的剩余參數(shù)
   */
  addBarrage(obj, ...args) {
    const barrage = new Barrage(obj, ...args)
    this.barrages.push(barrage)
  }
 }

添加功能知識點回顧

在這里我們可以看到,添加的時候,我們 組件 只需要去調(diào)用 addBarrage 方法進行彈幕添加,并且在調(diào)用的過程中我們?nèi)?new Barrage 這個類 , 也就是我們之前準(zhǔn)備好的 彈幕數(shù)據(jù)類 | 數(shù)據(jù)層設(shè)計

5.實現(xiàn)彈幕刪除功能

class BarrageManager {
constructor(barrageVue) {
    this.barrages = []; // 填彈幕的數(shù)組
    this.barragesIds = [] // 批量刪除彈幕的數(shù)組id
    this.sourceBarrages = [] // 源彈幕數(shù)據(jù)
    this.timer = null //控制彈幕的開啟和關(guān)
    this.barrageVue = barrageVue // 彈幕組件實例
    this.deleteCount = 0, // 銷毀彈幕的總數(shù)
    this.lastDeleteCount = 0, // 最后可銷毀的數(shù)量
    this.row = 0,
    this.count = 0
  }
/**
   * 
   * @param {*} barrageId  // 入?yún)?彈幕id
   * @returns 無返回值
   * @description 添加需要批量刪除的 id 到 批量刪除的棧中 barragesIds
   */
  addBatchRemoveId(barrageId) {
    this.barragesIds.push(barrageId)
    this.batchRemoveHandle()
  }
  /**
   * 
   * @param {*} start  你需要從第幾位開始刪除
   * @param {*} deleteCount  // 刪除的總數(shù)是多少個
   * @returns 無返回值
   */
  batchRemoveBarrage(start, deleteCount) {
    if (this.barrages.length === 0) return
    this.barrages.splice(start, deleteCount)
  }
  batchRemoveId(start, deleteCount) {
    if (this.barragesIds.length === 0) return
    this.barragesIds.splice(start, deleteCount)
  }
  /**
   * @param {*} barrageId  彈幕 id 針對單個刪除彈幕時 使用 
   */
  removeBarrage(barrageId) {
    let index = this.barrages.findIndex(item => item.barrageId === barrageId)
    this.barrages.splice(index, 1)
  }
  /**
   * @description 刪除全部的彈幕數(shù)據(jù)
   */
  removeAllBarrage() {
    this.barrages = []
  }
  // 批量移除邏輯處理
  batchRemoveHandle() {
    if (this.deleteCount === 0 || this.deleteCount === 0) {
      if (this.barragesIds.length === this.lastDeleteCount) {
        this.batchRemoveBarrage(0, this.lastDeleteCount)
        this.batchRemoveId(0, this.lastDeleteCount)
      }
    } else {
      if (this.barragesIds.length === deleteQuantity.FIFTY) {
        this.batchRemoveBarrage(0, deleteQuantity.FIFTY)
        this.batchRemoveId(0, deleteQuantity.FIFTY)
        this.deleteCount--
      }
    }
  }
} 

刪除功能知識點回顧

在這里我們可以看到,刪除的時候我們把每一個彈幕id加入到了一個數(shù)組中 , 當(dāng) 彈幕id數(shù)組長度達到我想要刪除的數(shù)量的時候, 調(diào)用 splice 方法 執(zhí)行批量刪除操作,當(dāng)數(shù)據(jù)發(fā)生更新,視圖也會更新,這樣我們只需要執(zhí)行一次dom操作,不需要每一次刪除彈幕更新dom,造成不必要的性能消耗。

6.實現(xiàn)彈幕重置功能

到這里,我相信你已經(jīng)明白了我的設(shè)計,如果現(xiàn)在讓你實現(xiàn)一個 重置彈幕方法 你會怎么做 ? 是不是只需要,調(diào)用一下 close 方法 , 然后再去 調(diào)用 open方法就可以了,ok 接下來我會將完整版代碼 放入我的github倉庫,小伙伴們可以去拉取 倉庫鏈接,具體代碼還需要小伙伴們自己從頭閱讀一次,這里只是說明了部分內(nèi)容 , 閱讀完成后 , 你就會徹底理解。

關(guān)于 barrageTypeCallback 函數(shù)

這個方法主要是可以解決彈幕樣式定制的問題,你可以根據(jù)每個彈幕的類型 做不同的樣式對象返回,我們會自動幫你渲染。

barrageTypeCallback ( {args} ) {
 const { barrageCategary } = args
 if(barrageCategary === 'type1'){
 retun {
 className : 'classOne',
 children : {
     show : false
     i : {
     showIcon : false,
     style : {
     color : 'red'
     }
     }
    }
   }
 }
 else{
 return { className : 'default' }
 }
}

以上就是基于Vue設(shè)計實現(xiàn)一個彈幕組件的詳細內(nèi)容,更多關(guān)于Vue彈幕組件的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue-router中hash模式與history模式的區(qū)別

    vue-router中hash模式與history模式的區(qū)別

    為了構(gòu)建 SPA(單頁面應(yīng)用),需要引入前端路由系統(tǒng),這就是 Vue-Router 存在的意義,而這篇文章主要給大家介紹了關(guān)于vue-router中兩種模式區(qū)別的相關(guān)資料,分別是hash模式、history模式,需要的朋友可以參考下
    2021-06-06
  • Vue中父子組件通信與事件觸發(fā)的深入講解

    Vue中父子組件通信與事件觸發(fā)的深入講解

    組件是Vue核心功能之一,合理的組件化,可以減少我們代碼的冗余,提高項目的可維護性,下面這篇文章主要給大家介紹了關(guān)于Vue中父子組件通信與事件觸發(fā)的相關(guān)資料,需要的朋友可以參考下
    2022-03-03
  • Vue3父子組件互調(diào)方法的實現(xiàn)

    Vue3父子組件互調(diào)方法的實現(xiàn)

    本文主要介紹了Vue3父子組件互調(diào)方法的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • vue3中watch和watchEffect的區(qū)別

    vue3中watch和watchEffect的區(qū)別

    本文主要介紹了vue3中watch和watchEffect的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • vue項目出現(xiàn)頁面空白的解決方案

    vue項目出現(xiàn)頁面空白的解決方案

    今天小編就為大家分享一篇vue項目出現(xiàn)頁面空白的解決方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • Vue3?跨域配置devServer的參數(shù)和設(shè)置方法

    Vue3?跨域配置devServer的參數(shù)和設(shè)置方法

    這篇文章主要介紹了Vue3?跨域配置devServer的參數(shù)和設(shè)置,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-04-04
  • Vue使用虛擬dom進行渲染view的方法

    Vue使用虛擬dom進行渲染view的方法

    這篇文章主要介紹了Vue使用虛擬dom進行渲染view的方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-12-12
  • 解決vue自定義全局消息框組件問題

    解決vue自定義全局消息框組件問題

    這篇文章主要介紹了vue自定義全局消息框組件問題及解決方法,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • vue-cli構(gòu)建項目下使用微信分享功能

    vue-cli構(gòu)建項目下使用微信分享功能

    這篇文章主要介紹了vue-cli構(gòu)建項目下使用微信分享功能,本文通過實例代碼相結(jié)合的形式給大家介紹的非常詳細,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2018-05-05
  • Vue 3中toRaw和markRaw的使用教程

    Vue 3中toRaw和markRaw的使用教程

    toRaw和markRaw是Vue 3中引入的新API,用于更精細地控制對象的代理和響應(yīng)性,它們提供了在需要時繞過代理或禁用響應(yīng)性的能力,有助于提高性能和更好地與第三方庫進行集成,本文給大家介紹Vue 3中toRaw和markRaw的使用,感興趣的朋友一起看看吧
    2023-10-10

最新評論