Показать сообщение отдельно
  #8 (permalink)  
Старый 24.12.2015, 09:40
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,109

Ruslan_xDD,
http://cubic-bezier.com/#.16,.73,.88,.39
https://github.com/gre/bezier-easing
<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="robots" content="noindex">
  <title> - jsFiddle demo</title>

  <style type='text/css'>
    html, body {
  height: 3000px;
}

#totop {
  position: fixed;
  bottom: 10%;
  right: 10%;
  background: red;
  width: 50px;
  height: 50px;
  cursor: pointer;
  opacity: 0;
  transition: all 0.5s linear;
  visibility: hidden;
}
#totop.show {
  opacity: 1;
  visibility: visible;
}
  </style>




<script>
var NEWTON_ITERATIONS = 4,
    NEWTON_MIN_SLOPE = .001,
    SUBDIVISION_PRECISION = 1E-7,
    SUBDIVISION_MAX_ITERATIONS = 10,
    kSplineTableSize = 11,
    kSampleStepSize = 1 / (kSplineTableSize - 1),
    float32ArraySupported = "function" === typeof Float32Array;

function A(a, b) {
    return 1 - 3 * b + 3 * a
}

function B(a, b) {
    return 3 * b - 6 * a
}

function C(a) {
    return 3 * a
}

function calcBezier(a, b, c) {
    return ((A(b, c) * a + B(b, c)) * a + C(b)) * a
}

function getSlope(a, b, c) {
    return 3 * A(b, c) * a * a + 2 * B(b, c) * a + C(b)
}

function binarySubdivide(a, b, c, d, e) {
    var f, g, h = 0;
    do g = b + (c - b) / 2, f = calcBezier(g, d, e) - a, 0 < f ? c = g : b = g; while (Math.abs(f) > SUBDIVISION_PRECISION && ++h < SUBDIVISION_MAX_ITERATIONS);
    return g
}

function newtonRaphsonIterate(a, b, c, d) {
    for (var e = 0; e < NEWTON_ITERATIONS; ++e) {
        var f = getSlope(b, c, d);
        if (0 === f) break;
        var g = calcBezier(b, c, d) - a;
        b -= g / f
    }
    return b
}

function BezierEasing(a, b, c, d) {
    if (4 === arguments.length) return new BezierEasing([a, b, c, d]);
    if (!(this instanceof BezierEasing)) return new BezierEasing(a);
    if (!a || 4 !== a.length) throw Error("BezierEasing: points must contains 4 values");
    for (var e = 0; 4 > e; ++e)
        if ("number" !== typeof a[e] || isNaN(a[e]) || !isFinite(a[e])) throw Error("BezierEasing: points should be integers.");
    if (0 > a[0] || 1 < a[0] || 0 > a[2] || 1 < a[2]) throw Error("BezierEasing x values must be in [0, 1] range.");
    this._str = "BezierEasing(" + a + ")";
    this._css =
        "cubic-bezier(" + a + ")";
    this._p = a;
    this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : Array(kSplineTableSize);
    this._precomputed = !1;
    this.get = this.get.bind(this)
}
BezierEasing.prototype = {
    get: function(a) {
        var b = this._p[0],
            c = this._p[1],
            d = this._p[2],
            e = this._p[3];
        this._precomputed || this._precompute();
        return b === c && d === e ? a : 0 === a ? 0 : 1 === a ? 1 : calcBezier(this._getTForX(a), c, e)
    },
    getPoints: function() {
        return this._p
    },
    toString: function() {
        return this._str
    },
    toCSS: function() {
        return this._css
    },
    _precompute: function() {
        var a = this._p[0],
            b = this._p[1],
            c = this._p[2],
            d = this._p[3];
        this._precomputed = !0;
        a === b && c === d || this._calcSampleValues()
    },
    _calcSampleValues: function() {
        for (var a = this._p[0],
                b = this._p[2], c = 0; c < kSplineTableSize; ++c) this._mSampleValues[c] = calcBezier(c * kSampleStepSize, a, b)
    },
    _getTForX: function(a) {
        for (var b = this._p[0], c = this._p[2], d = this._mSampleValues, e = 0, f = 1, g = kSplineTableSize - 1; f !== g && d[f] <= a; ++f) e += kSampleStepSize;
        --f;
        d = e + (a - d[f]) / (d[f + 1] - d[f]) * kSampleStepSize;
        f = getSlope(d, b, c);
        return f >= NEWTON_MIN_SLOPE ? newtonRaphsonIterate(a, d, b, c) : 0 === f ? d : binarySubdivide(a, e, e + kSampleStepSize, b, c)
    }
};
BezierEasing.css = {
    ease: BezierEasing.ease = BezierEasing(.25, .1, .25, 1),
    linear: BezierEasing.linear = BezierEasing(0, 0, 1, 1),
    "ease-in": BezierEasing.easeIn = BezierEasing(.42, 0, 1, 1),
    "ease-out": BezierEasing.easeOut = BezierEasing(0, 0, .58, 1),
    "ease-in-out": BezierEasing.easeInOut = BezierEasing(.42, 0, .58, 1)
};
</script>
<script>
window.onload = function() {
    var toTop = document.getElementById("totop"),
        toTopIsVisible = false,
        duration = 1000,
        play = false;
    window.onscroll = function() {
        if (window.pageYOffset > document.documentElement.clientHeight != toTopIsVisible) {
            toTopIsVisible = !toTopIsVisible;
            toTop.classList.toggle("show", toTopIsVisible)
        }
    };


    //var easing = BezierEasing.easeInOut;
    var easing = BezierEasing(.42,0,.58,1)
    toTop.onclick = function(e) {
        if (play) return;
        play = true;
        var d = performance.now();
        var from = window.pageYOffset;
        window.requestAnimationFrame(function foo(a) {
            var a = (a - d) / duration;
            1 < a && (a = 1);
            var progress = easing.get(a);
            window.scrollTo(0, from - from * progress);
            if (a == 1) {
                play = false;
               alert(performance.now() - d)
            } else window.requestAnimationFrame(foo)
        });
        return false
    }
};
</script>

</head>
<body>
  <a href="#" id="totop"></a>

</body>

</html>

Последний раз редактировалось рони, 24.12.2015 в 19:08.
Ответить с цитированием