Files
doodle-mini/miniprogram/components3.0/preview-card/preview-card.ts
T
2026-04-22 15:02:48 +08:00

146 lines
4.3 KiB
TypeScript

import { PAPER_SIZE, A4_EXPORT_SIZE_150DPI } from '../../constants/colors';
Component({
options: {
styleIsolation: 'apply-shared',
addGlobalClass: true,
},
properties: {
kicker: {
type: String,
value: '打印预览',
},
showRefresh: {
type: Boolean,
value: false,
},
showFavorite: {
type: Boolean,
value: false,
},
favorited: {
type: Boolean,
value: false,
},
favoritedIconColor: {
type: String,
value: '#E53935',
},
favoriteIdleIconColor: {
type: String,
value: '#605b50',
},
},
data: {
boxWidth: 0,
boxHeight: 0,
refreshIconAnimClass: '',
withFab: false,
},
observers: {
'showRefresh, showFavorite'(
showRefresh: boolean,
showFavorite: boolean,
) {
this.setData({ withFab: !!showRefresh || !!showFavorite });
},
},
lifetimes: {
ready() {
this.initCanvas();
},
},
methods: {
initCanvas() {
const query = this.createSelectorQuery();
query
.select('#canvasWrapper')
.boundingClientRect((rect) => {
if (!rect) return;
const { width, height } = PAPER_SIZE['A4'];
const boxWidth = rect.width;
const boxHeight = boxWidth / (width / height);
this.setData({ boxWidth, boxHeight });
this.createSelectorQuery()
.select('#canvasContent')
.fields({ node: true, size: true })
.exec((res) => {
if (!res[0]) return;
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = boxWidth * dpr;
canvas.height = boxHeight * dpr;
ctx.scale(dpr, dpr);
this._canvas = canvas;
this.triggerEvent('canvas-ready', {
canvas,
ctx,
width: boxWidth,
height: boxHeight,
});
});
})
.exec();
},
onRefreshTap() {
this.triggerEvent('refresh', {});
if ((this as any)._refreshSpinTimer) {
clearTimeout((this as any)._refreshSpinTimer);
}
this.setData({ refreshIconAnimClass: '' });
const n = ((this as any)._refreshTapCount || 0) + 1;
(this as any)._refreshTapCount = n;
const sub = n % 2 === 1 ? 'a' : 'b';
(this as any)._refreshSpinTimer = setTimeout(() => {
(this as any)._refreshSpinTimer = null;
this.setData({
refreshIconAnimClass: `pc-fab__icon-wrap--${sub}`,
});
}, 20);
},
onFavoriteTap() {
this.triggerEvent('favorite', {});
},
getCanvas(): WechatMiniprogram.Canvas | null {
return this._canvas || null;
},
exportToTempFile(
options?: { quality?: number; fileType?: 'png' | 'jpg' },
): Promise<string> {
const canvas = this._canvas;
if (!canvas) {
return Promise.reject(new Error('Canvas not initialized'));
}
return new Promise((resolve, reject) => {
wx.canvasToTempFilePath({
canvas,
fileType: options?.fileType || 'png',
quality: options?.quality ?? 1,
destWidth: A4_EXPORT_SIZE_150DPI.width,
destHeight: A4_EXPORT_SIZE_150DPI.height,
success: (res) => resolve(res.tempFilePath),
fail: (err) => reject(err),
});
});
},
},
});