<template>
	<view class="sh-barrage">
		<!-- 纵向 start -->
		<block v-if="type == 'portrait'">
			<swiper :current="current" class="sh-barrage-swiper" autoplay circular vertical
				:display-multiple-items="length" :interval="speed" easing-function="easeInCubic"
				@change="swiper_change">
				<swiper-item v-for="(item, index) in items" :key="index">
					<view class="sh-barrage-swiper-item" :style="{
							backgroundColor: bgColor,
							color: foneColor
						}">
						<slot :item="item"></slot>
						{{ item.text }}
					</view>
				</swiper-item>
			</swiper>
		</block>
		<!-- 纵向 end -->
		<!-- 横向 start -->
		<block v-if="type == 'horizontal'">
			<block v-for="(item, index) in items" :key="index">
				<view class="sh-barrage-item horizontal" :class="item.show ? 'move' : ''" :style="{
						top: `${item.top}px`,
						backgroundColor: bgColor,
						color: item.color,
						animationDuration: `${speed}ms`
					}">
					<slot :item="item"></slot>
					{{ item.text }}
				</view>
			</block>
		</block>
		<!-- 横向 end -->
	</view>
</template>

<script>
	// https://github.com/hellodigua/vue-danmaku
	// import GLRandom from '@/common/utils/GLRandom.js';
	let random;
	export default {
		name: 'sh-barrage',
		props: {
			//轨道数量
			channels: {
				type: Number,
				default: 10
			},
			//一屏幕最多显示数量
			length: {
				type: Number,
				default: 10
			},
			//速度
			speed: {
				type: Number,
				default: 10000
			},
			//背景
			bgColor: {
				type: String,
				default: ''
			},
			//文字颜色
			foneColor: {
				type: String,
				default: ''
			},
			//循环
			loop: {
				type: Boolean,
				default: true
			},
			//类型 portrait=纵向 horizontal=横向
			type: {
				type: String,
				default: 'horizontal'
			}
		},
		data() {
			return {
				current: 0,
				windowWidth: 0,
				windowHeight: 0,
				setIn: null,
				items: []
			};
		},
		created() {
			uni.getSystemInfo({
				success: res => {
					this.windowWidth = res.windowWidth;
					this.windowHeight = res.windowHeight;
				}
			});
		},
		methods: {
			/**
			 * 轮播触发
			 * @param {Object} e
			 */
			swiper_change(e) {
				this.current = e.detail.current;
			},
			/** 随机数
			 * @param {Object} max 最大随机数
			 * @param {Object} min 最小随机数
			 */
			random(max, min) {
				return Math.floor(Math.random() * (max - min + 1) + min);
			},
			/**
			 * 随机色值
			 */
			randomColor() {
				let str = '#';
				for (let i = 0; i < 3; i++) {
					str += Math.floor(Math.random() * 256)
						.toString(16)
						.padStart(2, '0');
				}
				return str;
			},
			/**
			 * 处理数据
			 * @param {Object} arr
			 */
			handle_data(arr) {
				return new Promise((resolve, reject) => {
					let arrData = [];
					arr.map(item => {
						arrData.push({
							...item,
							show: false
						});
					});
					resolve(arrData);
				});
			},
			/**
			 * 随机轨道定位
			 */
			channels_random() {
				let win_height = this.windowHeight - this.windowHeight / 5 - 60;
				let _number = this.random(this.channels, 1);
				return win_height / _number;
			},
			/**
			 * 添加
			 */
			add(item) {
				if (this.type == 'portrait') {
					this.items.splice(this.current + this.length, 0, item);
					this.current++;
				} else {
					this.items.push({
						...item,
						top: this.channels_random(),
						color: this.foneColor == '' ? this.randomColor() : this.foneColor,
						show: true
					});
				}
			},
			/**
			 * 启动
			 */
			async start(data) {
				let res = await this.handle_data(data);
				this.items = res;
				let _num = 0;
				this.setIn = setInterval(() => {
					let len = this.items.length - 1;
					if (_num < len) {
						_num++;
					} else {
						_num = 0;
					}
					if (this.loop) {
						this.show(_num);
					} else {
						if (_num == len) {
							clearInterval(this.setIn);
						}
					}
				}, parseInt(this.speed / this.length));
			},
			/**
			 * 显示
			 * @param {Object} _index 显示的索引
			 */
			show(_index) {
				this.$set(this.items[_index], 'show', true);
				this.$set(this.items[_index], 'top', this.channels_random());
				if (this.foneColor == '') {
					this.$set(this.items[_index], 'color', this.randomColor());
				} else {
					this.$set(this.items[_index], 'color', this.foneColor);
				}
				this.remove_dom(_index);
			},
			/**
			 * 移除
			 */
			remove_dom(_index) {
				setTimeout(() => {
					this.$set(this.items[_index], 'show', false);
				}, this.speed);
			}
		}
	};
</script>

<style>
	.sh-barrage {
		height: 100vh;
		width: 100vw;
		z-index: 3;
		width: 100%;
		position: fixed;
		top: 0;
		left: 0;
		pointer-events: none;
	}

	.sh-barrage-swiper {
		position: absolute;
		left: 20upx;
		bottom: 240upx;
		width: 100vw;
	}

	.sh-barrage-item,
	.sh-barrage-swiper-item {
		width: 100vw;
		display: inline-flex;
		align-items: center;
		padding: 0 10upx;
		line-height: 1;
		border-radius: 40upx;
		white-space: pre;
		white-space: nowrap;
		pointer-events: none;
	}

	.sh-barrage-item.horizontal {
		transform: translateX(100%);
		position: absolute;
		right: 0;
		height: 80upx;
	}

	.sh-barrage-item.background {
		background-color: rgba(0, 0, 0, 0.3);
	}

	.sh-barrage-item.move {
		z-index: 3;
		will-change: transform;
		animation-name: moveLeft;
		animation-timing-function: linear;
		animation-play-state: running;
	}

	.sh-barrage-item-text {
		font-size: 38upx;
		color: #fff;
		font-weight: 100;
		padding: 0 20upx;
	}

	@keyframes moveLeft {
		from {
			transform: translateX(100%);
		}

		to {
			transform: translateX(-200%);
		}
	}

	@-webkit-keyframes moveLeft {
		from {
			-webkit-transform: translateX(100%);
		}

		to {
			-webkit-transform: translateX(-200%);
		}
	}
</style>