Javascript使用三大家族和事件来DIY动画效果相关笔记(六)

1.图片轮播之旋转木马

◆原理:将每张图片的样式都存到一个数组中,每一张图片的样式有多个,所以那个数组里面的元素都是对象,通过制作的缓速框架,移动每一张图片对象,缓速改变图片的样式,缓速改变的样式都在数组元素的对象里,所以改变了数组中元素的位置,就让图片轮播起来,并且还是以旋转木马的方式,通过将第一个元素shift然后push达到顺时针旋转,通过将最后一个元素pop然后unshift达到逆时针旋转。防止狂点的方法是,定义一个标识,一开始这个表示为true,当点击一下之后,把这个标识赋值为false,等整个动画都执行完毕之后,在赋值为true,这样就能防止动画没有结束完毕右执行了下一个动画。

◆技巧:先定义一个数组,数组中的元素是json;json中的元素是属性。点击一个按钮,按顺序更换数组中元素的位置。(如果想完成旋转木马,只需要更换数组中元素的位置)

◆步骤:

    ◇.必须让页面加载的时候把所有的属性加载出来
    ◇鼠标放到大盒子上显示对应的左右切换按钮,移开隐藏
    ◇获取两个按钮。对他们进行事件绑定。对他们进行判断。
    ◇如果是左侧的按钮执行一套程序,如果是右侧的按钮执行另一套程序。
    ◇绑定按钮的函数,一个是正转,一个是反转。(传参确定)

    ◇调换相应的数组对应的元素。(先删除谁,在怎么添加)

◆正方向轮播与反方向轮播:

    ◇最开始是:12345;我想让他变成:23451
    ◇把1删除,在最后添加1;
    ◇在数组json中,删除第一个元素,添加到最末尾。(正转)

    ◇在数组json中,删除最后一个元素,添加到第一位。(反转)

◆函数节流:定义一个变量,只有函数执行完毕在去执行下一个。

★轮播动画旋转木马

    ☆index.js

/**
 * 功能:获取兼容borderRadius的getStyle框架
 * @param elemnet
 * @param attribute
 * @returns {string}
 */
