Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Snabbt.js – a minimalistic animation library (daniel-lundin.github.io)
323 points by sBUWK on Jan 1, 2015 | hide | past | favorite | 47 comments



Extremely impressive demo. This is how a Show HN for a front-end library should always be: take me straight to a demo of the coolest part.

What exactly makes this so fast? I'm not familiar enough with JS/CSS to know from the code. The 200-element sticks demo was by far the smoothest animation I have ever seen for that many elements.


Translation, rotation, scale, and opacity are the fastest things to animate in the browser. The GPU can be employed and the browser does not need to recompute layouts and reflow. Doesn't work for everything (without building layout systems in JS), but can be used for quite a lot of animations.


JS animations are inherently very fast, most likely because you're running a modern browser. :)

The code is basically just computing a 4x4 matrix for each card per frame built up from some tweened position/rotation/etc. Then it applies the matrix to the element's CSS. The code doesn't look optimized (ie allocates lots of typed arrays) but as the demo proves, its already pretty fast.


> allocates lots of typed arrays

Out of curiosity, can you show an example and how it should be done properly?


A better approach is to re-use arrays instead of creating intermediate ones, which is what gl-matrix[1] advocates. Each tween might still need its own matrix instance for start and end points, but at least these are not created per tick.

A similar approach is to use a "pool" of arrays[2] which allows you to re-use them without having to manually keep track of the temporary arrays.

[1] - https://github.com/toji/gl-matrix

[2] - https://github.com/mikolalysenko/typedarray-pool


Similarly, PhysicsJS employs a "scratchpad" of pre-initialized vectors for fast intermediate computations. That way you aren't constructing new objects, but grabbing a free one, zeroing it, and using it as you would before. Seems quite performant.

https://github.com/wellcaffeinated/PhysicsJS/blob/master/src...


what makes is fast is the use of requestAnimationFrame [1] (rather than setTimeout or setInterval) that exists in all modern browsers and simply applying css, letting the browser handle and GPU-accelerate as it sees fit. the only thing the js does is compute the matrices for each step/frame in fixed-length typed arrays.

[1] https://github.com/daniel-lundin/snabbt.js/blob/master/src/m...


"Snabbt" is Swedish, and means "fast".

(I've translated a couple of these Swedish named things on HN over the past time, I hope it's not off topic)


I was puzzled by the name, thanks for pointing this out!


The demo is certainly impressive, but the API doesn't look very idiomatic:

- JS is a camelCased language. While I certainly appreciate snake_case in Python, it doesn't belong in a JS library.

- The Matrix APIs are needlessly terse. rotate, multiply, translate, and identity are only a few characters longer than your choices, but they're oodles more intuitive and easier to read.


What a pedantic case for #1. Wow. Seriously?


Those things don't matter, though. Especially for anyone who has a passing familiarity with matrix operations.


Maybe I'm just naive (probably), but is it really that off putting that the casing convention isn't the same?

To be honest, I don't know what most languages "are" with regards to the casing convention..and I've never been explicitly told what they should be either.


I'm a big believer in consistent, readable codebases. Anything that doesn't make it easier to understand and improve the code shouldn't be occupying your headspace. You should never have to answer "now why didn't that work" with "I was supposed to use with_scale instead of withScale."

There are of course languages where the ecosystem itself is inconsistent (like PHP) or there are no conventions to follow (like CSS). In those cases, use whatever's your favorite; however, if you are snake_casing JavaScript or camelCasing Python, you're doing it wrong.

If you're the only one who ever touches your projects, it doesn't matter, but for anyone who has to work with your codebase, you've created a pain-in-the-ass for no good reason.


Of the many faults a library author can make, variable declaration style is pretty low on the list of things that are truly going to affect the product of the library. I'll always sacrifice style and convention for features such as performance, ease of use, or capabilities. Things like variable naming conventions being in line with the rest of my project are on the nice-to-have list, but definitely not going to drive my decision on whether to use a library or not.


To me, it says that the author is out of touch with the community and the commonly followed standards and suggests they're breaking other conventions (that affect the product more than naming convention)


> it says that the author is out of touch with the community and the commonly followed standards

Maybe. I suspect your interpretation may be the common one (which may be reason enough to follow the convention) but it is certainly possible that the author is aware of the convention and consciously chooses to ignore it.

If other code-quality signals (does it work? does it build? is there a demo/quick-start? is it tested? documented? readable? not re-invent the wheel? follow relevant architectural and organizational idioms, etc.) are there, this seems to me to be the more likely scenario, especially given this particular convention (which is somewhat controversial).

For what it's worth, I feel I'm pretty well versed in the JavaScript community standards and conventions and yet like the author I commonly follow an underscore_based_naming_convention rather than aCamelCaseOne in JavaScript/CoffeeScript (even in open source projects). There are some studies [1] that suggest that the underscore version is more readable in general, but I've seen earlier studies that come to the opposite conclusion.

For me it comes down to personal preference -- I find underscore-based-names more readable and easier to remember (e.g. `http_client` vs `httpClient` vs `HTTPClient` etc) -- but I concede it's essentially a matter of taste.

