uniapp 微信小程序 提词器(纯手工)

功能:在小程序中调取手机相机录制视频,录制过程中提词器中字体跟着滚动,提词器颜色改变。

效果展示

提词器不显示:

修改提词器样式:

内容编写:

提词器下拉增加高,提词器可上下拖动:

开始录制(再次点击接受录制返回视频路径):

退出录制:

以下粘贴为部分代码,获取全部代码可联系作者:

<template>
	<view class="box">
		<view class="fixedTop">
			<view
			  class="tui-status-bar"
			  :style="{ height: statusBarHeight + 'px' }"
			></view>
			<view class="btn" :style="{height:height+'px'}">
				<image src="https://doctor.sdxxtop.com/img/tools/teleprompterClone.png" @click="showBackPopUp = !showBackPopUp"></image>
				<image v-if="showTextPopUp" src="https://doctor.sdxxtop.com/img/tools/teleprompterShow.png" @click="showTextPopUp = false"></image>
				<image v-else src="https://doctor.sdxxtop.com/img/tools/teleprompterUnShow.png" @click="showTextPopUp = true"></image>
			</view>
			<view class="textPopUp" v-if="showTextPopUp" :style="'margin-top:'+dragPopUpHeight+'px'" @touchmove="handleTouchMovePopUp" @touchstart="touchstartPopUp($event)">
				<view class="text" :style="{ height: dragHeight + 'px',color:textColor }">
					<scroll-view scroll-y :style="{ height: dragHeight + 'px' }" lower-threshold="0" :scroll-top="scrollTop" @scrolltolower="scrollBottom">
						{{text?text:'你好,欢迎来到医生医影提词器,已为你开启智能跟随模式,台词跟着语速走,念到哪走到哪,节奏由你掌控;点击左下角设置按钮,可以修改台词样式配快来尝试录制示下吧~'}}
					</scroll-view>
				</view>
				<view class="textBtn">
					<image @click="teleprompterSet" src="https://doctor.sdxxtop.com/img/tools/teleprompterSet.png"></image>
					<image @click="teleprompterLog" src="https://doctor.sdxxtop.com/img/tools/teleprompterLog.png"></image>
					<image @touchmove.stop="handleTouchMove" @touchstart="touchstart($event)" src="https://doctor.sdxxtop.com/img/tools/teleprompterZoom.png"></image>
				</view>
			</view>
			<view class="backPopUp" v-if="showBackPopUp">
				<text></text>
				<view @click="quit">
					<image src="https://doctor.sdxxtop.com/img/tools/teleprompterBack.png"></image>
					<text>退出拍摄页</text>
				</view>
				<view @click="againTake">
					<image src="https://doctor.sdxxtop.com/img/tools/teleprompterAgain.png"></image>
					<text>重新拍摄</text>
				</view>
			</view>
		</view>
		<view class="content">
			<camera :device-position="devicePosition ? 'back' : 'front'" flash="off" @error="loadCameraError" :style="{width: '100%', height: winHeight+'px'}"></camera>
		</view>
		<!-- 开始录制 -->
		<view class="start">
			<image src="https://doctor.sdxxtop.com/img/tools/teleprompterStart.png" v-if="!isStartRecord" @click="startVideotape"></image>
			<image src="https://doctor.sdxxtop.com/img/tools/teleprompterStop.png" v-else @click="stopVideoTape"></image>
			<view class="turn" @click="turnCamera" v-if="!isStartRecord">
				<image src="https://doctor.sdxxtop.com/img/tools/teleprompterTurn.png"></image>
				<view>翻转</view>
			</view>
			<view class="time" v-if="isStartRecord">{{formatSeconds(recordTime)}}</view>
		</view>
		<!-- 蒙层 -->
		<view class="mongolian" v-if="mongolian">
			<view class="colorBox">
				<view v-for="(item,index) in 9" :class="chooseColorIndex == index ? 'chooseColor' : '' " @click="chooseColor(index)"></view>
			</view>
		</view>
		<!-- 修改编写 -->
		<view class="editText" v-if="editTextPopUp" :style="{ marginTop : ( statusBarHeight + 44 ) +'px' }">
			<view class="editTextTitle">
				<text @click="cancelText">取消</text>
				<text>修改编写</text>
				<text @click="confirmText">确认</text>
			</view>
			<view class="editTextContent">
				<textarea maxlength="-1" v-model="text" :style="'height:'+(winHeight-200)+'px;'" placeholder="请输入或粘贴"></textarea>
			</view>
		</view>
	</view>
</template>

