# Shared Element Animation
original App
We often see such interactions, such as from the product list page into the details page process, the product picture leaps between the pages, making the transition effect smoother, another case is the image preview magnification function of WeChat Moments. in Skyline
Rendering mode, which we call shared element animation, is available through share-element
Components to implement.
In a continuous Skyline
When pages jump, between pages key
The same share-element
The nodes will generate leap effects, and the developer can customize the interpolation method and animation curve. Usually act on the picture, in order to ensure the animation effect, before and after the page share-element
The child node structure should be as consistent as possible.
# Experience immediately
Scan the code to open the Mini Program example, interactive animation - Basic components - Shared Element Animation Can experience.
# Methods of Use
attribute | type | Default value | Required | Introductions | Minimum version |
---|---|---|---|---|---|
key | string | yes | Mapping tag, unique within the page | 2.29.2 | |
transition-on-gesture | boolean | false | no | Whether to animate when the gesture returns | 2.29.2 |
shuttle-on-push | string | to | no | Appoint push The Leap Thing of Stage | 2.30.2 |
shuttle-on-pop | string | to | no | Appoint pop The Leap Thing of Stage | 2.30.2 |
rect-tween-type | string | materialRectArc | no | Animation interpolation curve | 2.30.2 |
on - frame | worklet callback | no | Animation Frame Callback | 2.30.2 |
Assume A
Pages and B
The page has a corresponding share-element
assembly
push
Stage: Throughwx.navigateTo
byA
Get intoB
, saidA
The source page (from
page),B
For the target page (to
page)pop
Stage: Throughwx.navigateBack
byB
returnA
♪ at this pointB
For the source page (from
page),A
For the target page (to
Page)
# Designated Leap Object
For a selected source or target page share-element
As a leap.
Since the component involves two pages, here the target page share-element
Component-specified attributes prevail
push stage
: Default AdoptionB
Pageshare-element
Components to make the leap, set the propertiesshuttle-on-push=from
Can be switched toA
Pages.pop stage
: Default AdoptionA
Pageshare-element
Component, Set Propertiesshuttle-on-pop=from
Can be switched toB
Pages.
It should be noted that on - frame
The callback is always found in the share-element
Triggered on the component.
# Animation Frame Callback
Shared element animation is based on the source page share-element
In the rectangular box as the starting point, the target page share-element
In the rectangular box as the end point, interpolation calculation process, animation time and page routing time consistent.
enum FlightDirection {
push = 0,
pop = 1
}
Interface Rect {
top: number,
right: number,
bottom: number,
left: number,
width: number,
height: number
}
Interface ShareElementFrameData {
// Animation Progress, 01
progress: number,
// In animation direction, push; | pop
direction: FlightDirection
// Source page share-element Container size
begin: Rect,
// Target Page share-element Container size
end: Rect,
// Dimensions of the Current Frame Leap Object Container Calculated by Frame
current: Rect,
}
type ShareElementOnFrameCallback = (data: ShareElementFrameData) => undefined | Rect
The developer can pass on - frame
Callback to customize the interpolation method.ShareElementFrameData
Contains the beginning and end positions, and the frame according to the specified animation curve rect-tween-type
And Current Progress progress
Calculated current
Location.
The default interpolation is for Rect
of LTWH
Linear interpolation, respectivelyThe. When on - frame
return undefined
The real time position of the leap object in the current frame is determined by current
Determined, the developer may return the otherwise computed Rect
Object is overwritten.
const lerp = (begin: number, end: number, t: number) => {
'worklet'
return Begin + (end - Begin) * t
}
const lerpRect = (begin: Rect, end: Rect, t: number) => {
'worklet'
const left = lerp(begin.left, end.left, t)
const top = lerp(begin.top, end.top, t)
const width = lerp(begin.width, end.width, t)
const height = lerp(begin.height, end.height, t)
const right = left + width
const bottom = top + height
return {
left,
top,
right,
bottom,
width,
height
}
}
# Animation interpolation curve
In addition to customizing the interpolation method, you can also customize the animation curve. The default animation curve is [cubic-bezier (0.4, 0.0, 0.2, 1.0)](https://cubic-bezier.com /#.4,0,.2,1), recorded as fastOutSlowIn
。
when rect-tween-type
When set to the following type,The default interpolation method is for Rect
of LTWH
Linear interpolation, respectively。
- [linear](https://cubic-bezier.com /#0,0,1,1)
- elasticIn
- elasticOut
- elasticInOut
- BounceIn
- bounceOut
- bounceInOut
- [cubic-bezier (x1, y1, x2, y2)](https://cubic-bezier.com /#.17,.67,.83,.67)
In addition,rect-tween-type
Also supports two special classes of enumeration values for which the animation curve is still fastOutSlowIn
, but the interpolation method is different, the trajectory is an arc.
- Materialrectarc: Rectangular Diagonal Animation
- materialRectCenterArc:[Radial animation](https://web.archive.org/web/20180223140424/https://Material.io /guidelines/motion/transforming-material.html#)
# Working principle
Below with push
Process as an example of the various stages of shared element animation.
Note: Actually during the animation share-element
The nodes themselves do not animate; they move their children.
# Before the animation begins
Target page not yet rendered, created on top of all pages overlay
Layer, the leap object will be in the overlay
Layer for animation.
# Animation Start Time
call wx.navigateTo
Animation is triggered when a new page is pushed,progress = 0
The following actions occur at the moment
- Target header frame rendering, the frame calculates the target
share-element
Node location size. - source
share-element
The node is off the screen (not displayed). - Will target
share-element
Node moveoverlay
Layer, as a leaping object, the position and size of the homologousshare-element
Node.
# During the animation
According to the specified interpolation mode and the animation curve, the target share-element
in overlay
Layer animates, transitioning from the start to the end position.
# Animation End Time
progress = 1
Time to aim. share-element
from overlay
Layer moves to the destination page and appears at the destination location.
# Note
Skyline
versionshare-element
No need to combinepage-container
use- to
share-element
Component Settingspadding
、justify-content
Styles that affect the layout of child nodes will not take effect - Can be combined with the page life cycle onRouteDone Do some state recovery at the time of route completion
# Q & A
# Q1: Set up the same Key, but do not see the leap animation
The shared element animation needs to ensure that the first frame of the next page is created share-element
Node, and set the Key is used to calculate the target location.
If it is through setData
Set, may miss the first frame. In this case, you can use Component The constructor constructs the next page, as long as the component attached
Before the life cycle (including) through setData
Set it up, it will render in the first frame.
# Q2: During the leap, the child nodes do not follow the amplification/narrow
During the animation process, the size and position of the leap container will change continuously, and if the children want to adapt to the change, they need to use the percentage layout instead of writing a fixed width and height.
<!-- Because of the sub view Fixed size, only the position changes during the leap, the size remains the same -->
<share-element key="portrait">
<view style="width: 50px height: 50px"></view>
</share-element>
<!-- Because of the sub view Set as large as the parent node, position and size will change during the leap -->
<share-element key="portrait" style="width: 50px height: 50px">
<view style="width: 100% height: 100%"></view>
</share-element>
# Q3: many share-element Animate together, covering the hierarchy issues
The Leap Thing in overlay
Layers are animated, with layers above all pages. Leaps and bounds in the order they are defined in the page component treeDFS
Traversal), the later the higher the level.
# Q4: Return animation not seen when custom route gesture returns
The components must first be set transition-on-gesture=true
Property. While the custom route gesture returns, only the call to the startUserGesture
Interface before the shared element animation is triggered.
# Q5: The Relationship between Shared Element Animation and Route Animation
Shared elements start and end with the page route animation. If you set the page entry curve for the custom route and rect-tween-type
Consistent, then onFrame
Returned progress
Values are also associated with PrimaryAnimation.value
Values are always consistent.
# Example usage
# Basic usage
Product List Page
<block wx:for="{{list}}" wx:key="id">
<share-element key="box" transition-on-gesture>
<image
src="{{src}}"
mode="aspectFill"
/>
</share-element>
</block>
Product Detail Page
<share-element key="box" transition-on-gesture>
<image
src="{{src}}"
mode="aspectFit"
/>
</share-element>
Can experience the effect in the developer tools, here need to pay attention to the image mode
Different effects.
# Advanced usage
To imitate WeChat Moments picture preview zoom function, for example, introduced through the frame callback to solve the picture mode
Different problems caused by the jump. Related functions have been encapsulated into aniamted-image
Component, the developer can modify it on the basis of which.
Here is a brief introduction to the core ideas:
- Always with
list
pageshare-element
For Flying Objects - adopt
on - frame
Overwrite the position size of the leap container so that it is fulloverlay
layer - Determine the position size of the starting and ending containers based on the actual space occupied by the picture, rather than
share-element
The space occupied by nodes - Use thumbnails during the leap, and replace the HD image after downloading.
The default calculation is to share-element
Nodes occupy the space to determine the beginning and end position, will produce jump.
The actual space occupied by the picture to determine the beginning and end position, always using a single mode
Effect, will not produce a jump.
Use the latest nightly
Tool Preview, Mobile Android 8.0.33 Version.