jonobr1 / two.js

A renderer agnostic two-dimensional drawing api for the web.
https://two.js.org
MIT License
8.31k stars 455 forks source link

What is the origin of coordinates? #635

Closed rugarve closed 2 years ago

rugarve commented 2 years ago

I am reviewing the transformation matrix of my scene. I see that the matrix is the identity matrix, so I imagine that the origin of coordinates is the lower left corner, is it so? or is it the upper left corner as would be the case of offsetX and offsetY of the event.

I need to change the origin of coordinates of the transformation matrix of two.js and of offsetX and offsetY of the events and that the new (0, 0) is the lower left corner.

Thanks

jonobr1 commented 2 years ago

It's the upper-left corner. You can change it to the lower left corner like so:

const two = new Two().appendTo(document.body);
two.scene.position.y = two.height;
rugarve commented 2 years ago

Hello,

It is correct that by making the change you say it is changed but it has some drawbacks.

If I paint a point you won't see it on the screen because it will paint it outside the screen by taking the evt.offsetX and evt.offsetY coordinates. To see the point you have to modify evt.offsetY.

offsetY: -(this.boundyBoxView.top - evt.offsetY)

In addition, then there is a big problem with the zoom and the pan, when activating one of these tasks you will not see the previously painted, since for example zui.zoomby transforms the scene again and it will put again the origin of coordinates to the top left so you will not see what you have painted before.

How can I modify to have the origin of coordinates in the lower left corner but modifying the coordinates matrix?

In case this is not possible. How can I adapt the zoom and pan so that I don't change the quadrant when I activate it?

Thanks in advance

jonobr1 commented 2 years ago

That's correct, you need to have the screen space match whatever space the ZUI component operates in. Given:

const two = new Two({ fullscreen: true }).appendTo(document.body);
two.scene.position.y = two.height;

Then you'll need to account appropriately:

window.addEventListener('pointermove', function(e) {

  var px = e.clientX;
  var py = e.clientY;

  var x = px - two.scene.position.x;
  var y = py - two.scene.position.y;

  // Feed `x` and `y` into whatever ZUI methods

}, false);
rugarve commented 2 years ago

This was the first thing I thought and provided... but it doesn't work. The reason is that even if you enter x and y corrected as you indicate me in some zui method, for example zoomby or translateSurface when you make your internal changes in the transformation matrix it resets the matrix and puts back the origin of coordinates in the upper left corner.

It's becoming a puzzle this, a challenge... How can I solve this?

I have also tried setting the matrix to manual = true. But I lose the functionality of zui and several other things.... I have problems to modify the transformation matrix at will.... Even making a custom traslateSurface I can't apply it to the scene.

How to modify the matrix and apply the changes through custom methods?

Thanks in advance

jonobr1 commented 2 years ago

Right, what you can do is nest the groups and how ZUI is applied. This is just a snippet, but should give you an idea how to both take ZUI into account and offset the world by the offset:


var two = new Two({ fullscreen: true }).appendTo(body);
var stage = new Two.Group();
two.add(stage);

var zui = new ZUI(stage);
two.scene.position.y = two.height; // Create your offset so the origin is the bottom left corner

window.addEventListener('pointermove', function(e) {

  var px = e.clientX;
  var py = e.clientY;

  var x = px - two.scene.position.x;
  var y = py - two.scene.position.y;

  // Apply ZUI calculations with x, y

}, false);
rugarve commented 2 years ago

It worked!!! Thanks

In my case, I have points in a group of points, lines in a group of lines, circles in a group of selectables and another group of selectables, etc. All this I have put in a stage group to which I have applied zui.

I have applied to two.scene.position.y the height to position it in the lower left corner.

Then I make several transformations: 1- transformation of offsetY to coordinates to paint on screen (-(height - evt.offsetY)) 2- transformation of the result of the previous point to change sign of Y to save the y-coordinate in positive in the database. 3- When I recover from the database I change again the sign of the y-coordinate to draw on screen.

thanks for everything greetings

jonobr1 commented 2 years ago

Glad it worked