zoukankan      html  css  js  c++  java
  • jq实现百度图片移入移出内容提示框上下左右移动的效果

    闲来无聊,看到百度图片hover的时候提示框的效果,遂想试一试自己能否实现。

    百度图片hover的效果:

    需求:

      1. 当鼠标从图片上部移入的时候,提示框从上部移到正常位置。从上部移出的时候,提示框从正常位置移到上部。

      2. 当鼠标从图片左部移入的时候,提示框从左部移到正常位置。从左部移出的时候,提示框从正常位置移到左部

      3. 当鼠标从图片右部移入的时候,提示框从右部移到正常位置。从右部移出的时候,提示框从正常位置移到右部

      4. 当鼠标从图片下部移入的时候,提示框从下部移到正常位置。从下部移出的时候,提示框从正常位置移到下部

    先上实现的效果图:

     

    实现原理:

      1. 把图片看做一个矩形,把这个矩形,按对角线分成四份,每一份对应上下左右的部分。

      2. 获取鼠标移入div之后的坐标,获取该div离浏览器顶部和左部的距离,就能知道在该div中,鼠标移入的坐标。

      3. 以div左上角为原点,水平和竖直方向做坐标轴。

      4. 算出移入的点与x轴的夹角 β 和 θ。再与 α 角做比较,最后判断是在哪个范围内的。

    如图:

     说明:

      1) β,θ是移入的点与x轴的夹角,求这两个角与 α 的关系,才能知道到底是在哪个区域

      2)已知条件:x,y,x0,y0。分别代表图片宽和高,移入的x,y坐标。

      3)不管是鼠标从哪个区域移入或移出,只要求到移入的点与 x 轴的夹角的大小关系,就能正确判断。

    夹角判断所在区域: 

       当 0 < β  ≤  α,移入的点在 14 区域,

       当 α < β  ≤ 90,移入的点在 2 3 区域,

       当 0 < θ  ≤  α,移入的点在 12 区域, 

       当 α < θ  ≤ 90,移入的点在 34 区域,

    那么,要判断在 1 区域里面的话,满足的条件就必须为:0 < β  ≤  α,0 < θ  ≤  α  以此类推。。。

    原理搞清楚了,就可以上代码了。

    1. html

    <div class="box">
        <img src="upimg/comm.png"/>
        <div class="innerBox">
            <div class="inner"></div>
        </div>
    </div>

     说明:box是装图片的一个列表,innerBox是装提示框的盒子,inner是提示框的内容,inner也要设置绝对定位是因为只有这样才能设置top和left值。实际上就相当于给人错觉提示框innerBox在移动,实际上是提示框里的内容inner在移动。

    2. css

    *{
        padding:0;
        margin: 0;
    }
    .box{
        width: 300px;
        height: 300px;
        background: skyblue;
        float: left;
        position: relative;
        overflow: hidden;
        margin:10px 10px 0 0;
    }
    .innerBox{
        position: absolute;
        bottom: 0;
        left: 0;
        width: 100%;
        height: 40px;
    }
    img{
        width: 100%;
    }
    .inner{
        position: absolute;
        top:40px;
        left: 0;
        width: 100%;
        height: 40px;
        background: red;
    }

    3. js

    $('.box').hover(function(e){
        getIn($(this),e)
    },function(e){
        getOut($(this),e)
    })
    
    //获取在第几区域
    function getdirection(obj,e){
        var bleft=obj.offset().left;//距离左部的大小
        var btop=obj.offset().top;//距离顶部的大小
        
        var li_w=obj.width();//每个图片的宽度
        var li_h=obj.height();//每个图片的高度
        
        var evt=e||window.event;
        var x=evt.pageX-bleft;//鼠标在该图片中的x坐标
        var y=evt.pageY-btop;//鼠标在该图片中的y坐标
        x=Math.abs(x);//这里是防止移出的时候,x的值为负(bleft的值大于pageX)
        y=Math.abs(y);//与上同理
        
        if(x>li_w){
            x=li_w-(x-li_w);//这里是防止在第四部分移出的时候,pageX的值大于图片的长度,所以需要用到长度减去多余的部分就是在第四区域的对称位置
        }
        
        var Alltan=Math.atan(li_h/li_w);//这是α
        var leftTan=Math.atan(y/x);//这是β
        var rightTan=Math.atan(y/(li_w-x));//这是θ
        
        if(0<=leftTan&&leftTan<=Alltan&&0<=rightTan&&rightTan<=Alltan){
            console.log("在第一部分")
            return 1;
        }else if(Alltan<=leftTan&&leftTan<=Math.asin(1)&&0<=rightTan&&rightTan<=Alltan){
            console.log("在第二部分");
            return 2;
        }else if(Alltan<=leftTan&&leftTan<=Math.asin(1)&&Alltan<=rightTan&&rightTan<=Math.asin(1)){
            console.log("在第三部分");
            return 3;
        }else if(0<=leftTan&&leftTan<=Alltan&&Alltan<=rightTan&&rightTan<=Math.asin(1)){
            console.log("在第四部分");
            return 4;
        }
    }
    
    //移入
    function getIn(obj,e){
        var statu=getdirection(obj,e);
        var li_w=obj.width();
        
        var that=obj.find('.inner');
        var child_h=that.height();
        if(statu===1){
            that.css({
                "left":0,
                "top":-child_h
            }).stop().animate({
                "top":0
            },200)
        }else if(statu===2){
            that.css({
                "left":-li_w,
                "top":0
            }).stop().animate({
                "left":0
            },200)
        }else if(statu===3){
            that.stop().animate({
                "top":0
            },200)
        }else if(statu===4){
            that.css({
                "left":li_w,
                "top":0
            }).stop().animate({
                "left":0
            },200)
        }
    }
    
    
    //移出
    function getOut(obj,e){
        var statu=getdirection(obj,e);
        var li_w=obj.width();
        
        var that=obj.find('.inner');
        var child_h=that.height();
        if(statu===1){
            that.stop().animate({
                "top":-child_h
            },200,function(){
                $(this).css({
                    "left":0,
                    "top":child_h
                })
            })
        }else if(statu===2){
            that.stop().animate({
                "left":-li_w
            },200,function(){
                $(this).css({
                    "left":0,
                    "top":child_h
                })
            })
        }else if(statu===3){
            that.stop().animate({
                "top":child_h
            },200)
        }else if(statu===4){
            that.stop().animate({
                "left":li_w
            },200,function(){
                $(this).css({
                    "left":0,
                    "top":child_h
                })
            })
        }
    }

    说明:Math.asin(1) 表示 90度的反正弦值,由于tan90不存在,所以换成sin90了。

    总结:对比自己做的和百度的图片效果,发现百度的动画给人明显的要舒服点,估计是因为移出的时候,我直接设置css,导致动画不连贯原因,还有个就是stop()导致动画直接结束,所以还有可以修改的地方。这里只介绍一个思路

  • 相关阅读:
    卷积:如何成为一个很厉害的神经网络
    卷积的本质及物理意义(全面理解卷积)
    傅里叶分析之掐死教程(完整版)
    buf.writeUInt16BE()
    buf.writeUInt8()函数详解
    buf.writeUIntBE()函数详解
    buf.writeInt32BE()函数详解
    buf.writeInt16BE()函数详解
    buf.writeInt8()函数详解
    buf.writeDoubleBE()函数详解
  • 原文地址:https://www.cnblogs.com/zjjDaily/p/9138820.html
Copyright © 2011-2022 走看看