146 lines
4.3 KiB
TypeScript
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),
|
|
});
|
|
});
|
|
},
|
|
},
|
|
});
|