feat(layers): let a layer slide animation start from a point of its own - #865
Merged
Merged
Conversation
A slide could only travel to and from a canvas edge, named by
`slideDirection`. `LayerAnimation.slideFrom` now takes a start point
instead: the layer's position in the same coordinates as `Layer.offset`,
measured from the center of the editor canvas. It may sit outside the
canvas, and it overrides `slideDirection` when both are set, so nothing
existing changes.
The start point and the layer's resting place are both anchor points, so
their difference is the distance travelled — the layer's own size cancels
out, and with it the fractional component the edge-aware slide needs to
clear the border. The preview therefore composes the point slide as a
plain pixel translation.
This mirrors `pro_video_editor`'s feature of the same name, so a layer
timeline built here keeps matching the exported video. The one difference
is the origin: `pro_video_editor` measures its `slideFrom` from the video
frame's top-left corner because that is where its own layer offsets start,
while this one follows `Layer.offset` and measures from the canvas center.
`slideFrom` is serialized as `{dx, dy}` and carried through `copyWith`,
equality and `toString`. Parsing it reuses a new `safeParseOffset`, the
sibling of the existing `safeParseSize`.
…o_video_editor The two packages agree on the maths - only the distance between the start point and the layer's resting anchor is ever used - but disagree on the origin, because each follows its own layer offsets. An exporter that converts `Layer.offset` and forgets `slideFrom` therefore parks the layer correctly and moves it the wrong distance, silently.
The timeline preview cached the composed frame and only rebuilt it when the video position or an animation setting changed. The slide effect also reads the layer's offset, its center and the canvas size, so dragging a layer or resizing the canvas left the layer travelling the distance measured for the old geometry until the next time tick. `Layer` is mutable and is mutated in place while it is dragged, so the old and new widget hold the same instance and comparing them cannot see the move. Record the geometry each frame was computed from and compare against that instead. Also export `safeParseOffset` from the package barrel next to its `safeParseSize` sibling, which was left out when it was added.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports
pro_video_editor#194to the image editor's layer timeline, so a slide animation built here keeps matching the exported video.What
A slide could only travel to and from a canvas edge, named by
slideDirection.LayerAnimation.slideFromnow takes a start point instead:The point may sit outside the canvas, and it overrides
slideDirectionwhen both are set — so nothing existing changes.animateOutleaves towards it,animateInOutdoes both.How
The start point and the layer's resting place are both anchor points, so their difference is the distance travelled: the layer's own size cancels out, and with it the fractional component the edge-aware slide needs to clear the border. The preview composes a point slide as a plain pixel translation, which is what the native renderer does too.
The one deliberate difference from
pro_video_editor: it measures itsslideFromfrom the video frame's top-left corner, because that is where its own layer offsets start. This one followsLayer.offsetand measures from the canvas center. The doc comment says so.Also
slideFromis serialized as{dx, dy}and carried throughcopyWith, equality andtoString;fromMapstays lenient and ignores a non-map value.safeParseOffset, the sibling of the existingsafeParseSize, parses it.slideassert now accepts either a direction or a point.Testing
flutter analyzeclean,dart formatclean, all 594 tests pass — including 5 new preview cases (starts on the point, travels a linear fraction, settles at rest, overrides a direction, leaves back towards the point), 8 new model cases and a parser suite.