ssbc / visual-docs

Diagrams and animations documenting Secure Scuttlebutt (scuttlebutt.nz) and Āhau (ahau.io)

Home Page:https://scuttlebutt.nz

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Sort the order of an object's entries

cameralibre opened this issue · comments

Sort the order of an object's entries (or at least the order in which they are logged)

Context:

Problem

When I add 0% and 100% keyframes, it creates a new key:value pair, and therefore is logged after existing keyframes.

Before (everything nicely in order):

{
  "19%": { "opacity": "0" },
  "25%": { "opacity": "1" },
  "84%": { "opacity": "1" },
  "90%": { "opacity": "0" }
}

After adding 0% & 100% keyframes:

{
  "25%": { "opacity": "1" },
  "84%": { "opacity": "1" },
  "0%, 19%": { "opacity": "0" }, // this should be at the start!
  "90%, 100%": { "opacity": "0" }
}

Having keyframes listed out-of-order still works as valid CSS but it's not nice for humans trying to debug or alter the animations.

The relevant code:

targetIds.forEach(id => {
const absoluteKeyframes = Object.keys(targets[id])
let percentageKeyframe = ''
// convert absolute time keyframes to percentages
absoluteKeyframes.forEach(keyframe => {
percentageKeyframe = Math.round(keyframe / cumulativeTimelineDuration * 100 * 100 + Number.EPSILON) / 100 + '%'
targets[id][percentageKeyframe] = targets[id][keyframe]
delete targets[id][keyframe]
})
const percentageKeyframes = Object.keys(targets[id])
// add a 0% & 100% keyframe to each animation so they start in the
// correct initial position and hold at the end
const oldFirstKeyframe = percentageKeyframes[0]
const oldLastKeyframe = percentageKeyframes[percentageKeyframes.length - 1]
if (oldFirstKeyframe !== '0%') {
const newFirstKeyframe = '0%, ' + oldFirstKeyframe
targets[id][newFirstKeyframe] = targets[id][oldFirstKeyframe]
delete targets[id][oldFirstKeyframe]
}
if (oldLastKeyframe !== '100%') {
const newLastKeyframe = oldLastKeyframe + ', 100%'
targets[id][newLastKeyframe] = targets[id][oldLastKeyframe]
delete targets[id][oldLastKeyframe]
}

Is there some way to sort how Object entries are logged? Or would I have to recreate every entry again, in the correct order, i.e.

  1. create new 0% keyframe
  2. create new identical versions of all other keyframes
  3. create new 100% keyframe

This seems a bit over-the-top though...

I've opened a PR with one example of how you could do it. The simplest way, I think, is to replace your object with one where the keys are sorted by default.
So for a keyframe object I grabbed the array of its keys, and sorted this with a helper function.
Then, I reduce the array, which lets us compile it into an object, but this time the keys are sorted.
Then I just replace the targets[id] object with this new, sorted one.

I've commented the new work, but am happy to talk of it more!

Thanks! I went through it nice and slow to make sure I got it all - javascript.info was useful as usual :)