Closed jverkoey closed 7 years ago
TimeWindow would need to be associated with the Timeline in some way. A Transition would likely create a Timeline with a given duration and associate this with TimeWindow.
TransitionTween would then emit a Tween with the given Timeline.
runtime.add(
RadialTimelineGesture(
gesture: panGestureRecognizer,
withRadius: 50pt),
to: timeline
)
Probably prefer this to the top-down timeline building because it solves the "cascading animations" problem.
let tween = Tween("opacity", duration: 0.3)
let tween2 = Tween("position", duration: 0.3)
let timeline = Timeline()
timeline.append(tween.timeline)
timeline.append(tween2.timeline)
// timeline.duration == 0.6
runtime.addPlan(tween, to: view)
runtime.addPlan(tween2, to: view)
runtime.add(
RadialTimelineGesture(
gesture: panGestureRecognizer,
withRadius: 50pt),
to: timeline
)
runtime.add(Draggable(gesture: panGestureRecognizer), to: photoView)
runtime.add(SpringTo("progress", destination: 1), to: timeline)
let tween = Tween(property, duration: 0.3)
let tween2 = Tween(property, duration: 0.3, delay: 0.3)
let timeline = Timeline()
timeline.add(tween.timeline)
timeline.add(tween2.timeline)
timeline.paused = true
From the (admittedly limited) experience I have building TweenPerformerWeb
, Web Animations scare me:
element.animate
call, you need to use getComputedStyle
, which serializes scale() rotate() translate()
to a matrix. I'm not sure how you'd get the current values for scale
, rotate
, and translate
back out of there, since I imagine the matrix changes depending on the order in which you set those.
element.style.transform
to match the last frame of the animation, but you'd still end up in a bad spot if the animation is paused or reversed.Regardless of whether we use Web Animations, I think we're going to need a pure-JS shim on top of transform
that caches a target's translation, scale, and rotation; ensuring they're always output in the same order. Every performer that touches transform
will need to access it through this shim.
transform
on every frame.
transform
would need to be able to read its current value and only change the relevant pieces. This is a read and a write on every change on every frame, which makes the browser do a bunch of extra layout work, causing dropped frames.@shans probably has more insight here; he might have a solution to pulling human-readable values out of the matrix. Even if we had one, the other problems still make me lean heavily towards the simpler (and more robust) main-thread solution.
This might be a per-platform concern, but I'd expect setters with side effects (e.g. progress
, paused
) to be methods. At least in JavaScript, setters are expected to be cheap with minimal side effects. Triggering a bunch of recursive writes to progress
and thus to the style engine, might be heavy for a setter. Making it a setter does make the spring example simple though. Curious what @shyndman thinks.
FYI they are methods. Swift autogenerates methods for properties.
On Mon, Nov 7, 2016 at 7:51 PM Brenton Simpson notifications@github.com wrote:
This might be a per-platform concern, but I'd expect setters with side effects (e.g. progress, paused) to be methods. At least in JavaScript, setters are expected to be cheap with minimal side effects. Triggering a bunch of recursive writes to progress and thus to the style engine, might be heavy for a setter. Making it a setter does make the spring example simple though. Curious what @shyndman https://github.com/shyndman thinks.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/material-motion/starmap/issues/68#issuecomment-259011964, or mute the thread https://github.com/notifications/unsubscribe-auth/AAr8KmstVKixeX7J9ujoXspcGAdAkp6xks5q78eOgaJpZM4Kr1Us .
I'd like to see a more thorough explanation of how the bottoms-up approach would work. Can you sketch out the performer?
I'm mostly wondering how it's all wired together. What happens if the same tween is applied to two different targets? Timeline drives tween's progress, right? How does tween's progress get connected to the view? Can a timeline drive one tween that drives two separate views, or is there an implicit contract that there's a 1:1 relationship between tweens and views?
Can we consolidate timeline, window, and segment? They feel similar and overlapping. My intuition says we can express the same behavior with fewer concepts.
What happens if the same tween is applied to two different targets?
Same thing that presently happens: the tween is added to each target.
Timeline drives tween's progress, right?
Yes.
How does tween's progress get connected to the view?
Tween performers would react to changes in the Timeline's progress.
Can a timeline drive one tween that drives two separate views?
Yes, though keep in mind it's two performers in this case.
Can we consolidate timeline, window, and segment?
We do need an independent representation of structured time between two transition states. Perhaps TransitionWindow is a better name for TimeWindow; this will more accurately reflect the fact that we're planning out the window between two states.
So:
Need to allow Tweens to be driven by arbitrary values, such as a scroll position, gesture value, or time itself.
Important performance consideration is that if time is driving the Tweens, then the system compositor should be used to drive time forward rather than the main thread. This likely requires some hand-off between the main thread and the system compositor if the driver changes.
Proposal 1. Require that all Tween objects accept a Timeline instance
Timeline.segment()
returns a smaller Timeline whose.parent == timeline
.timeline
could enumerate all of its children timelines using.childTimelines
.If a timeline is
paused
, then any associated Tweens will stop reading time increments from the system compositor. On iOS this means setting the layerSpeed to 0.Setting timeline.progress will update all of the associated Tweens to the relevant time progress. On iOS this means changing the timeOffset of the corresponding layers.