day16-动画

  1. 匀速运动:在相同的时间内 移动的距离一样

    let box=document.querySelector("#box");
    let left=0;
    let timer=setInterval(function(){
    left+=13;
    if(left>=1000){
    left=1000;
    clearInterval(timer);
    }
    box.style.left=left+"px";
    },50);
    
  2. 加速运动:在相同的时间内 移动的距离 越来越长,速度越来越快

        let box = document.querySelector("#box");
        let left = 0;
        let speed = 10;
        let timer = setInterval(function () {
            left += speed;
            speed += 5;
    
            if (left >= 1000) {
                left = 1000;
                clearInterval(timer);
            }
            console.log(left);
            box.style.left = left + "px";
        }, 100);
    
  3. 减速运动:在相同的时间内 移动的巨鹿越来越短 速度越来越小

     let box = document.querySelector("#box");
        let left = 0;
        let speed = 80;
    
        let timer = setInterval(function () {
            speed -= 5;
            // 当速度为0的时候 就停止运动
            if (speed <= 0) {
                clearInterval(timer);
                speed = 0;
            }
            left += speed;
    
            box.style.left = left + "px";
        }, 100);
    
  4. 缓冲运动:在固定的距离中 做减速运动

let box = document.querySelector("#box1");
            // let left = 0;
            let target = 1000;
            // 移动到 left  = 1000的时候停止运动
            // 减速运动
            let speed;

            let timer = setInterval(function () {
                // 获取元素当前的left
                let left = parseInt(getStyle(box, "left"));

                // 最开始的left = 0  target = 1000
                // speed =( target - left)/10 = 100
                speed = Math.ceil((target - left) / 10);

                // 速度:0.3 ==>1
                // left = 999
                // 1000 - 999 = 1/10=0.1
                // speed = 0.1
                // left += 0.1==>999+0.1==999.1

                left += speed;

                if (left == target) {
                    clearInterval(timer);
                }

                box.style.left = left + "px";
            }, 100);

封装一个运动函数

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            #box {
                width: 100px;
                height: 100px;
                background: pink;
                position: absolute;
                top: 0px;
                left: 0px;
            }
            button {
                position: fixed;
                right: 0px;
            }
        </style>
        <script src="./utils.js"></script>
    </head>
    <body>
        <div id="box"></div>
        <button id="btn">点击</button>
        <script>
            /* 
                函数的需要的参数:在代码中是可变的
                    动画的对象     ele
                    参与动画的属性  attr
                    动画的目标值    target
            */

            let btn = document.querySelector("#btn");
            let box = document.querySelector("#box");

            // let timer;
            btn.onclick = function () {
                // 点击的时候 才去执行动画的时候
                // 当多次点击的时候 肯定会开启多定时器来执行这个动画
                // 不管点击多少次 ,始终保持一个定时器执行这个动画
                move(box, "height", 500);

                // move(box,{height:500,width:500})
            };

            // 思考 同时改变 宽度 和高度(同时执行两个以上的动画)
            // 一个属性有一个目标值
            // 多个属性的时候 可以以对象的形式传递参数
            function move(ele, attr, target) {
                let speed;

                // 在开启定时器之前 把已经存在的定时器 清除
                clearInterval(ele.timer);

                // 把定时器 添加到 dom对象中
                ele.timer = setInterval(function () {
                    let left = parseInt(getStyle(ele, attr));
                    speed = Math.ceil((target - left) / 10);

                    left += speed;

                    if (left == target) {
                        clearInterval(ele.timer);
                    }

                    ele.style[attr] = left + "px";
                }, 50);
            }
        </script>
    </body>
</html>

