# 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
pushStage: Throughwx.navigateTobyAGet intoB, saidAThe source page (frompage),BFor the target page (topage)popStage: Throughwx.navigateBackbyBreturnA♪ at this pointBFor the source page (frompage),AFor the target page (toPage)
# 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 AdoptionBPageshare-elementComponents to make the leap, set the propertiesshuttle-on-push=fromCan be switched toAPages.pop stage: Default AdoptionAPageshare-elementComponent, Set Propertiesshuttle-on-pop=fromCan be switched toBPages.
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-elementNode location size. - source
share-elementThe node is off the screen (not displayed). - Will target
share-elementNode moveoverlayLayer, as a leaping object, the position and size of the homologousshare-elementNode.
# 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
Skylineversionshare-elementNo need to combinepage-containeruse- to
share-elementComponent Settingspadding、justify-contentStyles 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
listpageshare-elementFor Flying Objects - adopt
on - frameOverwrite the position size of the leap container so that it is fulloverlaylayer - Determine the position size of the starting and ending containers based on the actual space occupied by the picture, rather than
share-elementThe 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.
Sample code snippet - Advanced
