2
2
* CanvasLite
3
3
* an html canvas implementation in pure JavaScript
4
4
*
5
- * @version 0.9.92 (2023-07-30 21:49:27 )
5
+ * @version 0.9.92 (2023-07-31 22:54:20 )
6
6
* https://github.com/foo123/CanvasLite
7
7
*
8
8
**/ /**
9
9
* CanvasLite
10
10
* an html canvas implementation in pure JavaScript
11
11
*
12
- * @version 0.9.92 (2023-07-30 21:49:27 )
12
+ * @version 0.9.92 (2023-07-31 22:54:20 )
13
13
* https://github.com/foo123/CanvasLite
14
14
*
15
15
**/
@@ -3268,7 +3268,7 @@ function NOOP() {}
3268
3268
* Gradient
3269
3269
* class to create linear/radial/elliptical/conic gradients as bitmaps even without canvas
3270
3270
*
3271
- * @version 1.2.2
3271
+ * @version 1.2.3
3272
3272
* https://github.com/foo123/Gradient
3273
3273
*
3274
3274
**/
@@ -3309,12 +3309,13 @@ function Gradient(grad_color_at)
3309
3309
} ) ;
3310
3310
self . addColorStop = function ( offset , color ) {
3311
3311
_stops = null ;
3312
- stops [ String ( offset ) ] = [ + offset , parseColor ( color ) || [ 0 , 0 , 0 , 0 ] ] ;
3312
+ stops [ String ( offset ) ] = [ + offset , parseColor ( color ) || BLANK ] ;
3313
3313
} ;
3314
3314
self . getColorAt = function ( x , y ) {
3315
3315
var im = transform . imatrix ( true ) ,
3316
- p = im ? im . transform ( x , y ) : null ;
3317
- return p ? grad_color_at ( p . x , p . y , colorStops ( ) , new ImArray ( 4 ) , 0 ) : new ImArray ( 4 ) ;
3316
+ p = im ? im . transform ( x , y ) : null ,
3317
+ rgba = new ImArray ( 4 ) ;
3318
+ return p ? grad_color_at ( p [ 0 ] , p [ 1 ] , colorStops ( ) , rgba , 0 ) : rgba ;
3318
3319
} ;
3319
3320
self . getBitmap = function ( width , height ) {
3320
3321
width = stdMath . round ( width ) ;
@@ -3331,13 +3332,13 @@ function Gradient(grad_color_at)
3331
3332
{
3332
3333
if ( x >= width ) { x = 0 ; ++ y ; }
3333
3334
p = imatrix . transform ( x , y ) ;
3334
- grad_color_at ( p . x , p . y , color_stops , bmp , i ) ;
3335
+ grad_color_at ( p [ 0 ] , p [ 1 ] , color_stops , bmp , i ) ;
3335
3336
}
3336
3337
}
3337
3338
return bmp ;
3338
3339
} ;
3339
3340
}
3340
- Gradient . VERSION = "1.2.2 " ;
3341
+ Gradient . VERSION = "1.2.3 " ;
3341
3342
Gradient [ PROTO ] = {
3342
3343
constructor : Gradient ,
3343
3344
transform : null ,
@@ -3448,7 +3449,7 @@ Gradient.createConicGradient = function(angle, cx, cy) {
3448
3449
cy = cy || 0 ;
3449
3450
return new Gradient ( function ( x , y , stops , pixel , i ) {
3450
3451
var t , stop1 , stop2 , sl = stops . length ;
3451
- t = stdMath . atan2 ( y - cy , x - cx ) + HALF_PI - angle ;
3452
+ t = stdMath . atan2 ( y - cy , x - cx ) /* + HALF_PI*/ - angle ;
3452
3453
if ( 0 > t ) t += TWO_PI ;
3453
3454
if ( t > TWO_PI ) t -= TWO_PI ;
3454
3455
t = clamp ( t / TWO_PI , 0 , 1 ) ;
@@ -3486,8 +3487,13 @@ function Pattern(pat_color_at)
3486
3487
configurable : false
3487
3488
} ) ;
3488
3489
self . getColorAt = function ( x , y ) {
3489
- var p = transform . imatrix ( true ) . transform ( x , y ) ;
3490
- return pat_color_at ( p . x , p . y , new ImArray ( 4 ) , 0 ) ;
3490
+ var im = transform . imatrix ( true ) , p , rgba = new ImArray ( 4 ) ;
3491
+ if ( im )
3492
+ {
3493
+ p = im . transform ( x , y ) ;
3494
+ pat_color_at ( p [ 0 ] , p [ 1 ] , rgba , 0 ) ;
3495
+ }
3496
+ return rgba ;
3491
3497
} ;
3492
3498
self . getBitmap = function ( width , height ) {
3493
3499
width = stdMath . round ( width ) ;
@@ -3496,11 +3502,14 @@ function Pattern(pat_color_at)
3496
3502
i , x , y , p ,
3497
3503
size = ( width * height ) << 2 ,
3498
3504
bmp = new ImArray ( size ) ;
3499
- for ( x = 0 , y = 0 , i = 0 ; i < size ; i += 4 , ++ x )
3505
+ if ( imatrix )
3500
3506
{
3501
- if ( x >= width ) { x = 0 ; ++ y ; }
3502
- p = imatrix . transform ( x , y ) ;
3503
- pat_color_at ( p . x , p . y , bmp , i ) ;
3507
+ for ( x = 0 , y = 0 , i = 0 ; i < size ; i += 4 , ++ x )
3508
+ {
3509
+ if ( x >= width ) { x = 0 ; ++ y ; }
3510
+ p = imatrix . transform ( x , y ) ;
3511
+ pat_color_at ( p [ 0 ] , p [ 1 ] , bmp , i ) ;
3512
+ }
3504
3513
}
3505
3514
return bmp ;
3506
3515
} ;
@@ -3530,6 +3539,7 @@ Pattern.createPattern = function(imageData, repetition) {
3530
3539
pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
3531
3540
pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
3532
3541
}
3542
+ return pixel ;
3533
3543
} ) ;
3534
3544
case 'repeat-x' :
3535
3545
return new Pattern ( function ( x , y , pixel , i ) {
@@ -3545,6 +3555,7 @@ Pattern.createPattern = function(imageData, repetition) {
3545
3555
pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
3546
3556
pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
3547
3557
}
3558
+ return pixel ;
3548
3559
} ) ;
3549
3560
case 'repeat-y' :
3550
3561
return new Pattern ( function ( x , y , pixel , i ) {
@@ -3560,6 +3571,7 @@ Pattern.createPattern = function(imageData, repetition) {
3560
3571
pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
3561
3572
pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
3562
3573
}
3574
+ return pixel ;
3563
3575
} ) ;
3564
3576
case 'repeat' :
3565
3577
default :
@@ -3575,6 +3587,7 @@ Pattern.createPattern = function(imageData, repetition) {
3575
3587
pixel [ i + 1 ] = imageData . data [ j + 1 ] ;
3576
3588
pixel [ i + 2 ] = imageData . data [ j + 2 ] ;
3577
3589
pixel [ i + 3 ] = imageData . data [ j + 3 ] ;
3590
+ return pixel ;
3578
3591
} ) ;
3579
3592
}
3580
3593
}
@@ -3633,34 +3646,36 @@ function Transform()
3633
3646
return self ;
3634
3647
} ;
3635
3648
self . scale = function ( sx , sy , ox , oy ) {
3636
- matrix = Matrix2D . scale ( sx , sy , ox , oy ) . mul ( matrix ) ;
3637
- imatrix = imatrix . mul ( Matrix2D . scale ( 1 / sx , 1 / sy , ox , oy ) ) ;
3649
+ matrix = matrix . mul ( Matrix2D . scale ( sx , sy , ox , oy ) ) ;
3650
+ imatrix = Matrix2D . scale ( 1 / sx , 1 / sy , ox , oy ) . mul ( imatrix ) ;
3638
3651
return self ;
3639
3652
} ;
3640
3653
self . rotate = function ( theta , ox , oy ) {
3641
- matrix = Matrix2D . rotate ( theta , ox , oy ) . mul ( matrix ) ;
3642
- imatrix = imatrix . mul ( Matrix2D . rotate ( - theta , ox , oy ) ) ;
3654
+ matrix = matrix . mul ( Matrix2D . rotate ( theta , ox , oy ) ) ;
3655
+ imatrix = Matrix2D . rotate ( - theta , ox , oy ) . mul ( imatrix ) ;
3643
3656
return self ;
3644
3657
} ;
3645
3658
self . translate = function ( tx , ty ) {
3646
- matrix = Matrix2D . translate ( tx , ty ) . mul ( matrix ) ;
3647
- imatrix = imatrix . mul ( Matrix2D . translate ( - tx , - ty ) ) ;
3659
+ matrix = matrix . mul ( Matrix2D . translate ( tx , ty ) ) ;
3660
+ imatrix = Matrix2D . translate ( - tx , - ty ) . mul ( imatrix ) ;
3648
3661
return self ;
3649
3662
} ;
3650
3663
self . skewX = function ( s ) {
3651
- matrix = Matrix2D . skewX ( s ) . mul ( matrix ) ;
3652
- imatrix = imatrix . mul ( Matrix2D . skewX ( s ) . inv ( ) ) ;
3664
+ var m = Matrix2D . skewX ( s ) ;
3665
+ matrix = matrix . mul ( m ) ;
3666
+ imatrix = m . inv ( ) . mul ( imatrix ) ;
3653
3667
return self ;
3654
3668
} ;
3655
3669
self . skewY = function ( s ) {
3656
- matrix = Matrix2D . skewY ( s ) . mul ( matrix ) ;
3657
- imatrix = imatrix . mul ( Matrix2D . skewY ( s ) . inv ( ) ) ;
3670
+ var m = Matrix2D . skewY ( s ) ;
3671
+ matrix = matrix . mul ( m ) ;
3672
+ imatrix = m . inv ( ) . mul ( imatrix ) ;
3658
3673
return self ;
3659
3674
} ;
3660
3675
self . transform = function ( a , b , c , d , e , f ) {
3661
3676
var m = new Matrix2D ( a , c , e , b , d , f ) ;
3662
- matrix = m . mul ( matrix ) ;
3663
- imatrix = imatrix . mul ( m . inv ( ) ) ;
3677
+ matrix = matrix . mul ( m ) ;
3678
+ imatrix = m . inv ( ) . mul ( imatrix ) ;
3664
3679
return self ;
3665
3680
} ;
3666
3681
@@ -3694,7 +3709,7 @@ function quadratic_roots(a, b, c)
3694
3709
{
3695
3710
if ( is_strictly_equal ( a , 0 ) ) return linear_roots ( b , c ) ;
3696
3711
var D = b * b - 4 * a * c , DS = 0 ;
3697
- if ( is_almost_equal ( D , 0 ) ) return [ - b / ( 2 * a ) ] ;
3712
+ if ( is_almost_equal ( D , 0 , 1e-6 ) ) return [ - b / ( 2 * a ) ] ;
3698
3713
if ( 0 > D ) return false ;
3699
3714
DS = stdMath . sqrt ( D ) ;
3700
3715
return [ ( - b - DS ) / ( 2 * a ) , ( - b + DS ) / ( 2 * a ) ] ;
@@ -6395,25 +6410,73 @@ async function imagepng(type, img, width, height, metaData)
6395
6410
return '' ;
6396
6411
}
6397
6412
6413
+ function detect_image_type ( buffer )
6414
+ {
6415
+ // https://en.wikipedia.org/wiki/List_of_file_signatures
6416
+ var data = new Uint8Array ( buffer [ buffer . subarray ? 'subarray' : 'slice' ] ( 0 , 8 ) ) ,
6417
+ byteAt = function ( offset ) { return offset < data . length ? data [ offset ] : 0 ; } ;
6418
+ if ( 0x89 === byteAt ( 0 )
6419
+ && 0x50 === byteAt ( 1 )
6420
+ && 0x4e === byteAt ( 2 )
6421
+ && 0x47 === byteAt ( 3 )
6422
+ && 0x0d === byteAt ( 4 )
6423
+ && 0x0a === byteAt ( 5 )
6424
+ && 0x1a === byteAt ( 6 )
6425
+ && 0x0a === byteAt ( 7 )
6426
+ ) return 'PNG' ;
6427
+ else if ( 0x47 === byteAt ( 0 )
6428
+ && 0x49 === byteAt ( 1 )
6429
+ && 0x46 === byteAt ( 2 )
6430
+ && 0x38 === byteAt ( 3 )
6431
+ && ( 0x37 === byteAt ( 4 ) || 0x39 === byteAt ( 4 ) )
6432
+ && 0x61 === byteAt ( 5 )
6433
+ ) return 'GIF' ;
6434
+ else if ( 0xff === byteAt ( 0 )
6435
+ && 0xd8 === byteAt ( 1 )
6436
+ /*&& 0xff === byteAt(2)
6437
+ && 0xdb === byteAt(3)*/
6438
+ ) return 'JPG' ;
6439
+ return 'NOT_SUPPORTED' ;
6440
+ }
6441
+ function base64_decode ( b64str )
6442
+ {
6443
+ if ( 'undefined' !== typeof Buffer )
6444
+ {
6445
+ return Buffer . from ( b64str , 'base64' ) ;
6446
+ }
6447
+ else if ( 'function' === typeof atob )
6448
+ {
6449
+ var binaryString = atob ( b64str ) ,
6450
+ i , n = binaryString . length ,
6451
+ bytes = new Uint8Array ( n ) ;
6452
+ for ( i = 0 ; i < n ; ++ i ) bytes [ i ] = binaryString . charCodeAt ( i ) ;
6453
+ return bytes . buffer ;
6454
+ }
6455
+ }
6456
+
6398
6457
function Image ( )
6399
6458
{
6400
- var self = this , src = '' , width = 0 , height = 0 , imageData = null , load ;
6459
+ var self = this , src = '' , width = 0 , height = 0 , imageData = null , error , load ;
6401
6460
6461
+ error = function ( e ) {
6462
+ if ( ! e instanceof Error ) e = new Error ( String ( e ) ) ;
6463
+ if ( self . onerror ) self . onerror ( e ) ;
6464
+ else throw e ;
6465
+ } ;
6402
6466
load = function load ( buffer ) {
6467
+ if ( ! buffer ) return ;
6403
6468
var imgReader = Image . Reader [ Image . detectImageType ( buffer ) ] ;
6404
- if ( ! imgReader ) err ( 'Image file type is not supported!' ) ;
6469
+ if ( ! imgReader ) return error ( 'Image file type is not supported!' ) ;
6405
6470
imgReader ( buffer )
6406
6471
. then ( function ( imgData ) {
6407
6472
imageData = imgData ;
6408
6473
width = imgData . width ;
6409
6474
height = imgData . height ;
6410
6475
if ( self . onload ) self . onload ( ) ;
6411
6476
} )
6412
- . catch ( function ( error ) {
6413
- if ( self . onerror ) self . onerror ( error ) ;
6414
- else throw error ;
6415
- } ) ;
6477
+ . catch ( error ) ;
6416
6478
} ;
6479
+
6417
6480
def ( self , 'width' , {
6418
6481
get : function ( ) {
6419
6482
return width ;
@@ -6450,41 +6513,38 @@ function Image()
6450
6513
if ( ( ( 'undefined' !== typeof ArrayBuffer ) && ( file instanceof ArrayBuffer ) )
6451
6514
|| ( ( 'undefined' !== typeof Buffer ) && ( file instanceof Buffer ) ) )
6452
6515
{
6516
+ // buffer passed
6453
6517
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
6454
6518
// https://nodejs.org/api/buffer.html#class-buffer
6455
6519
load ( src = file ) ;
6456
6520
}
6457
6521
else if ( ( ( 'undefined' !== typeof Blob ) && ( file instanceof Blob ) )
6458
6522
|| ( ( 'undefined' !== typeof Buffer ) && ( Buffer . Blob ) && ( file instanceof Buffer . Blob ) ) )
6459
6523
{
6524
+ // blob passed
6460
6525
// https://developer.mozilla.org/en-US/docs/Web/API/Blob
6461
6526
// https://nodejs.org/api/buffer.html#class-blob
6462
- ( src = file ) . arrayBuffer ( )
6463
- . then ( function ( buffer ) {
6464
- load ( buffer ) ;
6465
- } )
6466
- . catch ( function ( error ) {
6467
- if ( self . onerror ) self . onerror ( error ) ;
6468
- else throw error ;
6469
- } )
6527
+ ( src = file ) . arrayBuffer ( ) . then ( load ) . catch ( error ) ;
6470
6528
}
6471
- else if ( isNode && ( ( 'string' === typeof file ) || ( file instanceof String ) ) )
6529
+ else if ( ( 'string' === typeof file ) || ( file instanceof String ) )
6472
6530
{
6473
- require ( 'fs' ) . readFile ( src = file , function ( error , buffer ) {
6474
- if ( error )
6475
- {
6476
- if ( self . onerror ) self . onerror ( error ) ;
6477
- else throw error ;
6478
- }
6479
- else
6480
- {
6481
- load ( buffer ) ;
6482
- }
6483
- } ) ;
6531
+ if ( / ^ d a t a : i m a g e \/ [ a - z ] + ; b a s e 6 4 , / . test ( file ) )
6532
+ {
6533
+ // base64 encoded image
6534
+ load ( base64_decode ( ( src = file ) . slice ( file . indexOf ( ';base64,' ) + 8 ) ) ) ;
6535
+ }
6536
+ else if ( isNode )
6537
+ {
6538
+ // file path of image
6539
+ require ( 'fs' ) . readFile ( src = file , function ( err , buffer ) {
6540
+ if ( err ) error ( err ) ;
6541
+ else load ( buffer ) ;
6542
+ } ) ;
6543
+ }
6484
6544
}
6485
6545
/*else
6486
6546
{
6487
- err ('Unsupported src property');
6547
+ error ('Unsupported src property');
6488
6548
}*/
6489
6549
}
6490
6550
} ) ;
@@ -6509,33 +6569,7 @@ Image.Reader = {
6509
6569
'JPG' : read_jpg ,
6510
6570
'PNG' : read_png
6511
6571
} ;
6512
- Image . detectImageType = function ( buffer ) {
6513
- // https://en.wikipedia.org/wiki/List_of_file_signatures
6514
- var data = new Uint8Array ( buffer [ buffer . subarray ? 'subarray' : 'slice' ] ( 0 , 8 ) ) ,
6515
- byteAt = function ( offset ) { return offset < data . length ? data [ offset ] : 0 ; } ;
6516
- if ( 0x89 === byteAt ( 0 )
6517
- && 0x50 === byteAt ( 1 )
6518
- && 0x4e === byteAt ( 2 )
6519
- && 0x47 === byteAt ( 3 )
6520
- && 0x0d === byteAt ( 4 )
6521
- && 0x0a === byteAt ( 5 )
6522
- && 0x1a === byteAt ( 6 )
6523
- && 0x0a === byteAt ( 7 )
6524
- ) return 'PNG' ;
6525
- else if ( 0x47 === byteAt ( 0 )
6526
- && 0x49 === byteAt ( 1 )
6527
- && 0x46 === byteAt ( 2 )
6528
- && 0x38 === byteAt ( 3 )
6529
- && ( 0x37 === byteAt ( 4 ) || 0x39 === byteAt ( 4 ) )
6530
- && 0x61 === byteAt ( 5 )
6531
- ) return 'GIF' ;
6532
- else if ( 0xff === byteAt ( 0 )
6533
- && 0xd8 === byteAt ( 1 )
6534
- /*&& 0xff === byteAt(2)
6535
- && 0xdb === byteAt(3)*/
6536
- ) return 'JPG' ;
6537
- return 'NOT_SUPPORTED' ;
6538
- } ;
6572
+ Image . detectImageType = detect_image_type ;
6539
6573
6540
6574
function CanvasLite ( width , height )
6541
6575
{
0 commit comments