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

Embed matrix parsing logic to get original transform values? #269

Open
julianshapiro opened this issue Aug 24, 2014 · 21 comments
Open

Embed matrix parsing logic to get original transform values? #269

julianshapiro opened this issue Aug 24, 2014 · 21 comments

Comments

@julianshapiro
Copy link
Owner

This will add 4KB to Velocity when minified, but will allow Velocity to read an element's initial transform values without forcing the user to resort to workarounds like using Velocity.hook() or forcefeeding (which tells Velocity which transform value to start from).

I'm not sure if I'll ever implement this -- since, as just pointed out, there are workarounds -- but I'm considering it.

Please don't comment here just to "+1" this :) I'm opening this to see if there's any constructive feedback.

@kpeatt
Copy link

kpeatt commented Aug 25, 2014

I'm using some Velocity animations on transforms right now. I was initially stung by forcefeeding not working as expected but, now that I get how it works, I think this system is actually pretty good. My recommendation would be to avoid the parser and simply build out the documentation around using hook or force-feeding more clearly for these scenarios.

@julianshapiro
Copy link
Owner Author

That is also my preferred approach. If you feel like taking a stab at rewriting the relevant parts of the documentation, that would be awesome.

@julianshapiro julianshapiro changed the title Embed matrix parsing logic to get original transform values Embed matrix parsing logic to get original transform values? Aug 28, 2014
@Omniferum
Copy link

It is just as kpeatt, and I, experienced: they are quirks that you need to get 'used' to. Essentially that 4kb* is being off-loaded on to the user to try and figure out when and how to use it. That 4kb also translates as extra documentation for you to maintain and for someone to need to explain every time some noob (such as myself) asks 'what?' because the 'assumed' behavior is not intuitively understandable. But if that is purely just because of size then... shrug.

4kb to make a far simpler workflow for everyone I would say is probably a very worthwhile investment, but it really depends on any performance impact differences (if any). If you are using velocity to begin with then no doubt you are building something that is designed to be a little 'heavier than usual', and in the scheme of things that +4kb would really only matter when it is first requested. Of course I could be wrong and in JS ANY increase in file size is an immediate performance decrease (parsing? some other coding terminology that obviously I don't know?)

*so in the end 37kb minified instead of 33kb, according to my OS. What that ends up gzipped I don't know, but my 150kb worth of JS scripts only ends up as 30kb anyway. From a marketing perspective it might do good to advertise the final gzipped size of your plugin, rather than the minified as the actual production value (i.e. in use and on a site) is smaller than the minified (if someone wants to use your plugin, i'm sure they know about enabling compression).

@julianshapiro
Copy link
Owner Author

I completely agree :)

Also, I hugely appreciate all the input, but I must say your posts are getting too lengthy. GitHub Issues is primarily about short, to-the-point material updates <3

@Omniferum
Copy link

Yeah, sorry about that. I'm an author by trade so I can get a bit on the wordy side when I am trying to weigh in on something if I don't watch myself.

More just trying to give you feedback as way of thanks, and I'd like to see this plugin become more prevalent in the community as it is a worthwhile tool.

But yeah, i'll keep in mind to not submit my first drafts :P

@warpraptor0
Copy link

There are also some gotchas here related to the Matrix/Matrix3d values similar to the differences I mentioned in the other Issue related to using Matrix3D for animation. Could be that the code I borrowed to do this had some bugs in it.. but if you do a Matrix transform (using just plain CSS) and then try to extract values to be used for Velocity force feeding, you don't always get exactly the results you expect. My gut tells me this may have to do with the way the transformations get layered in a Matrix transform.

I've had to resort to fading elements out (and then moving them back to position) because they jump to much when I switch back to Velocity from doing CSS Matrix manipulations.

@okonet
Copy link

okonet commented Oct 1, 2014

I would love to remove additional dependencies for CSS matrix calculations I'm using now along with Velocity. I also think that it would be cool to add some modularity for features like this or color manipulations, so developers could decide what to include into production bundle.

I think that #320 might also be related to this discussion.

@tommiehansen
Copy link

No, instead remove as much as possible. The plugin idea is much better. In Velocity UI you could also remove the built in transitions since one would want to register custom transitions anyway. Not certain if the UI-version need to exist at all; i would rather see each function as separate extensions.

If people want a simple version that does it all you could also serve a velocity_all.js.

@julianshapiro
Copy link
Owner Author

As per #323: If this is implemented, I should also consider allowing for the passing in of a raw transform text string so that the order of transforms can be respected. If this is the case, I'll need to figure out the rule set for overwriting existing transforms in the future -- regardless of whether the string or standard object notation syntax is employed.

@dbuezas
Copy link

dbuezas commented Nov 25, 2014

