为什么程序员之间差距那么大? 环球热闻

2023-04-21 06:05:25 来源:微信开发者

青铜程序员

自定义切换效果真的那么难?


(资料图片)

难道没有其他更快捷的方法?

如果仅需要通过默认路由实现左右切换的页面效果,开发者写 3 行代码即可实现。

// 默认路由方式wx.navigateTo({url:"pageB"})

默认路由页面切换效果

但是如果想要实现更多样的页面切换效果,如下沉式切换等,开发者单独构建单页,需要更庞大的工作量。

是否有更加便捷的方法?继续看看高段位程序员如何高效解决这个问题

钻石程序员

自定义路由是什么?

它能够实现什么效果?

现在来看看

下沉式页面切换效果

上面展示的下沉式页面切换效果通过 自定义路由即可实现;同时 配合 可快速实现不同的动画曲线,视觉效果更丰富。

既然自定义页面切换有着更贴近原生的动画效果,开发者如何快速实现呢?

1、声明自定义路由

无论开发者使用何种自定义页面切换效果,开发者都需要先声明路由:

通过 wx.router.addRouteBuilder (以下统称 builder 函数)声明自定义路由

页面跳转新增routeType 参数,值为上一步的命名

点击查看代码

// 1、声明自定义路由 HalfScreenDialogwx.router.addRouteBuilder(\"HalfScreenDialog\"HalfScreenDialogRouteBuilder)// 2、页面跳转采用 HalfScreenDialog 路由wx.nagivateTo({url:"pageB",routeType:"HalfScreenDialog"})

其中 builder 函数的主要作用如下:

定义页面推入动画:结合推入进度、推入状态等参数,由开发者自定义计算得来

定义页面被推出动画:结合被推出进度、被推出状态等参数,由开发者自定义计算得来

2、分析页面切换方式

不同页面切换效果的推入与被推出状态有差异。以下沉式页面切换效果为例:页面切换过程中,新旧页面进行不同的过程

新页面:即页面 B 半屏打开

旧页面:即页面 A 下沉隐藏

3、实现页面切换过程

新旧页面分别进行不同的过程,需要使用 builder 函数中对应的参数,实现当前页面从 0 到 1 的打开 / 关闭进度:

新页面:使用 primaryAnimation 参数

旧页面:使用 secondaryAnimation 参数

然后在对应的 handlePrimaryAnimation / handleSecondaryAnimation 回调函数中,实现页面打开过程所需要的动画效果,如页面高度、圆角、与顶部的偏移距离等。

点击查看代码

// 新页面:页面 B 半屏打开const handlePrimaryAnimation = () => {"worklet"// primaryAnimation 为 builder 函数的参数,表示当前页面从 0 - 1 展示动画的进度// primaryAnimation 为 sharedValue 类型,当 primaryAnimation 变化时,这个函数就会被执行let t = primaryAnimation.value// 非手势触发时,可以通过动画曲线 easeInToLinear 来改变动画的进度值// worklet 支持了常见的动画缓动函数,开发者可以根据业务需求实现需要的页面切换动画效果if (!userGestureInProgress.value) {t = wx.worklet.Easing.bezier(0.35, 0.91, 0.33, 0.97).factory()(t)}const top = 0.12 // 半屏页面距离顶部的距离比例const selfHeight = (1 - top) * screenHeight // 半屏页面高度const marginTop = top * screenHeight // 半屏页面距离顶部的距离const translateY = selfHeight * (1 - t) // 页面动画过程中的纵向偏移值// 返回 AnimatedStyle,改变页面展示return {marginTop: `${marginTop}px`,borderRadius: "10px",height: `${selfHeight}px`,transform: `translateY(${translateY}px)`,}}// 旧页面:页面 A 页面下沉const handleSecondaryAnimation = () => {"worklet"// secondaryAnimation 为 builder 函数的参数,表示下一个页面推入时,当前页面从 1 - 0 隐藏动画的进度// secondaryAnimation 为 sharedValue 类型,当 secondaryAnimation 变化时,这个函数就会被执行let t = secondaryAnimation.value// 非手势触发时,可以通过动画曲线 fastOutSlowIn 来改变动画的进度值if (!userGestureInProgress.value) {t = wx.worklet.Easing.bezier(0.4, 0.0, 0.2, 1.0).factory()(t)}const top = 0.1 // 页面距离顶部的距离比例const scaleRatio = 0.08 // 缩放比例const translateY = screenHeight * (top - 0.5 * scaleRatio) * t // 页面动画过程中的纵向偏移值const scale = 1 - scaleRatio * t // 缩放过程中的比例const radius = 12 * t // 页面圆角// 返回 AnimatedStyle,改变页面展示return {borderRadius: `${radius}px`,transform: `translateY(${translateY}px) scale(${scale})`,}}

