123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- <template>
- <div class="barrageContainer" ref="barrageContainer">
- <slot />
- </div>
- </template>
- <script>
- import { CircularLinkedList } from './circularLinkedList.js'
- export default {
- props: {
- // 动画时间
- wheelTime: {
- type: Number,
- default: 3000
- },
- // 隐藏的过度距离
- excessive: {
- type: Number,
- default: 500
- },
- // 距离顶部最小高度
- mintop: {
- type: Number,
- default: 100
- },
- // 距离底部最小高度
- minbottom: {
- type: Number,
- default: 100
- },
- // 弹幕样式
- barrageStyle: {
- type: Object,
- default: () => ({})
- },
- // 默认的数据
- // 对象中必要参数又id与time
- // 默认以text为展示内容,text可以是文本或者是返回文本的函数。没有则展示id
- defaultBarrage: {
- type: Array,
- default: () => []
- }
- },
- data() {
- return {
- link: new CircularLinkedList(),
- containerWidth: 0,
- containerHeight: 0
- }
- },
- created() {
- this.defaultBarrage.map(item => {
- this.push(item)
- })
- },
- methods: {
- // 计算容器高度
- kg() {
- const element = this.$refs.barrageContainer
- this.containerWidth = element.offsetWidth
- this.containerHeight = element.offsetHeight
- },
- // 向后追加
- push(val) {
- this.link.append(val)
- },
- // 向前追加
- unshift(val) {
- this.link.prepend(val)
- },
- // 执行开始
- execute() {
- if (this.link.getLength() > 0) {
- this.currentData = this.link.head
- this.kg()
- this.dongtai()
- this.$nextTick(() => {
- this.start()
- })
- }
- },
- // 关闭
- close() {
- if (this.timeId) {
- clearTimeout(this.timeId)
- }
- // 删除样式
- const style = document.getElementById('dynamic-animation-style')
- if (style) {
- style.parentNode.removeChild(style)
- }
- // 删除元素
- document.querySelectorAll('.newBarrageChild').forEach(element => {
- element.remove()
- })
- },
- // 开始
- start() {
- if (this.timeId) {
- clearTimeout(this.timeId)
- }
- // 上一个距离下一个的时间
- var timeNum2 = Math.abs(
- new Date(this.currentData?.next?.value?.time).getTime() - new Date(this.currentData?.value?.time).getTime()
- )
- // 获取间隔时间
- var timenum =
- this?.currentData?.next === this.link?.head
- ? this.wheelTime
- : timeNum2 > this.wheelTime
- ? this.wheelTime
- : timeNum2
- // 删除之前的
- var node = document.getElementById(this.currentData?.value?.id)
- if (node) {
- node.parentNode.removeChild(node)
- }
- // 追加新的元素
- var parent = this.$refs.barrageContainer
- var newChild = document.createElement('div')
- newChild.id = this.currentData?.value?.id
- newChild.className = 'barrage newBarrageChild'
- newChild.style.top = `${this.getRandomIntInRange(
- this.mintop,
- this.containerHeight > this.minbottom ? this.containerHeight - this.minbottom : this.minbottom
- )}px`
- for (var key in this.barrageStyle) {
- newChild.style[key] = this.barrageStyle[key]
- }
- newChild.style.animation = `moveRight ${this.wheelTime / 1000}s linear infinite`
- newChild.innerText =
- typeof this.currentData?.value?.text === 'function'
- ? this.currentData?.value?.text?.()
- : typeof this.currentData?.value?.text === 'string'
- ? this.currentData?.value?.text
- : this.currentData?.value?.id
- parent.appendChild(newChild)
- // 赋值下一个数据为当前数据
- this.currentData = this.currentData.next
- // 定时器下一次执行追加
- this.timeId = setTimeout(() => {
- this.start()
- }, timenum)
- },
- // 获取随机高度
- getRandomIntInRange(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min
- },
- // 生成uid
- uid() {
- let d = new Date().getTime()
- let d2 = (performance && performance.now && performance.now() * 1000) || 0
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
- let r = Math.random() * 16
- if (d > 0) {
- r = (d + r) % 16 | 0
- d = Math.floor(d / 16)
- } else {
- r = (d2 + r) % 16 | 0
- d2 = Math.floor(d2 / 16)
- }
- return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16)
- })
- },
- dongtai() {
- // 创建一个 <style> 标签
- const style = document.createElement('style')
- style.id = 'dynamic-animation-style'
- style.type = 'text/css'
- style.innerHTML = `
- @keyframes moveRight {
- from {
- right: 0;
- }
- to {
- right: ${this.containerWidth + this.excessive}px;
- }
- }
- `
- document.getElementsByTagName('head')[0].appendChild(style)
- }
- }
- }
- </script>
- <style lang="scss">
- .barrageContainer {
- width: 100%;
- height: 100%;
- position: relative;
- overflow: hidden;
- .barrage {
- position: absolute;
- z-index: 9999999;
- transform: translateX(100%);
- }
- }
- </style>
|