Watch out on this one, the general case is hairy.

If you have combinations of rotations, translations, scales and/or skewings (as opposed to just one of them) it gets funky, parsing won't be enough.
The "unmatrix" algorithm is pretty math intensive and all js implementations I found (a year ago) were broken for non-trivial cases.

I should still have my patched version somewhere in case you need it. Its input is the 4x4 matrix and it outputs the individual translations, rotations, scales and skewings (which when applied IN ORDER, result in the input matrix). It has a math library dependency btw so it is not small.
My use case was also to transition properly between two matrices.

Here is the result: fancydemo.meteor.com (press the play button)

@okonet
Copy link

okonet commented Nov 26, 2014

The "unmatrix" algorithm is pretty math intensive and all js implementations I found (a year ago) were broken for non-trivial cases.

@dbuezas can you provide some examples of such cases? The algorithm I'm using is pretty straightforward.

@dbuezas
Copy link

dbuezas commented Nov 26, 2014

@okonet an example would be:

transform: translateX(100px) rotateZ(45deg) translateX(50px)

It is true that you can get the original (rotateZ(xx) trasnlateY(yy) etc) transform components from the css but since the order of them is important (because matrix multiplication is non-commutative), it gets tricky for the general 3d case.

Order is important:

rotateZ(45deg) translateX(100px) != translateX(100px) rotateZ(45deg)

As I understand, velocityjs uses a fixed order, so it would need to recompute the equivalent transform decomposition in the right order and I think you can only do that through unmatrix.

So parsing the transform string only works when:

  • There are no transform: matrix3d(.....) in the css
  • The order of the transform components in the css is the same that velocityjs uses
  • There are no sandwiched components (like in translateX(100px) rotateZ(45deg) translateX(50px))

That's why I think the general case is tricky, but probably 99% of the users just need the more trivial cases, they just need to be warned about the "right" order of the transform components. Of course that would make impossible to use velocity.js for things like this one here http://fancydemo.meteor.com (only webkit browsers, mobile included), what would be a pity.

If there is interest in putting this into velocity.js (or a separate module) I could help. I am no computer graphics specialist but I have some limited experience with that. It would be famo.us for the masses :D

@okonet
Copy link

okonet commented Nov 26, 2014

velocityjs uses a fixed order

Nope, this is exactly the problem what I'm having with velocity right now. See #323 So basically it fails even on trivial cases right now. But having the ability to pass a computed matrix (and hopefully, compute it by passing separate transforms) could solve this issue as well.

Order is important:
Again, #323 is exactly about this one. So hopefully matrix calculation in the core of velocity could resolve all such cases...

@julianshapiro please let me know if I could somehow help in this one. Also have some experience with matrix/unmatrix calculations.

@dbuezas
Copy link

dbuezas commented Nov 26, 2014

@okonet: oh, I see, it is not fixed but random? Well that is even more problematic...

What I did to solve these issues when I wrote my own js 3d transitions library(ish) was to compute the components (translate, rotate, etc) of both the start and end matrices and then to interpolate on their arguments independently of each other.

It works nicely without corner cases and the computations are cheap enough to run super fluidly in mobile. I think that's the way to go.

@julianshapiro: I would also be glad to work on that too if there is interest.

@okonet: do you think my approach makes sense?, also: do you have a link for your unmatrix algorithm? I followed the w3c css transitions algorithm and I didn't find it that straightforward :(

@okonet
Copy link

okonet commented Nov 26, 2014

@dbuezas I used the same algorithm I think. This doesn't look really complex to me: http://www.w3.org/TR/css3-transforms/#decomposing-a-2d-matrix

@dbuezas
Copy link

dbuezas commented Nov 26, 2014

@okonet Oh that's the 2d case, I am using the 3d case
Just down here http://www.w3.org/TR/css3-transforms/#interpolation-of-3d-matrices

That would allow to do this in velocity.js http://fancydemo.meteor.com (sorry about repeating the link, I think it applies)

@warpraptor0
Copy link

I'm pretty certain it's not random. See my notes in this issue [https://github.com//issues/236]

@julianshapiro
Copy link
Owner Author

Note to self re. #350: Might be interesting to include control for rotation angle depending on how I address this thread over the weekend.

@julianshapiro
Copy link
Owner Author

I will be integrating this by the end of this month.

@ydaniv
Copy link
Contributor

ydaniv commented Jan 5, 2015

✌️

@dbuezas
Copy link

dbuezas commented Jan 9, 2015

Three.js's Matrix4.decompose implementation might also be of use to get the translation, rotation and scale components. The rotation comes out as a quaternion, so to euler angles conversation must also be added. THREE.Euler.setFromQuaternion helps there. I don't know how the projective component is handled there though.

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

9 participants