Skip to content

Latest commit

 

History

History
336 lines (278 loc) · 10.9 KB

动画笔记.md

File metadata and controls

336 lines (278 loc) · 10.9 KB

动画实例

无限滚动

页面滚动的前提 : 出现滚动条 ===> 页面高度 > 可视区域高度

document.documentElement(body).offsetHeight  >  document.documentElement.clientHeight 

for循环生成内容

		// 页面高度大于可视区域高度  出现滚动条  不让滚动条到底  可增加可视区域高度
        for(;document.body.offsetHeight < document.documentElement.clientHeight + 100;){
        	//页面高度小于可视区域高度时 创建空标签  添加内容 
            var pEl = document.createElement("p");
            pEl.innerText = "sunday";
            document.body.appendChild(pEl);
        }

鼠标滚动

		//利用节流
		window.onscroll = throttle(function(){
            var now = new Date();//循环获取当前时间戳  添加到body
            var newEl = document.createElement("p");
            newEl.innerText = now;
            document.body.appendChild(newEl);
        },1000/60)
        
        // 节流
        function throttle(fun, wait) {
            return function () {
                if (!fun.timer) {
                    fun.timer = setTimeout(function () {
                        fun();
                        fun.timer = null;
                    }, wait)
                }
            }
        }

滚动进度

利用比例关系

		   滚动条滚动高度               页面宽度
         ---------------   =     --------------- 
          滚动条最大滚动距离          页面可视区域宽度
          
          滚动到底部时   页面高度  =  滚动条最大滚动距离 + 页面可视区域高度
          document.body.offsetHeight = 最大滚动距离 + document.documentElement.clientHeight
          
          	var box = document.querySelector(".box");
            var startL = document.documentElement.clientWidth;
            var startT = document.documentElement.clientHeight;
            window.onscroll = function(){
// box.style.width = Math.floor((startL *                            											window.pageYOffset)/(document.body.offsetHeight-startT)) + "px";
                //获取的是小数  需要用 Math.floor( ) 取整
                // 也可写成百分比的形式
                box.style.width = Math.floor(window.pageYOffset/(document.body.offsetHeight-																document.documentElement.clientHeight) * 100) + "%";
            }
          

旋转木马

参与动画的图片对称放置 位置使用定位固定

将参与动画的属性 按照顺序以对象形式放在数组中

		var styleLis = [
            {
                width: 400,
                left: 50,
                top: 0,
                opacity: 0.4,
                zIndex: 2
            },
            {
                width: 600,
                left: 0,
                top: 80,
                opacity: 0.8,
                zIndex: 3
            },
            {
                width: 800,
                left: 200,
                top: 40,
                opacity: 1,
                zIndex: 4
            },
            {
                width: 600,
                left: 600,
                top: 80,
                opacity: 0.8,
                zIndex: 3
            },
            {
                width: 400,
                left: 750,
                top: 0,
                opacity: 0.2,
                zIndex: 2
            }
        ]
        
        
        btn[0].onclick = function () {
            styleLis.push(styleLis.shift()); //删除第一个 把删除的元素添加到最后一个
            for(var i in styleLis){  //遍历对象中的属性  每个都添加动画
                animate(imgLi[i],styleLis[i]);  //单一对象多属性动画
            }
        }

        btn[1].onclick = function () {
            styleLis.unshift(styleLis.pop());  //删除最后一个  删除的元素添加到第一个
            for(var i in styleLis){
                animate(imgLi[i],styleLis[i]);
            }
        }
        
        
        
        // 单一元素多属性动画

        function animate(ele, objStyle) {
            if(ele.timer){
                clearInterval(ele.timer);
            }
            ele.timer = setInterval(function () {
                var start, target, isArrive = true;
                for (var i in objStyle) {
                    if (i === "zIndex") {
                        ele.style.zIndex = objStyle[i];
                        continue;
                        // 跳出当前循环,执行下次 continue
						// 打断 break
						// 跳出函数 return
                    } else if (i === "opacity") {
                        start = parseInt(getComputedStyle(ele, null)[i] * 100);
                        target = objStyle[i] * 100;
                    } else {
                        start = parseInt(getComputedStyle(ele, null)[i]);
                        target = objStyle[i];
                    }
                    var step = (target - start) / 10;
                    if (Math.abs(step) < 1) {
                        step = step > 0 ? 1 : Math.floor(step);
                    }
                    if (i === "opacity") {
                        ele.style.opacity = (step + start) / 100;
                    } else {
                        ele.style[i] = step + start + "px";
                    }
                    if (start + step !== target) {
                        isArrive = false;
                    }
                }
                if (isArrive) {
                    clearInterval(ele.timer);
                    ele.timer = null;
                }
            }, 1000 / 60)

        }

