1 | import { ComponentType } from 'react'
|
2 | import { StandardProps, CommonEventFunction } from './common'
|
3 | interface ShareElementProps extends StandardProps {
|
4 | /** 映射标记
|
5 | * @supported weapp
|
6 | * @deprecated 使用mapkey替换key
|
7 | */
|
8 | key?: string
|
9 | /** 映射标记
|
10 | * @supported weapp
|
11 | * @unique
|
12 | */
|
13 | mapkey?: string
|
14 | /** 映射标记
|
15 | * @supported alipay
|
16 | */
|
17 | name?: string
|
18 | /** 是否进行动画
|
19 | * @default false
|
20 | * @supported weapp, alipay
|
21 | */
|
22 | transform?: boolean
|
23 | /** 动画时长,单位毫秒
|
24 | * @default 300
|
25 | * @supported weapp, alipay
|
26 | */
|
27 | duration?: number
|
28 | /** css缓动函数
|
29 | * @default ease-out
|
30 | * @supported weapp, alipay
|
31 | */
|
32 | easingFunction?: string
|
33 | /** 手势返回时是否进行动画
|
34 | * @supported weapp
|
35 | * @default false
|
36 | */
|
37 | transitionOnGesture?: boolean
|
38 | /** 指定 push 阶段的飞跃物
|
39 | * @supported weapp
|
40 | * @default "to"
|
41 | */
|
42 | shuttleOnPush?: 'from' | 'to' | 'from' | 'to'
|
43 | /** 指定 pop 阶段的飞跃物
|
44 | * @supported weapp
|
45 | * @default "to"
|
46 | */
|
47 | shuttleOnPop?: string
|
48 | /** 动画插值曲线
|
49 | * @supported weapp
|
50 | * @default "materialRectArc"
|
51 | */
|
52 | rectTweenType?:
|
53 | | 'materialRectArc'
|
54 | | 'materialRectCenterArc'
|
55 | | 'linear'
|
56 | | 'elasticIn'
|
57 | | 'elasticOut'
|
58 | | 'elasticInOut'
|
59 | | 'bounceIn'
|
60 | | 'bounceOut'
|
61 | | 'bounceInOut'
|
62 | | 'cubic-bezier(x1,'
|
63 | /** 动画帧回调
|
64 | * @supported weapp
|
65 | */
|
66 | onFrame?: string
|
67 | }
|
68 | /** 共享元素
|
69 | *
|
70 | * 共享元素是一种动画形式,类似于 [`flutter Hero`](https://flutterchina.club/animations/hero-animations/) 动画,表现为元素像是在页面间穿越一样。该组件需与 [`PageContainer`](/docs/components/viewContainer/page-container) 组件结合使用。
|
71 | * 使用时需在当前页放置 `ShareElement` 组件,同时在 `PageContainer` 容器中放置对应的 `ShareElement` 组件,对应关系通过属性值 key 映射。当设置 `PageContainer` `显示时,transform` 属性为 `true` 的共享元素会产生动画。当前页面容器退出时,会产生返回动画。
|
72 | * @classification skyline
|
73 | * @supported weapp, alipay
|
74 | * @example_react
|
75 | * ```tsx
|
76 | * // index.js
|
77 | * import { useState, useCallback } from 'react'
|
78 | * import { View, Button, PageContainer, ShareElement } from '@tarojs/components'
|
79 | *
|
80 | * import './index.scss'
|
81 | *
|
82 | * const contacts = [
|
83 | * { id: 1, name: 'Frank', img: 'frank.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
84 | * { id: 2, name: 'Susan', img: 'susan.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
85 | * { id: 3, name: 'Emma', img: 'emma.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
86 | * { id: 4, name: 'Scott', img: 'scott.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
87 | * { id: 5, name: 'Bob', img: 'bob.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
88 | * { id: 6, name: 'Olivia', img: 'olivia.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
89 | * { id: 7, name: 'Anne', img: 'anne.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' },
|
90 | * { id: 8, name: 'sunny', img: 'olivia.png', phone: '0101 123456', mobile: '0770 123456', email: 'frank@emailionicsorter.com' }
|
91 | * ]
|
92 | *
|
93 | * export default function () {
|
94 | * const [show, setShow] = useState(false)
|
95 | * const [contact, setContact] = useState(contacts[0])
|
96 | * const [transformIdx, setTransformIdx] = useState(0)
|
97 | *
|
98 | * const onBeforeEnter = useCallback((res) => {
|
99 | * console.log('onBeforeEnter: ', res)
|
100 | * }, [])
|
101 | * const onEnter = useCallback((res) => {
|
102 | * console.log('onEnter: ', res)
|
103 | * }, [])
|
104 | * const onAfterEnter = useCallback((res) => {
|
105 | * console.log('onAfterEnter: ', res)
|
106 | * }, [])
|
107 | * const onBeforeLeave = useCallback((res) => {
|
108 | * console.log('onBeforeLeave: ', res)
|
109 | * }, [])
|
110 | * const onLeave = useCallback((res) => {
|
111 | * console.log('onLeave: ', res)
|
112 | * }, [])
|
113 | * const onAfterLeave = useCallback((res) => {
|
114 | * console.log('onAfterLeave: ', res)
|
115 | * }, [])
|
116 | *
|
117 | * const showNext = (e, index) => {
|
118 | * setShow(true)
|
119 | * setContact(contacts[index])
|
120 | * setTransformIdx(index)
|
121 | * }
|
122 | *
|
123 | * const showPrev = useCallback(() => {
|
124 | * setShow(false)
|
125 | * }, [])
|
126 | *
|
127 | * return (
|
128 | * <View>
|
129 | * <View className="screen screen1">
|
130 | * {
|
131 | * contacts.map((item, index) => (
|
132 | * <View key={item.id} className="contact" onClick={e => showNext(e, index)}>
|
133 | * <ShareElement duration={300} className="name" key="name" transform={transformIdx === index}>
|
134 | * {item.name}
|
135 | * </ShareElement>
|
136 | * <View className="list">
|
137 | * <View>Phone: {item.phone}</View>
|
138 | * <View>Mobile: {item.mobile}</View>
|
139 | * <View>Email: {item.email}</View>
|
140 | * </View>
|
141 | * </View>
|
142 | * ))
|
143 | * }
|
144 | * </View>
|
145 | * <PageContainer
|
146 | * show={show}
|
147 | * overlay={false}
|
148 | * closeOnSlideDown
|
149 | * duration={300}
|
150 | * position='center'
|
151 | * onBeforeEnter={onBeforeEnter}
|
152 | * onEnter={onEnter}
|
153 | * onAfterEnter={onAfterEnter}
|
154 | * onBeforeLeave={onBeforeLeave}
|
155 | * onLeave={onLeave}
|
156 | * onAfterLeave={onAfterLeave}
|
157 | * >
|
158 | * <View className="screen screen2">
|
159 | * <View className="contact">
|
160 | * <ShareElement className="name" key="name" duration={300} transform>
|
161 | * {contact.name}
|
162 | * </ShareElement>
|
163 | * <View className={`paragraph ${show ? 'enter' : ''}`}>
|
164 | * Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus nisl enim, sodales non augue efficitur, sagittis
|
165 | * varius neque. Fusce dolor turpis, maximus eu volutpat quis, pellentesque et ligula. Ut vehicula metus in nibh
|
166 | * mollis ornare. Etiam aliquam lacinia malesuada. Vestibulum dignissim mollis quam a tristique. Maecenas neque
|
167 | * mauris, malesuada vitae magna eu, congue consectetur risus. Etiam vitae pulvinar ex. Maecenas suscipit mi ac
|
168 | * imperdiet pretium. Aliquam velit mauris, euismod quis elementum sed, malesuada non dui. Nunc rutrum sagittis
|
169 | * ligula in dapibus. Cras suscipit ut augue eget mollis. Donec auctor feugiat ipsum id viverra. Vestibulum eu nisi
|
170 | * risus. Vestibulum eleifend dignissim.
|
171 | *
|
172 | * </View>
|
173 | * <Button className="screen2-button" onClick={showPrev} hidden={!show} hoverClass="none">Click Me</Button>
|
174 | * </View>
|
175 | * </View>
|
176 | * </PageContainer>
|
177 | * </View>
|
178 | * )
|
179 | * }
|
180 | * ```
|
181 | * ```scss
|
182 | * \/** index.scss *\/
|
183 | * page {
|
184 | * color: #333;
|
185 | * background-color: #ddd;
|
186 | * overflow: hidden;
|
187 | * }
|
188 | *
|
189 | * button {
|
190 | * border: 0 solid #0010ae;
|
191 | * background-color: #1f2afe;
|
192 | * color: #fff;
|
193 | * font-size: 120%;
|
194 | * padding: 8px 16px;
|
195 | * outline-width: 0;
|
196 | * -webkit-appearance: none;
|
197 | * box-shadow: 0 8px 17px rgba(0, 0, 0, 0.2);
|
198 | * }
|
199 | *
|
200 | * .screen {
|
201 | * position: absolute;
|
202 | * top: 0;
|
203 | * bottom: 0;
|
204 | * left: 0;
|
205 | * right: 0;
|
206 | * padding: 16px;
|
207 | * -webkit-overflow-scrolling: touch;
|
208 | * }
|
209 | *
|
210 | * .contact {
|
211 | * position: relative;
|
212 | * padding: 16px;
|
213 | * background-color: #fff;
|
214 | * width: 100%;
|
215 | * height: 100%;
|
216 | * box-sizing: border-box;
|
217 | * }
|
218 | *
|
219 | * .avatar {
|
220 | * position: absolute;
|
221 | * top: 16px;
|
222 | * left: 16px;
|
223 | * font-size: 0;
|
224 | * }
|
225 | *
|
226 | * .name {
|
227 | * height: 65px;
|
228 | * font-size: 2em;
|
229 | * font-weight: bold;
|
230 | * text-align: center;
|
231 | * margin: 10px 0;
|
232 | * }
|
233 | *
|
234 | * .list {
|
235 | * padding-top: 8px;
|
236 | * padding-left: 32px;
|
237 | * }
|
238 | *
|
239 | * .screen1 {
|
240 | * overflow-y: scroll;
|
241 | * padding: 0;
|
242 | * }
|
243 | *
|
244 | * .screen1 .contact {
|
245 | * margin: 16px;
|
246 | * height: auto;
|
247 | * width: auto;
|
248 | * box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.2);
|
249 | * }
|
250 | *
|
251 | * .screen2-button {
|
252 | * display: block;
|
253 | * margin: 24px auto;
|
254 | * }
|
255 | *
|
256 | * .paragraph {
|
257 | * -webkit-transition: transform ease-in-out 300ms;
|
258 | * transition: transform ease-in-out 300ms;
|
259 | * -webkit-transform: scale(0.6);
|
260 | * transform: scale(0.6);
|
261 | * }
|
262 | *
|
263 | * .enter.paragraph {
|
264 | * transform: none;
|
265 | * }
|
266 | * ```
|
267 | * @see https://developers.weixin.qq.com/miniprogram/dev/component/share-element.html
|
268 | */
|
269 | declare const ShareElement: ComponentType<ShareElementProps>
|
270 | export { ShareElement, ShareElementProps }
|