feat: 打印预览组件化
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
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),
|
||||
});
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user