越来越便捷的开发者工具正在
降低开发门]槛,提升开发效率
让每个人有机会快速接收技术
但对程序员的质疑也更多了
未来不需要程序员了!
低代码能够取代程序员
程序员门槛也太低了吧? !
我我我
写代码其实也没啥难度嘛
但是!
程序员也不是随随便便就能胜任的
不同程序员的差距可不是一般大包
不信?
今天来看看不同段位的程序员操作看看程序员的天花板究竟有多高
青铜程序员
开发小弟,我们上线评论页面,今天记得加,上切换效果哟
需求太简单,3行代码搞定它
但用户反映左右页面切换的体验一般。如果是下沉式切换,动画效果更好
自定义切换效果需要重新写好多代码,今天肯定干不完呀......
自定义切换效果真的那么难?
难道没有其他更快捷的方法?
如果仅需要通过默认路由实现左右切换的页面效果,开发者写 3 行代码即可实现。
但是如果想要实现更多样的页面切换效果,如下沉式切换等,开发者单独构建单页,需要更庞大的工作量。
是否有更加便捷的方法?继续看看高段位程序员如何高效解决这个问题
钻石程序员
不用重新写单页.....自定义路由就能实现多种页面切换效果
代码更少,自定义程度更高
你肯定没有认真看官方更新日志
瑞思拜大牛!马.上回去补知识
自定义路由是什么?
它能够实现什么效果?
现在来看看
既然自定义页面切换有着更贴近原生的动画效果,开发者如何快速实现呢?
1、声明自定义路由
无论开发者使用何种自定义页面切换效果,开发者都需要先声明路由:
2、分析页面切换方式
不同页面切换效果的推入与被推出状态有差异。以下沉式页面切换效果为例:页面切换过程中,新旧页面进行不同的过程
新页面:即页面 B 半屏打开
旧页面:即页面 A 下沉隐藏
3、实现页面切换过程
新旧页面分别进行不同的过程,需要使用 builder 函数中对应的参数,实现当前页面从 0 到 1 的打开 / 关闭进度:
然后在对应的 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 打开页面 B
wx.navigateTo({
url: 'pageB',
routeType: 'HalfScreenDialog',
})
王者程序员
Wow!自定义路由真的好用!
各种页面切换效果都能快速搞定
这样子就满足了?页面切换效果还可以更丝滑
还有更丝滑的操作方式?
还有更丝滑的操作方式?
上次提到小程序手势组件,结合自定义路由可以实现丝滑开关
还有这么妙的写法? !马上来写
想要更丝滑的页面切换效果?
结合手势组件试试看吧
在下沉式页面效果的基础上,开发者同样能够在外层组件上嵌套 horizontal-drag-gesture-handler 即可实现向右滑动关闭半屏页面的效果。
// .wxml
<horizontal-drag-gesture-handler onGestureEvent="handleHorizontalDrag">
<view class="gesture-back-area"></view>
<horizontal-drag-gesture-handler/>
// .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) {
// 触摸取消
}
}
随着小程序承载越来越多的功能,页面交互效果对用户体验也越发重要。开发者可以通过自定义路由开发定制化的页面切换效果,实现贴近原生的交互体验。
小程序渲染框架致力于提供更多实用、高效的渲染能力,长期支持开发者的渲染需求。开发者可关注 更新日志 获取更多最新信息或者访问 小程序示例 发现更多最佳实践。
如有更多接口相关问题,可点击 微信开放社区 发帖反馈,技术专员将为大家解答及进行深度交流。