美文网首页让前端飞程序员技术干货
记录一下对swiper4.x.js在H5单页中的滑动优化

记录一下对swiper4.x.js在H5单页中的滑动优化

作者: 高坚果兄弟 | 来源:发表于2019-02-26 19:26 被阅读0次

应用场景

仅仅应用于单页应用的滑动操作,用swiper4.x接管页面的滚动操作。用来支持顶部和尾部的回弹效果,进一步来支持常见那种下拉刷新动画效果。不适用于轮播图那种应用场景。

虽然只是针对swiper4.x,但相关原理,在别的框架中也是有参考意义的。

出现的问题

一、惯性动画不会在触摸时停止

快速滑动页面,手离开屏幕时产生的惯性动画还在运行时,此时触摸屏幕,动画不会停止。导致连续快速滑动页面,看起来有跳来跳去的感觉。

二、快速滑动手势大概率识别成慢滑动手势

连续快速多滑几下,有那么1、2下明显能够感知到滑动惯性动画变慢的情景,给人的感觉就是滑动不流畅。

三、惯性动画时长不合理

不管是很慢的滑动,还是很快的滑动,惯性动画时长只能设置一个固定值。慢慢移动松手后也会有一个很长的动画,快速滑的时候动画又有点短,综合看起来给人很卡的感觉。

解决手段

除了第一个问题,另外两个问题不修改swiper4.x源码似乎无法克服。

一、解决惯性动画不会在触摸时停止的问题

滑动时手离开屏幕时产生的惯性动画是css动画,并未直接提供停止动画的方法。动画还在运行时如果触摸屏幕,不改源代码,那我们就监听一下touchStart事件。

setTranslate(translate)可以移除这个动画css,需要提供页面当前的滚动位置。用getTranslate()就行了:

这与通过属性mySwiper.translate 获取到的数值稍有不同,即使是在过渡时(animating)也能获取到,而后者精度较高

解决方案代码

//在touchStart事件中执行
mySwiper.setTranslate(mySwiper.getTranslate());

二、解决快速滑动手势大概率识别成慢滑动手势问题

这个必须修改源代码才能解决,问题出在计算惯性动画起始速度时的计算参数精度不足。

原代码

