JS和CSS3结合实现动画

  • 我们知道,CSS3的transition过渡属性可以实现动画。
  • JavaScript可以利用CSS3的transition属性轻松实现元素动画。
  • JS和CSS3结合实现动画规避了定时器制作动画的缺点。

函数节流

  • 函数节流:一个函数执行一次后,只有大于设定的执行周期后才允许执行第二次。
  • 函数节流非常容易实现,只需要借助setTimeout()延时器。
var lock = true;

function 需要节流的函数() {
    // 如果锁是关闭状态,则不执行 
    if (!lock) return;

    // 函数核心语句 
    

    // 关锁
    lock = false;

    // 指定毫秒数后将锁打开 
    setTimeout(function() {
        lock = true;
    }, 2000);
}

示例:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box {
            position: absolute;
            top: 100px;
            left: 100px;
            width: 100px;
            height: 100px;
            background-color: orange;
        }
    </style>
</head>

<body>
    <button id="btn">开始运动</button>
    <div id="box"></div>

    <script>
        // 得到元素
        var btn = document.getElementById('btn');
        var box = document.getElementById('box');

        // 标识量,指示当前盒子在左边还是右边
        var pos = 1; // 1左边,2右边

        // 函数节流
        // 添加锁
        var lock = true;

        // 按钮监听
        btn.onclick = function() {
            // 首先检查锁是否是关闭
            if (!lock) return;

            // 把过渡加上
            box.style.transition = 'all .5s linear 0s';
            if (pos == 1) {
                // 瞬间移动,但是由于有过渡,所以是动画
                box.style.left = '500px';
                pos = 2;
            } else if (pos == 2) {
                // 瞬间移动,但是由于有过渡,所以是动画
                box.style.left = '100px';
                pos = 1;
            }

            // 关锁
            lock = false;

            // 设置延时器开锁,时间与过渡时间最好相同
            setTimeout(function() {
                lock = true;
            }, 500)
        };
    </script>
</body>

</html>

动画效果开发1 - 无缝连续滚动特效

  • 首先将页面上图片复制一倍在后面,然后依次滚动。
  • 当赋值的后半段火车的0号头贴到了盒子的左边框的时候,那么就瞬间移动到原点,重新执行动画。

  • 最后再将盒子外面的部分隐藏即可。 

完整代码:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .box {
            margin: 50px auto;
            width: 840px;
            height: 130px;
            border: 10px solid #999;
            overflow: hidden;
        }
        
        ul {
            list-style: none;
            width: 5000px;
            position: relative;
        }
        
        li {
            float: left;
            margin-right: 10px;
        }
    </style>
</head>

<body>
    <div id="box" class="box">
        <ul id="list">
            <li><img src="image/number/0.png" alt=""></li>
            <li><img src="image/number/1.png" alt=""></li>
            <li><img src="image/number/2.png" alt=""></li>
            <li><img src="image/number/3.png" alt=""></li>
            <li><img src="image/number/4.png" alt=""></li>
            <li><img src="image/number/5.png" alt=""></li>
        </ul>
    </div>

    <script>
        var box = document.getElementById('box');
        var list = document.getElementById('list');

        // 复制多一遍所有的li
        list.innerHTML += list.innerHTML;

        // 全局变量,表示当前list的left值
        var left = 0;

        // 定时器,全局变量
        var timer;

        // move();

        // 动画封装成函数
        function move() {
            // 设表先关,防止动画积累
            clearInterval(timer);

            timer = setInterval(function() {
                left -= 4;
                // 验收
                if (left <= -1260) {
                    left = 0;
                }
                list.style.left = left + 'px';
            }, 20);
        }

        // 鼠标进入停止定时器
        box.onmouseenter = function() {
            clearInterval(timer);
        };

        // 鼠标离开继续定时器
        box.onmouseleave = function() {
            move();
        };
    </script>
</body>

</html>

动画效果开发2 - 跑马灯轮播图特效

  • 首先需要克隆第一个图,并添加到列表最后。

  • 右按钮临界点(第五张图),需要先正常过渡到克隆的第一张图上(第六张图),在过渡完成时,瞬间用原始的第一张图(第一张图)去替换掉克隆的第一张图(第六张图)。

  • 左按钮临界点(第一张图),需要先瞬间用克隆的第一张图(第六张图)去替换掉原始的第一张图(第一张图),然后再正常过渡到第五张图即可。

  •  其他的图正常过渡,最后设置隐藏即可。

完整代码:

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .carousel {
            margin: 50px auto;
            width: 650px;
            height: 360px;
            border: 1px solid #000;
            position: relative;
            overflow: hidden;
        }
        
        .carousel ul {
            list-style: none;
            width: 5000px;
            position: relative;
            left: 0;
            transition: left .5s ease 0s;
        }
        
        .carousel ul li {
            float: left;
            width: 650px;
            height: 360px;
        }
        
        .carousel a {
            position: absolute;
            top: 50%;
            margin-top: -25px;
            width: 50px;
            height: 50px;
            background-color: rgb(28, 180, 226);
            border-radius: 50%;
        }
        
        .carousel a.leftbtn {
            left: 20px;
        }
        
        .carousel a.rightbtn {
            right: 20px;
        }
    </style>
</head>

