joelambert / morf

A Javascript work-around for hardware accelerated CSS3 transitions with custom easing functions
http://www.joelambert.co.uk/morf
Other
507 stars 51 forks source link

Cross browser support #9

Open jeremyckahn opened 12 years ago

jeremyckahn commented 12 years ago

It seems that all of the modern browsers now support matrix transforms: https://developer.mozilla.org/en/CSS/transform

Looks like support can be added for all browsers.

joelambert commented 12 years ago

The main problem with cross browser is that only WebKit implements the CSSMatrix object currently which is needed to do the interpolation.

jeremyckahn commented 12 years ago

I never quite understood what the CSSMatrix Object does. Is it just shorthand for setting all of the translateX/Y/Z, scale and rotation properties?

joelambert commented 12 years ago

Its a convenience object for doing the Matrix transform stuff, its also able to read/write the CSS matrix string syntax.

Apple Docs: WebKitCSSMatrix

That said, it would be possible to produce a pure JS alternative that could just use the native implementation where it existed. I know that @cubiq was talking about implementing this, I'm not sure if it ever happened. If not I may take a look at it if I get some spare time.

cubiq commented 12 years ago

I have an alpha stage object I use on my projects, nothing I'm proud of but it works (doesn't have skew and rotateAxisAngle). I should just take the time to polish it and release to the public ;) If you believe it is worth I can push it

jeremyckahn commented 12 years ago

Personally, I would love to see Morf's functionality available to all browsers. I have very similar @keyframe generating functionality with Rekapi called toCSS(). It would be great if I could use a CSSMatrix Object polyfill to support Matrix interpolation.

@cubiq, it seems like your code would be very beneficial to both projects. :)

jfsiii commented 12 years ago

I think I have the polyfill @jeremyckahn mentioned.

I took the work started in Firmin and added some code to make it behave like WebKitCSSMatrix

It's passing all the tests from the WebKit source (2D, 3D) except those which test for throwing an error on incorrect input[1]. Most importantly, IMO, you can give it a CSS transform string (like rotate(18rad) translate3d(50px, 100px, 10px)) and get an object with the proper matrix properties.

I'm at the point where I'm going to extract this out to a distinct project. @jeremyckahn and @joelambert, since your projects were the two primary consumers I imagined when working on this, care to vote on the name?

I've only test in FF but "it's just math" and I don't, to my knowledge, use any platform specific code so we should be cool.

[1] I'm planning on making the error behavior configurable since using try/catch is so expensive.

joelambert commented 12 years ago

Great work, I look forward to taking a look! Let me know when I can have a play.

Happy to vote on a name when you have a shortlist.

jfsiii commented 12 years ago

@joelambert You should be able to paste the JS from https://github.com/jfsiii/firmin/blob/master/src/matrix.js into a browser or Node and have at it.

Let me know if that doesn't work or you need something else.

jeremyckahn commented 12 years ago

Very cool! I'm not sure that Rekapi would really benefit from integrating your Firmin work at this point (it meets its requirements), but I still think there's a lot of value in this type of polyfill. Since this is basically a cross-browser WebKitCSSMatrix Object, maybe a name based on that - XCSSMatrix, or just CSSMatrix?

jfsiii commented 12 years ago

@jeremyckahn XCSSMatrix is the clubhouse leader. I thought about CSSMatrix b/c it's supposed to be spec-compliant. While no vendor ever released a CSSMatrix object (only WebKitCSSMatrix), they might after the spec is reimplemented. I'd hate to have a conflicting implementation or have to explain that "it's for the old one that was a spec but ..."

No pressure to use it, but didn't you say, "It would be great if I could use a CSSMatrix Object polyfill to support Matrix interpolation."?

jeremyckahn commented 12 years ago

You make a good point about using XCSSMatrix over CSSMatrix - my vote goes for the former.

