Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

245
Views
Javascript Canvas Relative Mouse Coordinates on Rotated Rectangle?

I am trying to treat a rectangle in canvas as a piece of paper, and get the same relative coordinates returned when I hover over the same point regardless of scale, rotation, or translation of the page.

Currently I get accurate results when in portrait or inverted portrait rotations and regardless of scale/translation. However, when I switch to landscape or inverted landscape my results are off.

I've attempted to switch to rotating mouse coordinates with some trigonometric functions I found, but math is not my strong suit and it didn't work.

If someone could point me in the right direction, I would be grateful. I suspect I need to swap axis or height/width when rotating landscape but that hasn't been fruitful either.

R key rotates the "page" through 4, 90 degree changes. Coordinates of your mouse relative to the page, clamped to the page's width/height are displayed in console.

https://jsfiddle.net/2hg6u3wd/2/ (Note, JSFiddle offsets coordinates slightly for an unknown reason)

const orientation = Object.freeze({
  portrait: 0,
  landscape: -90,
  invertedPortrait: 180,
  invertedLandscape: 90
});

function CameraRotate(rotation) {
  // Rotates using the center of target as origin. 
  ctx.translate(target.width / 2, target.height / 2);
  ctx.rotate(-(currentRot * Math.PI / 180)); // Negate currentRot because ctx.rotate() is additive.
  ctx.rotate(rotation * Math.PI / 180);
  ctx.translate(-(target.width / 2), -(target.height / 2));
  currentRot = rotation;
}

function CameraCalcRelTargetCoords(viewX, viewY) {
  return {
    x: clamp((viewX - ctx.getTransform().e) / ctx.getTransform().a, 0, page.width),
    y: clamp((viewY - ctx.getTransform().f) / ctx.getTransform().d, 0, page.height)
  };
}

function clamp(number, min, max) {
  return Math.max(min, Math.min(number, max));
}

canvas.addEventListener(`mousemove`, function(e) {
    console.log(CameraCalcRelTargetCoords(e.x, e.y));
});
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

When rotating (-)180 degrees, the scale is stored as skew since the axis are flipped. Thus you must divide by m12 and m21. This flipping also means x and y mouse coordinates need to be swapped as well.

Here is my solution:

function CameraCalcRelTargetCoords(viewX, viewY) {
    // Mouse coordinates are translated to a position within the target's rectangle.
    let relX, relY

    if (currentRot == orientation.landscape || currentRot == orientation.invertedLandscape) {
        // Landscape rotation uses skewing for scale as X/Y axis are flipped.
        relX = clamp((viewY - ctx.getTransform().f) / ctx.getTransform().b, 0, target.width);
        relY = clamp((viewX - ctx.getTransform().e) / ctx.getTransform().c, 0, target.height);
    } else {
        relX = clamp((viewX - ctx.getTransform().e) / ctx.getTransform().a, 0, target.width),
        relY = clamp((viewY - ctx.getTransform().f) / ctx.getTransform().d, 0, target.height)
    }

    return {x: relX, y: relY};
}
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!