要求实现一个无缝循环的图片滚动公告,支持上下,左右模式。
要求 1,不可有卡顿图片无缝轮播
2 ,手指拖拽暂停轮播,用户可左右(或上下)拖拽,快速滑动有惯性效果。
3, 用户拖拽完成后3秒继续播放循环滚动。
4,页面上可以存在多个走马灯。
这种需求和轮播图类似,但效果区别是轮播图是一张张切换,有切换的效果,我们要求更接近滚动公告效果。
实现逻辑 1 视窗设置overflow:hidden,复制dom结构追加到父元素上,让父元素总宽度超过视窗宽度(代码里paetPiiic为视窗,piiic_region为父元素,piiic_item为要求轮播的元素)
2 设置定时器,修改父元素piiic_region的left(或top)值,处理边界
3 touch start touchmove touchend事件绑定,touchmove的时候piiic_region跟手指左右(上下)移动,处理边界。
4 touchend的时候,获取手指滑动速度,给元素继续设置惯性移动,直至速度为0,每次移动要处理边界。
代码实现:我们的需求是要求上下和左右以及轮播速度可在后台配置的,所有有些属性写在dom上取用。
<!--上下方向图片--> <div class="partPiiic" style="position: absolute;width: 3.75rem;height: 3.75rem;top: 0rem;left: 0rem;overflow:hidden" slidespeed="10"> <div class="piiic_region" slidedirection="UD" slidespeed="10" style="position: relative; width: 100%;"> <div class="piiic_item" style="position:relative;width:100%"> < img style="width:100%;display:block;" src="test.jpg"> </div> </div> </div>
<!--左右方向--> <div class="partPiiic" style="position: absolute;width: 3.75rem;height: 1.81rem;top: 3.88rem;left: 0rem;overflow:hidden" slidespeed="10"> <div class="piiic_region" slidedirection="LR" slidespeed="10" style="display: flex; position: relative; height: 100%; "> <div class="piiic_item" style="position:relative;height:100%" > < img style="height:100%" src="test1.jpg"> </div> </div> </div>
js代码:
window.onload = function () { //初始化图片走马灯 longPicInit(); } function longPicInit() { var container = document.querySelector("body"); var partPiiicList = container.querySelectorAll(".partPiiic"); if (partPiiicList.length > 0) { for (var index = 0; index < partPiiicList.length; index++) { var partPiiicNode = partPiiicList[index]; //存在其他业务逻辑,删除后只保留走马灯逻辑 //根据你自己的实际情况,获取到所有走马灯元素即可 //执行循环动画 loopLongPic(partPiiicNode); } } }
//主方法
function loopLongPic(partPiiicNode) {
//timeflag标志位 offspeed走马灯每次移动距离 copynum需要复制的子元素数量 var timeFlag = 1, offSpeed = 1, copyNum = 1, picTimer; var piiic_region = partPiiicNode.querySelector(".piiic_region"); var speed = piiic_region.getAttribute("slidespeed"); //走马灯速度 var deraction = piiic_region.getAttribute("slidedirection");//走马灯方向 上下还是左右 var piiic_item = piiic_region.querySelector(".piiic_item");//走马灯元素 if (deraction == "LR") {
//根据视图宽度除子元素宽度计算需要复制几个子元素 copyNum = Math.ceil(partPiiicNode.offsetWidth / piiic_item.offsetWidth); var text = $(piiic_region).html(); for (var i = 0; i < copyNum; i++) {
//复制后追加 $(piiic_region).append(text); } piiic_region.style.width = piiic_item.offsetWidth * (copyNum + 1) + "px"; } else {
//上下方向上的复制,逻辑同理 copyNum = Math.ceil(partPiiicNode.offsetHeight / piiic_item.offsetHeight); var text = $(piiic_region).html(); for (var i = 0; i < copyNum; i++) { $(piiic_region).append(text); } piiic_region.style.height = piiic_item.offsetHeight * (copyNum + 1) + "px"; }
//复制后,开启跑马灯 picTimer = setInterval(LoopMove, speed) function LoopMove() { if (timeFlag == 0) { clearInterval(picTimer) picTimer = null; return false; } if (deraction == "LR") {
//边界处理函数,到头拉回 criticalX() piiic_region.style.left = piiic_region.offsetLeft - offSpeed + "px"; } if (deraction == "UD") { criticalY(); piiic_region.style.top = piiic_region.offsetTop - offSpeed + "px"; } }
//添加touch事件 var touchStartX = 0,touchStartY = 0, moveStartY = 0, starttime = 0,restart, animateMoveTimer; piiic_region.addEventListener("touchstart", function (e) { if (picTimer) { clearInterval(picTimer); picTimer = null; } if (restart) { clearTimeout(restart); restart = null; } if (animateMoveTimer) { clearInterval(animateMoveTimer) } timeFlag = 0 //暂停定时器 手动拖拽上下左右距离 var ev = e || window.event; var touch = ev.targetTouches[0];
//记录touch初始位置 touchStartX = touch.pageX; touchStartY = touch.pageY;
//记录元素初始位置 moveStartX = piiic_region.offsetLeft; moveStartY = piiic_region.offsetTop; starttime = Date.now(); piiic_region.addEventListener("touchmove", preventDefault, false); }) piiic_region.addEventListener("touchmove", picImgMove) function picImgMove(e) { timeFlag = 0; if (timeFlag == 0) { var ev = e || window.event; var touch = ev.targetTouches[0] if (deraction == "LR") {//左右移动
//根据当前位置-初始位置计算手指移动距离 改变元素left
var moveX = touch.pageX - touchStartX; piiic_region.style.left = moveStartX + moveX + "px"; criticalX() } if (deraction == "UD") {//上下移动 var moveY = touch.pageY - touchStartY; piiic_region.style.top = moveStartY + moveY + "px"; criticalY() } } } piiic_region.addEventListener("touchend", function (e) { piiic_region.removeEventListener("touchmove", preventDefault); //获取最总结束位置 var ev = e || window.event; var touch = ev.changedTouches[0] var time = Date.now() - starttime;
//获取手指滑动速度 设置参数 可以根据自己想要的效果设置不同值 var endeSpeed = 0, rationSpeed = 40; //执行惯性移动 if (deraction == "LR") { var distanceX = touch.pageX - touchStartX; endeSpeed = (distanceX / time) * rationSpeed; animateMove(endeSpeed) } if (deraction == "UD") { var distanceY = touch.pageY - touchStartY; endeSpeed = (distanceY / time) * rationSpeed; animateMove(endeSpeed) } }) function animateMove(endeSpeed) { if (animateMoveTimer) { clearInterval(animateMoveTimer) } //endeSpeed是结束时的初速度,a为加速度,每隔1ms速度递减执行当前速度*1ms时间的距离,如果速度接近0,则清除计时器 var a = endeSpeed < 0 ? 2 : -2; animateMoveTimer = setInterval(function () { if (Math.abs(endeSpeed) < 1) { clearInterval(animateMoveTimer); if (picTimer) {clearInterval(picTimer); picTimer = null;} if (restart) {clearTimeout(restart); restart = null;} restart = setTimeout(function () { timeFlag = 1; picTimer = setInterval(LoopMove, speed); }, 3000); return; } endeSpeed += a; if (deraction == "LR") { piiic_region.style.left = piiic_region.offsetLeft + endeSpeed + "px"; criticalX(); } if (deraction == "UD") { piiic_region.style.top = piiic_region.offsetTop + endeSpeed + "px"; criticalY(); } },1) } //边界处理函数 function criticalX() { if (piiic_region.offsetLeft < -piiic_region.offsetWidth / (copyNum + 1)) {
//拖到最右边 循环 piiic_region.style.left = 0; } else if (piiic_region.offsetLeft >= 0) {
//拖到最左边 循环 piiic_region.style.left = -piiic_region.offsetWidth / (copyNum + 1) + "px"; } } function criticalY() { if (piiic_region.offsetTop < -piiic_region.offsetHeight / (copyNum + 1)) { piiic_region.style.top = 0 } else if (piiic_region.offsetTop >= 0) { piiic_region.style.top = -piiic_region.offsetHeight / (copyNum + 1) + "px"; } } }
标签:endeSpeed,style,touch,region,piiic,js,var,走马灯,拖拽 From: https://www.cnblogs.com/stt-bky/p/17171899.html