19
2019
11

js鼠标跟随运动之方向跟随

  有许多网页都有方向跟随的效果。鼠标从哪个方向移入,元素就跟着从哪个方向移入。鼠标从哪个方向移出,类似地,元素也跟着从哪个方向移出

  移入移出的运动效果使用匀速直线运动即可,这里主要需要判断方向

  由示意图中所示,可以把一个正方形的元素分成(上-右、上-左、左-上、左-下、下-右、下-左、右-上、右-下)这8个部分,每个部分是一个等腰直角三角形,当元素进入某个区域时,横线前面的方向就表示元素的方向

  假设正方形的中心坐标为(x0,y0),动态元素(move)进入时的坐标为(x,y),以这两个坐标组成的直线与水平正方向的直线的夹角作为基准角,假设为a,则通过确定夹角a的范围,可以确定动态元素(move)进入的方向

  -45<a<45时,进入方向为右

  45<a<135时,进入方向为上

  a>135或a<-135时,进入方向为左

  -135<a<-45时,进入方向为下

  确定好动态元素(move)进入的方向后,需要根据方向,将动态元素(move)瞬间变换到对应的位置。然后,动态元素(move)进行匀速直线运动,最终停止在与静态元素(test)重合的位置

  动态元素(move)移出静态元素(test)的范围时,要注意的是,并不会触发静态元素(test)的mouseout事件。因为,此时鼠标一直处于动态元素(move)上。所以,触发的是动态元素(move)的mouseout事件

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
<style>
#box{overflow: hidden;position: relative;left: 100px;top: 100px;height: 100px;width: 300px;}
.test{width: 100px;height: 100px;position: absolute;font:20px/100px '宋体';text-align: center;} 
</style>
</head>
<body>
<div id="box">
    <div class="test" style="top: 0px;left: 0px;background-color: pink;">1</div>
   <div class="test" style="top: 0px;left: 100px;background-color: lightcoral;">2</div>
   <div class="test" style="top: 0px;left: 200px;background-color: lightgreen;">3</div>  
    <div id="move" style="width: 100px;height: 100px;background-color: lightblue;position: absolute;top: -100px;left: -100px;"></div>  
</div>
<script>
var tests = box.getElementsByTagName('div');
for(var i = 0; i < tests.length; i++){
    tests[i].onmouseover = fn;
}
//鼠标移出动态元素(move)时,再将fn()函数置于所有静态元素上
move.onmouseout = fn;
function fn(e){
    e = e || event;
    //阻止冒泡
    if(e.stopPropagation){
        e.stopPropagation();
    }else{
        e.cancelBubble = true;
    }
    for(var i = 0; i < tests.length; i++){
        tests[i].onmouseover = fn;
    }
    var _this = this;
    //鼠标移入动态元素(move)时,将静态元素上的mouseover事件置空
    move.onmouseover = function(){
        move.innerHTML = _this.innerHTML;
        _this.onmouseover = null;
    }
    //声明坐标
    var x = e.clientX;
    var y = e.clientY;
    //声明静态元素(test)左上角坐标(相对于父级)
    var x11 = this.offsetLeft;
    var y11 = this.offsetTop;    
     //声明静态元素(test)中心点坐标(相对于父级)
    var x10 = x11 + this.offsetWidth/2;
    var y10 = y11 + this.offsetHeight/2;   
    //声明静态元素(test)左上角坐标(相对于文档)
    var x21 = this.parentNode.offsetLeft + x11;
    var y21 = this.parentNode.offsetTop + y11;
    //声明静态元素(test)中心点坐标(相对于文档)
    var x20 = x21 + this.offsetWidth/2;
    var y20 = y21 + this.offsetHeight/2;
    //声明静态元素宽高
    var height = this.offsetHeight;
    var width = this.offsetWidth;
    //声明并计算夹角
    var a = Math.atan2(y20-y,x-x20)*180/Math.PI;
    //声明并计算方向
    var dir;
    if(a > -45 && a < 45){
        dir = 'right';
    }else if(a > 45 && a < 135){
        dir = 'top';
    }else if(a > -135 && a < 45){
        dir = 'bottom';
    }else{
        dir = 'left';
    }
    //鼠标移入时
    if(e.type == 'mouseover'){
        //更新动态元素(move)的初始位置
        //移动动态元素(move)直到完全覆盖静态元素(test)
        if(dir == 'right'){
            move.style.left = x10 + width/2 + 'px';
            move.style.top = y10 - height/2 + 'px';
            fnMove(move,'left',x11)
        }else if(dir == 'top'){
            move.style.left = x10 - width/2 + 'px';
            move.style.top = y10 - height/2 - height + 'px'; 
            fnMove(move,'top',y11)
        }else if(dir == 'left'){
            move.style.left = x10 - width/2 - width + 'px';
            move.style.top = y10 - height/2 + 'px';
            fnMove(move,'left',x11)         
        }else{
            move.style.left = x10 - width/2 + 'px';
            move.style.top = y10 - height/2 + height + 'px';  
            fnMove(move,'top',y11)        
        }          
    }
    if(e.type == 'mouseout'){
        //鼠标移出时
        if(dir == 'right'){
            fnMove(move,'left',x11 + width);
        }else if(dir == 'top'){
            fnMove(move,'top',y11 - height);
        }else if(dir == 'left'){
            fnMove(move,'left',x11 - width);
        }else{
            fnMove(move,'top',y11 + height);
        }          
    }
}
function getCSS(obj,style){
    if(window.getComputedStyle){
        return getComputedStyle(obj)[style];
    }
    return obj.currentStyle[style];
}
function fnMove(obj,attr,target){
    var H = obj.offsetHeight;
    if(obj.timer) return;
    var cur = parseFloat(getCSS(obj,attr));
    if(target > cur){
        var step = H/4;
    }else{
        var step = -H/4;
    }
    obj.timer = setInterval(function(){
        cur = parseFloat(getCSS(obj,attr));
        cur = cur + step;
        if((cur -target) * step >= 0){
            cur = target;  
        }
           obj.style[attr] = cur + 'px'; 
        if(cur == target){
            clearInterval(obj.timer);
            obj.timer = 0;
        }
    },20);
} 
</script>   
</body>
</html>

上面的具体效果(点运行代码)来看

原文链接:https://www.qiquanji.com/post/7022.html

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

gzh

微信扫码关注

更新实时通知

« 上一篇 下一篇 »

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。