From 8fd32e992f0fe12a81712aea90513bf6a5fa2790 Mon Sep 17 00:00:00 2001
From: lefengyang <lefengyang@tencent.com>
Date: Sun, 16 Aug 2026 03:54:02 +0800
Subject: [PATCH] 按钮收回

---
 ledApp/pages/addTemplate/addTemplate.vue |  190 +++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 172 insertions(+), 18 deletions(-)

diff --git a/ledApp/pages/addTemplate/addTemplate.vue b/ledApp/pages/addTemplate/addTemplate.vue
index 0a208de..b2f3783 100644
--- a/ledApp/pages/addTemplate/addTemplate.vue
+++ b/ledApp/pages/addTemplate/addTemplate.vue
@@ -97,7 +97,22 @@
 
 		<view class="footer_none"></view>
 		<view class="footer_btn">
-			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle" @click="clickTempleteAdd()"></uv-button>
+			<uv-button text="预览" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle" customStyle="width:40vw;" @click="openPreview"></uv-button>
+			<uv-button text="保存" color="linear-gradient( 142deg, #6FD2FF 0%, #268DFF 100%)" shape="circle" customStyle="width:40vw;" @click="clickTempleteAdd()"></uv-button>
+		</view>
+
+		<!-- 预览浮层 -->
+		<view class="preview_overlay" v-if="previewShow" @click.self="closePreview">
+			<view class="preview_title">预览动画</view>
+			<view class="preview_matrix">
+				<view class="preview_grid" :style="{
+					gridTemplateRows: 'repeat(' + previewHeight + ', auto)',
+					gridTemplateColumns: 'repeat(' + previewWidth + ', auto)'
+				}">
+					<view class="preview_cell" v-for="(cell, idx) in currentPreviewFrame" :key="idx" :style="{ backgroundColor: cell || '#1a1a1a' }"></view>
+				</view>
+			</view>
+			<view class="preview_close_btn" @click="closePreview">关闭</view>
 		</view>
 
 		<!-- 动画帧数 -->
@@ -112,8 +127,13 @@
 				<view class="back_btn" @click="popupAnimationClose">
 					<uv-icon name="arrow-leftward" color="#333" size="30"></uv-icon>
 				</view>
+				<!-- 操作按钮 -->
+				<view class="controls" style="left: 30rpx;">
+					<uv-button type="primary" :plain="true" :text="showControls ? '收回' : '操作'" @click="toggleControls"></uv-button>
+				</view>
+
 				<!-- 动画按钮 -->
-				<view class="controls">
+				<view class="controls" v-if="showControls">
 					<uv-button type="primary" :plain="true" text="分辨率" @click="changeRatio()"></uv-button>
 					<uv-button type="primary" :plain="true" text="颜色" @click="changeColor()"></uv-button>
 					<uv-button type="primary" :plain="true" text="添加文字" @click="addText()"></uv-button>
@@ -234,10 +254,24 @@
 				fpsList: [],
 				tId: '',
 				tempInfo:{},
-				titleName: '新增模版'
+				titleName: '新增模版',
+				previewShow: false,
+				previewFrames: [],
+				previewFrameIndex: 0,
+				previewTimer: null,
+				previewWidth: 24,
+				previewHeight: 12,
+				showControls: false
 				
 			}
 		},
