1
-
1
+
2
2
( function ( global , factory ) {
3
3
typeof exports === 'object' && typeof module !== 'undefined' ? factory ( exports ) :
4
4
typeof define === 'function' && define . amd ? define ( [ 'exports' ] , factory ) :
3797
3797
compose_shaders ( shader , { x, y, z} ) {
3798
3798
let id = unique_id ( 'shader' ) ;
3799
3799
this . shaders [ id ] = {
3800
+ id : '--' + id ,
3800
3801
shader,
3801
3802
cell : cell_id ( x , y , z )
3802
3803
} ;
@@ -5056,11 +5057,56 @@ void main() {
5056
5057
return transform ( getComputedStyle ( element ) . color ) ;
5057
5058
}
5058
5059
5060
+ const STEP60 = 1000 / 60 ; // 60fps
5061
+ const STEP1 = 1000 / 1 ; // 1fps
5062
+
5063
+ function createAnimationFrame ( fn ) {
5064
+ let id ;
5065
+ let time = 0 ;
5066
+ let lastTime = 0 ;
5067
+ let lastStep = 0 ;
5068
+ let paused = false ;
5069
+ function loop ( stamp ) {
5070
+ if ( ! time ) time = stamp ;
5071
+ fn ( time ) ;
5072
+ let step = ( stamp - lastTime ) ;
5073
+ if ( step < STEP60 ) step = STEP60 ;
5074
+ if ( step > STEP1 ) step = lastStep || STEP1 ;
5075
+ if ( lastTime ) time += step ;
5076
+ lastStep = step ;
5077
+ lastTime = stamp ;
5078
+ id = requestAnimationFrame ( loop ) ;
5079
+ }
5080
+ id = requestAnimationFrame ( loop ) ;
5081
+ return {
5082
+ resume ( ) {
5083
+ if ( id && paused ) {
5084
+ paused = false ;
5085
+ id = requestAnimationFrame ( loop ) ;
5086
+ }
5087
+ } ,
5088
+ pause ( ) {
5089
+ if ( id ) {
5090
+ cancelAnimationFrame ( id ) ;
5091
+ paused = true ;
5092
+ }
5093
+ } ,
5094
+ cancel ( ) {
5095
+ if ( id ) {
5096
+ paused = false ;
5097
+ cancelAnimationFrame ( id ) ;
5098
+ id = null ;
5099
+ }
5100
+ } ,
5101
+ }
5102
+ }
5103
+
5059
5104
if ( typeof customElements !== 'undefined' ) {
5060
5105
class Doodle extends HTMLElement {
5061
5106
constructor ( ) {
5062
5107
super ( ) ;
5063
5108
this . doodle = this . attachShadow ( { mode : 'open' } ) ;
5109
+ this . animations = [ ] ;
5064
5110
this . extra = {
5065
5111
get_variable : name => get_variable ( this , name ) ,
5066
5112
get_rgba_color : value => get_rgba_color ( this . shadowRoot , value ) ,
@@ -5075,8 +5121,17 @@ void main() {
5075
5121
}
5076
5122
}
5077
5123
5078
- update ( styles ) {
5124
+ disconnectedCallback ( ) {
5079
5125
Cache . clear ( ) ;
5126
+ for ( let animation of this . animations ) {
5127
+ animation . cancel ( ) ;
5128
+ }
5129
+ this . animations = [ ] ;
5130
+ }
5131
+
5132
+ update ( styles ) {
5133
+ this . disconnectedCallback ( ) ;
5134
+
5080
5135
let use = this . get_use ( ) ;
5081
5136
if ( ! styles ) styles = un_entity ( this . innerHTML ) ;
5082
5137
this . innerHTML = styles ;
@@ -5265,32 +5320,44 @@ void main() {
5265
5320
draw_canvas ( code ) . then ( fn ) ;
5266
5321
}
5267
5322
5268
- shader_to_image ( { shader, cell } , fn ) {
5323
+ pause ( ) {
5324
+ this . setAttribute ( 'cssd-paused-animation' , true ) ;
5325
+ for ( let animation of this . animations ) {
5326
+ animation . pause ( ) ;
5327
+ }
5328
+ }
5329
+
5330
+ resume ( ) {
5331
+ this . removeAttribute ( 'cssd-paused-animation' ) ;
5332
+ for ( let animation of this . animations ) {
5333
+ animation . resume ( ) ;
5334
+ }
5335
+ }
5336
+
5337
+ shader_to_image ( { shader, cell, id } , fn ) {
5269
5338
let parsed = typeof shader === 'string' ? parse$7 ( shader ) : shader ;
5270
5339
let element = this . doodle . getElementById ( cell ) ;
5340
+
5341
+ const set_shader_prop = ( v ) => {
5342
+ element . style . setProperty ( id , `url(${ v } )` ) ;
5343
+ } ;
5344
+
5271
5345
const tick = ( value ) => {
5272
- if ( typeof value === 'function' ) {
5273
- let currentImage ;
5274
- const update = ( t ) => {
5275
- if ( currentImage === element . style . backgroundImage ) {
5276
- element . style . backgroundImage = `url(${ value ( t ) } )` ;
5277
- currentImage = element . style . backgroundImage ;
5278
- requestAnimationFrame ( update ) ;
5279
- }
5280
- } ;
5281
- requestAnimationFrame ( update ) ;
5282
- const ret = value ( 0 ) ;
5283
- element . style . backgroundImage = `url(${ ret } )` ;
5284
- currentImage = element . style . backgroundImage ;
5346
+ if ( typeof value === 'function' ) {
5347
+ let animation = createAnimationFrame ( t => {
5348
+ set_shader_prop ( value ( t ) ) ;
5349
+ } ) ;
5350
+ this . animations . push ( animation ) ;
5285
5351
return '' ;
5286
5352
}
5287
- return value ;
5353
+ set_shader_prop ( value ) ;
5288
5354
} ;
5355
+
5289
5356
let { width, height } = element && element . getBoundingClientRect ( ) || {
5290
5357
width : 0 , height : 0
5291
5358
} ;
5292
- let ratio = window . devicePixelRatio || 1 ;
5293
5359
5360
+ let ratio = window . devicePixelRatio || 1 ;
5294
5361
if ( ! parsed . textures . length || parsed . ticker ) {
5295
5362
draw_shader ( parsed , width , height ) . then ( tick ) . then ( fn ) ;
5296
5363
}
@@ -5382,20 +5449,14 @@ void main() {
5382
5449
) ;
5383
5450
5384
5451
return Promise . all ( mappings ) . then ( mapping => {
5385
- if ( input . replaceAll ) {
5386
- mapping . forEach ( ( { id, value } ) => {
5387
- input = input . replaceAll (
5388
- '${' + id + '}' ,
5389
- / ^ c a n v a s / . test ( id ) ? value : `url(${ value } )`
5390
- ) ;
5391
- } ) ;
5392
- } else {
5393
- mapping . forEach ( ( { id, value } ) => {
5394
- input = input . replace (
5395
- '${' + id + '}' ,
5396
- / ^ c a n v a s / . test ( id ) ? value : `url(${ value } )`
5397
- ) ;
5398
- } ) ;
5452
+ for ( let { id, value} of mapping ) {
5453
+ /* default to data-uri for doodle and pattern */
5454
+ let target = `url(${ value } )` ;
5455
+ /* canvas uses css painting api */
5456
+ if ( / ^ c a n v a s / . test ( id ) ) target = value ;
5457
+ /* shader uses css vars */
5458
+ if ( / ^ s h a d e r / . test ( id ) ) target = `var(--${ id } )` ;
5459
+ input = input . replaceAll ( '${' + id + '}' , target ) ;
5399
5460
}
5400
5461
return input ;
5401
5462
} ) ;
@@ -5605,11 +5666,9 @@ void main() {
5605
5666
. map ( n => `${ n } : inherit;` )
5606
5667
. join ( '' ) ;
5607
5668
return `
5608
- * {
5609
- box-sizing: border-box
5610
- }
5611
- *::after, *::before {
5612
- box-sizing: inherit
5669
+ *, *::after, *::before {
5670
+ box-sizing: border-box;
5671
+ animation-play-state: var(--cssd-animation-play-state) !important;
5613
5672
}
5614
5673
:host, .host {
5615
5674
display: block;
@@ -5639,6 +5698,10 @@ void main() {
5639
5698
width: 100%;
5640
5699
height: 100%;
5641
5700
}
5701
+ :host([cssd-paused-animation]) {
5702
+ --cssd-animation-play-state: paused;
5703
+ animation-play-state: paused !important;
5704
+ }
5642
5705
` ;
5643
5706
}
5644
5707
0 commit comments