javaScript动画项目案例

javaScript动画项目案例

示例代码:我的github
demo效果演示示例:我的demo网站

1.动画库编写

匀速运动

案例一

效果:匀速运动





    
    
    Document
    



    

匀速运动

使用定时器控制位置

案例二:侧边栏效果

效果:侧边栏效果





    
    
    Document
    



    
拉开

缓动运动

效果:缓动运动
缓动运动就是通过控制速度,使动画达到淡出效果





    
    
    Document
    



    
拉开

注意:
speed = (end - box.offsetLeft)/20;
代表用(终点位置-当前位置)/动画系数
动画系数可以控制动画的快慢

透明度运动

效果:透明度运动
通过修改透明度变化进而修改动画




    
    
    Document
    


    

多物体运动

效果:多物体运动




    
    
    Document
    


    

注意:多物体运动时,定时器需要绑在对象上,清除定时器时,只需要清除自己的定时器即可

多值运动

效果:多值运动
将上述代码进一步封装,使其可以针对任意属性变化都能产生动画效果




    
    
    Document
    


    

链式运动

效果:链式运动
可以让物体先变宽再变长,只需要将上述代码加回调函数的参数即可
myAnimation.js

/**
 * 动画函数
 * @param {Object} obj 当前对象
 * @param {Object} attr 当前元素对象的属性
 * @param {Object} end 末尾位置
 * @param {Object} fn 回调函数
 * */
function startAnimation(obj,attr,end,fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        let cur = 0,speed = 0;
        if(attr === 'opacity'){
            cur = Math.round(parseFloat(getStyle(obj,attr)) * 100); 
            // console.log(getStyle(obj,attr));
        }else{
            cur = parseInt(getStyle(obj,attr));
        }
        if(end === cur){
            clearInterval(obj.timer);
            // 回调函数放在动画执行结束之后
            if(fn){
                fn();
            }
            return;
        }
        // 运动
        speed = end > cur ? 10:-10;
        if(attr === 'opacity'){
            // console.log(cur + speed);
            obj.style[attr] = (cur + speed) / 100;
            obj.style['filter'] = `alpha(opacity:${cur + speed})`;
        }else{
            obj.style[attr] = cur + speed + 'px';
        }
        
    },30)
}
// 获取属性
function getStyle(obj,attr) { 
    if(obj.currentStyle){
        // 针对IE浏览器
        return obj.currentStyle[attr];
    }else{
        // 针对于Firefox浏览器
        return getComputedStyle(obj,null)[attr];
    }
}

index.html




    
    
    Document
    


    

同时运动

效果:同时运动
可以让物体同时变长变宽,修改原来代码,将传入的属性和值改成传入json格式类型

动画库最终版本
myAnimation2.js

/**
 * 动画函数
 * @param {Object} obj 当前对象
 * @param {Object} json 当前元素属性列表
 * @param {Object} fn 回调函数
 * */
function startAnimation(obj,json,fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        let cur = 0,speed = 0;  
        let flag = true; // flag:代表所有动画执行完毕

        // 将json中所有元素属性遍历,修改
        for(attr in json){
            let end = json[attr];

            // 获取对象属性值
            switch(attr){
                case "opacity":
                    cur = Math.round(parseFloat(getStyle(obj,attr)) * 100);
                    break;
                case "scrollTop":
                    cur = obj[attr];
                    break;
                default:
                    cur = parseInt(getStyle(obj,attr));
            }

            // 临界处理 该动画没有执行完毕
            if(end !== cur){
                flag = false;
            }else{
                continue;
            }
            console.log(cur);
            // 设置速度:判断结束值end和当前值cur相差值小于speed速度
            if(end > cur){ 
                // end=100 cur=92   speed=10
                speed = end - cur < 100?end - cur:100;
            }else{
                // end=0 cur=2 speed=-10
                speed = end - cur > -100?end - cur:-100;
            }

            // 设置值
            switch(attr){
                case "opacity":
                    obj.style[attr] = (cur + speed) / 100;
                    obj.style['filter'] = `alpha(opacity:${cur + speed})`;
                    break;
                case "scrollTop":
                    obj[attr] = cur + speed;
                    break;
                default:
                    obj.style[attr] = cur + speed + 'px';
            }
        }
        // 查看flag是否为true,  都当所有属性都没有被修改时,flag为true,结束动画
        if(flag){
            clearInterval(obj.timer);
            if(fn){
                fn();
            }
            return ;
        }
    },30)
}
// 获取属性
function getStyle(obj,attr) { 
    if(obj.currentStyle){
        // 针对IE浏览器
        return obj.currentStyle[attr];
    }else{
        // 针对于Firefox浏览器
        return getComputedStyle(obj,null)[attr];
    }
}

使用for遍历json,将每个属性修改,直到最后,当每个属性都到最终值时,条件结束,清除定时器
index.html




    
    
    Document
    


    

案例

案例一:关闭页脚广告效果

效果:关闭页脚广告效果
点击关闭按钮,右下角广告就会先向下移动再向右移动至消失,具体myAnimation2.js文件在上述有写到
点击前往myAnimation2.js文件内容




    
    
    Document
    


    
    
    


案例二:侧边栏横幅效果

效果:侧边栏横幅效果
左侧中间的广告随着页面移动,而一直向中间移动的动画
点击前往myAnimation2.js文件内容




    
    
    Document
    


    

offsetTop 偏移量,相当于绝对定位的子盒子的top属性
docScroll 使用兼容性写法,因为获取滚动高度可能由于浏览器不同获取方法不同

案例三:淘宝侧边导航效果