柱状图

冒泡排序

		var lis = document.querySelector(".list");
        var btn = document.querySelectorAll("button");

        btn[0].onclick = function () {
            // console.log(0)
            var str = "";
            var newArr = [];
            for (var i = 0; i < 10; i++) {
                //获取随机数
                var num = getVil(30, 300);
                if (newArr.indexOf(num) === -1) {  //利用索引判断元素是否存在
                    newArr.push(num);
                    //拼接字符串  ${}
                 str += `<li style = "height: ${num}px ; left: ${40 + 90 * i}px;"></li>`;
                } else {
                    i--;  //如果有重复元素  需要在当前基础上重新查找
                }
            }
            lis.innerHTML = str;
        }
        
        
        //排序   采用for循环时  for循环过快 动画来不及执行
        btn[1].onclick = function () {
            var all = lis.children;
            // for循环冒泡排序
            for (var j = 0; j < all.length - 1; j++) {
                //内部循环
                for (var i = 0; i < all.length - 1 - j; i++) {
                    if (all[i].offsetHeight > all[i + 1].offsetHeight) {
                        var temp = all[i].offsetLeft;
                        // all[i].style.left = all[i + 1].offsetLeft + "px";
                        // all[i + 1].style.left = temp + "px";

                        // 动画
                        slow(all[i],all[i+1].offsetLeft);
                        slow(all[i+1],temp);

                        all[i].parentNode.insertBefore(all[i + 1], all[i]);
                    }
                }
            }
            
            
            //定时器模拟for循环
            var j = 0, i = 0, isfine = true;
            var timer = setInterval(function () {
                if (j < all.length - 1) {
                    if (i < all.length - 1 - j) {
                        if (all[i].offsetHeight > all[i + 1].offsetHeight) {
                            var temp = all[i].offsetLeft;//保留i的位置
                            // 进行位置交换
                            // all[i].style.left = all[i+1].offsetLeft + "px";
                            // all[i+1].style.left = temp + "px";

                            // // 动画
                            slow(all[i], all[i + 1].offsetLeft);
                            slow(all[i + 1], temp);


                            //父节点.insertBefore (新的子节点,参考的子节点)
                            all[i].parentNode.insertBefore(all[i + 1], all[i]);
                            //i元素前添加i后面的元素
                            
                            isfine = false;  //只要交换位置 就没排好顺序
                        }
                        i++;
                    } else {  //大于9 时判断是否排好顺序  排好 添加标记 清除定时器
                        if (isfine) {
                            for (var k = 0; k < all.length - j; k++) {
                                all[k].classList.add("do");
                            }
                            clearInterval(timer);
                        } else {  //没有排好  给最后一个添加标记  外层循环开始  i重新计数
                            all[all.length - j - 1].classList.add("do");
                            j++;
                            i = 0;
                            isfine = true;
                        }
                    }
                } else {
                    clearInterval(timer);
                }
            }, 600);
		}
		
		
		//获取随机数
        function getVil(min, max) {
            return Math.round(Math.random() * (max - min) / 15) * 15 + min; //先缩小 再放大
        }


        //缓动动画
        function slow(ele, target) {
            if (ele.offsetLeft === target) {
                return;
            }
            if (ele.timer) {
                clearInterval(ele.timer);
            }
            //移动时添加标记
            ele.classList.add("move");
            ele.timer = setInterval(function () {
                var start = ele.offsetLeft;
                var step = (target - start) / 10;
                if (Math.abs(step) < 1) {
                    step = step > 0 ? 1 : Math.floor(step);
                }
                ele.style.left = start + step + "px";
                if (start + step === target) {
                    clearInterval(ele.timer);
                    ele.timer = null;
                    ele.classList.remove("move");
                }
            }, 1000 / 60)
        }

技巧

把删除的第一个元素添加到最后一个
box.push ( box.shift (  ) )
把删除的最后一个元素添加到第一个
box. unshift( box.pop( ) )
生成随机数
Math.floor(Math.random() * (max-min+1)) + min;
Math.round(Math.random() * (max-min)) + min;
随机数变异
Math.round(Math.random() * (max-min)/15)*15 + min; 避免相邻数的数值相近 先缩小 再放大 此处相差15
拼接字符串
str += `<li style = "height: ${num}px ; left: ${40 + 90 * i}px;"></li>`; 
动态添加 li 每个li的高度不同 距离左边距离也不同   使用 反引号 ` ` + ${ } 拼接