Skip to content

Commit 2dcdcc1

Browse files
committed
Factor transformations into position and area
for shapes' accessible outputs
1 parent 3a30fec commit 2dcdcc1

File tree

1 file changed

+51
-18
lines changed

1 file changed

+51
-18
lines changed

src/accessibility/outputs.js

+51-18
Original file line numberDiff line numberDiff line change
@@ -347,8 +347,8 @@ p5.prototype._accsOutput = function(f, args) {
347347
//get lenght
348348
include.length = Math.round(this.dist(args[0], args[1], args[2], args[3]));
349349
//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]);
352352
include.loc = _canvasLocator(middle, this.width, this.height);
353353
if (p1 === p2) {
354354
include.pos = `at ${p1}`;
@@ -363,11 +363,11 @@ p5.prototype._accsOutput = function(f, args) {
363363
//make color fill
364364
include.color = this.ingredients.colors.fill;
365365
//get area of shape
366-
include.area = _getArea(f, args, this.width, this.height);
366+
include.area = this._getArea(f, args);
367367
}
368368
//get middle of shapes
369369
//calculate position using middle of shape
370-
include.pos = _getPos(middle, this.width, this.height);
370+
include.pos = this._getPos(...middle);
371371
//calculate location using middle of shape
372372
include.loc = _canvasLocator(middle, this.width, this.height);
373373
}
@@ -422,33 +422,38 @@ function _getMiddle(f, args) {
422422
}
423423

424424
//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.drawingContext.getTransform();
428+
const { x: transformedX, y: transformedY } = untransformedPosition
429+
.matrixTransform(currentTransform);
430+
const { width: canvasWidth, height: canvasHeight } = this;
431+
if (transformedX < 0.4 * canvasWidth) {
432+
if (transformedY < 0.4 * canvasHeight) {
428433
return 'top left';
429-
} else if (args[1] > 0.6 * canvasHeight) {
434+
} else if (transformedY > 0.6 * canvasHeight) {
430435
return 'bottom left';
431436
} else {
432437
return 'mid left';
433438
}
434-
} else if (args[0] > 0.6 * canvasWidth) {
435-
if (args[1] < 0.4 * canvasHeight) {
439+
} else if (transformedX > 0.6 * canvasWidth) {
440+
if (transformedY < 0.4 * canvasHeight) {
436441
return 'top right';
437-
} else if (args[1] > 0.6 * canvasHeight) {
442+
} else if (transformedY > 0.6 * canvasHeight) {
438443
return 'bottom right';
439444
} else {
440445
return 'mid right';
441446
}
442447
} else {
443-
if (args[1] < 0.4 * canvasHeight) {
448+
if (transformedY < 0.4 * canvasHeight) {
444449
return 'top middle';
445-
} else if (args[1] > 0.6 * canvasHeight) {
450+
} else if (transformedY > 0.6 * canvasHeight) {
446451
return 'bottom middle';
447452
} else {
448453
return 'middle';
449454
}
450455
}
451-
}
456+
};
452457

453458
//locates shape in a 10*10 grid
454459
function _canvasLocator(args, canvasWidth, canvasHeight) {
@@ -469,7 +474,7 @@ function _canvasLocator(args, canvasWidth, canvasHeight) {
469474
}
470475

471476
//calculates area of shape
472-
function _getArea(objectType, shapeArgs, canvasWidth, canvasHeight) {
477+
p5.prototype._getArea = function (objectType, shapeArgs) {
473478
let objectArea = 0;
474479
if (objectType === 'arc') {
475480
// area of full ellipse = PI * horizontal radius * vertical radius.
@@ -526,8 +531,36 @@ function _getArea(objectType, shapeArgs, canvasWidth, canvasHeight) {
526531
) / 2;
527532
// (Ax( By − Cy) + Bx(Cy − Ay) + Cx(Ay − By ))/2
528533
}
529-
530-
return Math.round(objectArea * 100 / (canvasWidth * canvasHeight));
531-
}
534+
// Store the positions of the canvas corners
535+
const canvasWidth = this.width * this._pixelDensity;
536+
const canvasHeight = this.height * this._pixelDensity;
537+
const canvasCorners = [
538+
new DOMPoint(0, 0),
539+
new DOMPoint(canvasWidth, 0),
540+
new DOMPoint(canvasWidth, canvasHeight),
541+
new DOMPoint(0, canvasHeight)
542+
];
543+
// Apply the inverse of the current transformations to the canvas corners
544+
const currentTransform = this.drawingContext.getTransform();
545+
const invertedTransform = currentTransform.inverse();
546+
const tc = canvasCorners.map(
547+
corner => corner.matrixTransform(invertedTransform)
548+
);
549+
/* Use same shoelace formula used for quad area (above) to calculate
550+
the area of the canvas with inverted transformation applied */
551+
const transformedCanvasArea = Math.abs(
552+
(tc[3].x + tc[0].x) * (tc[3].y - tc[0].y) +
553+
(tc[0].x + tc[1].x) * (tc[0].y - tc[1].y) +
554+
(tc[1].x + tc[2].x) * (tc[1].y - tc[2].y)+
555+
(tc[2].x + tc[3].x) * (tc[2].y - tc[3].y)
556+
) / 2;
557+
/* Compare area of shape (minus transformations) to area of canvas
558+
with inverted transformation applied.
559+
Return percentage */
560+
const untransformedArea = Math.round(
561+
objectArea * 100 / (transformedCanvasArea)
562+
);
563+
return untransformedArea;
564+
};
532565

533566
export default p5;

0 commit comments

Comments
 (0)