function getStyle(elemnet, attribute) {
    // 左边||右边
    // 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
    // 右边只能够获取到行内式的border-radius
    // 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
    // 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
    var sty = (elemnet.currentStyle
                ?
                elemnet.currentStyle[attribute]
                :
                window.getComputedStyle(elemnet, null)[attribute]
        ) || elemnet.style[attribute];
    //判断获取到的值是否为空字符串
    if ("" == sty) {
        switch (attribute) {
            case "borderRadius":
            case "border-radius":
                (sty = elemnet.currentStyle
                    ?
                    elemnet.currentStyle["border-top-left-radius"]
                    :
                    window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
                break;
            default:
                sty;
                break;
        }
    }
    return sty;
}

//3.封装animate缓速框架
/**
 * 功能:缓速改变元素的样式属性值 达到缓速动画的效果
 * @param element
 * @param styleJson
 * @param fn
 */
function animate(element, styleJson, fn) {
    //使用定时器之前必须先清除定时器
    clearInterval(element.timer);
    //开始使用定时器
    element.timer = setInterval(function () {
        //开闭思想 当每一个样式对象的成员都达到目标时
        element.bool = true;

        //遍历需要变化的每一个样式对象成员
        for (var key in styleJson) {
            //key 就是要变化的样式属性名
            //styleJson[key] 就是要变化的样式的属性的目标值

            //首先防止 突发情况的发生
            //例如:按住ctrl键然后鼠标滑轮滚动
            // 导致getStyle获取到的值本来没有小数,
            // 变得带有小数了,解决这个问题的方法是
            // 先替换掉px,然后再向上取整即可,
            // 就算你本来的值是有小数的,
            // 但是向上取整在整个动画中的改变也是没什么的。
            // 如果使用parseInt会导致getStyle获取到的值为0.9时
            // 变成0,所以不用parseInt向下取整。
//                element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;

            //如果值为透明度时
            if (key == "opacity") {
                element.leader = 100 * (getStyle(element, key).replace("px", "") / 1 || 1);
            } else {
                element.leader = Math.ceil(getStyle(element, key).replace("px", "") / 1) || 0;
            }

            //缓速步长的第一次获取
            element.speed = (styleJson[key] - element.leader) / 10;
            //缓速步长的第二次计算
            element.speed = element.speed > 0 ? Math.ceil(element.speed) : Math.floor(element.speed);

            //匀速步长的计算
            //element.speed = styleJson[key] > element.leader ? 10 : -10;

            //只剩一步之遥时
            if (Math.abs(styleJson[key] - element.leader) <= Math.abs(element.speed)) {

                //如果值为透明度时
                if (key == "opacity") {
                    element.style[key] = styleJson[key] / 100;
                    element.style["fliter"] = "alpha(opacity=" + styleJson[key] + ")";
                    continue;
                } else if (key == "z-index" || key == "zIndex") {//如果为层级时
                    element.style[key] = styleJson[key];
                    continue;
                }

                element.style[key] = styleJson[key] + "px";
                continue;
            } else {
                //只要有一个样式对象的成员没有达到目标
                // 这个清除定时器的bool值就为false
                element.bool = false;
            }

            //如果值为透明度时
            if (key == "opacity") {
                element.style[key] = (element.leader + element.speed) / 100;
                element.style["fliter"] = "alpha(opacity=" + (element.leader + element.speed) + ")";
                continue;
            } else if (key == "z-index" || key == "zIndex") { //如果为层级时
                element.style[key] = element.leader + element.speed;
                continue;
            }

            //开始移动
            element.style[key] = element.leader + element.speed + "px";
        }
        console.log(1);//测试定时器有没有停下来

        //是否都达到要求了
        if (element.bool) {
            clearInterval(element.timer);

            //回调函数是否存在
            if (fn) {
                //执行回调函数
                fn();
            }
        }
    }, 18);
}

    ☆json.js

var arr = [
    {   //  1
        width:350,
        top:50,
        left:225,
        opacity:10,
        z:1
    },
    {   //  1
        width:400,
        top:70,
        left:50,
        opacity:20,
        z:2
    },
    {  // 2
        width:600,
        top:120,
        left:0,
        opacity:80,
        z:3
    },
    {   // 3
        width:800,
        top:100,
        left:200,
        opacity:100,
        z:4
    },
    {  // 4
        width:600,
        top:120,
        left:600,
        opacity:80,
        z:3
    },
    {   //5
        width:400,
        top:70,
        left:750,
        opacity:20,
        z:2
    }
    ,
    {   //5
        width:350,
        top:50,
        left:625,
        opacity:10,
        z:1
    }
];

    ☆html:轮播图片大小800*500




    
    轮播动画旋转木马
    




2.有些样式的属性值,在某些浏览器上是无法直接获取的,原来的内嵌式与外链式的获取方式还有行内式的获取方式也是无法直接获取的,只能够通过获取获取其子样式属性来获取,于是以下是getStyle新版本的封装,兼容border-radius的获取

/**
     * 功能:获取兼容borderRadius的getStyle框架
     * @param elemnet
     * @param attribute
     * @returns {string}
     */
    function getStyle(elemnet, attribute) {
        // 左边||右边
        // 左边在有些主流浏览器上获取不到内嵌式和外链式以及行内式的border-radius
        // 右边只能够获取到行内式的border-radius
        // 所以无论是左边还是右边,在某些浏览器上 肯定获取不到内嵌式和外链式的 border-radius
        // 当左边和右边都获取不到时,返回值都是""空字符串,于是就判断一下 是否是border-radius
        var sty = (elemnet.currentStyle
                                ?
                                elemnet.currentStyle[attribute]
                                :
                                window.getComputedStyle(elemnet, null)[attribute]
                ) || elemnet.style[attribute];
        //判断获取到的值是否为空字符串
        if ("" == sty) {
            switch (attribute) {
                case "borderRadius":
                case "border-radius":
                    (sty = elemnet.currentStyle
                            ?
                            elemnet.currentStyle["border-top-left-radius"]
                            :
                            window.getComputedStyle(elemnet, null)["border-top-left-radius"]);
                    break;
                default:
                    sty;
                    break;
            }
        }
        return sty;
    }

3.改进改进兼容性缓速框架

◆改进兼容性缓速框架(高级版)-圆边框样式




    
    改进兼容性缓速框架(高级版)-圆边框样式
    


◆改进兼容性缓速框架(高级版)-透明度样式



    
    改进兼容性缓速框架(高级版)-透明度样式
    


◆改进兼容性缓速框架(高级版)-层级的改变



    
    改进兼容性缓速框架(高级版)-层级的改变
    



转载于:https://www.cnblogs.com/jwlLWJ2018/p/9247735.html

你可能感兴趣的:(Javascript使用三大家族和事件来DIY动画效果相关笔记(六))