Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please make current x and y available after translate and rotate. #1873

Closed
ChristerNilsson opened this issue Apr 2, 2017 · 3 comments
Closed

Comments

@ChristerNilsson
Copy link

Translate, rotate and scale are really helpful in drawing.
But, in mousePressed, the current coordinate is not available.
That is, the current translated and rotated, coordinate.
At least, I have not found it.

Error message: Uncaught ReferenceError: x is not defined

Example:
Four circles in the corners of a 20 degrees tilted square.
skarmklipp

setup = -> createCanvas 200,200

f = (g) ->
	translate 100,100
	rotate radians 20
	translate -50,-50
	for i in [0,1,2,3]		
		translate 100,0
		rotate radians 90
		g i

draw = ->
	background 0	
	f (i) -> circle 0,0,20 
	
mousePressed = ->	
	f (i) -> if dist(mouseX,mouseY,x,y) < 20 then console.log i

Above Coffeescript transpiled to Javascript, so everybody can understand:

var draw, f, mousePressed, setup;

setup = function() {
  return createCanvas(200, 200);
};

f = function(g) {
  var i, j, len, ref, results;
  translate(100, 100);
  rotate(radians(20));
  translate(-50, -50);
  ref = [0, 1, 2, 3];
  results = [];
  for (j = 0, len = ref.length; j < len; j++) {
    i = ref[j];
    translate(100, 0);
    rotate(radians(90));
    results.push(g(i));
  }
  return results;
};

draw = function() {
  background(0);
  return f(function(i) {
    return circle(0, 0, 20);
  });
};

mousePressed = function() {
  return f(function(i) {
    if (dist(mouseX, mouseY, x, y) < 20) {
      return console.log(i);
    }
  });
};
@lmccart
Copy link
Member

lmccart commented Apr 2, 2017

We currently have no access to the current transform matrix being applied to the canvas. It is an experimental feature that may get added to the HTML5Canvas spec, but it's not implemented across browsers yet: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/currentTransform

To maintain a copy of the matrix ourselves within p5.js and update as transforms are applied would be possible, but it would significantly slow performance.

For now, you might try using a library like this one: https://github.com/leeoniya/transformation-matrix-js/blob/master/readme.md. It wraps the canvas transform method and keeps track of the matrix, and allows you to apply it to (x,y) coords which I think is what you're trying to do.

@ChristerNilsson
Copy link
Author

I see.
I made my own transformation handler as well.
https://github.com/ChristerNilsson/Transformer/blob/master/transformer.coffee

@ChristerNilsson
Copy link
Author

ChristerNilsson commented Sep 12, 2022

I found a nice solution:

getLocalCoords = (mx,my) -> # takes 3 microsecs
	matrix = drawingContext.getTransform()
	pd = pixelDensity()
	matrix.inverse().transformPoint(new DOMPoint(mx * pd,my * pd))
{x,y} = getLocalCoords mouseX, mouseY

https://www.reddit.com/r/p5js/comments/jo7ucf/clicking_on_a_translated_scaled_and_rotated_shape/
Implemented in Chrome in 2018.
https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getTransform

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants