-原生js写的触摸滑动重力卡片,类似于下面这张图,实现卡片简单特效。
-分离了参数区和功能区,便于数据的写入和代码的重用能力。
-es6语法。
-
如果会产生左右或者上下的滚动条,则可以设置母标签的overflow: hidden,然后设置母标签的宽和高即可。
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--开始-滑动卡片-->
<div class="swipe-card" id="swipe-card"></div> <!--卡片区-->
<!--卡片样式-->
<style>
.swipe-card{
position: relative; /**必须**/
background: #EEEEEE;
overflow: unset;
width: 100%;
min-height: 500px;
}
.card-div{
min-width: 30px;min-height: 30px; /**必须**/
position: absolute;top: 0;left: 0;bottom: 0;right: 0;margin: auto; /**必须**/
background: #d8d8d8;
padding: 5px;
}
</style>
<!--参数区-->
<script>
// 自定义参数
const card_num = 100; // 卡片的数量
let card_div_width = 260; // 卡片宽px
let card_div_height = 260; // 卡片高px
</script>
<!--功能区-->
<script>
// 可以自定义参数
let card_drop_down = window.innerHeight; // 下掉距离
let card_drop_left = (window.innerWidth-card_div_width)/2.2; // 左或者右滑动距离
let _3d_ok = 50; // z方向距离,即就是跳出距离
const time_out = 800; // ms 动画时间
let _z_index = 8100000; // 为了反向取z-index,然后让数组最前面的先可视
// 不可修改参数
let left_ok = 1; // 向左还是向右动画偏移
let touch_index = 0; // 当前处于看触摸的监控的卡片
// 处理如何动画
function touch_data(_data) {
//console.log(_data);
let that_dom = _data.id;
if (Math.abs(_data.x1 - _data.x2) < 30){console.log("微小触摸不会误触");return;}
if (Math.abs(_data.y1 - _data.y2) > card_div_height*1.5){console.log("太多触摸不会误触");return;}
if (Math.abs(_data.x1 - _data.x2) > card_div_width){console.log("太多触摸不会误触");return;}
if (_data.dir_x === "left"){left_ok = -1;}else if(_data.dir_x === "right"){left_ok = 1;}
else { // 可以当作点击事件
left_ok = -left_ok;
}
_3d_ok = -_3d_ok;
animate_dom(that_dom);
setTimeout(function () {
that_dom.remove(); // 移除
}, (time_out-100));
touch_index++; // 下一个可视
swipe_touch(document.getElementById("card-div-"+touch_index)); // 重置触摸区域
}
// 表演该id动画
function animate_dom(_id) {
_id.style.cssText = "width: "+card_div_width+"px; transition-duration: "+ time_out +"ms; transform: translate3d("+ card_drop_left*left_ok +"px, "+ card_drop_down +"px, "+ _3d_ok +"px); z-index: "+ _z_index*1.1 +";width: "+ card_div_width +"px;height: "+ card_div_height +"px;opacity: 0.4;";
}
// 处理触摸手势
function swipe_touch(_id){
let startx; let endx; let starty; let endy;
function _touch_cons(){
let dir_x = "center_x";
let dir_y = "center_y";
if(startx > endx){dir_x = "left";}else if(startx < endx){dir_x = "right";}
if(starty > endy){dir_y = "up";}else if(starty < endy){dir_y = "down";}
let _data = {
"dir_x": dir_x,
"x1" : Math.floor(startx),
"x2" : Math.floor(endx),
"dir_y": dir_y,
"y1" : Math.floor(starty),
"y2" : Math.floor(endy),
"id" : _id,
};
try{
touch_data(_data);
}catch (e) {
// 必选日志打印
console.info("请使用function touch_data(data){console.log(data);}取出该区域触摸参数");
}
}
_id.addEventListener("touchstart",function(e){
let touch=e.changedTouches;
startx=touch[0].clientX;
starty=touch[0].clientY;
});
_id.addEventListener("touchend",function(e){
let touch=e.changedTouches;
endx=touch[0].clientX;
endy=touch[0].clientY;
_touch_cons();
});
}
// 创建母模板
(function () {
let swipe_card = document.getElementById("swipe-card");
let append_tag = [];
for (let i = 0; i < card_num; i++){
let tag = '<div class="card-div card-div-'+i+'" id="card-div-'+i+'" data-tag="'+i+'" style="z-index: '+ (_z_index) +'; width: '+ card_div_width +'px;height: '+ card_div_height +'px;">'+ '' +'</div>';
_z_index--;
append_tag.push(tag);
}
swipe_card.innerHTML = append_tag.join("");
swipe_touch(document.getElementById("card-div-0")); // 初始化触摸区域
})("创建视图");
</script>
<!--结束-滑动卡片-->
-
-