While I still think that such a polyfill is an excellent idea for general use, I made the comment you referenced 6 months ago. I've since implemented the functionality I needed for Rekapi, albeit in a more tightly coupled way than your Firmin/XCSSMatrix work. Considering where my code stands right now, it wouldn't benefit from an XCSSMatrix integration, it would only grow Rekapi's total file size, which doesn't benefit Rekapi users. Sorry it can't be a helpful test case for this anymore!

joelambert commented 12 years ago

+1 for XCSSMatrix

geekpunk commented 11 years ago

ie 10 now supports all of the webkit only dependencies here , would you be interested in accepting changes to support ie 10

jfsiii commented 11 years ago

@joelambert I just realized I never came back here to post about XCSSMatrix. It's been "ready" since around December 2012.

I have browser tests up on testling. They are/were passing in Chrome 6+, Safari 5+, FF4+, Opera 11+, IE9+. WebKitCSSMatrix conformance tests are included in those tests, but you can load them in a specific browser by visiting the Firmin test page.

jeremyckahn commented 11 years ago

Wow, XCSSMatrix looks great, thanks for the update! @joelambert, is this project still being maintained? Any chance this issue will be resolved?

Although I am not personally using Morf, I think it would be great for the community if this issue were resolved. At 328 stars, I imagine others would agree. :)

joelambert commented 11 years ago

Looks great, @jfsiii are you able to patch it into Morf and make a pull request?

jfsiii commented 11 years ago

@joelambert I'm not sure of the best way to do that.

I don't see script loaders for the individual src files or a build process for the various builds (min, with & without shifty, etc).

I guess I could just concatenate all the XCSSMatrix files together and put that in src/XCSSMatrix.js, replace all instances of WebKitCSSMatrix with XCSSMatrix and leave it to you to generate the builds?

Can you take a look at XCSSMatrix and give me some direction about how you'd like me to incorporate it?

joelambert commented 11 years ago

You're right, there isn't a script loader in the repo. I started this before Grunt/Yeoman etc too so there is only a makeshift build script that I wrote myself (in PHP).

