| | |
| | | |
| | | <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> |
| | | |
| | | <!-- 动画帧数 --> |
| | |
| | | fpsList: [], |
| | | tId: '', |
| | | tempInfo:{}, |
| | | titleName: '新增模版' |
| | | titleName: '新增模版', |
| | | previewShow: false, |
| | | previewFrames: [], |
| | | previewFrameIndex: 0, |
| | | previewTimer: null, |
| | | previewWidth: 24, |
| | | previewHeight: 12 |
| | | |
| | | } |
| | | }, |
| | | 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){ |
| | |
| | | }, |
| | | 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=>{ |
| | |
| | | }); |
| | | }, |
| | | |
| | | 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({ |
| | |
| | | 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 { |