if (params.freeModeMomentum) {
        if (data.velocities.length > 1) {
          var lastMoveEvent = data.velocities.pop();
          var velocityEvent = data.velocities.pop(); //此处取值方式会导致精度不够

          var distance = lastMoveEvent.position - velocityEvent.position;
          var time = lastMoveEvent.time - velocityEvent.time;
          swiper.velocity = distance / time;
          swiper.velocity /= 2;

可以看出,他计算起始速度velocity参考的是onTouchMove最后记录的两个点,单纯取最后两个点是不可靠的,可能因为最后两次onTouchMove触发间隔比较长,导致计算出来的速度过低。从而导致偶尔会快速滑动但惯性效果是慢滑动的效果。

如果触发间隔很短,导致动画速度变快,变快了其实感知上并无区别。最要命的还是变慢,感觉很卡一样。

解决方案

一个很短的时间内,人的滑动方向不太可能会产生变化,但这个短时间内产生的滑动位移能够很好的代表手势结尾的滑动速度。

经过反复尝试,用100毫秒内的位移来计算惯性起始速度最好,100毫秒内,如果是快速滑动,会触发多次onTouchMove,计算出来的速度是很接近实际的手势速度。

问题的解决指向了100毫秒内的第一个点。解决代码:

if (params.freeModeMomentum) {
        if (data.velocities.length > 1) {
            //fix 惯性动画
            var velos=data.velocities;
            var firstEvent=velos[0];
            var lastMoveEvent = velos.pop();
            var velocityEvent =velos.pop();
            for(var i=velos.length-1;i>=0;i--){//找出100毫秒内的起始位置
                var velo=velos[i];
                if(lastMoveEvent.time-velo.time>100){
                    break;
                }
                velocityEvent=velo;
            }

          var distance = lastMoveEvent.position - velocityEvent.position;
          var time = lastMoveEvent.time - velocityEvent.time;
          swiper.velocity = distance / time;
          swiper.velocity /= 2;

三、解决惯性动画时长不合理问题

慢滑动时惯性应该很小,动画很短;快速滑动时惯性应该很大,动画很长。swiper4.x只能提供一个固定的惯性动画时长,不改源代码是解决不了的。

原代码在第二问代码下面一点点

var momentumDuration = 1000 * params.freeModeMomentumRatio; //写死了固定动画时长

优化动画

其实也简单,小的就小,大的就大,用初始速度velocity来做乘法运算即可达到效果。

var momentumDuration = Math.abs(swiper.velocity) * 1000 * params.freeModeMomentumRatio;

结果:比原代码好很多,但跟别的app里面的滑动还是区别蛮大,慢滑时还是太快了点。

App原生滑动动画,感知上是慢的更慢,快的更快。轻微滑动慢的要死,快速动一点点,飞快。

对数曲线!1-0范围蛮符合,缓的地方比线性的还缓,陡的地方奇陡无比。在上面优化的结果基础上用对数加持一下,效果非常不错。另外限定最长动画不超过3秒。

//取对数曲线优化一下0.5-1.5倍之间,慢的越慢,快的越快
momentumDuration*=-Math.log10(Math.min(0.3,Math.max(0.03,(3000-momentumDuration)/3000)));

解决方案代码

//根据初始速度来确定惯性动画时长
var momentumDuration = Math.min(3000,Math.abs(swiper.velocity) * 1000 * params.freeModeMomentumRatio);
//取对数曲线优化一下0.5-1.5倍之间,慢的越慢,快的越快
momentumDuration*=-Math.log10(Math.min(0.3,Math.max(0.03,(3000-momentumDuration)/3000)));
momentumDuration=Math.min(3000,momentumDuration);

最终结果

应用swiper4.x修改后的单页滚动效果,已经很接近App的滚动效果,虽然还是会有些细微的抖动卡顿感,但要做到完全和App一样的流畅效果,估计蛮难,当前算是已经蛮优了。

还是iscroll省心些,但已经上了swiper4.x这条船了就算了,迁移过来又迁移过去白折腾。

改良后的滚动效果,目前[2019-02-27]号以后可以到 https://jiebian.life/start/xcx/tool_jieri 体验(这个时间之前新版本应该还没有上线),小程序和H5共用的页面。

相关文章

  • 记录一下对swiper4.x.js在H5单页中的滑动优化

    应用场景 仅仅应用于单页应用的滑动操作,用swiper4.x接管页面的滚动操作。用来支持顶部和尾部的回弹效果,进一...

  • H5页面在app端滑动,显示问题

    H5页面在IOS上滑动问题 IOS本身有个特性为弹性滑动,如果IOSAPP开启此功能,会造成H5页面中,底部固定定...

  • css篇

    文字在页面中居中 非固定高度在父元素中居中 文字单行隐藏 文字多行隐藏 x轴滑动查看 h5页面在iphone下滑动...

  • UIWebView新的URL注入JSContext对象时机问题

    H5一般分为单页应用和多页面应用 H5单页面 在H5单页面中注入JSContext可在UIWebViewDeleg...

  • h5报名页性能优化总结

    最近做了报名页的第三期,就顺手对该项目进行了一些优化。先看h5报名页优化前后性能的对比吧: 。优化前首屏的秒出率大...

  • webpack前端编译优化

    放开公司其他单页应用的项目不说,在我们快速迭代的app中,内嵌了很多h5页面,这些页面在不同的业务线中,也没有任何...

  • iOS与H5页面的简单交互

    简单的记录一下之前开发中用到的与H5页面的简单交互 1.点击H5页面上的按钮来进行跳转操作或者在应用内的操作 首先...

  • HTML移动端 实现刻度尺效果

    前言 在薄荷app的用户信息页看到在记录身高时,利用左右滑动刻度尺来取值。原本以为是h5实现,但上网搜索后并没有找...

  • 微信h5支付流程图

    一、H5页面在app环境中做微信支付 二、h5页面在浏览器环境中做h5支付

  • 关于APP的滑动卡顿性能优化

    看过很多技术贴,关于app的优化各家有各家的妙招,以此文记录自己优化的心得体会,及简单的对优化的理解。 就滑动控件...

网友评论

    本文标题:记录一下对swiper4.x.js在H5单页中的滑动优化

    本文链接:https://www.haomeiwen.com/subject/mthzyqtx.html