博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一入前端深似海,从此红尘是路人系列第十二弹之移动端模拟IOS虚拟按钮效果...
阅读量:6157 次
发布时间:2019-06-21

本文共 5447 字,大约阅读时间需要 18 分钟。

用过苹果的大家都知道,苹果公司做了一个虚拟按钮,让页面上的挂件可被拖拽并吸附到屏幕边框处,降低挂件对用户的干扰。该效果如果用JavaScript进行实现又该如何实现呢,接下来我将分享给大家。首先上一张效果图

 

一、思路来源

首先体验过该虚拟按钮的都知道,它是根据距离屏幕边距进行一个位移判断的。当手从屏幕中放开的时候,对边距判断后进行动态效果操纵,这里动态我们将用到transform进行控制,代码也是纯原生JavaScript。这里我们也只是做一个移动效果的模拟,对于其中的一些功能并没有添加进来。

二、代码编写

1、html

2、css

.i-pendant {  width: 60px;  height: 60px;  border-radius: 5px;  background: #999;  position: fixed;  top: 300px;  right: 0;  z-index: 90;  -webkit-transform: translate3d(0, 0, 0);          transform: translate3d(0, 0, 0);  -webkit-transition-property: -webkit-transform;  transition-property: -webkit-transform;  transition-property: transform;  transition-property: transform, -webkit-transform;  -webkit-transition-delay: 0s;          transition-delay: 0s;  -webkit-transition-timing-function: ease-out;          transition-timing-function: ease-out;}.drag {  width: 80%;  height: 80%;  margin: 10%;  border-radius: 100%;  background: #fff;}

3、JavaScript

首先我们需要先获取虚拟按钮,并定义一些全局状态,方便之后的拖拽判定

var pendant = document.getElementById("pendant");var posX = parseInt(pendant.offsetLeft);var posY = parseInt(pendant.offsetTop);var screenWidth = document.documentElement.clientWidth;var screenHeight = document.documentElement.clientHeight;// 判断手势按下状态var state = {  type: null};//检测是否move事件var isMove = false;
定义不同手势对应的事件

var Events = {  // 手势按下  onmousedown: function (event) {},  // 手势抬起  onmouseup: function (event) {},  // 手势移动  onmousemove: function (event) {}};
接下来我们需要做的就是一一实现这些手势事件,手势按下事件实现:

// 手势按下onmousedown: function (event) {  state.type = 'down';  screenWidth = document.documentElement.clientWidth;  screenHeight = document.documentElement.clientHeight;  var _touchs = event.targetTouches[0];  posX = _touchs.clientX;  posY = _touchs.clientY;  isMove = false;}
手势抬起事件实现:

// 手势抬起onmouseup: function (event) {  if (isMove) {    var _top = posY,      _left = posX;    state.type = 'up';    if ((posY + parseInt(pendant.clientHeight) / 2) <= (screenHeight / 2)) {      //在上半部分      if ((posX + parseInt(pendant.clientWidth) / 2) <= (screenWidth / 2)) {        //在左半部分        if ((posY + parseInt(pendant.clientHeight) / 2) <= (posX + parseInt(pendant.clientWidth) / 2)) {          //靠近上方          _top = 0;        } else {          //靠近左边          _left = 0;        }      } else {        //在右半部分        if ((posY + parseInt(pendant.clientHeight) / 2) <= (screenWidth - (posX + parseInt(pendant.clientWidth) / 2))) {          //靠近上方          _top = 0;        } else {          //靠近右边          _left = (screenWidth - parseInt(pendant.clientWidth));        }      }    } else {      //下半部分      if ((posX + parseInt(pendant.clientWidth) / 2) <= (screenWidth / 2)) {        //在左半部分        if ((screenHeight - (posY + parseInt(pendant.clientHeight) / 2)) <= (posX + parseInt(pendant.clientWidth) / 2)) {          //靠近下方          _top = (screenHeight - parseInt(pendant.clientHeight));        } else {          //靠近左边          _left = 0;        }      } else {//在右半部分        if ((screenHeight - (posY + parseInt(pendant.clientHeight) / 2)) <= (screenWidth - (posX + parseInt(pendant.clientWidth) / 2))) {          //靠近上方          _top = (screenHeight - parseInt(pendant.clientHeight));        } else {          //靠近右边          _left = (screenWidth - parseInt(pendant.clientWidth));        }      }    }    setTransform(_left, _top);  } else {    if (!!event) {      //点击事件触发入口      console.log('touch event');    }  }}
手势移动事件实现:

// 手势移动onmousemove: function (event) {  isMove = true;  // 如果这个元素的位置内只有一个手指的话  var _top = posY,    _left = posX;  state.type = 'move';  if (event.targetTouches.length === 1) {    event.preventDefault();// 阻止浏览器默认事件,重要    var touch = event.targetTouches[0];    if ((touch.clientY) <= 0) {      //超过顶部      _top = 0;    } else if (touch.clientY > (screenHeight - parseInt(pendant.clientHeight))) {//超过底部      _top = screenHeight - parseInt(pendant.clientHeight);    } else {      _top = touch.clientY - parseInt(pendant.clientHeight) / 2;    }    if (touch.clientX <= 0) {      //超过左边      _left = 0;    } else if (touch.clientX > (screenWidth - parseInt(pendant.clientWidth))) {      //超过右边      _left = screenWidth - parseInt(pendant.clientWidth);    } else {      _left = touch.clientX - parseInt(pendant.clientWidth) / 2;    }    setTransform(_left, _top);  }}
我们在手势事件中可以看到一个函数叫setTransform,接下来我们将实现它:

/** * @param {[type]} _left [左偏移] * @param {[type]} _top  [顶部偏移] */function setTransform(_left, _top) {  posX = _left;  posY = _top;  if (state.type === 'up') {    pendant.style.webkitTransitionDuration = '.2s';  } else {    pendant.style.webkitTransitionDuration = '0s';  }  pendant.style.webkitTransform = 'translate3d(' + posX + 'px,' + posY + 'px,0)';}
最后我们还需要对虚拟按钮进行一个参数的初始化

//初始化虚拟按钮参数function init() {  screenWidth = document.documentElement.clientWidth;  screenHeight = document.documentElement.clientHeight;  var _top = posY,    _left = posX;  if ((posY + parseInt(pendant.clientHeight)) > screenHeight) {    //窗口改变适应超出的部分    _top = (screenHeight - parseInt(pendant.clientHeight));  }  if ((posX + parseInt(pendant.clientWidth)) > screenWidth) {    //窗口改变适应超出的部分    _left = (screenWidth - parseInt(pendant.clientWidth));  }  //把样式的top、left赋值到transform去  setTransform(_left, _top);  pendant.style.top = 0;  pendant.style.left = 0;  state.type = 'init';  Events.onmouseup(null);}

最后我们调用一下init方法,虚拟按钮拖动效果就模拟出来了。小伙伴还不赶紧去试一下看看,是不是和苹果的虚拟按钮拖动起来是一样的效果呢。如果觉得好用或者好玩的话,记得给qiangdada点个赞哦↖(^ω^)↗

原文发布时间为:2017年01月18日

原文作者:

本文来源:如需转载请联系原作者

你可能感兴趣的文章
hibernate总结-N+1问题
查看>>
iOS技术周报-第28期
查看>>
iOS常用于显示几小时前/几天前/几月前/几年前的代码片段
查看>>
SLS:海量日志数据管理利器
查看>>
cocos2dxFlappyBird开发总结二:开发环境介绍
查看>>
(一四三)类设计回顾
查看>>
剑指offer系列之四十四:翻转单词顺序
查看>>
分布式系统学习资料(ing)
查看>>
堆和栈详解
查看>>
Apache Velocity官方指南-资源
查看>>
设计模式---读书笔记
查看>>
乐观锁与悲观锁及应用举例
查看>>
Tomcat中JVM内存溢出及合理配置
查看>>
还是时间惹的祸
查看>>
2017年------阿里大神带你详解Dubbo架构设计
查看>>
使用RxJava帮助低功耗蓝牙(BLE)进行通信
查看>>
Nginx综合介绍以及配置文件详解
查看>>
git的常用操作(个人整理使用)
查看>>
基于webpack4.X从零搭建React脚手架
查看>>
source 导入大批量sql文件的方法
查看>>