I'm not trying to convince you that underscores are better, just that the use of underscores in JavaScript isn't as directly related to code quality as you seem to assume.

[1] http://www.cs.kent.edu/~jmaletic/papers/ICPC2010-CamelCaseUn...


Yeah, that's it. I'm not saying that because the author he uses underscores he's a bad programmer and everything he makes is rubbish.

All I'm saying is that I would use that as one of many signals to judge the library and see if I'm interested/able to use it.


What other conventions would be broken if the library has quality performance and features?

How does being out of touch with the community affect how good a library is?


I'm just saying that after seeing the project demo or readme on github or whatever, I would use that as just one signal as to assess the quality of the project and whether I would use it or not.


Although most Python is written in snake_casing, it there's still a few big frameworks that use camelCasing and when you're using them, camelCasing is the way to go. One that comes to mind off the top of my head is Twisted/Zope.


I was once turned down for a coding job based on stylistic complaints with my code, one of which was that I used snake_casing instead of the (apparently preferred) camelCasing in Java.

Since then I've resolved myself to the fact that in almost all things CS, there are many different ways to get to the final answer or finished product and your way of doing it is fine if it gets the job done in a timely manner while minimizing future complications. Anyone claiming a "right way" to do something at the level of irrelevant casing either has a larger organization to worry about in terms of code readability, etc and is therefore justified if your project is meant to be shared with others OR is professing code piousness as a way to stroke their own ego.


It's not that the style was "wrong", it's that anyone who writes java and doesn't know something as basic about the language as the style conventions. I would also reject a candidate that didn't know the rudimentary stuff. What else don't they know? Especially for Java, not so much for JS, but Java is an enterprise language which means you'll be one cog in a big machine and you need to know and respect the coding conventions to stand any chance of being an efficient member of their team.

I would actually say that coding style is a big predictor of how likely an interview candidate would turn out to be a good developer in a team. Casing isn't irrelevant at all, it's a predictor. It has nothing to do with piousness. Another indicator of bad java developers (in my experience) is those that write near 'c', lots of for(int i=0; i<.... and not using language constructs that are their to reduce bugs. Another good indicator I have found (in java) is little to no use of 'final'.

If you'd have prefaced your coding in the interview with "I'm not familiar with Java, I use X, but I'll take a stab at the problem" I'm sure the interviewer would have been less worried about your style, but if you claim to know a language, you'll know the conventions too.


I don't think it's reason to turn somebody down, but it can be fairly annoying using a library that doesn't follow standard naming conventions. If your code brings together four different libraries and they all use drastically different conventions (case, wording, parameter style, etc) it can quickly lead to a messy and difficult to maintain codebase.


Fair enough, I can definitely see that being an annoyance. Especially in the context of this being a light library, it's undoubtedly going to be utilized with any number of other libraries. Good point.


Not to be rude, but there was likely more to their decision than style errors and they didn't tell you.


Velocity.js http://julian.com/research/velocity/ is pretty damn good already and just 12kb Gzipped.


Competition is healthy. :) https://www.npmjs.com/package/tweenr

Besides, different authors will tackle the problem a little differently.


This is under 4kb.


I have to say, I'm glad I can now build a house of cards using JavaScript. I've tried and failed too many times in real life.


This looks very similar to http://famo.us/. What is the main difference of Snabbt.js as compared to famo.us?


Obviously famo.us is more famous than snabbt.js. But seriously, they both do the same thing. Instead of using css transitions they both use request animation frames and then only do the transformations that are fast to do. The main differences is the size of Snabbt, which only does animation, and Famo.us which handles touch events has a larger physics engine and more utility functions.

There are efforts being done to implement parts of Material design using famo.us:

Demo http://skelware.com/famous-material/demo/1/

Source https://github.com/StephanBijzitter/Famous-Material-Examples


Nice library.

The current implementation leads to a lot of garbage since you are allocating several typed arrays per tick for each tween.

Also looks like gimbal lock and Euler interpolation could be a problem for some 3D rotations. I guess fixing that would lead to extra complexity.


Really impressive! I like this a lot. One thing I noted however, was when I resize and refresh to a smaller browser size the squares turn into long rectangles. Is there a way to make them scale together so they stay as a square in a narrow view?


Unfortunate name similarity with “Snabb Switch”, as featured here on HN six months ago:

https://news.ycombinator.com/item?id=8008963


An impressive demo, but I'd like to see this being done with photos of varying quality and see how the performance fairs. I've got a Chrome extension that I could probably use this with...


Nice demo dude! And indeed it's really fast. Well done and thanks for sharing. Will try this out.


These are awesome animations! I'll add this to Toolyo.

I'm creating a new category for these kind of items :)


This looks great at a glance. Looking forward to tooling around with it this weekend.


This is incredibly impressive. Thank you for sharing.


This looks amazing.


Very fluid on my phone too!

(Nexus 5 on lollipop)


Jaw dropping demo, great work!


Those crazy sticks are crazy!


how would one do the equivalent of the createjs timeline?


How manipulate the DOM without reading it actually work?


Impressive.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: