zoukankan      html  css  js  c++  java
  • 利用requestAnimationFrame和Tween算法实现兼容所有浏览器的运动动画,直接秒杀Css3动画

    以下贴出Tween的代码:

    /*
     * Tween.js
     * t: current time(当前时间);
     * b: beginning value(初始值);
     * c: change in value(变化量);
     * d: duration(持续时间)。
     * you can visit 'http://easings.net/zh-cn' to get effect
    */
    var Tween = {
        Linear: function(t, b, c, d) { return c*t/d + b; },
        Quad: {
            easeIn: function(t, b, c, d) {
                return c * (t /= d) * t + b;
            },
            easeOut: function(t, b, c, d) {
                return -c *(t /= d)*(t-2) + b;
            },
            easeInOut: function(t, b, c, d) {
                if ((t /= d / 2) < 1) return c / 2 * t * t + b;
                return -c / 2 * ((--t) * (t-2) - 1) + b;
            }
        },
        Cubic: {
            easeIn: function(t, b, c, d) {
                return c * (t /= d) * t * t + b;
            },
            easeOut: function(t, b, c, d) {
                return c * ((t = t/d - 1) * t * t + 1) + b;
            },
            easeInOut: function(t, b, c, d) {
                if ((t /= d / 2) < 1) return c / 2 * t * t*t + b;
                return c / 2*((t -= 2) * t * t + 2) + b;
            }
        },
        Quart: {
            easeIn: function(t, b, c, d) {
                return c * (t /= d) * t * t*t + b;
            },
            easeOut: function(t, b, c, d) {
                return -c * ((t = t/d - 1) * t * t*t - 1) + b;
            },
            easeInOut: function(t, b, c, d) {
                if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
                return -c / 2 * ((t -= 2) * t * t*t - 2) + b;
            }
        },
        Quint: {
            easeIn: function(t, b, c, d) {
                return c * (t /= d) * t * t * t * t + b;
            },
            easeOut: function(t, b, c, d) {
                return c * ((t = t/d - 1) * t * t * t * t + 1) + b;
            },
            easeInOut: function(t, b, c, d) {
                if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
                return c / 2*((t -= 2) * t * t * t * t + 2) + b;
            }
        },
        Sine: {
            easeIn: function(t, b, c, d) {
                return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
            },
            easeOut: function(t, b, c, d) {
                return c * Math.sin(t/d * (Math.PI/2)) + b;
            },
            easeInOut: function(t, b, c, d) {
                return -c / 2 * (Math.cos(Math.PI * t/d) - 1) + b;
            }
        },
        Expo: {
            easeIn: function(t, b, c, d) {
                return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
            },
            easeOut: function(t, b, c, d) {
                return (t==d) ? b + c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
            },
            easeInOut: function(t, b, c, d) {
                if (t==0) return b;
                if (t==d) return b+c;
                if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
                return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
            }
        },
        Circ: {
            easeIn: function(t, b, c, d) {
                return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
            },
            easeOut: function(t, b, c, d) {
                return c * Math.sqrt(1 - (t = t/d - 1) * t) + b;
            },
            easeInOut: function(t, b, c, d) {
                if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
                return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
            }
        },
        Elastic: {
            easeIn: function(t, b, c, d, a, p) {
                var s;
                if (t==0) return b;
                if ((t /= d) == 1) return b + c;
                if (typeof p == "undefined") p = d * .3;
                if (!a || a < Math.abs(c)) {
                    s = p / 4;
                    a = c;
                } else {
                    s = p / (2 * Math.PI) * Math.asin(c / a);
                }
                return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
            },
            easeOut: function(t, b, c, d, a, p) {
                var s;
                if (t==0) return b;
                if ((t /= d) == 1) return b + c;
                if (typeof p == "undefined") p = d * .3;
                if (!a || a < Math.abs(c)) {
                    a = c; 
                    s = p / 4;
                } else {
                    s = p/(2*Math.PI) * Math.asin(c/a);
                }
                return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
            },
            easeInOut: function(t, b, c, d, a, p) {
                var s;
                if (t==0) return b;
                if ((t /= d / 2) == 2) return b+c;
                if (typeof p == "undefined") p = d * (.3 * 1.5);
                if (!a || a < Math.abs(c)) {
                    a = c; 
                    s = p / 4;
                } else {
                    s = p / (2  *Math.PI) * Math.asin(c / a);
                }
                if (t < 1) return -.5 * (a * Math.pow(2, 10* (t -=1 )) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
                return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p ) * .5 + c + b;
            }
        },
        Back: {
            easeIn: function(t, b, c, d, s) {
                if (typeof s == "undefined") s = 1.70158;
                return c * (t /= d) * t * ((s + 1) * t - s) + b;
            },
            easeOut: function(t, b, c, d, s) {
                if (typeof s == "undefined") s = 1.70158;
                return c * ((t = t/d - 1) * t * ((s + 1) * t + s) + 1) + b;
            },
            easeInOut: function(t, b, c, d, s) {
                if (typeof s == "undefined") s = 1.70158; 
                if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
                return c / 2*((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
            }
        },
        Bounce: {
            easeIn: function(t, b, c, d) {
                return c - Tween.Bounce.easeOut(d-t, 0, c, d) + b;
            },
            easeOut: function(t, b, c, d) {
                if ((t /= d) < (1 / 2.75)) {
                    return c * (7.5625 * t * t) + b;
                } else if (t < (2 / 2.75)) {
                    return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
                } else if (t < (2.5 / 2.75)) {
                    return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
                } else {
                    return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
                }
            },
            easeInOut: function(t, b, c, d) {
                if (t < d / 2) {
                    return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
                } else {
                    return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
                }
            }
        }
    }
    Math.tween = Tween;

    requestAnimationFrame兼容性代码:

    (function() {
        var lastTime = 0;
        var vendors = ['webkit', 'moz'];
        for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
            window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
            window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||    // name has changed in Webkit
                                          window[vendors[x] + 'CancelRequestAnimationFrame'];
        }
    
        if (!window.requestAnimationFrame) {
            window.requestAnimationFrame = function(callback, element) {
                var currTime = new Date().getTime();
                var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));
                var id = window.setTimeout(function() {
                    callback(currTime + timeToCall);
                }, timeToCall);
                lastTime = currTime + timeToCall;
                return id;
            };
        }
        if (!window.cancelAnimationFrame) {
            window.cancelAnimationFrame = function(id) {
                clearTimeout(id);
            };
        }
    }());

    调用方式和setTime类似

    实际案例:

    <!DOCTYPE html>
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>requestAnimationFrame实现皮球落地的缓动效果</title>
    <script>
    document.createElement("ball");
    document.createElement("shadow");
    </script>
    <style>
    .demo {
        height: 600px;
        position: relative;
    }
    h4 {
        text-align: center;
        font-size: 110%;
    }
    ball {
        width: 100px; height: 100px; border-radius: 100px;
        position: absolute; left: 50%; top: 500px;
        margin-left: -50px;
        background-color: #34538b;
        background-image: -webkit-radial-gradient(100px 100px at 50px 20px, #a0b3d6, #34538b);
        background-image:    -moz-radial-gradient(100px 100px at 50px 20px, #a0b3d6, #34538b);
        background-image:         radial-gradient(100px 100px at 50px 20px, #a0b3d6, #34538b);
        cursor: move;
        z-index: 1;
    }
    shadow {
        position: absolute;
        width: 100px; height: 30px;
        position: absolute; left: 50%; bottom: 5px;
        margin-left: -50px;
        background-image: -webkit-radial-gradient(ellipse closest-side, rgba(0,0,0,.75), rgba(0,0,0,0));
        background-image:    -moz-radial-gradient(ellipse closest-side, rgba(0,0,0,.75), rgba(0,0,0,0));
        background-image:         radial-gradient(ellipse closest-side, rgba(0,0,0,.75), rgba(0,0,0,0));
    }
    </style>
    </head>
    <body>
    <div id="main">
        <h1>requestAnimationFrame实现皮球落地的缓动效果实例页面</h1>
        <div id="body" class="light">
            <div id="content" class="show">
                <h3>展示</h3>
                <div class="demo">
                    <h4>向上拖动小球然后放下</h4>
                    <ball></ball><shadow></shadow>         
                </div>
            </div>       
        </div>
    </div>
    <script src="js/jquery.min.js"></script>
    <script src="js/requestAnimationFrame.js"></script>
    <script src="js/tween.js"></script>
    <script>
    var ball = $("ball"), shadow = $("shadow");
    var objBall = {};
    var shadowWithBall = function(top) {
        // 0 ~ 500
        var top = top || parseInt(ball.css("top")),
        scale = 1 + (500 - top) / 500;
        opacity = 1 - (500 - top) / 500;
        if (opacity < 0) opacity = 0;
        shadow.css("opacity", opacity)
        .css("WebkitTransform", "scale("+ [scale, scale].join(",") +")")
        .css("transform", "scale("+ [scale, scale].join(",") +")");
    }, funFall = function() {
        var start = 0, during = 100;
        var _run = function() {
            start++;
            var top = Tween.Bounce.easeOut(start, objBall.top, 500 - objBall.top, during);
            ball.css("top", top);
            shadowWithBall(top);
            if (start < during) requestAnimationFrame(_run);
        };
        _run();
    };
    ball.bind("mousedown", function(event) {
        objBall.pageY = event.pageY;
        objBall.flagFollow = true;    
    });
    $(document).bind("mousemove", function(event) {
        if (objBall.flagFollow) {
            var pageY = event.pageY;
            console.log(objBall.pageY + " === " + pageY);
            objBall.top = 500 - (objBall.pageY - pageY);
            if (objBall.top < 0) {
                objBall.top = 0;
            } else if (objBall.top > 500) {
                objBall.top = 500;
            }
            //cosnole.log(objBall.top);
            ball.css("top", objBall.top);
            shadowWithBall(objBall.top);    
        }
    });
    $(document).bind("mouseup", function(event) {
        if (objBall.flagFollow) funFall();
        objBall.flagFollow = false;    
    });
    </script>
    </body>
    </html>
  • 相关阅读:
    (Go)03.go类型
    (Go)02.go 安装delve调试工具测试
    (Go)01.Windows 安装 Go语言开发环境以及使用
    etcd创建集群并增加节点
    libhiredis.so.0.13 => not found 缺少
    Linux查找并杀死僵尸进程
    k8s istio 配置请求的路由规则
    k8s 安装并试用Istio service mesh
    k8s Job、Cronjob 的使用
    k8s Gitlab CI/CD 之自动编译Docker镜像并推送到指定的Registry
  • 原文地址:https://www.cnblogs.com/fengyuqing/p/requestAnimationFrame.html
Copyright © 2011-2022 走看看