<script>
	import { Debounce } from "@/utils/debounce.js";
	export default {
		data(){
			return {
				// 手机高度
				winHeight: 0,
				//状态栏高度
				statusBarHeight: 0, 
				//header高度
				height: 44, 
				// 显示提词器弹窗
				showTextPopUp:true,
				// 触摸开始的Y坐标
				startY: 0, 
				// 拖动区域的高度
				dragHeight: 150, 
				// 最大高度限制
				maxHeight: 450 ,
				// 整个弹窗触摸开始y的坐标
				startPopUpY:0,
				// 拖动区域的高度
				dragPopUpHeight: 0, 
				// 选中颜色下标
				chooseColorIndex:0,
				// 动态字体颜色
				textColor:"#FFFFFF",
				// 是否显示蒙层
				mongolian:false,
				// 内容
				text:"",
				// 编辑文字弹窗
				editTextPopUp:false,
				// 相机内置
				ctx:null,
				// 录制生成的视频
				createVideoUrl:'https://xxx/jinan_demo/video/20240328/d8a426d9a9ef37b2a28040fbcd470f28.mp4',
				// 是否开始录制
				isStartRecord:false,
				// 前后置摄像头  true:前置 false:后置
				devicePosition:true,
				// 录制时长
				recordTime:0,
				// 录制时长定时器
				recordTimeFun:null,
				// 显示返回弹窗
				showBackPopUp:false,
				// 提词器移动定时事件
				scrollTopTimeFun:null,
				// 滚动条位置
				scrollTop:0
			}
		},
		created() {
			uni.getSystemInfo({
			  success: (res) => {
			    this.statusBarHeight = res.statusBarHeight
			  }
			})
		},
		onLoad(option) {
			var that = this;
			if(option.text){
				this.text = option.text
			}
			uni.getSystemInfo({
				success: function(res) {
					that.winHeight = res.windowHeight
				},
			});
		},
		onReady() {
			this.ctx = uni.createCameraContext();
		},
		methods:{
			
		}
	}
</script>

<style lang="scss" scoped>
	.box{
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		right: 0;
		.fixedTop{
			background-color: black;
			position: fixed;
			width: 100%;
			top: 0;
			left: 0;
			z-index: 123;
			.tui-status-bar {
			  width: 100%;
			}
			.btn{
				padding-right: 250rpx;
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding-left: 30rpx;
				image{
					width: 50rpx;
					height: 50rpx;
				}
			}
			.textPopUp{
				position: absolute;
				top:100%;
				left: 50%;
				z-index: 123;
				width: 90%;
				box-sizing: border-box;
				background-color: #00000050;
				padding: 30rpx;
				border-radius: 20rpx;
				transform: translateX(-50%);
				.text{
					font-size: 35rpx;
					color: #FFFFFF;
					line-height: 63rpx;
					overflow: hidden;
				}
				.textBtn{
					margin-top: 60rpx;
					display: flex;
					align-items: center;
					justify-content: space-between;
					image{
						width: 43rpx;
						height: 43rpx;
					}
					image:nth-of-type(1){
						height: 36rpx
					}
					image:nth-of-type(2){
						width: 35rpx;
						height: 35rpx;
					}
				}
			}
			.backPopUp{
				position: absolute;
				top: 115%;
				left: 20rpx;
				z-index: 1111;
				background-color: white;
				border-radius: 20rpx;
				font-size: 28rpx;
				&>text{
					border-color: #ff450000 #ff450000 white #ff450000;
					display: inline-block;
					width: 0;
					height: 0;
					border-width: 20rpx;
					border-style: solid;
					position: absolute;
					top: 0%;
					transform: translateY(-90%);
					left: 15rpx;
				}
				&>view{
					padding: 30rpx;
					display: flex;
					align-items: center;
					&>image{
						width: 32rpx;
						height: 32rpx;
						margin-right: 20rpx;
					}
				}
				&>view:nth-of-type(1){
					border-bottom: 2rpx solid #EFEFEF;
					color: #621AA4;
					&>image{
						width: 40rpx;
						height: 32rpx;
					}
				}
			}
		}
		.start{
			position: fixed;
			bottom: 180rpx;
			left: 50%;
			transform: translateX(-50%);
			display: flex;
			align-items: center;
			
			&>image{
				width: 120rpx;
				height: 120rpx;
			}
			.turn{
				margin-left: 80rpx;
				text-align: center;
				image{
					height: 35rpx;
					width: 42rpx;
				}
				font-size: 28rpx;
				color: #FFFFFF;
			}
			.time{
				font-size: 38rpx;
				color: #FFFFFF;
				position: absolute;
				top: -80%;
				left: 50%;
				transform: translateX(-50%);
			}
		}
		.mongolian{
			position: fixed;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			background-color: #000000;
			.colorBox{
				position: absolute;
				bottom: 200rpx;
				left: 50%;
				transform: translateX(-50%);
				display: flex;
				align-items: center;
				justify-items: center;
				.chooseColor{
					border: 2rpx solid white;
				}
				view{
					width: 63rpx;
					height: 63rpx;
				}
				view:nth-of-type(1){
					background-color: white;
				}
				view:nth-of-type(2){
					background-color: #424242;
				}
				view:nth-of-type(3){
					background-color: #000000;
				}
				view:nth-of-type(4){
					background-color: #FA797D;
				}
				view:nth-of-type(5){
					background-color: #FB6F24;
				}
				view:nth-of-type(6){
					background-color: #F9D63C;
				}
				view:nth-of-type(7){
					background-color: #77E46F;
				}
				view:nth-of-type(8){
					background-color: #5A95EF;
				}
				view:nth-of-type(9){
					background-color: #998BFC;
				}
			}
		}
		.editText{
			position: fixed;
			top: 0;
			left: 0;
			right: 0;
			bottom: 0;
			background-color: white;
			z-index: 123;
			border-radius: 20rpx 20rpx 0 0;
			.editTextTitle{
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 30rpx 20rpx;
				border-bottom: 2rpx solid #D8D8D8;
				text:nth-of-type(1){
					font-size: 28rpx;
					color: #666666;
				}
				text:nth-of-type(2){
					font-size: 32rpx;
				}
				text:nth-of-type(3){
					font-size: 28rpx;
					color: #621AA4;
				}
			}
			.editTextContent{
				padding: 20rpx;
				textarea{
					width: 100%;
				}
			}
		}
	}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值