question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Been thinking about how to do animations a lil, and think having a component with Nanomorph would be the right place to add them. We should be able to do stuff like this at 60fps:

react-f1-chief

This is my current state of thinking; I’m not entirely sure how to approach this yet but I think laying out the constraints can help us with figuring out how to approach this. Apologies if I’m rambling a lil here, figured it’d be better to share notes & thoughts in the open, even if they’re not as polished as they could be.

Constraints

There’s a few things I think would be cool if we could pull off:

  • animate individual components
  • create complex full page animations with multiple components
  • have it run smoothly at 60fps
  • try and keep the new terminology and APIs introduced to a minimum
  • find a way to allow this to work for modals and (infinite) list elements too

Component lifecycle events

Nanomorph takes care pretty well of rendering things on a screen. If you want to add an element, it’ll take care of it with little trouble. However, it can’t pause element mutation, which is crucial for animations. For example, say an element has a fade-in effect when it’s first rendered. If we re-render midway through the animation it’ll look weird. So we want to make sure the animation completes before any further mutations occur. Stuff like a fade-out before a component is removed isn’t even possible right now, so we should allow for that.

Types of events

There’s generally 3 types of events that happen¹:

  • component will be rendered for the first time
  • component will be rendered, but it’s not the first time
  • component will be removed from the DOM

Each of these events should be handed a lock that can be cleared using a callback. E.g. somewhat similar to:

component.on('rendered-for-the-first-time', function (done) {
   this.component.classList.add('my-500-ms-transition')
   setTimeout(done, 500) // tell we're done animating, allowing mutations to trigger again
})

While an animation is in progress, other animations and Nanomorph mutations should be put on hold.

The leave event

Because we just diff DOM nodes and don’t do extra lifecycle tricks, we can’t prevent elements from being unmounted. This means we can’t trigger any animation when an element is removed from the DOM. To counter this we could, however, leave an element in the DOM that can instrument between its child elements and trigger hooks on each of them.

I think the approach might be to have some form of scheduler live in the DOM, that doesn’t get unmounted so it can have its own Nanomorph instance. It can then do fine grained scheduling for its child elements, exposing all sorts of events².

Instrumenting Nanomorph through locks

As mentioned above, we would hand animation handlers a lock which they can free at the end of an animation. This is so we can make sure animations complete and don’t conflict. E.g. imagine this scenario:

  • element is rendered for the first time, triggers the “enter” animation
  • element is marked to be removed from the DOM, triggers the “leave” animation

In this case we’d want the “enter” animation to complete, and only then mark the element to be removed from the DOM. Now, we can’t immediately unmount the element - we need the animation to complete first. So we need a way to prevent the element from being removed.

Maintaining 60fps

ideally we’d be able to schedule the animations to the best of our abilities. E.g. not smush them all together in the same frame - but perhaps even better: schedule them when there’s free time available. Something interesting to experiment be would be to find a midway: try and run the animation with window.requestIdleCallback() but run it anyway if it takes longer than 10ms or something. If every component would employ something like this, then things should run relatively smoothly (is my guess). Worth experimenting with at least haha.

Instrumentation

So far we’ve only talked about how to allow transitions to work with nanomorph. Sometimes we’ll need to instrument full page animations³. In react-f1 there’s a distinction between individual element renders, and full page instrumentation. Another good example of this would be jam3.com.

The way f1 / react-f1 does it is by declaring a finite state machine, and using a pathfinding algorithm to navigate between the nodes. If you do several layers of this, you can create pretty wild animations. An example of a pathfinding algorithm is jkstra for Dijkstra / A* pathfinding.

Unanswered questions

A tricky thing with Nanomorph is that we can’t have multiple on-load handlers on any given node so we’re slightly constrained in that regard. But there’s a few more things I think we should try to figure out:

  1. is it possible to have a “pure” scheduler - e.g. one where we don’t need to mount any wrapper components on the DOM?
  2. What does a application level scheduler look like, and how does it interact with choo’s events?
  3. How can we integrate elements like infinite lists and modals with animations and application level schedulers?

Wrapping up

I hope this somewhat explains the constraints my thoughts on the matter, and helps start a discussion on how to best approach animations. Thanks heaps for making it this far, and keen to hear your thoughts!

See Also

edit: meant nanomorph, not morphdom haha

Issue Analytics

  • State:open
  • Created 6 years ago
  • Reactions:7
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

5reactions
yoshuawuytscommented, Nov 26, 2017

Oh by the way, updates!

1reaction
YerkoPalmacommented, Apr 28, 2017

In fact you can manipulate css animations from javascript, so you could include them in the app state, but, IMO, things can get a litle hacky from here.

Links

Read more comments on GitHub >

github_iconTop Results From Across the Web

Animation - Wikipedia
Animation is a method by which still figures are manipulated to appear as moving images. In traditional animation, images are drawn or painted...
Read more >
Animaker, Make Animated Videos on Cloud for free
Animaker is an online do-it-yourself (#DIY) animation video maker that brings studio quality presentations within everyone's reach. Animated Videos ...
Read more >
Trending animations, motion graphics, and 3D designs
Explore popular animation and motion graphics work from designers on Dribbble, your best resource to connect with designers worldwide.
Read more >
Top 50 Animation Movies and TV Shows - IMDb
A list of the best Animation movies and TV shows, as ranked by IMDb users, like you. Find something great to watch now....
Read more >
CSS Animations - W3Schools
An animation lets an element gradually change from one style to another. You can change as many CSS properties you want, as many...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found