<body>
    <div class="carousel">
        <ul id="list">
            <li><img src="image/0.jpg" alt=""></li>
            <li><img src="image/1.jpg" alt=""></li>
            <li><img src="image/2.jpg" alt=""></li>
            <li><img src="image/3.jpg" alt=""></li>
            <li><img src="image/4.jpg" alt=""></li>
        </ul>
        <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
        <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
    </div>

    <script>
        // 得到按钮和ul,ul整体进行运动
        var list = document.getElementById('list');
        var leftbtn = document.getElementById('leftbtn');
        var rightbtn = document.getElementById('rightbtn');

        // 克隆第一张图片
        // 要设置true使用深克隆
        var cloneli = list.firstElementChild.cloneNode(true);
        list.appendChild(cloneli);

        // 当前ul显示到第几张了,从0开始数
        var idx = 0;

        // 节流锁
        var lock = true;

        // 右边按钮监听
        rightbtn.onclick = function() {
            // 判断锁的状态
            if (!lock) return;

            // 给list加过渡,为什么要加??css中不是已经加了么??
            // 这是因为最后一张图片会把过渡去掉
            list.style.transition = 'left .5s ease 0s';
            idx--;
            if (idx < -4) {
                // 设置一个延时器,延时器的目的就是让过渡动画结束之后,将ul瞬间拉回0的位置
                setTimeout(function() {
                    // 取消掉过渡,因为要的是瞬间移动,不是“咕噜”回去
                    list.style.transition = 'none';
                    list.style.left = 0;
                    idx = 0;
                }, 500);
            }
            list.style.left = idx * 650 + 'px';

            lock = false;

            // 函数节流
            setTimeout(function() {
                lock = true;
            }, 500);
        }

        // 左边按钮监听
        leftbtn.onclick = function() {
            // 判断锁的状态
            if (!lock) return;

            lock = false;

            // 判断是不是第0张,如果是,就要瞬间用假的替换真的
            if (idx == 0) {
                // 取消掉过渡,因为要的是瞬间移动,不是“咕噜”过去
                list.style.transition = 'none';
                // 直接瞬间移动到最后的假图片上
                list.style.left = -5 * 650 + 'px';
                // 设置一个延时器,这个延时器的延时时间可以是0毫秒,虽然是0毫秒,但是可以让我们过渡先是瞬间取消,然后再加上
                setTimeout(function() {
                    // 加过渡
                    list.style.transition = 'left .5s ease 0s';
                    // idx改为真正的最后一张
                    idx = -4;
                    list.style.left = idx * 650 + 'px';
                }, 0)
            } else {
                idx++;
                list.style.left = idx * 650 + 'px';
            }


            // 函数节流
            setTimeout(function() {
                lock = true;
            }, 500);
        }
    </script>

</body>

</html>

动画效果开发3 - 呼吸轮播图特效

  • 需要注意的是点击按钮切换时,先将老图淡出,再将新图淡入即可。
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        
        .carousel {
            margin: 50px auto;
            width: 650px;
            height: 360px;
            border: 1px solid #000;
            position: relative;
        }
        
        .carousel ul {
            list-style: none;
        }
        
        .carousel ul li {
            position: absolute;
            top: 0;
            left: 0;
            /* 透明度都是0 */
            opacity: 0;
            transition: opacity 1s ease 0s;
        }
        /* 只有第一张透明度是1 */
        
        .carousel ul li:first-child {
            opacity: 1;
        }
        
        .carousel a {
            position: absolute;
            top: 50%;
            margin-top: -25px;
            width: 50px;
            height: 50px;
            background-color: rgb(28, 180, 226);
            border-radius: 50%;
        }
        
        .carousel a.leftbtn {
            left: 20px;
        }
        
        .carousel a.rightbtn {
            right: 20px;
        }
    </style>
</head>

<body>
    <div class="carousel">
        <ul id="list">
            <li><img src="image/0.jpg" alt=""></li>
            <li><img src="image/1.jpg" alt=""></li>
            <li><img src="image/2.jpg" alt=""></li>
            <li><img src="image/3.jpg" alt=""></li>
            <li><img src="image/4.jpg" alt=""></li>
        </ul>
        <a href="javascript:;" class="leftbtn" id="leftbtn"></a>
        <a href="javascript:;" class="rightbtn" id="rightbtn"></a>
    </div>

    <script>
        // 得到按钮和ul,ul整体进行运动
        var list = document.getElementById('list');
        var leftbtn = document.getElementById('leftbtn');
        var rightbtn = document.getElementById('rightbtn');
        var lis = list.getElementsByTagName('li');

        // 当前是第几张图显示
        var idx = 0;

        // 节流锁
        var lock = true;

        // 右边按钮监听
        rightbtn.onclick = function() {
            // 判断锁的状态
            if (!lock) return;

            lock = false;

            // 还没有改idx,此时的idx这个图片就是老图,老图淡出
            lis[idx].style.opacity = 0;
            idx++;
            if (idx > 4) idx = 0;
            // 改了idx,此时的idx这个图片就是新图,新图淡入
            lis[idx].style.opacity = 1;

            // 动画结束之后,开锁
            setTimeout(function() {
                lock = true;
            }, 500);
        }

        // 左边按钮监听
        leftbtn.onclick = function() {
            // 判断锁的状态
            if (!lock) return;

            lock = false;

            // 还没有改idx,此时的idx这个图片就是老图,老图淡出
            lis[idx].style.opacity = 0;
            idx--;
            if (idx < 0) idx = 4;
            // 改了idx,此时的idx这个图片就是新图,新图淡入
            lis[idx].style.opacity = 1;

            // 动画结束之后,开锁
            setTimeout(function() {
                lock = true;
            }, 500);
        }
    </script>

</body>

</html>

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值