feat(新年活动): 补充弹幕翻译,补充注释
This commit is contained in:
parent
996e5dbd5f
commit
995b2fba4c
@ -441,5 +441,8 @@
|
|||||||
"Spend 50000 coins in the game ({currentValue}/{targetValue})": "أنفق 50000 عملة في اللعبة ({currentValue}/{targetValue})",
|
"Spend 50000 coins in the game ({currentValue}/{targetValue})": "أنفق 50000 عملة في اللعبة ({currentValue}/{targetValue})",
|
||||||
"Gifts: 5 gifts({currentValue}/{targetValue})": "هدايا: 5 هدايا({currentValue}/{targetValue})",
|
"Gifts: 5 gifts({currentValue}/{targetValue})": "هدايا: 5 هدايا({currentValue}/{targetValue})",
|
||||||
"exchange_success_coins": "تم تبادل {amount} عملة بنجاح",
|
"exchange_success_coins": "تم تبادل {amount} عملة بنجاح",
|
||||||
"exchange_failed_coins": "فشل التبادل لـ {amount} عملة، يرجى المحاولة لاحقاً."
|
"exchange_failed_coins": "فشل التبادل لـ {amount} عملة، يرجى المحاولة لاحقاً.",
|
||||||
|
|
||||||
|
"barrage_won_prize": "فاز {nickname} بـ {prizeName}",
|
||||||
|
"barrage_won_the_prize": "فاز {nickname} بـ {prizeName}"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -441,5 +441,8 @@
|
|||||||
"Spend 50000 coins in the game ({currentValue}/{targetValue})": "Spend 50000 coins in the game ({currentValue}/{targetValue})",
|
"Spend 50000 coins in the game ({currentValue}/{targetValue})": "Spend 50000 coins in the game ({currentValue}/{targetValue})",
|
||||||
"Gifts: 5 gifts({currentValue}/{targetValue})": "Gifts: 5 gifts({currentValue}/{targetValue})",
|
"Gifts: 5 gifts({currentValue}/{targetValue})": "Gifts: 5 gifts({currentValue}/{targetValue})",
|
||||||
"exchange_success_coins": "Successfully exchanged {amount} coins",
|
"exchange_success_coins": "Successfully exchanged {amount} coins",
|
||||||
"exchange_failed_coins": "Exchange failed for {amount} coins, please try again later."
|
"exchange_failed_coins": "Exchange failed for {amount} coins, please try again later.",
|
||||||
|
|
||||||
|
"barrage_won_prize": "{nickname} won {prizeName}",
|
||||||
|
"barrage_won_the_prize": "{nickname} won the {prizeName}"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -441,5 +441,8 @@
|
|||||||
"Spend 50000 coins in the game ({currentValue}/{targetValue})": "在游戏内消费50000金币 ({currentValue}/{targetValue})",
|
"Spend 50000 coins in the game ({currentValue}/{targetValue})": "在游戏内消费50000金币 ({currentValue}/{targetValue})",
|
||||||
"Gifts: 5 gifts({currentValue}/{targetValue})": "礼物: 5个礼物({currentValue}/{targetValue})",
|
"Gifts: 5 gifts({currentValue}/{targetValue})": "礼物: 5个礼物({currentValue}/{targetValue})",
|
||||||
"exchange_success_coins": "成功兑换 {amount} 金币",
|
"exchange_success_coins": "成功兑换 {amount} 金币",
|
||||||
"exchange_failed_coins": "兑换 {amount} 金币失败,请稍后重试。"
|
"exchange_failed_coins": "兑换 {amount} 金币失败,请稍后重试。",
|
||||||
|
|
||||||
|
"barrage_won_prize": "{nickname} 赢得了 {prizeName}",
|
||||||
|
"barrage_won_the_prize": "{nickname} 赢得了 {prizeName}"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -64,7 +64,7 @@ import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
|
|||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { handleAvatarImageError } from '@/utils/imageHandler.js'
|
import { handleAvatarImageError } from '@/utils/imageHandler.js'
|
||||||
|
|
||||||
const { locale } = useI18n()
|
const { locale, t } = useI18n()
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
barrageList: {
|
barrageList: {
|
||||||
@ -91,16 +91,17 @@ const props = defineProps({
|
|||||||
|
|
||||||
const tracks = ref([[], []]) // 弹幕轨道数据
|
const tracks = ref([[], []]) // 弹幕轨道数据
|
||||||
const idCounter = ref(0) // 弹幕ID计数器
|
const idCounter = ref(0) // 弹幕ID计数器
|
||||||
const currentIndex = ref(0) // 当前播放索引(用于循环)
|
const currentIndex = ref(0) // 用于取下一项弹幕的索引
|
||||||
|
|
||||||
// 计算实际显示的轨道(过滤空轨道)
|
// 计算实际显示的轨道(过滤空轨道)
|
||||||
const visibleTracks = computed(() => tracks.value.filter((track) => track.length > 0))
|
const visibleTracks = computed(() => tracks.value.filter((track) => track.length > 0))
|
||||||
|
|
||||||
// 显示的文本
|
// 显示的文本
|
||||||
const barrageText = (item) => {
|
const barrageText = (item) => {
|
||||||
|
const params = { nickname: item.nickname, prizeName: item.prizeName }
|
||||||
return item.prizeType == 'GOLD' || item.prizeType == 'MONEY'
|
return item.prizeType == 'GOLD' || item.prizeType == 'MONEY'
|
||||||
? `${item.nickname} won ${item.prizeName}`
|
? t('barrage_won_prize', params)
|
||||||
: `${item.nickname} won the ${item.prizeName}`
|
: t('barrage_won_the_prize', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取弹幕样式
|
// 获取弹幕样式
|
||||||
@ -135,14 +136,14 @@ const getBarrageStyle = (item) => {
|
|||||||
const generateBarrageProps = (item) => {
|
const generateBarrageProps = (item) => {
|
||||||
const textLength = barrageText(item).length
|
const textLength = barrageText(item).length
|
||||||
return {
|
return {
|
||||||
duration: Math.max(8 - textLength * 0.2, 5) * (100 / props.speed), // 弹幕项持续时间
|
duration: Math.max(8 - textLength * 0.2, 5) * (100 / props.speed), // 弹幕项持续时间(每字符减少0.2秒,持续时间不低于5秒)
|
||||||
startPos: Math.floor(Math.random() * 21) - 10, // 弹幕项起始位置
|
startPos: Math.floor(Math.random() * 21) - 10, // 弹幕项起始位置(得到-10到10之间的随机整数,避免所有弹幕都从完全相同的起点开始移动)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加弹幕到轨道
|
// 添加弹幕到轨道
|
||||||
const addToTrack = (item) => {
|
const addToTrack = (item) => {
|
||||||
// 寻找最短的轨道
|
// 寻找最短的轨道的下标值
|
||||||
const trackIndex = tracks.value.reduce(
|
const trackIndex = tracks.value.reduce(
|
||||||
(minIndex, track, index) => (track.length < tracks.value[minIndex].length ? index : minIndex),
|
(minIndex, track, index) => (track.length < tracks.value[minIndex].length ? index : minIndex),
|
||||||
0
|
0
|
||||||
@ -151,14 +152,14 @@ const addToTrack = (item) => {
|
|||||||
if (tracks.value[trackIndex].length < props.maxItems) {
|
if (tracks.value[trackIndex].length < props.maxItems) {
|
||||||
tracks.value[trackIndex].push({
|
tracks.value[trackIndex].push({
|
||||||
...item,
|
...item,
|
||||||
id: idCounter.value++,
|
id: idCounter.value++, //寻找完成动画的弹幕项唯一标识
|
||||||
delay: Math.random() * 4, // 随机延迟(0-4秒)
|
delay: Math.random() * 4, // 随机延迟(0-4秒)
|
||||||
...generateBarrageProps(item),
|
...generateBarrageProps(item),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清理完成动画的弹幕
|
// 清理完成动画的弹幕(根据动画结束状态遍历)
|
||||||
const cleanCompleted = () => {
|
const cleanCompleted = () => {
|
||||||
tracks.value.forEach((track) => {
|
tracks.value.forEach((track) => {
|
||||||
for (let i = track.length - 1; i >= 0; i--) {
|
for (let i = track.length - 1; i >= 0; i--) {
|
||||||
@ -169,7 +170,7 @@ const cleanCompleted = () => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 弹幕动画结束处理
|
// 设置弹幕动画结束状态
|
||||||
const handleAnimationEnd = (id) => {
|
const handleAnimationEnd = (id) => {
|
||||||
tracks.value.forEach((track) => {
|
tracks.value.forEach((track) => {
|
||||||
const item = track.find((item) => item.id === id)
|
const item = track.find((item) => item.id === id)
|
||||||
@ -181,43 +182,45 @@ const handleAnimationEnd = (id) => {
|
|||||||
const getNextBarrage = () => {
|
const getNextBarrage = () => {
|
||||||
if (props.barrageList.length === 0) return null
|
if (props.barrageList.length === 0) return null
|
||||||
|
|
||||||
// 循环获取弹幕
|
const item = props.barrageList[currentIndex.value] // 取得下一项弹幕项
|
||||||
const item = props.barrageList[currentIndex.value]
|
currentIndex.value = (currentIndex.value + 1) % props.barrageList.length //索引达到最大时则重置为0
|
||||||
currentIndex.value = (currentIndex.value + 1) % props.barrageList.length
|
|
||||||
|
|
||||||
return { ...item } // 返回副本避免污染原始数据
|
return { ...item } // 返回副本避免污染原始数据
|
||||||
}
|
}
|
||||||
|
|
||||||
// 弹幕循环逻辑
|
// 弹幕循环逻辑
|
||||||
let barrageInterval = null
|
let barrageInterval = null
|
||||||
|
|
||||||
|
// 根据设置的时间间隔自动获取下一项弹幕
|
||||||
const startBarrage = () => {
|
const startBarrage = () => {
|
||||||
barrageInterval = setInterval(() => {
|
barrageInterval = setInterval(() => {
|
||||||
cleanCompleted()
|
cleanCompleted() // 清理完成动画的弹幕
|
||||||
|
|
||||||
const nextBarrage = getNextBarrage()
|
const nextBarrage = getNextBarrage() // 获取下一项弹幕
|
||||||
if (nextBarrage) {
|
if (nextBarrage) {
|
||||||
addToTrack(nextBarrage)
|
addToTrack(nextBarrage) // 添加弹幕到轨道
|
||||||
}
|
}
|
||||||
}, props.loopInterval)
|
}, props.loopInterval)
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(startBarrage)
|
onMounted(() => {
|
||||||
onUnmounted(() => clearInterval(barrageInterval))
|
startBarrage() // 开启弹幕循环
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
clearInterval(barrageInterval) // 清空弹幕
|
||||||
|
})
|
||||||
|
|
||||||
// 监听数据源变化
|
// 监听数据源变化
|
||||||
watch(
|
watch(
|
||||||
() => props.barrageList,
|
() => props.barrageList,
|
||||||
(newList) => {
|
(newList) => {
|
||||||
// 重置索引,确保重新开始循环
|
currentIndex.value = 0 // 重置索引,确保重新开始循环
|
||||||
currentIndex.value = 0
|
clearInterval(barrageInterval) // 清空弹幕
|
||||||
|
|
||||||
// 如果列表为空,停止生成新弹幕
|
// 如果列表为空,停止生成新弹幕
|
||||||
if (newList.length === 0) {
|
if (newList.length !== 0) {
|
||||||
clearInterval(barrageInterval)
|
startBarrage() // 重启弹幕循环
|
||||||
} else {
|
|
||||||
// 重启弹幕循环
|
|
||||||
clearInterval(barrageInterval)
|
|
||||||
startBarrage()
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user