1.实现效果
2.实现原理
page-container
page-container
小程序如果在页面内进行复杂的界面设计(如在页面内弹出半屏的弹窗、在页面内加载一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件。 为此提供“假页”容器组件,效果类似于 popup 弹出层,页面内存在该容器时,当用户进行返回操作,关闭该容器不关闭页面。返回操作包括三种情形,右滑手势、安卓物理返回键和调用 navigateBack 接口。
- tip: 当前页面最多只有 1 个容器,若已存在容器的情况下,无法增加新的容器。
- tip: wx.navigateBack 无法在页面栈顶调用,此时没有上一级页面 示例代码。
eg:
<page-container show="{{show}}" round="{{round}}" overlay="{{overlay}}" duration="{{duration}}" position="{{position}}" close-on-slide-down="{{false}}" bindbeforeenter="onBeforeEnter" bindenter="onEnter" bindafterenter="onAfterEnter" bindbeforeleave="onBeforeLeave" bindleave="onLeave" bindafterleave="onAfterLeave" bindclickoverlay="onClickOverlay" custom-style="{{customStyle}}" overlay-style="{{overlayStyle}}">
</page-container>
share-element
共享元素是一种动画形式,类似于 flutter Hero动画,表现为元素像是在页面间穿越一样。该组件需与 page-container 组件结合使用。
使用时需在当前页放置 share-element 组件,同时在 page-container 容器中放置对应的 share-element 组件,对应关系通过属性值 key 映射。当设置 page-container 显示时,transform 属性为 true 的共享元素会产生动画。当前页面容器退出时,会产生返回动画。
<share-element class="avatar" duration="{{duration}}" key="avatar" transform><image style="width: 40px;border-radius: 50%;" mode="widthFix" src="{{contact.img}}" /></share-element><share-element class="name" key="name" duration="{{duration}}" transform>{{contact.name}}</share-element>
key值映射:
page-container中的share-element相绑定。
3.缩放效果
实现一个缩放效果,将元素大小放到share-element标签上。
4.实现代码
<view><view class="screen screen1"><block wx:for="{{contacts}}" wx:key="id" wx:for-item="contact"><view class="contact" bindtap="showNext" data-idx="{{index}}"><share-element class="avatar" key="avatar" duration="{{duration}}" transform="{{transformIdx === index}}"><image mode="widthFix" src="{{contact.img}}"></image></share-element><share-element duration="{{duration}}" class="name" key="name" transform="{{transformIdx === index}}">{{contact.name}}</share-element><view class="list"><view>手机号: {{contact.phone}}</view><view>邮箱: {{contact.email}}</view></view></view></block></view>
</view>
<page-container show="{{show}}" overlay="{{overlay}}" close-on-slide-down duration="{{duration}}" position="{{position}}" bindbeforeenter="onBeforeEnter" bindenter="onEnter" bindafterenter="onAfterEnter" bindbeforeleave="onBeforeLeave" bindleave="onLeave" bindafterleave="onAfterLeave" bindclickoverlay="onClickOverlay"><view class="screen screen2"><view class="contact"><share-element class="avatar ava_pa" duration="{{duration}}" key="avatar" transform><image mode="widthFix" src="{{contact.img}}" /></share-element><share-element class="name" key="name" duration="{{duration}}" transform>{{contact.name}}</share-element><view class="paragraph {{show ? 'enter' : ''}}">共享元素是一种动画形式,类似于 flutter Hero动画,表现为元素像是在页面间穿越一样。该组件需与 page-container 组件结合使用。使用时需在当前页放置 share-element 组件,同时在 page-container 容器中放置对应的 share-element 组件,对应关系通过属性值 key 映射。当设置 page-container 显示时,transform 属性为 true 的共享元素会产生动画。当前页面容器退出时,会产生返回动画。<view></view>小程序如果在页面内进行复杂的界面设计(如在页面内弹出半屏的弹窗、在页面内加载一个全屏的子页面等),用户进行返回操作会直接离开当前页面,不符合用户预期,预期应为关闭当前弹出的组件。 为此提供“假页”容器组件,效果类似于 popup 弹出层,页面内存在该容器时,当用户进行返回操作,关闭该容器不关闭页面。返回操作包括三种情形,右滑手势、安卓物理返回键和调用 navigateBack 接口。</view><button class="screen2-button" bindtap="showPrev" hidden="{{!show}}" hover-class="none">Click Me</button></view></view>
</page-container>
/* pages/jsCase/pageCon/index.wxss */
page {color : #333;background-color: #fff;overflow : hidden;
}button {border-radius : 60rpx;border : 0 solid orange;background-color : orange;color : #fff;font-size : 120%;padding : 8px 16px;outline-width : 0;-webkit-appearance: none;box-shadow : 0 8px 17px rgba(0, 0, 0, 0.2);
}.screen {position : absolute;top : 0;bottom : 0;left : 0;right : 0;padding : 16px;-webkit-overflow-scrolling: touch;
}.contact {position : relative;padding : 16px;background-color: #fff;width : 100%;height : 100%;box-sizing : border-box;
}.avatar {position : absolute;top : 16px;left : 16px;font-size : 0;border-radius: 50%;width : 160rpx;height : 160rpx;overflow : hidden;
}.avatar image {width : 100%;height: 100%;
}.ava_pa {width : 80rpx;height: 80rpx;
}.ava_pa image {width : 100%;height: 100%;
}.name {height : 65px;font-size : 2em;font-weight: bold;text-align : center;margin : 10px 0;
}.list {padding-top : 8px;padding-left: 32px;
}.screen1 {overflow-y: scroll;padding : 0;
}.screen1 .contact {margin : 16px;height : auto;width : auto;box-shadow : 0 2px 5px 0 rgba(0, 0, 0, 0.2);border-radius: 20rpx;overflow : hidden;
}.screen2-button {display: block;margin : 24px auto;
}.paragraph {-webkit-transition: transform ease-in-out 300ms;transition : transform ease-in-out 300ms;-webkit-transform : scale(0.6);transform : scale(0.6);color : #999;font-size : 27rpx;
}.enter.paragraph {transform: none;
}
Page({/*** 页面的初始数据*/data: {contacts: [{id: 1,name: 'susu1',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 2,name: 'susu2',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 3,name: 'susu3',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 4,name: 'susu4',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 5,name: 'susu5',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 6,name: 'susu6',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 7,name: 'susu7',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'},{id: 8,name: 'susu8',img: 'https://i.postimg.cc/mgsKJGLw/susu1.jpg',phone: '0101 123456',mobile: '0770 123456',email: 'frank@emailionicsorter.com'}],contact: {},transformIdx: 0,position: 'center',duration: 300,show: false,overlay: false},onLoad: function (options) {this.setData({contact: this.data.contacts[0]})},showNext(e) {const idx = e.currentTarget.dataset.idx;this.setData({show: true,contact: this.data.contacts[idx],transformIdx: idx})},showPrev() {this.setData({show: false})},onBeforeEnter(res) {console.log(res)},onEnter(res) {console.log(res)},onAfterEnter(res) {console.log(res)},onBeforeLeave(res) {console.log(res)},onLeave(res) {console.log(res)},onAfterLeave(res) {console.log(res)},
})