本文共 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日原文作者:
本文来源:如需转载请联系原作者