Closed imgdiegoleal closed 2 years ago
I am closing this issue.
I decided to setup and publish a fork as I need these changes quickly, plus some other improvements and bug fixes that are on the way.
Not sure I understand the alternative you considered, is it this?
var myMarker = 2000;
var anotherMarker = myMarker-1000;
anime
.timeline()
.add(props, myMarker)
.add(props, myMarker+1000)
.add(props, anotherMarker);
It doesn't seem any less wieldy to me, and it seems a bit less confusing and a lot more expressive than the offset & referenceMarker syntax. Looking at where similar syntax is used, none of the reasons for it existing in those places (mostly either obnoxious-to-reference stuff or nearly-self-referential stuff) seems to apply to markers, so it'd be nice to keep markers as JS variables rather than completely eating them and losing something in the process. But I think a marker system definitely is a good idea to bind those variables to the timeline they belong to. And it'd help inject more semantics into animations, it's easy to get lost in it all.
Not gonna lie though, I'm not sure how to bind them to the timeline without making them almost as obnoxious to type out. Some scattered thoughts, maybe just keep it the same way animations currently work, applying their offset relative to the most-recently-added thing.
anime.timeline()
.addMarker({name: "myMarker", offset: 2000})
.addMarker({name: "anotherMarker", offset: "-=1000"})
// Could just use the name of a marker as the offset
.add(props, "myMarker")
But trying to change as little as possible we still lose just about everything that's nice about having accessible variables. Maybe instead we break the chain if a reference to the timeline is needed?
var tl = anime.timeline();
tl
.addMarker("myMarker", {offset: 2000})
.addMarker("anotherMarker", {offset: tl.marker("myMarker")-1000})
// Probably would keep += syntax around, and also keep it relative to the last marker added.
.addMarker("evenMoreMarker", {offset: "+=500"})
// Can just reference the marker name straight,
.add(props, "myMarker")
// Or use the longer form for complex changes like aiming perfectly in between two markers.
.add(props, (tl.marker("myMarker") + tl.marker("anotherMarker")) / 2);
Alternatively, maybe we could do offsets completely differently. That long marker expression would pretty weird stapled onto the end of a long list of props, so what about doing away with that argument entirely? Insertion position seems to be a function of the timeline anyway, so we could make that relationship more explicit by splitting the offset off into its own function.
tl
// Starts after last animation
.add(props)
// Starts 500ms after last animation
// Equivalent to .add(props, "+=500")
// Needs a better name, maybe something related to the start time, the in-point, a cursor, I'm not sure.
.timeShift("+=500")
.add(props)
// Also works with markers. Starts at 2000ms.
.timeShift("myMarker")
.add(props)
// Or combine them both. Starts at 2500ms:
.timeShift("myMarker").timeShift("+=500")
.add(props)
// Absolute values are still here, and the lengthy syntax could still work for the things that need it.
.timeShift(500)
.timeShift((tl.marker("myMarker")+tl.marker("anotherMarker))/2);
Now that I think about it, you could also add markers mid-timeline. For example, adding a marker to help sync multiple animations to one end point. Could get screwy with spring easing but it seems like everything gets screwy with spring easing.
var timeline = anime.timeline();
timeline
.add(props) // Fancy intro animation
.addMarker("introEnd") // Offset is whenever the last animation ends
.add(props)
.timeShift("introEnd")
.add(props);
Good points all around.
You're also right about it being obnoxious to reference. On the fork I made, labels are held in timeline.labels
, you should be able to the following:
// ps I renamed addMarker to label
timeline.label({ name: 'bar', reference: timeline.labels.foo, offset: '-=1000' })
// or
timeline.label('bar', timeline.labels.foo, '-=1000' )
// then
timeline.add({...}, 'bar')
// or
timeline.add({...}, timeline.labels.bar)
the alternative (as you mentioned) would be to just use constants:
const FOO_OFFSET = 1000
const BAR_OFFSET = FOO_OFFSET + 500
const BAZ_OFFSET = FOO_OFFSET - 50
timeline.add({...}, BAZ_OFFSET)
which is probably better, except:
I'll sit down to think about it. Good stuff.
Is your feature request related to a problem? Please describe.
I would like to add labelled offsets (aka markers) to
anime.timeline()
, which would solve the following scenarios:Extra benefits from this PR
Describe the solution you'd like
Describe alternatives you've considered
Calculating and using absolute offsets in client code then feeding it into anime. This becomes incredibly unwieldy, resulting in quite a lot of boilerplate being introduced.
Additional context
PR: https://github.com/juliangarnier/anime/pull/809 Working example: https://github.com/diegolealco/anime-test/blob/main/index.jsx
I am happy to move the working example to the examples folder.