2
2
* Gradient
3
3
* class to create linear/radial/elliptical/conic gradients as bitmaps even without canvas
4
4
*
5
- * @version 1.1.1
5
+ * @version 1.2.0
6
6
* https://github.com/foo123/Gradient
7
7
*
8
8
**/
9
9
! function ( root , name , factory ) {
10
10
"use strict" ;
11
11
if ( ( 'object' === typeof module ) && module . exports ) /* CommonJS */
12
- ( module . $deps = module . $deps || { } ) && ( module . exports = module . $deps [ name ] = factory . call ( root ) ) ;
12
+ module . exports = factory . call ( root ) ;
13
13
else if ( ( 'function' === typeof define ) && define . amd && ( 'function' === typeof require ) && ( 'function' === typeof require . specified ) && require . specified ( name ) /*&& !require.defined(name)*/ ) /* AMD */
14
- define ( name , [ 'module' ] , function ( module ) { factory . moduleUri = module . uri ; return factory . call ( root ) ; } ) ;
14
+ define ( name , [ 'module' ] , function ( module ) { return factory . call ( root ) ; } ) ;
15
15
else if ( ! ( name in root ) ) /* Browser/WebWorker/.. */
16
16
( root [ name ] = factory . call ( root ) || 1 ) && ( 'function' === typeof ( define ) ) && define . amd && define ( function ( ) { return root [ name ] ; } ) ;
17
17
} ( /* current root */ 'undefined' !== typeof self ? self : this ,
@@ -23,6 +23,7 @@ var HAS = Object.prototype.hasOwnProperty,
23
23
stdMath = Math , PI = stdMath . PI , TWO_PI = 2 * PI , HALF_PI = PI / 2 , EPS = 1e-6 ,
24
24
ImArray = 'undefined' !== typeof Uint8ClampedArray ? Uint8ClampedArray : ( 'undefined' !== typeof Uint8Array ? Uint8Array : Array ) ;
25
25
26
+ // Gradient Pattern
26
27
function Gradient ( grad_color_at )
27
28
{
28
29
if (
@@ -71,23 +72,25 @@ function Gradient(grad_color_at)
71
72
self . addColorStop = function ( offset , color ) {
72
73
_stops = null ;
73
74
stops [ String ( offset ) ] = [ + offset , parseColor ( color ) || [ 0 , 0 , 0 , 0 ] ] ;
74
- }
75
+ } ;
75
76
self . getColorAt = function ( x , y ) {
76
77
var p = imatrix . transform ( x , y ) ;
77
78
return grad_color_at ( p . x , p . y , colorStops ( ) , new ImArray ( 4 ) , 0 ) ;
78
79
} ;
79
- self . getBitmap = function ( w , h ) {
80
- var color_stops = colorStops ( ) , i , x , y , p , size = ( w * h ) << 2 , bmp = new ImArray ( size ) ;
80
+ self . getBitmap = function ( width , height ) {
81
+ width = stdMath . round ( width ) ;
82
+ height = stdMath . round ( height ) ;
83
+ var color_stops = colorStops ( ) , i , x , y , p , size = ( width * height ) << 2 , bmp = new ImArray ( size ) ;
81
84
for ( x = 0 , y = 0 , i = 0 ; i < size ; i += 4 , ++ x )
82
85
{
83
- if ( x >= w ) { x = 0 ; ++ y ; }
86
+ if ( x >= width ) { x = 0 ; ++ y ; }
84
87
p = imatrix . transform ( x , y ) ;
85
88
grad_color_at ( p . x , p . y , color_stops , bmp , i ) ;
86
89
}
87
90
return bmp ;
88
91
} ;
89
92
}
90
- Gradient . VERSION = "1.1.1 " ;
93
+ Gradient . VERSION = "1.2.0 " ;
91
94
Gradient . prototype = {
92
95
constructor : Gradient ,
93
96
transform : null ,
@@ -241,6 +244,138 @@ Gradient.createEllipticGradient = function(cx, cy, rx, ry, angle) {
241
244
} ) ;
242
245
} ;
243
246
247
+ // Image Pattern
248
+ function Pattern ( pat_color_at )
249
+ {
250
+ if (
251
+ ! ( this instanceof Pattern ) ||
252
+ ( 'function' !== typeof pat_color_at ) ||
253
+ ( 4 > pat_color_at . length )
254
+ )
255
+ {
256
+ throw new Error ( 'Pattern: invalid pattern' ) ;
257
+ }
258
+
259
+ var self = this , imatrix = new Matrix ( ) ;
260
+
261
+ self . transform = {
262
+ reset : function ( ) {
263
+ imatrix = new Matrix ( ) ;
264
+ } ,
265
+ scale : function ( sx , sy , ox , oy ) {
266
+ imatrix = imatrix . mul ( Matrix . scale ( 1 / sx , 1 / sy , ox , oy ) ) ;
267
+ } ,
268
+ rotate : function ( theta , ox , oy ) {
269
+ imatrix = imatrix . mul ( Matrix . rotate ( - theta , ox , oy ) ) ;
270
+ } ,
271
+ translate : function ( tx , ty ) {
272
+ imatrix = imatrix . mul ( Matrix . translate ( - tx , - ty ) ) ;
273
+ } ,
274
+ skewX : function ( s ) {
275
+ imatrix = imatrix . mul ( Matrix . skewX ( s ) . inv ( ) ) ;
276
+ } ,
277
+ skewX : function ( s ) {
278
+ imatrix = imatrix . mul ( Matrix . skewY ( s ) . inv ( ) ) ;
279
+ }
280
+ } ;
281
+ self . getColorAt = function ( x , y ) {
282
+ var p = imatrix . transform ( x , y ) ;
283
+ return pat_color_at ( p . x , p . y , new ImArray ( 4 ) , 0 ) ;
284
+ } ;
285
+ self . getBitmap = function ( width , height ) {
286
+ width = stdMath . round ( width ) ;
287
+ height = stdMath . round ( height ) ;
288
+ var i , x , y , p , size = ( width * height ) << 2 , bmp = new ImArray ( size ) ;
289
+ for ( x = 0 , y = 0 , i = 0 ; i < size ; i += 4 , ++ x )
290
+ {
291
+ if ( x >= width ) { x = 0 ; ++ y ; }
292
+ p = imatrix . transform ( x , y ) ;
293
+ pat_color_at ( p . x , p . y , bmp , i ) ;
294
+ }
295
+ return bmp ;
296
+ } ;
297
+ }
298
+ Pattern . prototype = {
299
+ constructor : Pattern ,
300
+ transform : null ,
301
+ getColorAt : null ,
302
+ getBitmap : null
303
+ } ;
304
+ Pattern . createPattern = function ( imageData , repetition ) {
305
+ if ( imageData && imageData . data && imageData . width && imageData . height && ( imageData . data . length === 4 * imageData . width * imageData . height ) )
306
+ {
307
+ var width = imageData . width , height = imageData . height ;
308
+ switch ( repetition )
309
+ {
310
+ case 'no-repeat' :
311
+ return new Pattern ( function ( x , y , pixel , i ) {
312
+ x = stdMath . round ( x ) ;
313
+ y = stdMath . round ( y ) ;
314
+ if ( 0 <= x && x < width && 0 <= y && y < height )
315
+ {
316
+ var j = ( x + y * width ) << 2 ;
317
+ pixel [ i + 0 ] = imageData . data [ j + 0 ] ;
318
+ pixel [ i + 1 ] = imageData . data [ j + 1 ] ;
319
+ pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
320
+ pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
321
+ }
322
+ } ) ;
323
+ case 'repeat-x' :
324
+ return new Pattern ( function ( x , y , pixel , i ) {
325
+ x = stdMath . round ( x ) ;
326
+ y = stdMath . round ( y ) ;
327
+ if ( 0 <= y && y < height )
328
+ {
329
+ x = x % width ;
330
+ if ( 0 > x ) x += width ;
331
+ var j = ( x + y * width ) << 2 ;
332
+ pixel [ i + 0 ] = imageData . data [ j + 0 ] ;
333
+ pixel [ i + 1 ] = imageData . data [ j + 1 ] ;
334
+ pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
335
+ pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
336
+ }
337
+ } ) ;
338
+ case 'repeat-y' :
339
+ return new Pattern ( function ( x , y , pixel , i ) {
340
+ x = stdMath . round ( x ) ;
341
+ y = stdMath . round ( y ) ;
342
+ if ( 0 <= x && x < width )
343
+ {
344
+ y = y % height ;
345
+ if ( 0 > y ) y += height ;
346
+ var j = ( x + y * width ) << 2 ;
347
+ pixel [ i + 0 ] = imageData . data [ j + 0 ] ;
348
+ pixel [ i + 1 ] = imageData . data [ j + 1 ] ;
349
+ pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
350
+ pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
351
+ }
352
+ } ) ;
353
+ case 'repeat' :
354
+ default :
355
+ return new Pattern ( function ( x , y , pixel , i ) {
356
+ x = stdMath . round ( x ) ;
357
+ y = stdMath . round ( y ) ;
358
+ x = x % width ;
359
+ if ( 0 > x ) x += width ;
360
+ y = y % height ;
361
+ if ( 0 > y ) y += height ;
362
+ var j = ( x + y * width ) << 2 ;
363
+ pixel [ i + 0 ] = imageData . data [ j + 0 ] ;
364
+ pixel [ i + 1 ] = imageData . data [ j + 1 ] ;
365
+ pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
366
+ pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
367
+ } ) ;
368
+ }
369
+ }
370
+ else
371
+ {
372
+ throw new Error ( 'Pattern: invalid image data' ) ;
373
+ }
374
+ } ;
375
+ Gradient . Pattern = Pattern ;
376
+ Gradient . createPattern = Pattern . createPattern ;
377
+
378
+ // Homogeneous Transformation Matrix
244
379
function Matrix ( m00 , m01 , m02 , m10 , m11 , m12 )
245
380
{
246
381
var self = this ;
@@ -376,6 +511,7 @@ function binary_search(x, a, n)
376
511
}
377
512
return l ;
378
513
}
514
+ // color utilities
379
515
function interpolatePixel ( pixel , index , rgba0 , rgba1 , t )
380
516
{
381
517
pixel [ index + 0 ] = clamp ( stdMath . round ( rgba0 [ 0 ] + t * ( rgba1 [ 0 ] - rgba0 [ 0 ] ) ) , 0 , 255 ) ;
0 commit comments