MightyMouse
MightyMouse

Reputation: 185

DOMPoint transformation (rotation) not returning the expected result in JavaScript

Can someone confirm the transformation of this DOMPoint is working correctly?

let point = new DOMPoint(1, 1);
let matrix = new DOMMatrix('rotate(-45deg)');
let transformedPoint = point.matrixTransform(matrix);

console.log(point, transformedPoint);

The result we get in the console is:

DOMPoint { x: 1, y: 1, z: 0, w: 1 }
 
DOMPoint { x: 1.4142135381698608, y: 0, z: 0, w: 1 }

I would have expected the transformedPoint to have x: 1 and y: 0 since point at (1, 1) would have an angle of 45 degrees. I assume the transformation is based off the origin point at (0, 0)?

enter image description here

Can we enlightening me on how the transformation actually worked?

Upvotes: 1

Views: 636

Answers (1)

Kaiido
Kaiido

Reputation: 136638

You have your graphic inversed, the origin is at top-left, so 1, 1 is actually at the bottom right.

Then, the distance between your point 1,1 and the origin 0,0 is hypot( 1 - 0, 1 - 0 ) which is indeed approximately 1.414213....
So it's indeed correct to have this { x: 1.4142135381698608, y: 0, z: 0, w: 1 } result.

Maybe a visualization will make it clearer:

Yellow is the origin 0,0. Green is the initial point 1,1. Red gets rotated by one degree every frame.

const point = new DOMPoint(1, 1);
const matrix = new DOMMatrix("rotate(-1deg)");
let transformedPoint = point.matrixTransform(matrix);
let angle = 1;

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

const axes = new Path2D( "M150 0L150 150M0 75L300 75" );
ctx.font = "14px sans-serif";
draw();

function draw() {
  transformedPoint = transformedPoint.matrixTransform(matrix);
  angle = (angle + 1) % 360;

  // clear
  ctx.setTransform( 1, 0, 0, 1, 0, 0 );
  ctx.clearRect( 0, 0, canvas.width, canvas.height );

  ctx.fillText( `angle: -${ angle }`, 10, 10 );

  ctx.stroke( axes );

  // move to the center of canvas and scale by 20
  ctx.setTransform( 20, 0, 0, 20, canvas.width / 2, canvas.height / 2 );
  // origin
  ctx.fillStyle = "yellow";
  ctx.fillRect( 0 - 0.5, 0 - 0.5, 1, 1 );
  // reference point
  ctx.fillStyle = "green";
  ctx.fillRect( point.x - 0.5, point.y - 0.5, 1, 1 );
  // transformed
  ctx.fillStyle = "red";
  ctx.fillRect( transformedPoint.x - 0.5, transformedPoint.y - 0.5, 1, 1 );
  
  requestAnimationFrame( draw );
}
<canvas id="canvas"></canvas>

Upvotes: 1

Related Questions