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()導致動畫直接結束,所以還有可以修改的地方。這里只介紹一個思路

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM