悬浮球只在一侧滑动 而且是横屏状态下

公司有一个新的需求 是须要悬浮球在一侧上下滑动 实际上是很简单的 并且网上都有各类案例,可是 恰恰是横屏状态下 ,并且不是手机横屏 是用css强制旋转屏幕90度以后的横屏,因此就会出现坐标系的紊乱,而后我这个功能一开始作成的效果就是触摸上下滑动的时候 ,悬浮球是左右走(目前的这个图片的上下左右),当时很是的苦恼,接下来贴上个人代码,你们能够参考,有问题能够评论指出,谢谢!我先把个人基本布局拿过来,用的js是  flexible.js  写的移动端的布局;css

由于代码是有一阵子了 我也是从网上找的相关的正常悬浮球的移动的案例   以后再研究的横屏下的悬浮球移动;如涉及侵权,请谅解 或者指出 我会标明出处;感谢配合;html

 

 

 

 

下面的是html web

图片那里你们能够自行更换ide

 1 <body>
 2     <div id="example">
 3         <!-- 侧边的悬浮球 -->
 4         <div class="sideDown">
 5             <ul class="smallDown">
 6                 <img class="suspBall" src="./images/sideDownLogo.png" alt="">
 7                 <li class="comeOut">
 8                     <p class="Take_back"><img src="./images/putAway.png" alt=""></p>
 9                     <p class="save_game">
10                         <img src="./images/saveLogo.png" alt="">
11                         <i>保存</i>
12                     </p>
13                     <p class="down_game">
14                         <img src="./images/downLogo.png" alt="">
15                         <i>下载</i>
16                     </p>
17                 </li>
18             </ul>
19         </div>
20     </div>
21 </body>

下面的是css  由于我当时写这个的时候是依赖于一个云项目中的SDK 自带的样式  它的样式就是这么强制横屏的 因此我当时为了测试,就本身先写在了本身的样式里面 仅供参考  若有更好的 你们能够尽量的提出!布局

#example {
    width: 100%;
    height: 100%;
    position: relative;
    /* 这是分割线  如下是为了屏幕旋转成横屏 仅供参考  */
    width: 667px;
    height: 375px;
    left: -146px;
    top: 146px;
    -moz-transform: rotate(90deg);
    -webkit-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    -ms-transform: rotate(90deg);
    transform: rotate(90deg);
    -moz-transform-origin: center center;
    -webkit-transform-origin: center center;
    -o-transform-origin: center center;
    -ms-transform-origin: center center;
    transform-origin: center center
}


/* 侧边的悬浮球 */
.sideDown {
    width: 1rem;
    height: 100%;
    position: absolute;
    z-index: 444;
    right: 0;
    display: block;
}

.sideDown ul {
    width: 1rem;
    height: 1rem;
    display: flex;
    align-items: center;
    position: absolute;
    top: 20px;
    right: 0;
    opacity: 1;
}

.sideDown ul img.suspBall {
    display: inline-block;
    width: 1rem;
    height: 1rem;
    z-index: 333;
}

.sideDown li {
    position: absolute;
    z-index: 222;
    right: 0.15rem;
    width: 3.3rem;
    height: 0.60rem;
    background: rgba(255, 230, 0, 1);
    border-radius: 0.35rem;
    opacity: 0.9;
    display: flex;
    align-items: center;
}

.sideDown li p {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    margin-left: 0.5rem;
}

.sideDown li p img {
    display: inline-block;
    width: 0.29rem;
    height: 0.29rem;
}

.sideDown li p:first-child {
    width: 0.2rem;
    height: 0.2rem;
    margin-left: 0.16rem;
}

.sideDown li p:first-child img {
    display: inline-block;
    width: 0.2rem;
    height: 0.2rem;
}



.sideDown li p:first-child img {
    display: inline-block;
    width: 0.2rem;
    height: 0.2rem;
}

.sideDown li p i {
    display: inline-block;
    font-size: 0.17rem;
    font-family: PingFangSC-Regular, PingFang SC;
    font-weight: 400;
    color: rgba(51, 51, 51, 1);
}

