1. 程式人生 > >常見JS動畫效果

常見JS動畫效果

作為一名前端開發人員,想要的大多都是,在開發過程中,看著自己製作的動畫的炫酷以及困難的解決;開發結束後,自己的專案、成果可以被他人認可接受。人們瀏覽網頁時,若一個網頁動畫效果豐富炫酷,效能良好,體驗度良好,自然會受到吸引去打來瀏覽。吸引使用者,自然少不了網頁的佈局優美、色彩搭配的恰當,更重要的是其中吸引人的炫酷動畫效果。
在這裡,我為大家提供幾種常用的動畫效果,雖然沒有什麼特別,不是很炫酷,但很常見也很便捷。
一、輪播圖:
輪播圖在網頁中運用較廣,經常使用於頭部banner,使用於電商網站中,例如;淘寶、京東、天貓等購物平臺都少不了。而輪播圖有多種型別,這次就和大家說說其中的兩款。輪播圖的原理:點選上一張或下一張時,圖片移動的距離為圖片本身的寬度;點選圖片下的原點導航時跳轉到相應的圖片位置。
1、一般的輪播圖。這一型別的輪播圖,在切換圖片的過程中,圖片會緩慢的滑動到達相應的位置,即可以看到圖片到達相應位置的全過程。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
            }
            img{
                width: 520px;
            }
div.box{ width: 520px; height: 280px; overflow: hidden; margin: 100px auto; position: relative; } ul.img{ top: 0px; left: 0px; width: 1000%; position
: absolute
; }
ul.img li{ float: left; list-style: none; } ul.circle{ left: 50%; bottom: 10px; margin-left: -75px; position: absolute; } ul.circle li{ width: 20px; height: 20px; float: left; color: #666; cursor: pointer; margin: 0px 5px; list-style: none; text-align: center; border-radius: 10px; background: #e4e4e4; font: normal 12px/20px "conslas"; } ul.arrow{ top: 50%; width: 100%; position: absolute; margin-bottom: -25px; } ul.arrow li{ width: 35px; height: 50px; color: #666; cursor: pointer; list-style: none; text-align: center; background: #ccc; font: 800 30px/50px "conslas"; } ul.arrow li.left{ float:left; } ul.arrow li.right{ float: right; } ul.circle li.current{ color:#fff; background: red; }
</style> </head> <body> <div class="box"> <ul class="img"> <li><img src="img/p1.jpg" alt="" /></li> <li><img src="img/p2.jpg" alt="" /></li> <li><img src="img/p3.jpg" alt="" /></li> <li><img src="img/p4.jpg" alt="" /></li> <li><img src="img/p5.jpg" alt="" /></li> </ul> <ul class="circle"> </ul> <ul class="arrow"> <li class="left"><</li> <li class="right">></li> </ul> </div> <script> var box=document.getElementsByTagName("div")[0];//輪播圖容器 var img=box.children[0];//圖片容器 var circle=box.children[1];//小圓點容器 var arrow=box.children[2];//箭頭容器 var left=arrow.children[0];//左箭頭 var right=arrow.children[1];//右箭頭 var index=0;//當前顯示的圖片的索引 //需求分析: //1、在最後一幅圖後面新增第一幅圖 var addImg=img.children[0].cloneNode(true); img.appendChild(addImg); //2、動態新增小圓點,同時點亮第一個 var circles=img.children;//小圓點的個數即所有圖片的個數集合 for(var i=1;i<circles.length;i++){ var circleLi=document.createElement("li"); circleLi.innerHTML=i; circle.appendChild(circleLi); } var points=circle.children; light(); function light(){ for(var i=0;i<points.length;i++){ points[i].className=""; if(index>4){ points[0].className="current"; }else{ points[index].className="current"; } } } //3、點選小圓點,ul移動到相應的圖片,同時點亮小圓點 for(var j=0;j<points.length;j++){ points[j].index=j; points[j].onclick=function(){ index=this.index; animate(img,-index*box.offsetWidth); light(); } } //4、左右箭頭切換圖片 right.onclick=autoplay; function autoplay(){ index++; if(index>circles.length-1){ img.style.left=0; index=1; } animate(img,-index*box.offsetWidth); light(); } left.onclick=function(){ index--; if(index<0){ img.style.left=-(circles.length-1)*box.offsetWidth+"px"; index=circles.length-2; } animate(img,-index*box.offsetWidth); light(); } //5、新增自動輪播功能 box.timer=setInterval(autoplay,2000); box.onmouseover=function(){ clearInterval(box.timer); } box.onmouseout=function(){ clearInterval(box.timer); box.timer=setInterval(autoplay,2000); } function animate(obj,target){ clearInterval(obj.timer); obj.timer=setInterval(function(){ var speed=(obj.offsetLeft>target?-20:20); if(Math.abs(obj.offsetLeft-target)>20){ obj.style.left=obj.offsetLeft+speed+"px"; }else{ obj.style.left=target+"px"; } },20) } </script> </body> </html>

2、無縫輪播圖。此類輪播圖不會顯示圖片移動的全過程。

<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
                border: none;
                list-style: none;
            }

            img {
                width: 310px;
                height: 220px;
            }

            .slider {
                width: 310px;
                height: 265px;
                margin: 100px auto;
                position: relative;
                overflow: hidden;
                cursor: pointer;
            }

            .slider-img {
                width: 310px;
                height: 220px;
            }

            ul {
                list-style: none;
            }

            li {
                position: absolute;
                top: 0;
                left: 0;
            }

            .slider-ctrl {
                text-align: center;
                padding-top: 10px;
            }

            .slider-ctrl-con {
                display: inline-block;
                width: 24px;
                height: 24px;
                background: url("img/icon.png") no-repeat -24px -780px;
                text-indent: -99999px;
                margin: 0 5px;
                cursor: pointer;
            }

            .slider-ctrl-con.current {
                background-position: -24px -760px;
            }

            .prev,
            .next {
                position: absolute;
                top: 40%;
                width: 30px;
                height: 35px;
                background: url("img/icon.png") no-repeat;
            }

            .prev {
                left: 10px;
            }

            .next {
                right: 10px;
                background-position: 0 -44px;
            }
        </style>
    </head>

    <body>
        <div class="slider" id="slider" style="overflow: hidden;">
            <div class="slider-img">
                <ul>
                    <li>
                        <a href="#"><img src="img/p1.jpg" alt="" /></a>
                    </li>
                    <li>
                        <a href="#"><img src="img/p2.jpg" alt="" /></a>
                    </li>
                    <li>
                        <a href="#"><img src="img/p3.jpg" alt="" /></a>
                    </li>
                    <li>
                        <a href="#"><img src="img/p4.jpg" alt="" /></a>
                    </li>
                    <li>
                        <a href="#"><img src="img/p5.jpg" alt="" /></a>
                    </li>
                    <li>
                        <a href="#"><img src="img/p6.jpg" alt="" /></a>
                    </li>
                </ul>
            </div>
            <div class="slider-ctrl">
                <span class="prev" id="prev"></span>
                <span class="next" id="next"></span>
            </div>
        </div>
        <script type="text/javascript">
            window.onload = function() {
                var slider = document.getElementById("slider"); //獲取元素
                var ul = document.getElementsByTagName('ul')[0];
                var lis = ul.children;
                var per = document.getElementById('prev');
                var next = document.getElementById('next');
                var imgWidth = slider.offsetWidth; //獲取圖片的寬度作為緩動的距離

                for (var i = 0; i < lis.length; i++) { //新增span,用於點選跳轉到指定圖片
                    var span = document.createElement('span');
                    span.innerHTML = i;
                    span.className = "slider-ctrl-con "; //新增未選中狀態
                    per.parentNode.insertBefore(span, per);
                    lis[i].style.left = imgWidth + "px";
                }

                var num = 0; //標記索引值
                var span = document.getElementsByTagName('span'); //獲取span元素
                span[0].className += " current"; //為第一個span標籤狀態設定為選中狀態
                lis[0].style.left = 0 + "px"; //為第一張圖片設定顯示位置
                for (var k = 0; k < span.length; k++) {
                    span[k].onclick = function() { //為所有span標籤新增點選事件(包括左右按鈕)
                        if (this.className == "prev") { //當點選的是向前播放按鈕時
                            //要看上一張
                            animation(lis[num], imgWidth); //當前圖片緩動到右邊位置
                            num = --num < 0 ? lis.length - 1 : num; //索引值設定為前一張圖片的索引,當索引值小於0時則等於最後一張的索引
                            lis[num].style.left = -imgWidth + "px"; //將前一張圖片瞬間移動到左側
                            animation(lis[num], 0); //將移動到左側的圖片,緩動到顯示位置
                            light(); //點亮底部相應的span標籤
                        } else if (this.className == 'next') { //當點選的是向後播放按鈕時
                            //要看下一張
                            autoplay(); //按自動播放順序播放
                        } else {
                            //獲取當前被點選的盒子的索引值
                            var index = this.innerHTML;
                            //中間:left = 0;左邊:left = -imgWidth+“px";右邊:left = +imgWidth+”px“
                            //判斷點選的span和當前的圖片的索引,誰大誰小
                            if (index > num) { //當點選索引值大於當前播放圖片的索引值時
                                lis[index].style.left = imgWidth + "px"; //該索引值對應的圖片瞬間移動到右側
                                animation(lis[num], -imgWidth); //當前播放圖片緩動到左側
                                animation(lis[index], 0); //再緩動至當前播放位置
                                num = index; //改變索引值
                                light(); //點亮底部相應的span標籤
                            }
                            if (index < num) {
                                lis[index].style.left = -imgWidth + "px";
                                animation(lis[num], imgWidth);
                                animation(lis[index], 0);
                                num = index;
                                light();
                            }
                        }

                    }
                }

                function animation(obj, target) { //緩動
                    clearInterval(obj.timer); //為避免多個定時器同時執行帶來的bug,在用定時器之前先清理定時器
                    obj.timer = setInterval(function() {
                        var speed = (target - obj.offsetLeft) / 10; 
                        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); //為確保能搞達到最終目標值,給speed取整
                        obj.style.left = obj.offsetLeft + speed + "px"; //賦值給當前元素
                        if (target == obj.offsetLeft) { //屬性達到目標值時,清理定時器
                            clearInterval(obj.timer);
                        }
                    }, 20);
                }

                slider.timer = setInterval(function() { //當前無操作時自動播放
                    autoplay();
                }, 2000);

                slider.onmouseover = function() { //滑鼠進入圖片區域停止自動播放
                    clearInterval(slider.timer);
                }

                slider.onmouseout = function() { //滑鼠離開圖片區域恢復自動播放
                    clearInterval(slider.timer);
                    slider.timer = setInterval(function() {
                        autoplay();
                    }, 2000);
                }

                function light() {
                    for (var j = 0; j < span.length - 2; j++) {
                        span[j].className = "slider-ctrl-con ";
                    }
                    span[num].className += " current";
                }

                function autoplay() { //封裝自動播放函式
                    animation(lis[num], -imgWidth);
                    num = ++num > lis.length - 1 ? 0 : num;
                    lis[num].style.left = imgWidth + "px";
                    animation(lis[num], 0);
                    light();
                }
            }
        </script>
    </body>

