Commit 3870608b authored by 黄韬's avatar 黄韬

[feat]横向弹幕

parent 129ec776
import React from 'react'
import React, { useState, useEffect, useCallback, useRef } from 'react'
import { View, Text } from '@tarojs/components'
import styles from './Barrage.module.less'
import Taro from '@tarojs/taro'
class Barrage extends React.Component {
constructor(props) {
super(props)
// 页面数据存储
this.state = {
barrageWay: [],
barrageList: []
}
this.timer = null
}
import styles from './Barrage.module.less'
componentDidMount() {
this.createData()
const self = this
setTimeout(() => {
self.addBarrageListObj()
}, 200)
}
const Barrage = props => {
const {
dataList = [
'1撒撒打算打算打算的',
'2撒撒打算打算打算的',
'3撒撒打算打算打算的',
'4撒撒打算打算打算的',
'5撒撒打算打算打算的',
'3撒撒打算打算打算的',
'3撒撒打算打算打算的',
'3撒撒打算打算打算的',
'3撒撒打算打算打算的',
'3撒撒打算打算打算的',
'3撒撒打算打算打算的',
'3撒撒打算打算打算的'
],
interval = 5000,
width = 500,
trackCount = 1
} = props
componentWillUnmount() {
clearInterval(this.timer)
}
const [ barrageList, setBarrageList ] = useState([])
const [ animationData, setAnimationData ] = useState(null)
const timer = useRef(null)
const nowIndex = useRef(0)
createData() {
const { dataList, trackCount = 1 } = this.props
const Tracks = Array.from(
{ length: trackCount },
(v, k) => (k + 1) * 40 - 40
)
this.setState({
barrageList: dataList.map((item, index) => ({
width: item.length * 17 + 5,
const createData = () => {
const Tracks = Array.from({ length: trackCount }, (v, k) => (k + 1) * 40 - 40)
// TODO 多轨道弹幕
setBarrageList(
dataList.map((item, index) => ({
top: Tracks[index < Tracks.length ? index : index % trackCount],
time: 5,
context: item
}))
})
)
}
/* *
* 因为从后台获取到的是全部的数据,所以要把数据分开,让每条数据有先后之分
* 每隔一秒往barrageList 数组插入一条数据
* */
addBarrageListObj() {
const self = this
const { barrageList, barrageWay } = this.state
let i = 0
this.timer = setInterval(function () {
barrageWay.push(barrageList[i])
self.setState({
barrageWay: barrageWay
})
i++
if (i === barrageList.length - 1) {
if (self.props.Infinite) {
i = 0
} else {
clearInterval(self.timer)
}
const callback = useCallback(() => {
timer.current = setInterval(() => {
setAnimationData(
Taro.createAnimation()
.translateX(nowIndex.current === 0 ? 0 : (-width / 2) * nowIndex.current)
.step({
duration: nowIndex.current === 0 ? 0 : 1000
})
.export()
)
if (nowIndex.current < barrageList.length - 1) {
nowIndex.current = nowIndex.current + 1
} else {
nowIndex.current = 0
}
}, 1500)
}
}, interval + 1000)
}, [ barrageList, width ])
useEffect(() => {
callback()
return () => clearInterval(timer.current)
}, [ callback ])
render() {
const { barrageWay } = this.state
return (
<View className={styles['barrage-fly']}>
{barrageWay.map((item, i) => {
if (!item?.context) return null
useEffect(() => {
createData()
return () => {}
}, [])
return (
<View id='barrage_wrap' style={`width:${width / 100}rem`} className={styles['barrage-wrap']}>
<View id='barrage_container' animation={animationData} className={styles['barrage-fly']}>
{barrageList.map((item, index) => {
return (
<View
key={i}
className={styles['barrage-textFly']}
style={`animation: ${styles.first} ${item.time}s linear forwards; top: ${item.top}px`}
>
<View id={`barrage-${index}`} key={index} style={`width:${width / 100}rem`} className={styles['barrage-textFly']}>
{/* 弹幕内容 */}
<Text className={styles['barrage-text']}>{item.context}</Text>
</View>
)
})}
</View>
)
}
</View>
)
}
export default Barrage
.barrage-wrap {
height: 64px;
border: 1px solid red;
overflow: hidden;
}
.barrage-fly {
position: relative;
height: 100%;
width: 700px;
z-index: 3;
display: flex;
}
.barrage-textFly {
position: absolute;
height: 64px;
line-height: 64px;
color: #f9c797;
font-size: 32px;
padding-right: 30px;
}
.barrage-textFly {
flex-shrink: 0;
height: 64px;
overflow: hidden;
line-height: 64px;
color: #f9c797;
font-size: 32px;
padding: 0 10px;
box-sizing: border-box;
text-align: center;
}
.barrage-text {
white-space: nowrap;
}
.barrage-text {
white-space: nowrap;
}
@keyframes first {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment