// 引入形状数据 import { shapes, colors } from './shapes'; Page({ data: { shapeCards: [], columns: 3, bgColor: '#FFFFFF', generatedImage: null, isGenerating: false, backgrounds: [ { name: '纯白', value: '#FFFFFF', color: '#f2f2f2' }, { name: '米黄', value: '#FAF5E8', color: '#d4c5a0' }, { name: '淡灰', value: '#F5F5F5', color: '#cccccc' }, { name: '无背景', value: 'transparent', color: '#000000' }, ], }, onLoad() { // 初始化示例卡片 const initialCards = [ this.createShapeCard('square', '#FF5252'), this.createShapeCard('diamond', '#69F0AE'), this.createShapeCard('cylinder', '#448AFF'), this.createShapeCard('cube', '#FFD740'), this.createShapeCard('circle', '#E040FB'), this.createShapeCard('sphere', '#FAF5E8'), // this.createShapeCard('triangle', '#FF9800'), ]; this.setData({ shapeCards: initialCards }); }, createShapeCard(shapeId, fillColor) { const shape = shapes.find((s) => s.id === shapeId); return { shape: shapeId, fillColor, svgData: this.generateSvgData(shape.svg, fillColor), name: shape.name, }; }, // SVG Base64生成器 generateSvgData(svgContent, fillColor) { const styledSvg = svgContent.replace(/var\(--fill-color\)/g, fillColor); const base64 = wx.arrayBufferToBase64( new TextEncoder().encode(styledSvg), ); return `data:image/svg+xml;base64,${base64}`; }, // 设置列数 setColumns(e) { this.setData({ columns: e.detail.value, }); }, // 设置背景颜色 setBackground(e) { this.setData({ bgColor: e.detail.value, }); }, // 生成拼接图片 async generateImage() { this.setData({ isGenerating: true }); try { // 计算布局和画布尺寸 const cardCount = this.data.shapeCards.length; const cardsPerRow = this.data.columns; const canvasWidth = 750; // 以rpx为单位的宽度设计 const cardSize = canvasWidth / cardsPerRow; const rowCount = Math.ceil(cardCount / cardsPerRow); const canvasHeight = cardSize * rowCount; // 创建离屏Canvas const offscreenCanvas = wx.createOffscreenCanvas({ type: '2d', width: canvasWidth, height: canvasHeight, }); const ctx = offscreenCanvas.getContext('2d'); // 填充背景 if (this.data.bgColor !== 'transparent') { ctx.fillStyle = this.data.bgColor; ctx.fillRect(0, 0, canvasWidth, canvasHeight); } // 批量加载图片的Promise数组 const loadPromises = this.data.shapeCards.map((card) => { return new Promise((resolve) => { wx.getImageInfo({ src: card.svgData, success: (res) => { resolve({ path: res.path, card, }); }, fail: () => { resolve(null); }, }); }); }); // 等待所有图片加载完成 const images = await Promise.all(loadPromises); // 绘制所有卡片 images.forEach((imgInfo, index) => { if (!imgInfo) return; const row = Math.floor(index / cardsPerRow); const col = index % cardsPerRow; const x = col * cardSize + cardSize / 2; const y = row * cardSize + cardSize / 2; // 保存当前绘制状态 ctx.save(); // 添加卡片投影效果 ctx.shadowColor = 'rgba(0, 0, 0, 0.2)'; ctx.shadowBlur = 8; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 3; // 绘制卡片SVG ctx.drawImage( imgInfo.path, x - (cardSize * 0.8) / 2, y - (cardSize * 0.8) / 2, cardSize * 0.8, cardSize * 0.8, ); // 恢复绘制状态 ctx.restore(); }); // 将Canvas转换为临时图片路径 wx.canvasToTempFilePath({ canvas: offscreenCanvas, success: (res) => { this.setData({ generatedImage: res.tempFilePath, isGenerating: false, }); }, fail: () => { this.setData({ isGenerating: false }); wx.showToast({ title: '图片生成失败', icon: 'none' }); }, }); } catch (e) { this.setData({ isGenerating: false }); console.error(e); wx.showToast({ title: '生成出错,请重试', icon: 'none' }); } }, // 保存到相册 saveToAlbum() { if (!this.data.generatedImage) return; wx.saveImageToPhotosAlbum({ filePath: this.data.generatedImage, success: () => { wx.showToast({ title: '保存成功', icon: 'success' }); }, fail: (err) => { if (err.errMsg === 'saveImageToPhotosAlbum:fail auth deny') { this.showAuthGuide(); } else { wx.showToast({ title: '保存失败', icon: 'none' }); } }, }); }, // 显示授权引导 showAuthGuide() { wx.showModal({ title: '权限申请', content: '需要相册访问权限才能保存图片,请开启权限', success: (res) => { if (res.confirm) { wx.openSetting(); } }, }); }, // 预览大图 previewFullImage() { if (!this.data.generatedImage) return; wx.previewImage({ current: this.data.generatedImage, urls: [this.data.generatedImage], }); }, });