前言
彈幕功能在大伙刷視頻、直播的時(shí)候肯定都有遇到過,可以讓觀看者之間有一個(gè)很好的互動(dòng)效果赃泡。我想用在vue3.X里用這個(gè)功能但是沒找到,就拿了2版本的改了下乘盼,在這推廣推廣升熊,歡迎大家來用!绸栅!
使用介紹
安裝
$ npm install vue3-barrage --save
導(dǎo)入
// main.ts
import vue3Barrage from 'vue3-barrage';
app.use(vue3Barrage);
案例
<template>
<vue3-barrage ref="barrage" :lanesCount="6" :boxHeight="data.stageHeight" :isShow="data.barrageIsShow" :list="data.list" :loop="data.barrageLoop" :speed="data.speed" attachId="barrage" :fontSize="data.fontSize">
<!-- 自定義彈幕樣式 -->
<template #barrage="list">
<span style="color: #00099">{{ list.item.msg }}</span>
</template>
</vue3-barrage>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue';
type PositionStatus = 'normal' | 'top' | 'bottom';
interface BarrageList {
msg: string | undefined;
position: PositionStatus;
}
// 響應(yīng)式數(shù)據(jù)
let data = reactive({
barrageList: [] as Array<BarrageList>,
msg: [
'禮',
'老子',
'孔子云:',
'何陋之有',
'談笑有鴻儒',
'孔子云:何陋之有级野?',
'山不在高,有仙則名',
'予謂菊阴幌,花之隱逸者也',
'無絲竹之亂耳勺阐,無案牘之勞形',
'Hello! vue3-barrage 0.0.1',
'崇禎五年十二月卷中,余住西湖',
'莫說相公癡,更有癡似相公者渊抽。',
'先天下之憂而憂蟆豫,后天下之樂而樂',
'是進(jìn)亦憂,退亦憂懒闷。然則何時(shí)而樂耶十减?',
'居廟堂之高則憂其民,處江湖之遠(yuǎn)則憂其君愤估。',
'嗟夫帮辟!予嘗求古仁人之心,或異二者之為玩焰,何哉由驹?',
'是日更定矣,余拏一小舟昔园,擁毳衣爐火蔓榄,獨(dú)往湖心亭看雪',
'惟長堤一痕、湖心亭一點(diǎn)默刚、與余舟一芥甥郑、舟中人兩三粒而已。',
'醉翁之意不在酒荤西,在乎山水之間也澜搅。山水之樂,得之心而寓之酒也邪锌。',
'然而禽鳥知山林之樂勉躺,而不知人之樂;人知從太守游而樂秃流,而不知太守之樂其樂也赂蕴。',
],
position: 'normal',
fontSize: 12,
stageHeight: 300,
barrageIsShow: true,
currentId: 0,
barrageLoop: true,
speed: 10
});
const addToList = () => {
if (data.position === 'bottom') {
const arr: Array<BarrageList> = Array.from({ length: 3 }, (e) => {
return {
id: ++data.currentId,
msg: data.msg[Math.floor(Math.random() * 20)],
position: 'bottom',
};
});
data.barrageList.push(...arr);
} else if (data.position === 'top') {
const arr: Array<BarrageList> = Array.from({ length: 3 }, (e) => {
return {
id: ++data.currentId,
msg: data.msg[Math.floor(Math.random() * 20)],
position: 'top',
};
});
data.barrageList.push(...arr);
} else {
const arr: Array<BarrageList> = Array.from({ length: 30 }, (e) => {
return {
id: ++data.currentId,
msg: data.msg[Math.floor(Math.random() * 20)],
position: 'top',
};
});
data.barrageList.push(...arr);
}
};
</script>
屬性
參數(shù) | 說明 | 類型 | 可選值 | 默認(rèn)值 |
---|---|---|---|---|
attachId | 掛載的DOM元素id,不設(shè)置就正常顯示 | string | ||
isShow | 是否展示彈幕 | Boolean | true | |
list | 彈幕列表 | Array | [] | |
lanesCount | 彈幕軌道數(shù)量 | Number | 5 | |
boxWidth | 元素寬度 | Number | 父元素寬度 | |
boxHeight | 元素高度 | Number | 父元素高度 | |
fontSize | 彈幕字體大小舶胀,單位px | Number | 18 | |
speed | 彈幕速度 | Number | 1-10 | 6 |
loop | 是否循環(huán)展示 | Boolean | false | |
defineLanes | 自定義彈幕顯示軌道。注意必須返回一個(gè)[1-lanesCount]的數(shù)字 | Function |
list屬性
參數(shù) | 說明 | 類型 |
---|---|---|
msg | 彈幕文本 | string |
position | 彈幕位置碧注。滾動(dòng)嚣伐、頂部固定、底部固定 | normal | top | bottom |
其他 | 自己定義的在插槽里自己使用萍丐,插槽使用見下面 |
方法
方法 | 說明 | 參數(shù) |
---|---|---|
maxRows | 最大行數(shù)改變時(shí)觸發(fā) | (value: number) |
插槽配置
<template>
<vue-barrage ref="barrage" :lanesCount="6" :boxHeight="data.stageHeight" :isShow="data.barrageIsShow" :list="data.list" :loop="data.barrageLoop" :speed="data.speed" attachId="barrage" :fontSize="data.fontSize">
<!-- 自定義彈幕樣式 -->
<!-- #barrage為聚名插槽轩端,必須為這個(gè),下面item也必須為item逝变,其他自定義 -->
<!-- item里自己加的東西就自己發(fā)揮了 -->
<template #barrage="xxx">
<span style="color: #00099">{{ xxx.item.msg }}</span>
</template>
</vue-barrage>
</template>
實(shí)現(xiàn)原理
看了幾個(gè)2版本的源代碼基茵,基本都是使用css的animation屬性實(shí)現(xiàn)動(dòng)畫的效果奋构。
我使用的是requestAnimationFrame結(jié)合css transform屬性實(shí)現(xiàn)動(dòng)畫的效果。requestAnimationFrame字面意思:請求動(dòng)畫幀拱层。官方解釋:幀動(dòng)畫弥臼。就是可以一幀一幀的執(zhí)行動(dòng)畫。詳細(xì)的介紹可以去這里看:全面了解requestAnimationFrame根灯。
requestAnimationFrame實(shí)現(xiàn)幀刷新径缅,然后配合方法修改transform參數(shù)從而達(dá)到移動(dòng)的效果。固定的效果就固定transform參數(shù)不變烙肺,到時(shí)間了移除就實(shí)現(xiàn)了纳猪。
核心原理就這兩句話,感興趣的朋友去源碼看下桃笙,原理簡單氏堤,就是數(shù)據(jù)的處理寫了一大堆。
缺點(diǎn)
還有不足的就是和時(shí)間的關(guān)聯(lián)沒實(shí)現(xiàn)搏明,拿到彈幕列表鼠锈,一股腦的全部顯示就沒了,不懂如何優(yōu)雅的和時(shí)間關(guān)聯(lián)熏瞄,有idea的朋友歡迎評論告訴下脚祟,十分感謝!