动画函数的优化

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            #box {
                width: 100px;
                height: 100px;
                background: pink;
                position: absolute;
                top: 0px;
                left: 0px;
            }
            button {
                position: fixed;
                right: 0px;
            }
        </style>
        <script src="./utils.js"></script>
    </head>
    <body>
        <div id="box"></div>
        <button id="btn">点击</button>
        <script>
            /* 
                函数的需要的参数:在代码中是可变的
                    动画的对象     ele
                    参与动画的属性  attr
                    动画的目标值    target
            */

            let btn = document.querySelector("#btn");
            let box = document.querySelector("#box");

            btn.onclick = function () {
                // move(box, "height", 500);

                move(box, { height: 500, width: 800 }, function () {
                    // console.log('动画已经执行完成 ,我是回调函数');
                    box.style.background = "orange";
                });
            };

            // 思考 同时改变 宽度 和高度(同时执行两个以上的动画)
            // 一个属性有一个目标值
            // 多个属性的时候 可以以对象的形式传递参数
            function move(ele, obj, callback) {
               
                let index = 0; // 记录定时器的个数(记录动画的个数)
                for (let attr in obj) {
                    index++;
                    // 在开启定时器之前 把已经存在的定时器 清除
                    clearInterval(ele[attr]);

                    // 把定时器 添加到 dom对象中
                    // ele.width
                    // ele.height
                    ele[attr] = setInterval(function () {
                        let left = parseInt(getStyle(ele, attr));
                        let speed = Math.ceil((obj[attr] - left) / 10);
                        left += speed;
                        ele.style[attr] = left + "px";

                        if (left == obj[attr]) {
                            clearInterval(ele[attr]);
                            // 动画结束,只有两个动画都执行完成 才表示这个动画结束
                            // 没清除一个定时器的时候 就index--
                            index--;
                            if (index == 0) {
                                // 当动画执行完成时候 执行回调函数
                                // 不一定每一次都会有回调函数
                                // 没有回调函数的时候 就不执行callback
                                // 短路运算符:当callback存在的时候 才会执行 callback()
                                callback && callback();
                            }
                        }
                    }, 50);
                }
            }
        </script>
    </body>
</html>

动画函数升级版

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box{
            width: 500px;height: 500px;
            background: pink;
        }
    </style>
    <script src="./utils.js"></script>
</head>
<body>
    <div class="box"></div>

    <script>
        let box = document.querySelector('.box');
        box.onmouseover = function(){
            move(box,{width:100,height:100},function(){
                console.log(1);
            })
        }

    </script>
    
</body>
</html>

透明度的动画效果

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            .box {
                width: 200px;
                height: 200px;
                background: red;
                opacity: 0.8;
            }
        </style>

        <script src="./utils.js"></script>
    </head>
    <body>
        <div class="box"></div>

        <script>
            let box = document.querySelector(".box");
            box.onmouseover = function () {
                // box.style.opacity = "0.3";
                // 透明度的取值只能取0-1
                // 0-1  改变为 0-100
                // move(box,{opacity:25})
                move(box, { width: 500, opacity: 25 });
            };
        </script>
    </body>
</html>

