pskink / matrix_gesture_detector

A gesture detector mapping translation/rotation/scale gestures to a Matrix4 object.
Other
134 stars 101 forks source link

Rotation snapping #21

Open segidev opened 4 years ago

segidev commented 4 years ago

Would it be possible to add rotation snapping?

Something like this:

https://konvajs.org/docs/select_and_transform/Rotation_Snaps.html

That would be a great addition.

UnHired-Coder commented 4 years ago

It's already possible. You might have missed it, have a look at the class. :)

singhayush1403 commented 4 years ago

@1-2-ka-4-4-2-ka-1 Could you explain more? I tried using the rotate matrix and even the decomposed values, but could not get it to work.

UnHired-Coder commented 4 years ago

Use the matrix returned by callback of Matrix Gesture Detector update the transform of desired container accordingly , and set the should rotate property to false if don't wanna rotate on certain axis. Eg. shouldRotateX :false,

UnHired-Coder commented 4 years ago

You can manipulate this to actually get this https://konvajs.org/docs/select_and_transform/Rotation_Snaps.html

I have got the same in one of my project https://github.com/1-2-ka-4-4-2-ka-1/WritoGram

singhayush1403 commented 4 years ago

You can manipulate this to actually get this https://konvajs.org/docs/select_and_transform/Rotation_Snaps.html

I have got the same in one of my project https://github.com/1-2-ka-4-4-2-ka-1/WritoGram

I thought it was a public repo. Nevertheless, thank you. Will try using it

segidev commented 4 years ago

@1-2-ka-4-4-2-ka-1 Thank you for the hint.

The thing with your suggestion is. How do you handle for example that when you get close to a 90 degree rotation, to snap at 88 degrees keep it still till 92 degress and then let the user rotate further?

Somehow you need track of the further rotation (that is not applied). I used to calculate a rotation value all the time to be able to identify the actual rotation but it lead to inconsistent behavior.

Best regards

singhayush1403 commented 4 years ago

@1-2-ka-4-4-2-ka-1 Thank you for the hint.

The thing with your suggestion is. How do you handle for example that when you get close to a 90 degree rotation, to snap at 88 degrees keep it still till 92 degress and then let the user rotate further?

Somehow you need track of the further rotation (that is not applied). I used to calculate a rotation value all the time to be able to identify the actual rotation but it lead to inconsistent behavior.

Best regards I'm facing the same problem. @1-2-ka-4-4-2-ka-1 would you mind pasting a small code snippet of possible? It would really help.

UnHired-Coder commented 4 years ago

See you want user to be able to rotate at exactly 90°. You can achieve it in this way, do a little math or Google what's the matrix when it's vertical (90°), create a slight pause when the matrix is ever equal to this value during it's motion.......if the user has moved further the matrix will update else will remain as it is. Here slight pause means stop listening to the matrix values. This may not be the best workaround but is you see above snapping demo in slomo you would see it will work.

UnHired-Coder commented 4 years ago

I you want to achieve in your way by imposing limits then you can stop listening in between the limits. For calculating just print the desired position matrix in logs.

singhayush1403 commented 4 years ago

@segidev I figured out how to do it for 0 degrees. Replace the rotate function with this code:

Matrix4 _rotate(double angle, Offset focalPoint) { double toBeRotated = 0; var array = matrix.applyToVector3Array([0, 0, 0, 1, 0, 0]); Offset delta = Offset(array[3] - array[0], array[4] - array[1]); double rotation = delta.direction; deltaAngle = deltaAngle + angle; if ((rotation + deltaAngle).abs() > 0.2) { toBeRotated = deltaAngle; deltaAngle = 0; } else if (rotation != 0 && (rotation + deltaAngle).abs() <= 0.2) { toBeRotated = -rotation; deltaAngle = deltaAngle + rotation; } else { toBeRotated = 0; } var c = cos(toBeRotated); var s = sin(toBeRotated); var dx = (1 - c) * focalPoint.dx + s * focalPoint.dy; var dy = (1 - c) * focalPoint.dy - s * focalPoint.dx; // ..[0] = c # x scale // ..[1] = s # y skew // ..[4] = -s # x skew // ..[5] = c # y scale // ..[10] = 1 # diagonal "one" // ..[12] = dx # x translation // ..[13] = dy # y translation // ..[15] = 1 # diagonal "one" return Matrix4(c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, dx, dy, 0, 1); }