TL;DR
- You can stop glitches in your animations when you are running Javascript code, without waiting for your animation to end
- I've written a library that lets you easily run processes in the spare time between each frame of your animations
- It works on the Browser and now tested working in React Native
- You can stringify, parse, compress, sort, filter, reduce and transform to your hearts content and animations remain smooth
- You can use it with async functions or dive into using generator functions if you need to break up your own complex calculations
- It's available on MIT license from my GitHub and as
npm -i js-coroutines
- There's a detailed article on how it works internally available here
How to use js-coroutines to keep your animations smooth:
If you are just sorting, compressing or using array operations you can get away with importing the xxxxAsync methods and using them inside a normal Javascript async
function:
import {sortAsync, parseAsync, filterAsync} from 'js-coroutines'
...
async doMyProcess(input) {
const records = await parseAsync(input)
const filtered = await filterAsync(records, r=>r.age < 30)
return await sortAsync(filtered, item=>item.surname)
}
If you have your own complicated process you can use generator functions and run
:
import {run, parseAsync} from 'js-coroutines'
async doMyProcess(input) {
const records = await parseAsync(input)
return await run(function*() { return yield * myComplicatedProcess(records) })
function * myComplicatedProcess(data) {
let total = 0
for(let i = 0; i < data.items.length - 1; i++) {
if(i % 100 === 0) yield // Check how much time is available
if(typeof data.items[i] === 'number') {
total += (data.items[i+1] - data.items[i]) ** 2
} else if (typeof data.items[i] === 'object') {
total += Math.sqrt(yield * myComplicatedProcess(data.items[i]))
}
}
return total
}
}
Demo
Animations Too!
js-coroutines also allows you to write imperative code for animations
More on that here:
Top comments (2)
Very cool!
I've had a quick peek at the source code. Do you exclusively use requestAnimationFrame for the animations? I noticed you also have setTimeOut as well but I wasn't sure if you use that as well.
Also what are your thoughts on using a service worker for off the main thread animations?
So the animations use requestAnimationFrame - the key thing being to use generators to create imperative for next loops in that case.
The processing stuff uses requestIdleCallback. I polyfill that in a variety of ways.
The problem with other threads is the effort of moving things to and from them, so if the animation was basically a ton of processing that resulted in something simple and small enough to move then it would work. I'm thinking some kind of complex particle simulation or 3d work.