摘要:此时需要判断当前位置是否大于或者小于,若超过这个极限值需要重设目标位移及帧位移,使其在极限值内。判断第二次滑动是否与第一次不同方向,若不同向需重置上次帧位移为。以免上次帧位移太大影响移动方向。
本文由云+社区发表
最近的一个活动页面需要做一个可以左右滑动的抽签效果,故通过用css的transform属性和js结合来模拟可以无限滚动的效果。
先上效果:
demo地址:https://kiroroyoyo.github.io/cardTransform/index.html
结构:卡片分前后两排,每列插入10个div结点,以便做左右位移效果。
样式:设置每一列都恰好好在中间位置(或中间位置附近),如下所示。
a. 前排(cardFrond)相对于视口的初始位置(left:-255.5%;):
b. 后排(backFrond)相对于视口的初始位置(left:-228.3%;):
由于这里的停止位置是固定的,前排永远是当前卡片相对于视口居中,后排永远是两个卡片相对于视口居中,且每个卡片是一样的,所以当卡片列表向前或向右移动到一个目标位置时,都将列表重置为初始位置继续滚动。如下图以前排卡片为例:
所以当滚动停止后会统一将列表样式设置为transform: translateX(0)。而对于用户这一操作是无感知的,认为已经滑动到了新的位置。
a. 目标位移与帧位移
为了做出滑动后到停留位置的缓动效果,所以当用户左右滑动屏幕时,会记录滑动距离,计算出卡片该到的目标位移位置,目标位移位置是有规则的,因为这里有10张卡片均分宽度,位置必须是(100%/10)的整数倍,例如-40%、-30%、……40%,这样才能保证目标位置与初始位置相重合。
目标位移代码片段
onDocumentMouseUp : function(e){
//如果是点击事件 不设置移动
if (!this.fingerTouch)
return;
this.moveDirect = this.lon > 0 ? 1 : -1;
this.transNum = this.lon/10 + this.moveDirect;
this.lon = Math.round(this.transNum) * 10;
this.fingerTouch = false;
}
记录了目标位移后,每一帧会以一定的帧位移不断靠近目标位移,使其在手指离开屏幕时仍有慢慢滑动到目标位置的缓动效果。此时需要判断当前位置是否大于40%或者小于-40%,若超过这个极限值需要重设目标位移及帧位移,使其在极限值内。
animate: function(){
this.prePos += (this.lon - this.prePos) * 0.1;
if (this.prePos > 40) {
this.lon = this.lon - 40;
this.prePos = this.prePos - 40;
}else if (this.prePos < -40) {
this.lon = this.lon + 40;
this.prePos = this.prePos + 40;
}
//判断是否到达了目标位置
if (Math.abs(this.prePos - this.lon) < 0.01 && Math.abs(this.lon) > 0.01 && (!this.fingerTouch))
{
this.ani_move = false;
this.prePos = 0;
this.frondCard.style = "transform: translateX("+ this.prePos +"%)";
this.backCard.style = "transform: translateX("+ this.prePos +"%)";
}else{
this.frondCard.style = "transform: translateX("+ this.prePos +"%)";
this.backCard.style = "transform: translateX("+ (-this.prePos) +"%)";
requestAnimationFrame(this.animate.bind(this));
}
},
b. 连续滑动判断
当在上次滑动动画还未播放结束时用户又进行了第二次滑动时,需要执行一下操作:
1). 判断滑动时机处于上次滑动手指已离开屏幕但动画还未结束,此时需要记录两个flag,一个是ani_move,记录动画是否仍在进行,fingerTouch记录手指是否停留屏幕。
2). 判断第二次滑动是否与第一次不同方向,若不同向需重置上次帧位移为0。以免上次帧位移太大影响移动方向。
1)与2)代码片段:
if( this.ani_move && this.fingerTouch == false) {
// 判断是否不同向
if (((e.clientX - prex) > 0 ? 1: -1) == -this.moveDirect ) {
this.lon = 0;
this.prePos = 0;
this.moveDirect = -this.moveDirect;
}
}
3). 取消第二次滑动时的动画播放和位移重置
// 若是上次动画未结束不需要再次启动动画和重置目标位移
if( this.ani_move && this.fingerTouch == false) {
}
else {
this.lon = 0;
cardAnimate.animate();
}
目前这个滑动效果只能针对卡片相同,停留位置固定的情况,因为需要做到位置重合。使用css transform来做无限滚动的效果,可以避免改变dom结点带来的页面重新布局。
下图是chrome cpu6倍减速调试效果,没有触发layout,FPS基本维持在60左右。
代码地址:
https://github.com/kiroroyoyo/cardTransform
此文已由作者授权腾讯云+社区发布
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/1413.html
摘要:此时需要判断当前位置是否大于或者小于,若超过这个极限值需要重设目标位移及帧位移,使其在极限值内。判断第二次滑动是否与第一次不同方向,若不同向需重置上次帧位移为。以免上次帧位移太大影响移动方向。 本文由云+社区发表 最近的一个活动页面需要做一个可以左右滑动的抽签效果,故通过用css的transform属性和js结合来模拟可以无限滚动的效果。 先上效果: showImg(https://s...
摘要:此时需要判断当前位置是否大于或者小于,若超过这个极限值需要重设目标位移及帧位移,使其在极限值内。判断第二次滑动是否与第一次不同方向,若不同向需重置上次帧位移为。以免上次帧位移太大影响移动方向。 本文由云+社区发表 最近的一个活动页面需要做一个可以左右滑动的抽签效果,故通过用css的transform属性和js结合来模拟可以无限滚动的效果。 先上效果: showImg(https://s...
摘要:因此,如果可能,最好利用好毫秒响应预先计算开销大的工作,这样网站就更有可能实现的性能。空闲主线程工作分成不大于毫秒的块。点击按钮见图示,会在页面运行时捕获性能指标。 前言 经常能在博客或者论坛上看到很多有关前端性能优化的文章,但是却很少看到如何分析一个网页的性能的文章。到底什么样的指标(或者说是标准)代表这个网页性能好或者不好,通过什么方式来得到这些指标呢?因此,本文来讲述下如何分析一...
原文链接:https://github.com/AlloyTeam/AlloyTouch/wiki/AlloyTouch-FullPage-Plugin 先验货 showImg(https://segmentfault.com/img/remote/1460000007885626?w=280&h=280); 插件代码可以在这里找到。 注意,虽然是扫码体验,但是AlloyTouch.FullPag...
阅读 2111·2021-11-16 11:45
阅读 1181·2021-10-22 09:53
阅读 4001·2021-09-07 10:26
阅读 1209·2021-09-06 15:00
阅读 2071·2019-08-28 18:09
阅读 2794·2019-08-26 14:06
阅读 3932·2019-08-26 13:48
阅读 1294·2019-08-26 12:11