如下是重点 js代码测试

 1 <script>
 2     window.onload = function () {
 3         var flag = 0;  //标记是拖曳仍是点击
 4         var disX, disY;
 5         var targetW = 0;//刚进来的时候悬浮球左边的宽度是正常的;
 6         // 获取元素
 7         var bigBox = document.querySelector(".sideDown");
 8         var sBox = document.querySelector(".smallDown");
 9         var sBoxImg = document.querySelector(".suspBall");
10         // console.log('获取元素', bigBox, sBox)
11         // 获取大盒子的大小
12         var bigbox_w = bigBox.offsetHeight;
13         var bigbox_h = bigBox.offsetWidth;
14         // console.log('获取大盒子的大小', bigbox_w, bigbox_h)
15         // 获取小盒子的大小
16         var sbox_w = sBox.offsetHeight;
17         var sbox_h = sBox.offsetWidth ;
18         // console.log('获取小盒子的大小', sbox_w, sbox_h)
19         // 获取大盒子的间距
20         var bigBox_l = bigBox.offsetLeft;
21         var bigBox_t = bigBox.offsetTop ;
22         // console.log('获取大盒子的间距', bigBox_l, bigBox_t)
23 
24         // 小盒子鼠标按下才触发事件
25         sBoxImg.addEventListener('touchstart', function (ev) {
26             flag = 0;
27             ev = ev || window.event;
28             ev.preventDefault();//阻止触摸时页面的滚动,缩放
29 
30             // 获取鼠标在盒子中的位置
31             // 触点位置减去小盒子的间距就是鼠标在小盒子中的位置
32             disX =  bigbox_w - ev.touches[0].pageX - sBox.offsetTop;
33             disY = ev.touches[0].pageY - bigBox_l;
34 
35             console.log('获取触点位置', ev.touches[0].pageY, ev.touches[0].pageX)
36             console.log('小盒子的左和上间距', sBox.offsetLeft, sBox.offsetTop)
37             console.log('获取鼠标在盒子中的位置', disX, disY)
38         })
39         sBoxImg.addEventListener('touchmove', function (e) {
40             flag = 1;
41             e = e || window.event;
42             // 用此次获取到的鼠标的位置减去上次鼠标在小盒子的位置就是小盒子的左和上间距
43             var moveX = bigbox_w - e.touches[0].pageX - disX;
44             var moveY = e.touches[0].pageY - disY;
45             // console.log('移动的时候~~获取触点位置', e.touches[0].pageX, e.touches[0].pageY)
46             // console.log('获取上次鼠标在盒子中的位置', disX, disY)
47             // console.log('小盒子的左和上间距', moveX, moveY)
48 
49             if (moveX < 0) {
50                 moveX = 0;
51             }
52             if (moveY < 0) {
53                 moveY = 0;
54             }
55             if (moveX > bigbox_w - sbox_w) {
56                 moveX = bigbox_w - sbox_w;
57             }
58             if (moveY > bigbox_h - sbox_h) {
59                 moveY = bigbox_h - sbox_h;
60             }
61             sBox.style.top = moveX + 'px';
62             sBox.style.left = moveY + 'px';
63         })
64         sBoxImg.addEventListener('touchend', function (e) {
65             // console.log('结束')
66             //判断滑动方向
67             if (flag === 0) {//点击
68 
69                 // console.log('点击了');
70 
71                 if (targetW == 0) {
72                     console.log('收回去了', targetW)
73                     $(".comeOut").animate({ width: '0.3rem', opacity: '0.5', }, 'slow', function () {
74                         targetW = 1;  //改变悬浮球左边大小的时候 改变这个值 以便于后面的判断;
75                     })
76                 }
77                 if (targetW == 1) {
78                     console.log('放出来了', targetW)
79                     $(".comeOut").animate({ width: '3.3rem', opacity: '0.9', }, 'slow', function () {
80                         targetW = 0;
81                     })
82                 }
83 
84             }
85         });
86 
87         $(".Take_back").click(function (event) {
88             console.log('点击箭头', targetW)
89             $(".comeOut").animate({ width: '0.3rem', opacity: '0.5', }, 'slow', function () {
90                 targetW = 1;  //改变悬浮球左边大小的时候 改变这个值 以便于后面的判断;
91             })
92             event.stopPropagation()
93         });
94     }
95 
96 </script>

下面进行详细的解说:flex

var bigbox_w = bigBox.offsetHeight;
var bigbox_h = bigBox.offsetWidth;
这两句 按正常的竖屏的话应该是
var bigbox_w = bigBox.offsetWidth;
var bigbox_h = bigBox.offsetHeight;
offsetWidth 显示的是盒子正常的宽 (也就是你css里面写的宽)
offsetHeight 显示的是盒子正常的高 (也就是你css里面写的高)
可是 因为横屏 你的视觉中看到的就是一下左图中 宽 高
这就是须要把 offsetWidth 和 offsetHeight 换一下 才是右图中打印出来的宽高 才是视觉中的宽高;
同理 小盒子的大小(16,17行)也须要换一下,尽管小盒子是一个正方形的 ;

 

 

 

 

这个是大盒子的间距; offsetLeft 和 offsetTop  也不是视觉中的left和top  
var bigBox_l = bigBox.offsetLeft; var bigBox_t = bigBox.offsetTop ;
此时的大盒子的
offsetTop 为0 我就不在图中标出来了;你们应该明白 就是图中的右边距离;

手机按下事件  这里就很少说了  基本上就是按下(touchstart) 移动(touchmove ) 抬起  (touchendspa

总体的逻辑 就是按下的时候 记录一下鼠标在小盒子里面的位置 3d

如下就是关键,弄很差鼠标的位置就记录错了,我也是反反复复的想 才想明白;code

我会用图向你们解说

 

  disX =  bigbox_w - ev.touches[0].pageX - smallBox.offsetTop;
  disY = ev.touches[0].pageY - bigBox_l;
 

 

 

 

 鼠标按下的值已经记录完毕  而后就是鼠标移动的时候 小球也要跟着动

 var moveX = bigbox_w - e.touches[0].pageX - disX;
 var moveY = e.touches[0].pageY - disY;

 

 最后就是赋值 

固然了 临界值的话 比较好判断 这里就很少说了;

 smallBox.style.top = moveX + 'px';
 smallBox.style.left = moveY + 'px';
这里须要注意的是 小盒子的top值 实际上是你最后算出来的moveX 值;
left值 就是moveY 值;
 
写了很久了 本身的能力有限 若是有更好的或者能够改进的方式 随时等待你们的评论来指点,谢谢你们;