@@ -347,8 +347,8 @@ p5.prototype._accsOutput = function(f, args) {
347
347
//get lenght
348
348
include . length = Math . round ( this . dist ( args [ 0 ] , args [ 1 ] , args [ 2 ] , args [ 3 ] ) ) ;
349
349
//get position of end points
350
- let p1 = _getPos ( [ args [ 0 ] , [ 1 ] ] , this . width , this . height ) ;
351
- let p2 = _getPos ( [ args [ 2 ] , [ 3 ] ] , this . width , this . height ) ;
350
+ let p1 = this . _getPos ( args [ 0 ] , [ 1 ] ) ;
351
+ let p2 = this . _getPos ( args [ 2 ] , [ 3 ] ) ;
352
352
include . loc = _canvasLocator ( middle , this . width , this . height ) ;
353
353
if ( p1 === p2 ) {
354
354
include . pos = `at ${ p1 } ` ;
@@ -363,11 +363,11 @@ p5.prototype._accsOutput = function(f, args) {
363
363
//make color fill
364
364
include . color = this . ingredients . colors . fill ;
365
365
//get area of shape
366
- include . area = _getArea ( f , args , this . width , this . height ) ;
366
+ include . area = this . _getArea ( f , args ) ;
367
367
}
368
368
//get middle of shapes
369
369
//calculate position using middle of shape
370
- include . pos = _getPos ( middle , this . width , this . height ) ;
370
+ include . pos = this . _getPos ( ... middle ) ;
371
371
//calculate location using middle of shape
372
372
include . loc = _canvasLocator ( middle , this . width , this . height ) ;
373
373
}
@@ -422,33 +422,40 @@ function _getMiddle(f, args) {
422
422
}
423
423
424
424
//gets position of shape in the canvas
425
- function _getPos ( args , canvasWidth , canvasHeight ) {
426
- if ( args [ 0 ] < 0.4 * canvasWidth ) {
427
- if ( args [ 1 ] < 0.4 * canvasHeight ) {
425
+ p5 . prototype . _getPos = function ( x , y ) {
426
+ const untransformedPosition = new DOMPointReadOnly ( x , y ) ;
427
+ const currentTransform = this . _renderer . isP3D ?
428
+ new DOMMatrix ( this . _renderer . uMVMatrix . mat4 ) :
429
+ this . drawingContext . getTransform ( ) ;
430
+ const { x : transformedX , y : transformedY } = untransformedPosition
431
+ . matrixTransform ( currentTransform ) ;
432
+ const { width : canvasWidth , height : canvasHeight } = this ;
433
+ if ( transformedX < 0.4 * canvasWidth ) {
434
+ if ( transformedY < 0.4 * canvasHeight ) {
428
435
return 'top left' ;
429
- } else if ( args [ 1 ] > 0.6 * canvasHeight ) {
436
+ } else if ( transformedY > 0.6 * canvasHeight ) {
430
437
return 'bottom left' ;
431
438
} else {
432
439
return 'mid left' ;
433
440
}
434
- } else if ( args [ 0 ] > 0.6 * canvasWidth ) {
435
- if ( args [ 1 ] < 0.4 * canvasHeight ) {
441
+ } else if ( transformedX > 0.6 * canvasWidth ) {
442
+ if ( transformedY < 0.4 * canvasHeight ) {
436
443
return 'top right' ;
437
- } else if ( args [ 1 ] > 0.6 * canvasHeight ) {
444
+ } else if ( transformedY > 0.6 * canvasHeight ) {
438
445
return 'bottom right' ;
439
446
} else {
440
447
return 'mid right' ;
441
448
}
442
449
} else {
443
- if ( args [ 1 ] < 0.4 * canvasHeight ) {
450
+ if ( transformedY < 0.4 * canvasHeight ) {
444
451
return 'top middle' ;
445
- } else if ( args [ 1 ] > 0.6 * canvasHeight ) {
452
+ } else if ( transformedY > 0.6 * canvasHeight ) {
446
453
return 'bottom middle' ;
447
454
} else {
448
455
return 'middle' ;
449
456
}
450
457
}
451
- }
458
+ } ;
452
459
453
460
//locates shape in a 10*10 grid
454
461
function _canvasLocator ( args , canvasWidth , canvasHeight ) {
@@ -469,7 +476,7 @@ function _canvasLocator(args, canvasWidth, canvasHeight) {
469
476
}
470
477
471
478
//calculates area of shape
472
- function _getArea ( objectType , shapeArgs , canvasWidth , canvasHeight ) {
479
+ p5 . prototype . _getArea = function ( objectType , shapeArgs ) {
473
480
let objectArea = 0 ;
474
481
if ( objectType === 'arc' ) {
475
482
// area of full ellipse = PI * horizontal radius * vertical radius.
@@ -526,8 +533,38 @@ function _getArea(objectType, shapeArgs, canvasWidth, canvasHeight) {
526
533
) / 2 ;
527
534
// (Ax( By − Cy) + Bx(Cy − Ay) + Cx(Ay − By ))/2
528
535
}
529
-
530
- return Math . round ( objectArea * 100 / ( canvasWidth * canvasHeight ) ) ;
531
- }
536
+ // Store the positions of the canvas corners
537
+ const canvasWidth = this . width * this . _pixelDensity ;
538
+ const canvasHeight = this . height * this . _pixelDensity ;
539
+ const canvasCorners = [
540
+ new DOMPoint ( 0 , 0 ) ,
541
+ new DOMPoint ( canvasWidth , 0 ) ,
542
+ new DOMPoint ( canvasWidth , canvasHeight ) ,
543
+ new DOMPoint ( 0 , canvasHeight )
544
+ ] ;
545
+ // Apply the inverse of the current transformations to the canvas corners
546
+ const currentTransform = this . _renderer . isP3D ?
547
+ new DOMMatrix ( this . _renderer . uMVMatrix . mat4 ) :
548
+ this . drawingContext . getTransform ( ) ;
549
+ const invertedTransform = currentTransform . inverse ( ) ;
550
+ const tc = canvasCorners . map (
551
+ corner => corner . matrixTransform ( invertedTransform )
552
+ ) ;
553
+ /* Use same shoelace formula used for quad area (above) to calculate
554
+ the area of the canvas with inverted transformation applied */
555
+ const transformedCanvasArea = Math . abs (
556
+ ( tc [ 3 ] . x + tc [ 0 ] . x ) * ( tc [ 3 ] . y - tc [ 0 ] . y ) +
557
+ ( tc [ 0 ] . x + tc [ 1 ] . x ) * ( tc [ 0 ] . y - tc [ 1 ] . y ) +
558
+ ( tc [ 1 ] . x + tc [ 2 ] . x ) * ( tc [ 1 ] . y - tc [ 2 ] . y ) +
559
+ ( tc [ 2 ] . x + tc [ 3 ] . x ) * ( tc [ 2 ] . y - tc [ 3 ] . y )
560
+ ) / 2 ;
561
+ /* Compare area of shape (minus transformations) to area of canvas
562
+ with inverted transformation applied.
563
+ Return percentage */
564
+ const untransformedArea = Math . round (
565
+ objectArea * 100 / ( transformedCanvasArea )
566
+ ) ;
567
+ return untransformedArea ;
568
+ } ;
532
569
533
570
export default p5 ;
0 commit comments