1+ class Gfx {
2+ static load_image ( url ) { return new Promise ( ( resolve , reject ) => {
3+ const img = new Image ( )
4+ img . onload = ( ) => resolve ( img )
5+ img . onerror = ( e ) => console . error ( `image load failed ${ url } ` , e )
6+ img . src = url
7+ } ) }
8+ static drawLine ( c , x1 , y1 , x2 , y2 , color = 'white' , lineWidth = 1 ) {
9+ c . strokeStyle = color
10+ c . lineWidth = lineWidth
11+ c . beginPath ( )
12+ c . moveTo ( x1 , y1 )
13+ c . lineTo ( x2 , y2 )
14+ c . stroke ( )
15+ }
16+ static subsurface ( img , x , y , width , height ) {
17+ // TODO: consider using https://developer.mozilla.org/en-US/docs/Web/API/Window/createImageBitmap
18+ const o = new OffscreenCanvas ( width , height )
19+ const c = o . getContext ( "2d" )
20+ c . drawImage ( img , - x , - y )
21+ return o . transferToImageBitmap ( )
22+ }
23+ static invert ( img ) {
24+ const o1 = new OffscreenCanvas ( img . width , img . height )
25+ const c1 = o1 . getContext ( "2d" )
26+ // Invert image (but destroys transparency)
27+ c1 . drawImage ( img , 0 , 0 )
28+ c1 . globalCompositeOperation = 'difference'
29+ c1 . fillStyle = 'white'
30+ c1 . fillRect ( 0 , 0 , img . width , img . height )
31+ // Mask
32+ const o2 = new OffscreenCanvas ( img . width , img . height )
33+ const c2 = o2 . getContext ( '2d' )
34+ c2 . drawImage ( img , 0 , 0 ) ;
35+ c2 . globalCompositeOperation = 'source-in' ;
36+ c2 . fillStyle = 'black' ;
37+ c2 . fillRect ( 0 , 0 , img . width , img . height ) ;
38+ // Cut Mask out of Inverted image
39+ c1 . globalCompositeOperation = 'destination-in' ;
40+ c1 . drawImage ( o2 , 0 , 0 ) ;
41+ return o1 . transferToImageBitmap ( )
42+ }
43+ }
44+
145function createFullScreenCanvasElement ( { width= 480 , height= 270 , background_color= 'black' } = { } ) {
246 const body_style = `
347 margin: 0;
@@ -38,7 +82,7 @@ function createAudioElement() {
3882 //play_audio = (url) => {this.audio.src = url}
3983}
4084
41- export class CanvasAnimationBase {
85+ class CanvasAnimationBase {
4286 constructor ( canvas = undefined , fps = 60 , canvas_attrs = { background_color : 'black' } ) {
4387 this . canvas = canvas || createFullScreenCanvasElement ( canvas_attrs )
4488 this . context = this . canvas . getContext ( '2d' , { alpha : true } )
@@ -91,20 +135,8 @@ export class CanvasAnimationBase {
91135 }
92136 }
93137
94- load_image = ( name , url ) => {
95- let resolve_image_loaded = undefined
96- const promise = new Promise ( ( resolve , reject ) => {
97- resolve_image_loaded = resolve
98- } )
99- const images = this . images
100- images [ name ] = new Image ( )
101- images [ name ] . onload = function ( ) {
102- images [ name ] = this
103- resolve_image_loaded ( this )
104- }
105- images [ name ] . src = url
106- return promise
107- }
138+ // TODO! In making this async, many of the earlier examples will not function and need reworking
139+ async load_image ( name , url ) { this . images [ name ] = await Gfx . load_image ( url ) }
108140
109141 run = ( time ) => {
110142 if ( this . keys_pressed . has ( "Escape" ) ) { this . setRunning ( false ) }
@@ -125,45 +157,7 @@ export class CanvasAnimationBase {
125157 throw new Error ( "Not Implemented Error" )
126158 }
127159
128- // Graphics Utils ----------------------------------------------------------
129-
130- static drawLine ( c , x1 , y1 , x2 , y2 , color = 'white' , lineWidth = 1 ) {
131- c . strokeStyle = color
132- c . lineWidth = lineWidth
133- c . beginPath ( )
134- c . moveTo ( x1 , y1 )
135- c . lineTo ( x2 , y2 )
136- c . stroke ( )
137- }
138-
139- static subsurface ( img , x , y , width , height ) {
140- const o = new OffscreenCanvas ( width , height )
141- const c = o . getContext ( "2d" )
142- c . drawImage ( img , - x , - y )
143- return o . transferToImageBitmap ( )
144- }
145-
146- static invert ( img ) {
147- const o1 = new OffscreenCanvas ( img . width , img . height )
148- const c1 = o1 . getContext ( "2d" )
149- // Invert image (but destroys transparency)
150- c1 . drawImage ( img , 0 , 0 )
151- c1 . globalCompositeOperation = 'difference'
152- c1 . fillStyle = 'white'
153- c1 . fillRect ( 0 , 0 , img . width , img . height )
154-
155- // Mask
156- const o2 = new OffscreenCanvas ( img . width , img . height )
157- const c2 = o2 . getContext ( '2d' )
158- c2 . drawImage ( img , 0 , 0 ) ;
159- c2 . globalCompositeOperation = 'source-in' ;
160- c2 . fillStyle = 'black' ;
161- c2 . fillRect ( 0 , 0 , img . width , img . height ) ;
160+ }
162161
163- // Cut Mask out of Inverted image
164- c1 . globalCompositeOperation = 'destination-in' ;
165- c1 . drawImage ( o2 , 0 , 0 ) ;
166- return o1 . transferToImageBitmap ( )
167- }
168162
169- }
163+ export { Gfx , CanvasAnimationBase }
0 commit comments