lefengyang
2026-08-17 3451bad0ba5a219fde8d4d9f6cb7bc4aedd07ac4
允许追加文字
1 files modified
172 ■■■■ changed files
ledApp/pages/addTemplate/addTemplate.vue 172 ●●●● patch | view | raw | blame | history
ledApp/pages/addTemplate/addTemplate.vue
@@ -182,6 +182,33 @@
            </view>
        </uv-popup>
        
        <!-- 添加文字弹窗 -->
        <uv-popup ref="popupText" mode="center" round="10" :safeAreaInsetTop="false" :safeAreaInsetBottom="false" :zoom="false" duration="0">
            <view class="text_popup">
                <view class="text_popup_title">添加文字</view>
                <view class="text_popup_item">
                    <view class="text_popup_label">文字</view>
                    <view class="text_popup_input">
                        <uv-input placeholder="请输入文字" border="none" v-model="tempText" fontSize="16px"
                            customStyle="background: #ECEFF6;padding:8px 10px;border-radius: 6px;"></uv-input>
                    </view>
                </view>
                <view class="text_popup_item">
                    <view class="text_popup_label">类型</view>
                    <view class="text_popup_type">
                        <uv-radio-group v-model="textType" placement="row" labelSize="16px" style="gap:10px;">
                            <uv-radio label="覆盖" name="overwrite"></uv-radio>
                            <uv-radio label="追加" name="append"></uv-radio>
                        </uv-radio-group>
                    </view>
                </view>
                <view class="text_popup_btn">
                    <uv-button type="info" text="取消" @click="closeTextPopup"></uv-button>
                    <uv-button type="primary" text="确定" @click="confirmAddText" customStyle=""></uv-button>
                </view>
            </view>
        </uv-popup>
    </view>
</template>
@@ -282,6 +309,8 @@
                previewHeight: 12,
                showControls: false,
                scrollLeft: 0,
                textType: 'overwrite',
                tempText: '',
            }
        },
        computed: {
@@ -875,7 +904,7 @@
                })
            },
            // 生成点阵数据
            generateDotMatrix(char) {
            generateDotMatrix(char, startCol = null) {
                return new Promise((resolve, reject) => {
            
                    // 使用 uni-app 的 canvas context
@@ -888,8 +917,14 @@
                    // 绘制文字
                    // 垂直居中,稍微向上偏移一点
                    const y = this.canvasHeight / 2 + 10;
                    const colCount = this.width * (this.modeVal == 2 ? 10 : 1)
                    
                    if (this.modeVal == 2) {
                    if (startCol !== null) {
                        ctx.setTextAlign('left')
                        const cellWidth = this.canvasWidth / colCount;
                        const x = startCol * cellWidth;
                        ctx.fillText(char, x, y);
                    } else if (this.modeVal == 2) {
                        // 滚动动画:文字靠左对齐
                        ctx.setTextAlign('left')
                        const x = 20;
@@ -1043,38 +1078,66 @@
                    this.previewTimer = null;
                }
            },
            // 修改添加文字方法
            async addText() {
                uni.showModal({
                    title: '添加文字',
                    content: '',
                    editable: true,
                    placeholderText: '请输入文字',
                    success: async (res) => {
                        if (res.confirm) {
                            const text = res.content;
                            if (text.length > 0) {
                                try {
                                    // 生成点阵数据
                                    const dotMatrix = await this.generateDotMatrix(text);
                                    console.log('点阵数据:', dotMatrix);
                                    this.pixelData = dotMatrix
                                } catch (error) {
                                    console.error('生成点阵失败:', error);
                                    uni.showToast({
                                        title: '生成点阵失败',
                                        icon: 'none'
                                    });
                                }
                            } else {
                                uni.showToast({
                                    title: '请输入文字',
                                    icon: 'none'
                                });
                            }
            addText() {
                this.tempText = '';
                this.textType = 'overwrite';
                this.$refs.popupText.open();
            },
            closeTextPopup() {
                this.$refs.popupText.close();
            },
            async confirmAddText() {
                const text = this.tempText;
                if (!text || text.length === 0) {
                    uni.showToast({
                        title: '请输入文字',
                        icon: 'none'
                    });
                    return;
                }
                try {
                    if (this.textType === 'overwrite') {
                        const dotMatrix = await this.generateDotMatrix(text);
                        this.pixelData = dotMatrix;
                    } else {
                        const colCount = this.width * (this.modeVal == 2 ? 10 : 1);
                        const rightmostCol = this.findRightmostNonEmptyCol(colCount);
                        const startCol = rightmostCol === -1 ? 0 : rightmostCol + 2;
                        const dotMatrix = await this.generateDotMatrix(text, startCol);
                        this.mergePixelData(dotMatrix);
                    }
                    this.$refs.popupText.close();
                } catch (error) {
                    console.error('生成点阵失败:', error);
                    uni.showToast({
                        title: '生成点阵失败',
                        icon: 'none'
                    });
                }
            },
            findRightmostNonEmptyCol(colCount) {
                for (let col = colCount - 1; col >= 0; col--) {
                    let isEmpty = true;
                    for (let row = 0; row < this.height; row++) {
                        const index = row * colCount + col;
                        if (this.pixelData[index] !== '' && this.pixelData[index] !== null && this.pixelData[index] !== undefined) {
                            isEmpty = false;
                            break;
                        }
                    }
                });
                    if (!isEmpty) {
                        return col;
                    }
                }
                return -1;
            },
            mergePixelData(dotMatrix) {
                for (let i = 0; i < dotMatrix.length; i++) {
                    if (dotMatrix[i] !== '' && dotMatrix[i] !== null && dotMatrix[i] !== undefined) {
                        this.$set(this.pixelData, i, dotMatrix[i]);
                    }
                }
            },
        }
    }
@@ -1335,4 +1398,49 @@
        background: url('/static/img/bg_2.jpg') no-repeat center top;
        background-size: 100% auto;
    }
    .text_popup {
        width: 600rpx;
        background: #fff;
        border-radius: 20rpx;
        padding: 40rpx 30rpx;
        box-sizing: border-box;
        .text_popup_title {
            font-size: 16px;
            font-weight: bold;
            color: #333;
            text-align: center;
            margin-bottom: 15px;
        }
        .text_popup_item {
            display: flex;
            align-items: center;
            margin-bottom: 15px;
            .text_popup_label {
                width: 50px;
                font-size: 16px;
                color: #666;
                flex-shrink: 0;
            }
            .text_popup_input {
                flex: 1;
                font-size: 16px;
            }
            .text_popup_type {
                flex: 1;
            }
        }
        .text_popup_btn {
            display: flex;
            margin-top: 20px;
            justify-content: center;
            gap: 20px;
        }
    }
</style>