uniapp 手持弹幕全端实现(微信/QQ小程序 + APP)

发布时间:2023年12月20日


见下述效果图,本文话少纯干货

请添加图片描述请添加图片描述请添加图片描述


代码实现

<template>

	<view class="main" :style="state.backgroundStyle" @click="state.showOpts = !state.showOpts">
		<text class="barrage-text" :style="{
			color: state.textColor, fontSize: state.textFontSize,
			fontWeight: state.textFontWeight, animation: state.textAnimation
		}">{{ state.barrageText }}</text>
	</view>

	<view class="opts" v-show="state.showOpts">
		<uni-segmented-control  :current="state.tabCurrent"
			:values="state.tabCurrents" style-type="text" @clickItem="(e) => {
				if (e.currentIndex != state.tabCurrent) state.tabCurrent = e.currentIndex; }" />
		<view v-if="state.tabCurrent == 0">
			<uni-section title="弹幕内容" type="line">
				<template v-slot:right>
					<uni-easyinput v-model="state.barrageText" placeholder="请输入弹幕内容" :clearable="false"/>
				</template>
			</uni-section>
			<uni-section title="方向" type="line">
				<template v-slot:right>
					<uni-data-checkbox mode="button" v-model="state.direction" :localdata="state.directions"
					@change="(e) => state.textAnimation = `barrage-${e.detail.value} ${state.speed == 0? 0: 20 - state.speed}s linear infinite`"/>
				</template>
			</uni-section>
		</view>
		<view v-if="state.tabCurrent == 1">
			<uni-section title="加粗" type="line">
				<template v-slot:right>
					<switch color="#d6ba44" style="transform:scale(0.7)"
						@change="(e) => state.textFontWeight = e.detail.value? 'bold': 'revert'"/>
				</template>
			</uni-section>
			<uni-section title="大小" type="line">
				<template v-slot:right>
					<slider :value="state.textSize" min="1" max="350"
						@changing="(e) => state.textFontSize = e.detail.value + 'px'" />
				</template>
			</uni-section>
		</view>

		<view v-if="state.tabCurrent == 2" class="color-opt">
			<view v-for="(textColor, index) in state.textColors" :key="index" class="change-colors"
				@click="() => state.textColor = `rgb(${textColor.r},${textColor.g},${textColor.b})`"
				:style="'background-color: rgb(' + textColor.r + ', ' + textColor.g + ', ' + textColor.b + ')'">
				<text>{{ textColor.name }}</text>
			</view>
		</view>
		<view v-if="state.tabCurrent == 3">
			<uni-section title="速度" type="line">
				<template v-slot:right>
					<slider :value="state.speed" min="0" max="19"
						@changing="(e) => state.textAnimation =
						`barrage-${state.direction} ${e.detail.value == 0? 0: 20 - e.detail.value}s linear infinite`" />
				</template>
			</uni-section>
		</view>
		<view class='btns'>
			<button type="primary" size="mini" @click="reset">重置</button>
			<button type="primary" size="mini" @click="saveQuit">保存并退出</button>
		</view>
	</view>

</template>

<script setup>
	import { onLoad, onShareAppMessage } from "@dcloudio/uni-app";
	import { reactive, getCurrentInstance } from 'vue'
	const { proxy } = getCurrentInstance();
	onShareAppMessage(() => proxy.$shareApp);
	const storageDataKey = "handBarrage-info";
	let state = reactive({
		barrageText: '哇!是954L!', textSize: 128, speed: 15, direction: 'r2l',
		directions: [{ text: '从左到右', value: 'l2r' }, { text: '从右到左', value: 'r2l' }],
		backgroundStyle: { 'background-color': '#000', 'height': proxy.$systemInfo.screenHeight + 'px' },

		textColor: 'rgb(255,255,255)', textFontSize: '128rpx', textFontWeight: 'revert',
		textAnimation: 'barrage-r2l 5s linear infinite',
		showOpts: true, textReversal: false, tabCurrent: 0, tabCurrents: ['文字', '字号', '颜色', '速度'],
		textColors: [ { name: '白色', r: '255', g: '255', b: '255' },  { name: '深红', r: '200', g: '0', b: '2' },
		    { name: '红色', r: '255', g: '0', b: '0' }, { name: '钴蓝', r: '0', g: '75', b: '115' },
		    { name: '靛青', r: '51', g: '143', b: '178' }, { name: '蓝色', r: '4', g: '107', b: '255' },
		    { name: '天蓝', r: '68', g: '142', b: '219' }, { name: '青蓝', r: '0', g: '191', b: '243' } ]
	});

	const reset = () => { uni.removeStorageSync(storageDataKey);
		state = Object.assign(state, JSON.parse(oldState)); proxy.$showSuccessToast('重置成功!'); }

	const saveQuit = () => {
		uni.setStorageSync(storageDataKey, JSON.stringify(state));
		proxy.$navigateBack();
	}

	let oldState;
	onLoad(() => {
		oldState = JSON.stringify(state);
		const info = uni.getStorageSync(storageDataKey);
		if (info != null) state = Object.assign(state, JSON.parse(info));
	})

</script>

<style lang="scss">

	@keyframes barrage-l2r {
		from{ transform: rotate(90deg) translateX(-100%); }
		to{ transform: rotate(90deg) translateX(100%); }
	}

	@keyframes barrage-r2l {
		from{ transform: rotate(90deg) translateX(100%); }
		to{ transform: rotate(90deg) translateX(-100%); }
	}

</style>
<style lang="scss" scoped >

	.main { display: flex; align-items: center; justify-content: center; position: relative; }
	.barrage-text { transform: rotate(90deg); display: flex; white-space: nowrap; position: absolute; }
	.opts ::v-deep {
		position: absolute; bottom: 5%; width: 100%; height: 350rpx;
		.is-checked { border-color: #d6ba44 !important; }
		.checklist-box .checklist-text { color: gray !important; }
		.uni-section { background-color: transparent !important; }
		.segmented-control__text, .uni-section__content-title { color: gray !important; }
		.segmented-control__item--text { color: #bda131 !important; }
		.uni-section-header__content { flex: none !important; width: 20%; }
		.uni-section-header__slot-right { width: 100%; }
		.uni-easyinput__content { border-color: transparent !important;
			background-color: #272727c2 !important; input { color: #d6ba44 !important; } }

		.color-opt { height: 55%; display: flex; align-items: center; justify-content: center;
			.change-colors {
				vertical-align: middle; display: inline-block;
				border-radius: 12rpx; width: 60rpx; height: 60rpx;
				position: relative; margin: 0 10rpx 0 10rpx; border: 1rpx solid #dddddd;
				> text { color: gray; font-size: 22rpx; position: absolute;
					width: 60rpx; text-align: center; bottom: -35rpx; }
				}
		}
		.btns { position: fixed; bottom: 2%; text-align: center; button { margin-top: 20rpx !important;
			margin-left: 100rpx !important; margin-right: 100rpx !important; } }
	}

</style>
文章来源:https://blog.csdn.net/wkh___/article/details/135105374
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。