应用场景

仅仅应用于单页应用的滑动操作,用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单页中的滑动优化的更多相关文章

  1. 新手教程:不写JS,在MIP页中实现异步加载数据

    从需求谈起:在 MIP 页中异步加载数据 MIP(移动网页加速器) 的 加速原理 除了靠谱的 MIP-Cache CDN 加速外,最值得一提的就是组件系统.所有 JS 交互都需要使用 MIP 组件实现 ...

  2. 记H5单页遇到的几个ios兼容问题

    最近写一个H5活动页,安卓里的表现很不错,写下来很少出现兼容性问题,ios就不一样了,好多问题都出现在ios上(手动狗头)

  3. 前后端分离最佳实现,使用Nuxt.js快速搭建单页SSR应用

    通常我们搭建ssr应用需要自己选择多个组件集成到一起 webpack babel loaders router server-render 各种入口配置等 如果是基于vue+vuex+vue-rout ...

  4. 偏前端 - div+mui+vue.js 制作问卷调查单页 ——题目答案由后台随机给出10道

    封装的ajax获取数据.代码可能有些是多余的,没做处理!!点击提交后有弹框,在这里我没有贴出来.第一次写博客,这些也是别人教我的,经理解后,贴出来于大家分享 ——html—— <script t ...

  5. 浅谈单页应用和多页应用——Vue.js向

    浅谈单页应用和多页应用--Vue.js向 多页面 多页面应用:每次页面跳转,后台都会返回一个新的HTML文档,就是多页面应用. 在以往传统开发的应用(网站)大多都是多页面应用,路由由后端来写. 页面跳 ...

  6. HTML5单页框架View.js介绍

    什么是单页应用单页应用,是指将用户视觉上的多个页面在技术上使用一个载体来实现的应用. 换句话来讲,用户视觉效果,与技术实现的载体,并不是一定要一一对应的.采取哪种技术方案,取决于产品设计.技术组成以及 ...

  7. 纯css、js 的H5页面对接echarts

    做项目时,会遇到一些零碎的技术点.记录下来以防忘记 需求:做可视化界面,但是需要兼容ie8,需要用纯css.js 的H5页面对接echarts,下面为效果图(带定时器循环显示tooltip). 实现方 ...

  8. 前端视频直播技术总结及video.js在h5页面中的应用

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/12557070.html,多谢,=.=~ (如果对你有帮助的话请帮我点个赞啦) 目前有一个需求是在 ...

  9. 详细解剖大型H5单页面应用的核心技术点

    项目 Xut.js 阐述下开发中一个比较核心的优化技术点,这是一套平台代码,并非某一个插件功能或者框架可以直接拿来使用,核心代码大概是6万行左右(不包含任何插件) .这也并非一个开源项目,不能商业使用 ...

随机推荐

  1. 第46章:MongoDB-监控应用状态

    ① MongoDB监控  1 db.serverStatus() 查看实例运行状态(内存使用.锁.用户连接等信息) 通过比对前后快照进行性能分析 "connections" # 当 ...

  2. java中super(),与构造方法链(constructor chaining)

    public class Apple extends Fruit { } class Fruit{ public Fruit(String name){ System.out.println(&quo ...

  3. 用chrome模拟微信浏览器访问页面

    有的网页通过限制 user agent  来达到禁止在微信浏览器以外的地方访问,我们通过chrome修改user agent即可破解. CHROME浏览器,进入开发者模式 切换到手机浏览模板 打开 N ...

  4. Codeforces Round #485 (Div. 2) D. Fair

    Codeforces Round #485 (Div. 2) D. Fair 题目连接: http://codeforces.com/contest/987/problem/D Description ...

  5. numpy 库简单使用

    numpy 库简单使用 一.numpy库简介 Python标准库中提供了一个array类型,用于保存数组类型的数据,然而这个类型不支持多维数据,不适合数值运算.作为Python的第三方库numpy便有 ...

  6. android-音量管理

    推荐简书夕月风: 前两个主要设计音频建设置流程. 一.https://www.jianshu.com/p/a48fc2c830da 二.https://www.jianshu.com/p/892761 ...

  7. Python 日常技巧

    jupyter notebook 本地开启jupyter,画图需打开限制:jupyter notebook --NotebookApp.iopub_data_rate_limit=2147483647 ...

  8. 英语演讲稿——Get Along with Fear

    Hi. My name is Zhang Meng. I’m an engineer at Keysight. Today I’m not going to introduce my birthpla ...

  9. iOS开发之ReactiveCocoa下的MVVM

    最近工作比较忙,但还是出来更新博客了,今天给大家分享一些ReactiveCocoa以及MVVM的一些东西,干活还是比较足的.在之前发表过一篇博文,名字叫做<iOS开发之浅谈MVVM的架构设计与团 ...

  10. 【病毒分析】对一个vbs脚本病毒的分析

    [病毒分析]对一个vbs脚本病毒的分析 本文来源:i春秋社区-分享你的技术,为安全加点温度 一.前言 病毒课老师丢给我们一份加密过的vbs脚本病毒的代码去尝试分析,这里把分析过程发出来,供大家参考,如 ...