1+ import { WebviewWindow } from '@tauri-apps/api/window' ;
2+ import { DrawableProject } from '../../dtos/Drawable' ;
3+
4+ export function exportImage ( image : ImageBitmap , drawable : DrawableProject ) {
5+ const layer0 = document . createElement ( 'canvas' ) ;
6+ layer0 . width = image . width ;
7+ layer0 . height = image . height ;
8+ const layer1 = document . createElement ( 'canvas' ) ;
9+ layer1 . width = image . width ;
10+ layer1 . height = image . height ;
11+ const ctx0 = layer0 . getContext ( '2d' ) ! ;
12+ const ctx1 = layer1 . getContext ( '2d' ) ! ;
13+ ctx0 . drawImage ( image , 0 , 0 ) ;
14+ // draw warning strip in layer1
15+ const pattern = drawWarningStrip ( ctx1 ) ;
16+ ctx1 . fillStyle = pattern ;
17+ ctx1 . fillRect ( 0 , 0 , layer1 . width , layer1 . height ) ;
18+ ctx1 . clearRect ( drawable . bounds . x , drawable . bounds . y , drawable . bounds . width , drawable . bounds . height ) ;
19+ ctx1 . fillStyle = 'rgba(255, 255, 255, 0.5)' ;
20+ // draw layer1 on layer0
21+ ctx0 . drawImage ( layer1 , 0 , 0 ) ;
22+ // export to data url and open in webview
23+ const dataURL = layer0 . toDataURL ( 'image/png' ) ;
24+ console . log ( dataURL ) ;
25+ openExportedImage ( dataURL ) ;
26+ }
27+
28+ export async function openExportedImage ( dataURL : string ) {
29+ let webview : WebviewWindow ;
30+ try {
31+ webview = WebviewWindow . getByLabel ( 'export-image' ) ! ;
32+ if ( ! webview ) {
33+ throw new Error ( 'webview not found' ) ;
34+ }
35+ webview . emit ( 'export-load' , { dataURL } ) ;
36+ } catch ( error ) {
37+ webview = new WebviewWindow ( 'export-image' , {
38+ url : 'export-image.html' ,
39+ center : true ,
40+ resizable : true ,
41+ minHeight : 600 ,
42+ minWidth : 600 ,
43+ width : 600 ,
44+ height : 600 ,
45+ title : 'Export Image' ,
46+ } ) ;
47+ await webview . once ( 'export-inited' , ( e ) => {
48+ console . log ( 'export-inited' ) ;
49+ WebviewWindow . getByLabel ( e . windowLabel ) ?. emit ( 'export-load' , { dataURL } ) ;
50+ } ) ;
51+ } finally {
52+ webview ! . setFocus ( ) ;
53+ }
54+ }
55+
56+ /**
57+ * 绘制倾角为 45° 的黄黑相间的警告条纹
58+ * @param ctx Canvas 的上下文
59+ * @param interval 同色条纹之间的间隔
60+ */
61+ function drawWarningStrip ( ctx : CanvasRenderingContext2D , interval = 100 ) {
62+ const patternCanvas = document . createElement ( 'canvas' ) ;
63+ patternCanvas . width = interval * 2 ;
64+ patternCanvas . height = interval * 2 ;
65+ const pCtx = patternCanvas . getContext ( '2d' ) ! ;
66+ pCtx . fillStyle = 'rgba(0, 0, 0, 0.5)' ;
67+ pCtx . beginPath ( ) ;
68+ pCtx . moveTo ( 0 , 0 ) ;
69+ pCtx . lineTo ( interval , 0 ) ;
70+ pCtx . lineTo ( 0 , interval ) ;
71+ pCtx . closePath ( ) ;
72+ pCtx . fill ( ) ;
73+ pCtx . beginPath ( ) ;
74+ pCtx . moveTo ( interval * 2 , 0 ) ;
75+ pCtx . lineTo ( 0 , interval * 2 ) ;
76+ pCtx . lineTo ( interval , interval * 2 ) ;
77+ pCtx . lineTo ( interval * 2 , interval ) ;
78+ pCtx . closePath ( ) ;
79+ pCtx . fill ( ) ;
80+ pCtx . fillStyle = 'rgba(255, 255, 0, 0.5)' ;
81+ pCtx . beginPath ( ) ;
82+ pCtx . moveTo ( 0 , interval ) ;
83+ pCtx . lineTo ( 0 , interval * 2 ) ;
84+ pCtx . lineTo ( interval * 2 , 0 ) ;
85+ pCtx . lineTo ( interval , 0 ) ;
86+ pCtx . closePath ( ) ;
87+ pCtx . fill ( ) ;
88+ pCtx . beginPath ( ) ;
89+ pCtx . moveTo ( interval , interval * 2 ) ;
90+ pCtx . lineTo ( interval * 2 , interval * 2 ) ;
91+ pCtx . lineTo ( interval * 2 , interval ) ;
92+ pCtx . closePath ( ) ;
93+ pCtx . fill ( ) ;
94+ return ctx . createPattern ( patternCanvas , 'repeat' ) ! ;
95+ }
0 commit comments