</html>

二、旋轉木馬。顧名思義,旋轉木馬的動畫效果和遊樂園中旋轉木馬類似,因此而得名。旋轉木馬的原理和輪播圖其實差不多,只是旋轉木馬需要設定每一張圖片的z-index屬性,且每一張的z-index的設定精準、滿意需要一定的經驗。

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }

            .wrap {
                width: 1200px;
                margin: 10px auto;
            }

            .slider {
                height: 500px;
                position: relative;
            }

            .slider li {
                list-style: none;
                position: absolute;
                left: 200px;
                top: 0;
            }

            .slider li img {
                width: 100%;
                display: block;
            }

            .arrow {
                opacity: 1;
            }

            .prev,
            .next {
                width: 76px;
                height: 112px;
                position: absolute;
                top: 50%;
                margin-top: -56px;
                background: url(img/prev.png) no-repeat;
                z-index: 99;
            }

            .next {
                right: 0;
                background: url("img/next.png") no-repeat;
            }

            .prev {
                left: 0;
            }
        </style>
    </head>

    <body>
        <div class="wrap">
            <div class="slider">
                <ul>
                    <li><img src="img/1.jpg" /></li>
                    <li><img src="img/2.png" /></li>
                    <li><img src="img/3.jpg" /></li>
                    <li><img src="img/4.jpg" /></li>
                    <li><img src="img/5.jpg" /></li>
                </ul>
                <div class="arrow">
                    <div class="prev" id="prev"></div>
                    <div class="next" id='next'></div>
                </div>
            </div>
        </div>
        <script>
            var json = [{ //  0
                width: 400,
                top: 70,
                left: 50,
                opacity: 0.2,
                zIndex: 2
            }, { // 1
                width: 600,
                top: 120,
                left: 0,
                opacity: 0.8,
                zIndex: 3
            }, { // 2
                width: 800,
                top: 100,
                left: 200,
                opacity: 1,
                zIndex: 4
            }, { // 3
                width: 600,
                top: 120,
                left: 600,
                opacity: 0.8,
                zIndex: 3
            }, { //4
                width: 400,
                top: 70,
                left: 750,
                opacity: 0.2,
                zIndex: 2
            }];
            //根據json的內容把圖片緩動到相應位置,同時緩動
            var liArr = document.getElementsByTagName('li');
            var next = document.getElementById('next');
            var prev = document.getElementById('prev');

            function move() {
                for (var i = 0; i < liArr.length; i++) {
                    animation(liArr[i], json[i]);
                }
            }
            move()
            next.onclick = function() {
                var last = json.pop();
                json.unshift(last);
                move()
            }
            prev.onclick = function() {
                var first = json.shift();
                json.push(first);
                move();
            }

            function animation(obj, json, fn) {
                clearInterval(obj.timer);
                obj.timer = setInterval(function() {
                    var flag = true;
                    //json裡面有幾個屬性就要執行幾次
                    var target = 0; //記錄目標位置
                    var leader = 0; //記錄當前位置
                    var speed = 0; //記錄速度
                    for (var key in json) {
                        if (key == 'opacity') {
                            target = Math.round(json['opacity'] * 100) //0-100
                            leader = getStyle(obj, 'opacity') * 100 //0-100
                        } else {
                            target = parseInt(json[key]);
                            leader = parseInt(getStyle(obj, key));
                        }
                        speed = (target - leader) / 10;
                        speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
                        leader = leader + speed; //0-100
                        if (key == 'opacity') {
                            obj.style.opacity = leader / 100;
                            obj.style.filter = "alpha(opacity=" + leader + ")";
                        } else if (key == "zIndex") {
                            obj.style.zIndex = json['zIndex'];
                        } else {
                            obj.style[key] = leader + "px";
                        }

                        if (leader != target) {
                            flag = false
                        }
                    }
                    if (flag) {
                        clearInterval(obj.timer);
                        if (fn) {
                            fn();
                        }
                    }

                }, 20)
            }

            function getStyle(obj, attr) {
                if (window.getComputedStyle) {
                    return window.getComputedStyle(obj, null)[attr]
                } else {
                    return obj.currentStyle[attr];
                }
            }
        </script>
    </body>

</html>

三、樓層跳躍。該動畫效果也大多使用在電商網站,當點選到相應的標籤時就會跳到該位置的內容。例如:當點選淘寶旁的樓層跳躍中的美妝/女裝時就會跳到美妝/女裝模組。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>