效果:淘宝侧边导航效果
右侧侧边导航,随着页面移动,导航条上也移动到相应栏目;如果点击导航条上板块名,页面也会移动到相应板块处
点击前往myAnimation2.js文件内容




    
    
    Document
    


    
爱逛好货
好店直播
品质特色
实惠热卖

[…Divs] 使用了es6写法,将dom获取的集合类型转换为真正的数组,有forEach变量方法;这一步等价于使用for(element in Divs) 循环

案例四:轮播图

效果:轮播图
可以自动滚动,鼠标悬停时,取消滚动;可以上一页下一页,可以点击索引跳到相应位置
点击前往myAnimation2.js文件内容
index.html




    
    
    Document
    


    
    
    


index.css

*{
    padding: 0;
    margin: 0;
}
.slider{
    width: 400px;
    height: 500px;
    margin: 100px auto;
    position: relative;
    overflow: hidden;
}
.slider_scroll {
    position: relative;
    width: 400px;
    height: 500px;
}
.slider_main{
    position: relative;
    width: 400px;
    height: 500px;
}
.slider_main .item{
    width: 40px;
    height: 500px;
    position: absolute;
}
.slider_main .item img{
    width: 400px;
    height: 500px;
}
/* 索引部分 */
.slider_index{
    width: 400px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    color:#fff;
    font-weight: 700;
    z-index: 20;
    position: absolute;
    bottom: 0;
    background-color: rgba(0,0,0,.5);
}
.slider_index .slider_index_icon{
    margin: 0 10px;
    line-height: 40px;
    cursor: pointer;
}
.slider_index .slider_index_icon.current{
    color: red;
}
/* 下一张和上一张定位 */
.slider_scroll>span{
    position: absolute;
    width: 30px;
    height: 68px;
    background: url(../images/icon-slides.png) no-repeat;
    top: 50%;
    margin-top: -34px;
    cursor: pointer;
}
.slider_scroll span.next{
    right: 0;
    background-position: -46px 0;
}
.slider_scroll span.prev{
    left: 0;
    background-position: 0 0;
}

index.js

window.onload = function () {
    // 获取元素
    const slider = document.getElementById("slider");
    const slider_main = document.getElementById("slider_main");
    const slider_items = slider_main.children;
    
    const next = document.getElementById("next");
    const prev = document.getElementById("prev");

    const slider_index = document.getElementById("slider_index");
    
    let iNode = 0;  //当前显示索引的坐标  
    // 动态创建索引
    [...slider_items].forEach((v,i)=>{
        let span = document.createElement("span");
        span.innerText = i+1;
        // 给索引添加类
        if(i === 0){
            span.className = "slider_index_icon current"
        }else{
            span.className = "slider_index_icon"
        }

        slider_index.appendChild(span);
    })
    // 让滚动元素归位
    let scroll_w = this.parseInt(getStyle(slider,'width'));
    // console.log(scroll_w);
    [...slider_items].forEach((item,i,arr)=>{
        if(i !== 0){
            item.style.left = scroll_w + "px";
        }
    });
    // 下一步按钮
    function autoPlay() { 
        // 1.将显示的图片向左移动
        startAnimation(slider_items[iNode],{
            "left":-scroll_w
        });
        // 将下一张图片放在中心盒子的右边
        iNode++;
        if(iNode >= slider_items.length){
            iNode = 0;
        }
        // console.log(slider_items[iNode].left);
        slider_items[iNode].style.left = scroll_w + "px";
        // console.log(slider_items[iNode].left);
        // 将下一张图片向左移动
        startAnimation(slider_items[iNode],{
            "left":0
        });
        
        updateIndex();
     }
    next.onclick = autoPlay;
    // 更新索引样式
    let slider_index_items = slider_index.children;
    function updateIndex() {
        // console.log(slider_index_items);
        [...slider_index_items].forEach((item,i)=>{
            if(i == iNode){
                item.className = "slider_index_icon current";
            }else{
                item.className = "slider_index_icon"
            }
        })
    }
    //  上一步按钮
    prev.onclick = function () {
        // 1.将该元素右移动
        startAnimation(slider_items[iNode],{
            "left":scroll_w
        })
        // 2.将上一个元素放在左边
        iNode--;
        if(iNode < 0){
            iNode += slider_items.length
        }
        slider_items[iNode].style.left = -scroll_w + "px";
        // 3.将上一个元素右移
        startAnimation(slider_items[iNode],{
            "left":0
        })
        // 更新下面索引
        updateIndex();
    };
    // 设置索引点击事件
    [...slider_index_items].forEach((item,i)=> {
        item.onmousedown = function () {
            // 1.判断点击的索引与当前索引关系
            if(iNode > i){  // 上一张图片效果
                startAnimation(slider_items[iNode],{
                    "left":scroll_w
                })
                
                slider_items[i].style.left = -scroll_w + "px";


            }else if(iNode < i){  // 下一张图片效果
                startAnimation(slider_items[iNode],{
                    "left":-scroll_w
                })
                
                slider_items[i].style.left = scroll_w + "px";

            }
            iNode = i;
            startAnimation(slider_items[iNode],{
                "left":0
            })
            updateIndex();
        }
    });;
    // 设置自动播放
    let timer = window.setInterval(autoPlay,2000);
    // 设置鼠标悬浮停止定时器,离开开启定时器
    slider.onmouseover = function () {
        clearInterval(timer);
    }
    slider.onmouseout = function () {
        timer = window.setInterval(autoPlay,2000);
    }
}

图片部分,在上传到github上面时,已经将素材上传上去了。

你可能感兴趣的:(前端学习)