/* global Page, wx */ /* eslint-disable no-console */ const { buildShareGridTileFileName, buildShareGridTilePlan, normalizeShareGridQuery, } = require('./index.shared'); function downloadImage(imageUrl) { return new Promise((resolve, reject) => { wx.downloadFile({ url: imageUrl, success(response) { if (response.statusCode >= 200 && response.statusCode < 300) { resolve(response.tempFilePath); return; } reject(new Error(`封面下载失败:${response.statusCode}`)); }, fail(error) { reject(new Error(error.errMsg || '封面下载失败')); }, }); }); } function getImageInfo(src) { return new Promise((resolve, reject) => { wx.getImageInfo({ src, success: resolve, fail(error) { reject(new Error(error.errMsg || '读取封面失败')); }, }); }); } function getCanvasNode(page) { return new Promise((resolve, reject) => { wx.createSelectorQuery() .in(page) .select('#share-grid-canvas') .fields({ node: true, size: true }) .exec((results) => { const canvas = results && results[0] && results[0].node; if (canvas) { resolve(canvas); return; } reject(new Error('切图画布初始化失败')); }); }); } function canvasToTempFilePath(canvas, width, height) { return new Promise((resolve, reject) => { wx.canvasToTempFilePath({ canvas, width, height, destWidth: width, destHeight: height, fileType: 'png', success(response) { resolve(response.tempFilePath); }, fail(error) { reject(new Error(error.errMsg || '导出切图失败')); }, }); }); } function saveImageToAlbum(filePath) { return new Promise((resolve, reject) => { wx.saveImageToPhotosAlbum({ filePath, success() { resolve(); }, fail(error) { reject(new Error(error.errMsg || '保存到相册失败')); }, }); }); } function copyTempFileWithName(tempFilePath, fileName) { const fileSystem = wx.getFileSystemManager && wx.getFileSystemManager(); const userDataPath = wx.env && wx.env.USER_DATA_PATH; if (!fileSystem || !userDataPath || typeof fileSystem.copyFile !== 'function') { return Promise.resolve(tempFilePath); } const targetPath = `${userDataPath}/${fileName}`; return new Promise((resolve) => { fileSystem.copyFile({ srcPath: tempFilePath, destPath: targetPath, success() { resolve(targetPath); }, fail() { resolve(tempFilePath); }, }); }); } async function saveGridTiles(page, params, localImagePath, imageInfo) { const canvas = await getCanvasNode(page); const context = canvas.getContext('2d'); const image = canvas.createImage(); await new Promise((resolve, reject) => { image.onload = resolve; image.onerror = () => reject(new Error('封面绘制失败')); image.src = localImagePath; }); const plan = buildShareGridTilePlan(imageInfo.width, imageInfo.height); for (const tile of plan) { canvas.width = tile.sourceWidth; canvas.height = tile.sourceHeight; context.clearRect(0, 0, tile.sourceWidth, tile.sourceHeight); context.drawImage( image, tile.sourceX, tile.sourceY, tile.sourceWidth, tile.sourceHeight, 0, 0, tile.sourceWidth, tile.sourceHeight, ); const tempFilePath = await canvasToTempFilePath( canvas, tile.sourceWidth, tile.sourceHeight, ); const namedFilePath = await copyTempFileWithName( tempFilePath, buildShareGridTileFileName(params, tile.index), ); await saveImageToAlbum(namedFilePath); page.setData({ savedCount: tile.index + 1, }); } } Page({ data: { errorMessage: '', loading: true, savedCount: 0, title: '九宫切图', }, async onLoad(query = {}) { const params = normalizeShareGridQuery(query); this._shareGridParams = params; this.setData({ errorMessage: '', loading: true, savedCount: 0, title: params.title, }); if (!params.imageUrl) { this.setData({ errorMessage: '缺少封面图。', loading: false, }); return; } try { const localImagePath = await downloadImage(params.imageUrl); const imageInfo = await getImageInfo(localImagePath); await saveGridTiles(this, params, localImagePath, imageInfo); this.setData({ loading: false, savedCount: 9, }); wx.showToast({ title: '已保存', icon: 'success', }); } catch (error) { console.error('[share-grid] save failed', error); this.setData({ errorMessage: error && error.message ? error.message : '九宫切图保存失败。', loading: false, }); } }, handleBack() { wx.navigateBack(); }, });