轮播图的结构

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            * {
                padding: 0;
                margin: 0;
            }
            ul,
            li {
                list-style: none;
            }
            .box {
                width: 500px;
                height: 300px;
                border: 1px solid #ccc;
                overflow: hidden;
                position: absolute;
                left: 0px;
                top: 0px;
                right: 0px;
                bottom: 0px;
                margin: auto;
            }
            .box ul {
                width: 3000px;
                height: 300px;
                position: absolute;
            }
            .box ul li {
                width: 500px;
                float: left;
                height: 300px;
                text-align: center;
                line-height: 300px;
                font-size: 50px;
            }

            .box ol {
                position: absolute;
                bottom: 20px;
                right: 20px;
            }
            .box ol li {
                float: left;
                width: 20px;
                height: 20px;
                background: #58bc58;
                border-radius: 50%;
                text-align: center;
                line-height: 20px;
                font-size: 12px;
                margin-right: 5px;
                cursor: pointer;
                user-select: none;
                color: #fff;
            }
            .box ol .active {
                background: blue;
            }
            .box .btn {
                position: absolute;
                height: 40px;
                width: 100%;
                top: 50%;
                transform: translateY(-50%);
            }
            .box .btn .leftBtn {
                float: left;
                height: 40px;
                width: 60px;
                font-size: 50px;
                text-align: center;
                line-height: 40px;
                color: #fff;
                cursor: pointer;
                user-select: none;
                background: rgba(0, 0, 0, 0.336);
            }
            .box .btn .rightBtn {
                float: right;
                height: 40px;
                width: 60px;
                font-size: 50px;
                text-align: center;
                line-height: 40px;
                color: #fff;
                cursor: pointer;
                user-select: none;
                background: rgba(0, 0, 0, 0.336);
            }
        </style>

        <script src="./utils.js"></script>
    </head>
    <body>
        <div class="box">
            <ul>
                <li style="background: pink">li1</li>
                <li style="background: orange">li2</li>
                <li style="background: blueviolet">li3</li>
                <li style="background: palevioletred">li4</li>
                <li style="background: yellowgreen">li5</li>
                <li style="background: skyblue">li6</li>
            </ul>
            <ol>
                <!-- <li>1</li>
                <li>2</li>
                <li>3</li>
                <li>4</li>
                <li>5</li>
                <li>6</li> -->
            </ol>
            <div class="btn">
                <span class="leftBtn">&lt;</span>
                <span class="rightBtn">&gt;</span>
            </div>
        </div>

        <script>
            /*
                【1】根据 ul中的li元素 来生成ol中li元素
                【2】复制第一个轮播图 追加到 最后一个元素的后面
                【3】改变 ul的宽度
                【4】移动ul的left
                【5】当移入box的时候 停止轮播图的切换
                【6】当移出的是 轮播图继续轮播
                【7】点击左右按钮的时候 切换轮播图

                【9】点击 ol中的li元素的时候 切换到对应的图片
                    把点击的这个元素的索引 赋值给index
            */
            //    获取元素
            let box = document.querySelector(".box");
            let ul = box.querySelector("ul");
            let lis = ul.querySelectorAll("li");
            let ol = box.querySelector("ol");
            let leftBtn = box.querySelector(".leftBtn");
            let rightBtn = box.querySelector(".rightBtn");

            let flag = true; //表示可以点击

            // 【1】根据 ul中的li元素 来生成ol中li元素
            let str = "";
            lis.forEach((item, index) => {
                if (index == 0) {
                    str += `<li class="active">${index + 1}</li>`;
                } else {
                    str += `<li>${index + 1}</li>`;
                }
            });
            ol.innerHTML = str;

            let btnLi = ol.querySelectorAll("li");

            // 【2】复制第一个轮播图 追加到 最后一个元素的后面
            let copyLi = lis[0].cloneNode(true);
            ul.appendChild(copyLi);

            // 【3】改变 ul的宽度(获取添加之后的li的个数 和li的宽度)
            lis = ul.querySelectorAll("li");
            let width = lis[0].offsetWidth;

            ul.style.width = lis.length * width + "px";

            // 【4】移动ul的left
            // 需要定一个定时器不断的去执行 move函数
            // 当存在定时器的嵌套的时候 一定保证 外面定时器的切换时间 大于 里面定时器执行的总时间
            let index = 0;

            let timer = setInterval(function () {
                index++;
                autoPlay();
            }, 2000);

            // 【5】当移入box的时候 停止轮播图的切换
            box.onmouseover = function () {
                clearInterval(timer);
            };

            // 【6】当鼠标移出的时候 继续轮播图的切换
            box.onmouseout = function () {
                timer = setInterval(function () {
                    index++;
                    autoPlay();
                }, 2000);
            };

            // 【7】点击左边按钮
            leftBtn.onclick = function () {
                if (flag) {
                    flag = false;
                    // 如果index = 0的时候表示第一张图片
                    // 把index设置为 最后一章图片的索引,ul的left 瞬间移动到最后一张图片
                    if (index == 0) {
                        index = 6;
                        ul.style.left = index * -500 + "px";
                    }
                    index--;
                    autoPlay();
                }
            };

            // 【8】点击右边的按钮
            rightBtn.onclick = function () {
                if (flag) {
                    console.log(1);
                    index++;
                    flag = false;
                    autoPlay();
                }
            };

            // 把函数部分封装
            function autoPlay() {
                // index++;
                for (let i = 0; i < btnLi.length; i++) {
                    btnLi[i].classList.remove("active");
                }

                // 当index=6的时候 显示的就是最后一张 内容就为第一张
                if (index == 6) {
                    btnLi[0].classList.add("active");
                } else {
                    btnLi[index].classList.add("active");
                }

                move(ul, { left: -500 * index }, function () {
                    // 动画结束之后  把flag改为true,表示可以继续点击
                    flag = true;
                    // 当index 移动到最后一张图片的时候 应该改变index = 0
                    // 并且ul 瞬间 移动left = 0的位置
                    if (index == 6) {
                        index = 0;
                        ul.style.left = 0 + "px";
                    }
                });
            }
        </script>
    </body>
</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值