1+ <template >
2+ <div class =" panel" >
3+ <div class =" background" ref =" bgDiv" ></div >
4+ <!-- <canvas ref="rBgCanvasElement" width="100" height="100"></canvas> -->
5+ <canvas ref =" rCanvasElement" width =" 100" height =" 100" ></canvas >
6+ </div >
7+ </template >
8+
9+ <script setup lang="ts">
10+ import { projectInjectKey } from " @/utils/injects" ;
11+ import { inject , onBeforeUnmount , onMounted , ref , watch } from " vue" ;
12+ import RendererWorker from ' ../core/renderer-worker?worker' ;
13+
14+ if (window .myWorker ) {
15+ window .myWorker .terminate ();
16+ }
17+ window .myWorker = new RendererWorker ();
18+
19+ const project = inject (projectInjectKey );
20+ const bgDiv = ref <HTMLDivElement >();
21+ // const rBgCanvasElement = ref<HTMLCanvasElement>();
22+ const rCanvasElement = ref <HTMLCanvasElement >();
23+ let mCtx: CanvasRenderingContext2D | null = null ;
24+ let count = 0 ;
25+
26+ window .myWorker .addEventListener (' message' , (e ) => {
27+ // console.log('message', e.data);
28+ const bitmap: ImageBitmap = e .data ;
29+ mCtx ?.clearRect (0 , 0 , rCanvasElement .value ! .width , rCanvasElement .value ! .height );
30+ mCtx ?.drawImage (bitmap , 0 , 0 );
31+ bitmap .close ();
32+ count ++ ;
33+ });
34+
35+
36+
37+ function initDrawable() {
38+ if (project ?.value ) {
39+ const { screenHeight : h, screenWidth : w } = project .value
40+ if (rCanvasElement .value ) {
41+ rCanvasElement .value .width = w ;
42+ rCanvasElement .value .height = h ;
43+ }
44+ if (bgDiv .value ) {
45+ bgDiv .value .style .aspectRatio = ` ${w }/${h } `
46+ if (w > h ) {
47+ bgDiv .value .style .width = ' 100%' ;
48+ bgDiv .value .style .height = ' auto' ;
49+ } else {
50+ bgDiv .value .style .width = ' auto' ;
51+ bgDiv .value .style .height = ' 100%' ;
52+ }
53+ bgDiv .value .style .backgroundImage = ` url(${project .value .image ?.src }) ` ;
54+ }
55+ window .myWorker ?.postMessage ({
56+ type: ' init' ,
57+ width: w ,
58+ height: h ,
59+ drawable: project .value .toDrawable ()
60+ });
61+ }
62+ }
63+
64+ watch (() => project ?.value ?.uuid , () => initDrawable ());
65+ watch (() => project ?.value , (p ) => {
66+ if (p ) {
67+ window .myWorker ?.postMessage ({
68+ type: ' draw' ,
69+ drawable: p .toDrawable ()
70+ });
71+ }
72+ });
73+
74+ let intervalId: number | null = null ;
75+ onMounted (() => {
76+ mCtx = rCanvasElement .value ! .getContext (' 2d' )! ;
77+ initDrawable ();
78+ intervalId = window .setInterval (() => {
79+ if (project ?.value ) {
80+ window .myWorker ?.postMessage ({
81+ type: ' update' ,
82+ drawable: project .value .toDrawable ()
83+ });
84+ }
85+ }, 20 );
86+ });
87+
88+ onBeforeUnmount (() => {
89+ window .myWorker ?.terminate ();
90+ clearInterval (intervalId ! );
91+ });
92+ </script >
93+
94+ <style scoped lang="scss">
95+ div .panel {
96+ position : relative ;
97+ flex : 1 ;
98+ display : flex ;
99+ align-items : center ;
100+ justify-content : center ;
101+
102+ canvas {
103+ position : absolute ;
104+ display : block ;
105+ flex : none ;
106+ max-width : 100% ;
107+ max-height : 100% ;
108+ background-color : transparent ;
109+ }
110+
111+ div .background {
112+ position : absolute ;
113+ display : block ;
114+ flex : none ;
115+ max-width : 100% ;
116+ max-height : 100% ;
117+ background-color : transparent ;
118+ background-size : contain ;
119+ }
120+
121+ div .image {
122+ position : relative ;
123+
124+ img {
125+ max-width : 100% ;
126+ max-height : 100% ;
127+ margin-left : 1px ;
128+ }
129+
130+ div .safe-area {
131+ position : absolute ;
132+ top : 50% ;
133+ border : 1px solid red ;
134+ width : 100% ;
135+ margin-top : -50% ;
136+ aspect-ratio : 9 / 16 ;
137+ }
138+ }
139+
140+ }
141+ </style >
0 commit comments