js动画效果 - 动画曲线

1 参考

  常见的动画都是速率相同的平滑效果,而有些动画在变动过程中速率不同,比如有些网站的返回顶部的动画效果会经过慢-快-慢的效果,这就设计到数学模型了,有一片参考文章:http://blog.csdn.net/jebe7282/article/details/7521067。这里讲解了tween算法代码。可以将里面的代码拷贝下来,可以直观的看到速度的曲率变化
  这里写图片描述

2 简化

  变换一下算法:http://greweb.me/2012/02/bezier-curve-based-easing-functions-from-concept-to-implementation/
 

EasingFunctions = {
  linear: function (t) { return t },
  easeInQuad: function (t) { return t*t },
  easeOutQuad: function (t) { return t*(2-t) },
  easeInOutQuad: function (t) { return t<.5 ? 2*t*t : -1+(4-2*t)*t },
  easeInCubic: function (t) { return t*t*t },
  easeOutCubic: function (t) { return (--t)*t*t+1 },
  easeInOutCubic: function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 },
  easeInQuart: function (t) { return t*t*t*t },
  easeOutQuart: function (t) { return 1-(--t)*t*t*t },
  easeInOutQuart: function (t) { return t<.5 ? 8*t*t*t*t : 1-8*(--t)*t*t*t },
  easeInQuint: function (t) { return t*t*t*t*t },
  easeOutQuint: function (t) { return 1+(--t)*t*t*t*t },
  easeInOutQuint: function (t) { return t<.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t }
}

这里只需要一个参数t:已用时间/总时间。

下面实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style lang="css">
        #test1 {
            background-color: aliceblue;
        }

        #test2 {
            background-color: aqua;
        }

        #test3 {
            background-color: aquamarine;
        }

        #test4 {
            background-color: cadetblue;
        }

        #test5 {
            background-color: aliceblue;
        }

        #test6 {
            background-color: aqua;
        }

        #test7 {
            background-color: aquamarine;
        }

        #test8 {
            background-color: cadetblue;
        }

        .box {
            width: 100%;
            height: 500px;
        }

        #backtop {
            position: fixed;
            right: 20px;
            bottom: 20px;
        }
    </style>
</head>

<body>
    <div id="test1" class="box"></div>
    <div id="test2" class="box"></div>
    <div id="test3" class="box"></div>
    <div id="test4" class="box"></div>
    <div id="test5" class="box"></div>
    <div id="test6" class="box"></div>
    <div id="test7" class="box"></div>
    <div id="test8" class="box"></div>
    <button id="backtop">顶部</button>
    <script>
        var requestAnimationFrame = window.requestAnimationFrame ||
            window.webkitRequestAnimationFrame ||
            window.mozRequestAnimationFrame ||
            window.msRquestAnimationFrame || function (fn) {
                setTimeout(fn, 15);
            }
        EasingFunctions = {
            linear: function (t) {
                return t
            },
            easeInQuad: function (t) {
                return t * t
            },
            easeOutQuad: function (t) {
                return t * (2 - t)
            },
            easeInOutQuad: function (t) {
                return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t
            },
            easeInCubic: function (t) {
                return t * t * t
            },
            easeOutCubic: function (t) {
                return (--t) * t * t + 1
            },
            easeInOutCubic: function (t) {
                return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1
            },
            easeInQuart: function (t) {
                return t * t * t * t
            },
            easeOutQuart: function (t) {
                return 1 - (--t) * t * t * t
            },
            easeInOutQuart: function (t) {
                return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t
            },
            easeInQuint: function (t) {
                return t * t * t * t * t
            },
            easeOutQuint: function (t) {
                return 1 + (--t) * t * t * t * t
            },
            easeInOutQuint: function (t) {
                return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t
            }
        }
        var position = function (start, end, elapsed, duration) {
            if (elapsed > duration) {
                return end;
            };
            return start + (end - start) * this.EasingFunctions.easeInOutQuint(elapsed / duration);
        }
        var smoothScroll = function (el) {
            var el = document.getElementById('test1');
            var duration = 1000;
            var clock = Date.now();
            var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop -
                el.offsetTop;
            var start = scrollTop;
            var end = 0;
            var _selt = this;
            var step = function () {
                console.log(1);
                var elapsed = Date.now() - clock;
                var position = _selt.position(start, end, elapsed, duration);
                window.scrollTo(0, position);
                if (elapsed > duration) {} else {
                    requestAnimationFrame(step);
                }
            }
            requestAnimationFrame(step);
        };
        document.getElementById('backtop').onclick = function () {
            var el = document.getElementById('test1')
            smoothScroll(el)
        };
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值