4、完成页面切换效果

成功调用 builder 函数后,开发者完成以下步骤即可实现整个自定义页面切换效果:

包装并且注册 builder 函数

指定路由类型实现返回效果

点击查看代码

// 注册 builder 函数wx.router.addRouteBuilder(\"HalfScreenDialog\", HalfScreenDialogRouteBuilder)wx.router.addRouteBuilder(\"ScaleTransition\", ScaleTransitionRouteBuilder)// 实现页面 B 的 builder 函数:页面打开时半屏打开const HalfScreenDialogRouteBuilder = ({primaryAnimation}) => {return {handlePrimaryAnimation // 页面 B 打开时的动画,上文中实现的 handlePrimaryAnimation 函数}}// 实现页面 A 的 builder 函数:下一个页面打开时,当前页面下沉const ScaleTransitionRouteBuilder = ({primaryAnimation,secondaryAnimation}) => {return {handlePrimaryAnimation, // 页面 A 打开时的动画handleSecondaryAnimation // 页面 B 隐藏时的动画,上文中实现的 handleSecondaryAnimation 函数}}// home.js// 首页打开页面 A,wx.navigateTo({url: "pageA",routeType: "ScaleTransition",})// page.js// 页面 A 打开页面 Bwx.navigateTo({url: "pageB",routeType: "HalfScreenDialog",})

王者程序员

想要更丝滑的页面切换效果?

结合手势组件试试看吧

提及到半屏页面可通过手势组件实现上下丝滑打开 / 关闭。

在下沉式页面效果的基础上,开发者同样能够在外层组件上嵌套 horizontal-drag-gesture-handler 即可实现向右滑动关闭半屏页面的效果。

点击查看代码

// .wxml// .js// 根据手势状态改变页面展示状态// this.customRouteContext 中包含当前页面定义路由 builder 时的全部变量handleHorizontalDrag(gestureEvent) {\"worklet\";if (gestureEvent.state === GestureState.BEGIN) {// 触摸开始const { startUserGesture } = this.customRouteContext;startUserGesture();} else if (gestureEvent.state === GestureState.ACTIVE) {// 触摸中,实现跟随手指拖动页面效果const delta = gestureEvent.deltaX / windowWidth;const { primaryAnimation } = this.customRouteContext;const newVal = primaryAnimation.value - delta;primaryAnimation.value = clamp(newVal, 0.0, 1.0);} else if (gestureEvent.state === GestureState.END) {// 触摸结束const { stopUserGesture, didPop } = this.customRouteContext;...didPop(); // 退出页面调用stopUserGesture(); // 结束必须调用} else if (gestureEvent.state === GestureState.CANCELLED) {// 触摸取消}}

随着小程序承载越来越多的功能,页面交互效果对用户体验也越发重要。开发者可以通过自定义路由开发定制化的页面切换效果,实现贴近原生的交互体验。

小程序渲染框架致力于提供更多实用、高效的渲染能力,长期支持开发者的渲染需求。开发者可关注获取更多最新信息或者访问 发现更多最佳实践。

如有更多接口相关问题,可点击发帖反馈,技术专员将为大家解答及进行深度交流。

关键词:

Copyright   2015-2032 华西社团网 版权所有  备案号:京ICP备2022016840号-35  联系邮箱: 920 891 263@qq.com