+		computed: {
+			currentPreviewFrame() {
+				if (this.previewFrames.length === 0) return [];
+				const frame = this.previewFrames[this.previewFrameIndex % this.previewFrames.length];
+				return frame || [];
+			}
+		},
 		onLoad(opt) {
 			this.baseURL = uni.$uv.http.config.baseURL
 			if(opt.id){
@@ -254,23 +288,18 @@
 		},
 		onHide() {
 			this.$refs.popupAnimation.close();
+			this.stopPreviewAnimation();
 			if (typeof plus !== 'undefined') {
 				plus.screen.lockOrientation('portrait')
 			}
 		},
 		onUnload() {
+			this.stopPreviewAnimation();
 			if (typeof plus !== 'undefined') {
 				plus.screen.lockOrientation('portrait')
 			}
 		},
 		methods: {
-			// 跳转到编辑动画页面
-			goToAnimaiton(index){
-				this.fpsIndex = index
-				uni.navigateTo({
-				  url: '/pages/animation/animation?index='+index
-				})
-			},
 			// 获取编辑详情
 			getTempleteInfo(){
 				templeteInfo(this.tId).then(res=>{
@@ -561,6 +590,9 @@
 				// 将所有像素点设置为空字符串
 				this.pixelData = new Array(this.height * this.width).fill('')
 			},
+			toggleControls() {
+				this.showControls = !this.showControls;
+			},
 			// 模版动画弹出框
 			changeAnimation(e){
 				//console.log('打开关闭模版动画弹窗触发---',e)
@@ -741,7 +773,7 @@
 					ctx = uni.createCanvasContext('myCanvas', this);
 			
 					// 设置字体样式
-					ctx.setFontSize(this.canvasHeight * 0.9);
+					ctx.setFontSize(this.canvasHeight);
 					ctx.setFillStyle('#000')
 					ctx.setTextAlign('center')
 					ctx.setTextBaseline('middle')
@@ -750,7 +782,7 @@
 					// 水平居中
 					const x = this.canvasWidth / 2;
 					// 垂直居中,稍微向上偏移一点
-					const y = this.canvasHeight / 2;
+					const y = this.canvasHeight / 2 + 10;
 			
 					// 绘制文字
 					ctx.fillText(char, x, y);
@@ -820,6 +852,78 @@
 				});
 			},
 			
+			openPreview() {
+				if (this.fpsList.length === 0 || this.fpsList.every(f => f === null || f === undefined)) {
+					uni.showToast({
+						title: '请先编辑动画帧',
+						icon: 'none'
+					});
+					return;
+				}
+				this.previewWidth = this.width;
+				this.previewHeight = this.height;
+				this.previewFrames = this.buildPreviewFrames();
+				this.previewFrameIndex = 0;
+				this.previewShow = true;
+				this.$nextTick(() => {
+					this.startPreviewAnimation();
+				});
+			},
+			closePreview() {
+				this.stopPreviewAnimation();
+				this.previewShow = false;
+			},
+			buildPreviewFrames() {
+				if (this.modeVal == 0) {
+					const data = this.fpsList[0];
+					if (!data) return [];
+					return this.generatePreviewFrames(data, 24);
+				} else {
+					const frames = [];
+					for (let i = 0; i < this.total; i++) {
+						if (this.fpsList[i] && this.fpsList[i] !== null) {
+							frames.push(this.fpsList[i]);
+						} else {
+							frames.push(new Array(this.width * this.height).fill(''));
+						}
+					}
+					return frames;
+				}
+			},
+			generatePreviewFrames(data, frameCount) {
+				const cols = this.width;
+				const rows = this.height;
+				const frames = [];
+				let grid = [];
+				for (let r = 0; r < rows; r++) {
+					grid.push(data.slice(r * cols, (r + 1) * cols));
+				}
+				for (let f = 0; f < frameCount; f++) {
+					let frame = [];
+					for (let r = 0; r < rows; r++) {
+						let row = grid[r].slice();
+						let shifted = row.slice(f % cols).concat(row.slice(0, f % cols));
+						frame = frame.concat(shifted);
+					}
+					frames.push(frame);
+				}
+				return frames;
+			},
+			startPreviewAnimation() {
+				this.stopPreviewAnimation();
+				if (!this.speed || this.speed <= 0 || this.previewFrames.length === 0) return;
+				const interval = this.speed * 2.8;
+				console.log('interval', interval)
+				this.previewTimer = setInterval(() => {
+					this.previewFrameIndex = (this.previewFrameIndex + 1) % this.previewFrames.length;
+				}, interval);
+			},
+			stopPreviewAnimation() {
+				if (this.previewTimer) {
+					clearInterval(this.previewTimer);
+					this.previewTimer = null;
+				}
+			},
 			// 修改添加文字方法
 			async addText() {
 				uni.showModal({
@@ -887,10 +991,20 @@
 		}
 	}
 	
-	.controls {
+	.action_btn {
 		position: absolute;
 		bottom: 10px;
 		left: 50px;
+		z-index: 10;
+		background: linear-gradient(142deg, #6FD2FF 0%, #268DFF 100%);
+		padding: 12px 24px;
+		border-radius: 30px;
+		box-shadow: 0 4px 12px rgba(38, 141, 255, 0.4);
+	}
+	.controls {
+		position: absolute;
+		bottom: 10px;
+		left: 130px;
 		display: flex;
 		gap: 20px;
 		z-index: 9;
@@ -957,18 +1071,58 @@
 		bottom: 0;
 		background: #fff;
 		padding: 30rpx 40rpx;
+		display: flex;
+		justify-content: space-between;
 	}
-	.footer_btn2 {
+
+	.preview_overlay {
 		position: fixed;
+		top: 0;
 		left: 0;
 		right: 0;
 		bottom: 0;
-		background: #fff;
-		padding: 30rpx 40rpx;
+		background: rgba(0, 0, 0, 0.85);
 		display: flex;
+		flex-direction: column;
 		align-items: center;
-		justify-content: space-between;
-		box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
+		justify-content: center;
+		z-index: 9999;
+	}
+	.preview_title {
+		color: #fff;
+		font-size: 34rpx;
+		margin-bottom: 40rpx;
+	}
+	.preview_matrix {
+		background: #000;
+		padding: 20rpx;
+		border-radius: 16rpx;
+		box-shadow: 0 0 30rpx rgba(0, 150, 255, 0.3);
+	}
+	.preview_grid {
+		display: grid;
+		gap: 2rpx;
+		background: #111;
+		padding: 4rpx;
+		border-radius: 8rpx;
+	}
+	.preview_cell {
+		width: 22rpx;
+		height: 22rpx;
+		border-radius: 50%;
+		background: #1a1a1a;
+		box-shadow: inset 0 0 4rpx rgba(0, 0, 0, 0.5);
+	}
+	.preview_close_btn {
+		margin-top: 60rpx;
+		width: 300rpx;
+		height: 80rpx;
+		line-height: 80rpx;
+		text-align: center;
+		color: #fff;
+		background: linear-gradient(142deg, #6FD2FF 0%, #268DFF 100%);
+		border-radius: 40rpx;
+		font-size: 30rpx;
 	}
 
 	.temp_btn {

--
Gitblit v1.10.0