If you take a look at the build directory, you'll see an XML file. That basically groups the files that need to be concatenated. It currently builds two versions of Morf:

  1. Morf packaged with Shifty (@jeremykahn's framework)
  2. Morf, without Shifty incase you're already including it in your app

Depending on how XCSSMatrix works, it might just be a case of adding the deploy script to the src folder, adding it to the XML and running the build/build script.

jfsiii commented 11 years ago

Oh, cool. I completely missed the build script and build.xml file.

XCSSMatrix is designed to be a drop-in replacement for WebKitCSSMatrix so, as you said, I can likely just put it in src and edit build.xml.

I'll likely replace all instances of WebKitCSSMatrix with XCSSMatrix. Cool?

joelambert commented 11 years ago

I'll likely replace all instances of WebKitCSSMatrix with XCSSMatrix

Sounds good, thanks

jfsiii commented 11 years ago

I forgot to discuss removing the other WebKit-prefixed JS and CSS properties.

How do you feel about adding a custom build of Modernizr as a dependency/additional script? Here's what I did for 2012 BeerCamp site.

Let me know your thoughts. Especially any alternative ideas. It is your project, after all.

jfsiii commented 11 years ago

OK, the preliminary attempt is committed to my feature-cross-platform branch.

I cut a gh-pages branch an pushed an updated demo page.

It seems to work well in Chrome, Safari and Firefox, but Opera (12.15) is failing. No JS errors but I'm not quite sure why (unsupported CSS, wrong events, etc).

Have a look at the comparison between branches and let me know what you think (e.g. Is it OK to expose Morf.prefixed?).

jeremyckahn commented 11 years ago

@jfsiii: Wow, great work! Thanks for taking the time to put this all together.

I didn't do a through code review, I mostly just skimmed through the diff. It looks like Morf will be getting a lot bigger because of this change — is there a way to easily configure a smaller build that doesn't have XCSSMatrix and Modernizr baked in? I may have missed it if you built in the option to omit them. I think it's reasonable to load all of these libraries, but I it's important to support minimal builds and stripped-down feature sets.

jfsiii commented 11 years ago

IMO, it's getting bigger in the relative (%) but not the absolute (KB):

file name gzip before after diff % diff KB
morf.js no 27.71 58.98 112.85 31.27
morf.js yes 8.33 16.21 94.60 7.88
morf.min.js no 16.01 29.38 83.51 13.37
morf.min.js yes 4.95 9.33 88.48 4.38
morf.noshifty.js no 20.57 51.84 151.87 31.24
morf.noshifty.js yes 6.35 14.27 124.72 7.92
morf.noshifty.min.js no 9.17 22.53 145.69 13.36
morf.noshifty.min.js yes 3.17 7.59 139.43 4.42

If gzipping is supported the difference is 4 or 8KB on the morf.js build.

Assuming additional builds are desired, I'm pretty sure it's possible. Off the top of my head, I think I'd do something like Morf.Matrix = window.XCSSMatrix || window.WebKitCSSMatrix, then switch all the references from XCSSMatrix to Morf.Matrix.

Then I'll just add another <file> block to build\build.xml. Maybe I'll revert morf.js to be the build based on WebKitCSSMatrix (for backwards-compatibility)

jeremyckahn commented 11 years ago

Thanks for the graph, that's awesome. I agree that the absolute size difference is negligible.

The minified and gzipped numbers are what's most important here. I still think it's worthwhile to support a modular build process to configure binaries and feature sets, but that can be done later — it's outside the scope of this issue.

joelambert commented 11 years ago

Thanks for doing this, really appreciate you making this work cross platform.

+1 for a modular build process. I like the idea of Morf.Matrix = window.XCSSMatrix || window.WebKitCSSMatrix as it can be extended if/when others implement a native matrix implementation. It's probably better to do it the other way round though, so the native is used if it exists and XCSSMatrix is a polyfill, or does the API differ from WebKitCSSMatrix?

I agree that this is outside the scope of this issue but it would probably be useful to convert the build process to grunt at somepoint anyway, just to make it a bit more robust and easier for others to understand/contribute to.

jfsiii commented 11 years ago

OK, I'll take a crack an additional build and the Morf.Matrix approach.

Are you OK with everything else (e.g., Adding/exposing Morf.prefixed or anything else I did)?

Oh, fair warning, I'm making a ticket for tests :D

jfsiii commented 11 years ago

OK, latest effort up at https://github.com/jfsiii/morf/commit/a19fe2cd24c1429cf1344666dcfecbc63fc38da7

Have a look. Test away. I think it works.

jfsiii commented 11 years ago

Just curious where this stands. Take a look at the cross-platform test page and let me know what you think.

jeremyckahn commented 11 years ago

I get a JavaScript error in Chrome 29.0.1547.32 beta when I click any of the custom tweens:

Uncaught TypeError: Object [object WebKitCSSMatrix] has no method 'decompose' morf.xplatform.js:1060

Morf morf.xplatform.js:1060
Morf.transition morf.xplatform.js:1200
(anonymous function) demo-xplatform.html:35
Ka jquery.min.js:18
c.event.handle jquery.min.js:63
h.handle.o jquery.min.js:56
jfsiii commented 11 years ago

@jeremyckahn :/ you sure do. I'll see what's going on and follow up in a moment.

jfsiii commented 11 years ago

@jeremyckahn Everything should work as expected now. See fed8c5e for the fix.

jeremyckahn commented 11 years ago

Works perfectly for me in Firefox and Chrome!

jfsiii commented 11 years ago

@joelambert have you seen the cross-platform test page? Can you let me know if there any blockers? Should I just submit a PR so we can discuss there?

joelambert commented 11 years ago

Sorry John, I've just been flat out and not had chance to look until now. As @jeremyckahn mentions it does appear to work really well in both Firefox & Webkit browsers.

Can you put together a pull request where XCSSMatrix isn't a hard dependency? I'm imagining site authors can then load XCSSMatrix as a polyfill where needed?