starling-framework
Version:
A fast, productive library for 2D cross-platform development.
136 lines (119 loc) • 3.76 kB
JavaScript
// Class: starling.animation.BezierEasing
var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this
$global.Object.defineProperty(exports, "__esModule", {value: true});
var __map_reserved = {};
// Imports
var $hxClasses = require("./../../hxClasses_stub").default;
var $import = require("./../../import_stub").default;
function js__$Boot_HaxeError() {return require("./../../js/_Boot/HaxeError");}
function openfl_errors_ArgumentError() {return $import(require("openfl/errors/ArgumentError"));}
function _$UInt_UInt_$Impl_$() {return require("./../../_UInt/UInt_Impl_");}
// Constructor
var BezierEasing = function(){}
// Meta
BezierEasing.__name__ = ["starling","animation","BezierEasing"];
BezierEasing.prototype = {
};
BezierEasing.prototype.__class__ = BezierEasing.prototype.constructor = $hxClasses["starling.animation.BezierEasing"] = BezierEasing;
// Init
// Statics
BezierEasing.create = function(x1,y1,x2,y2) {
if(x1 < 0 || x1 > 1 || x2 < 0 || x2 > 1) {
throw new (js__$Boot_HaxeError().default)(new (openfl_errors_ArgumentError().default)("x values must be in range [0, 1]"));
}
if(x1 == y1 && x2 == y2) {
return BezierEasing.linearEasing;
}
var sampleValues = [];
var _g = 0;
while(_g < 11) {
var i = _g++;
var tmp = BezierEasing.calcBezier(i * BezierEasing.SAMPLE_STEP_SIZE,x1,x2);
sampleValues[i] = tmp;
}
var getTForX = function(x) {
var intervalStart = 0.0;
var currentSample = 1;
var lastSample = 10;
while(currentSample != lastSample && sampleValues[currentSample] <= x) {
intervalStart += BezierEasing.SAMPLE_STEP_SIZE;
++currentSample;
}
--currentSample;
var dist = (x - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
var guessForT = intervalStart + dist * BezierEasing.SAMPLE_STEP_SIZE;
var initialSlope = BezierEasing.getSlope(guessForT,x1,x2);
if(initialSlope >= 0.001) {
return BezierEasing.newtonRaphsonIterate(x,guessForT,x1,x2);
} else if(initialSlope == 0.0) {
return guessForT;
} else {
return BezierEasing.binarySubdivide(x,intervalStart,intervalStart + BezierEasing.SAMPLE_STEP_SIZE,x1,x2);
}
};
var bezierEasing = function(ratio) {
if(ratio == 0) {
return 0;
} else if(ratio == 1) {
return 1;
} else {
return BezierEasing.calcBezier(getTForX(ratio),y1,y2);
}
};
return bezierEasing;
}
BezierEasing.calcBezier = function(t,a1,a2) {
return (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
}
BezierEasing.getSlope = function(t,a1,a2) {
return 3 * (1 - 3 * a2 + 3 * a1) * t * t + 2 * (3 * a2 - 6 * a1) * t + 3 * a1;
}
BezierEasing.binarySubdivide = function(ratio,a,b,x1,x2) {
var currentX;
var t;
var i = 0;
while(true) {
t = a + (b - a) / 2;
currentX = BezierEasing.calcBezier(t,x1,x2) - ratio;
if(currentX > 0) {
b = t;
} else {
a = t;
}
var tmp;
if(Math.abs(currentX) > 0.0000001) {
++i;
tmp = (_$UInt_UInt_$Impl_$().default).gt(10,i);
} else {
tmp = false;
}
if(!tmp) {
break;
}
}
return t;
}
BezierEasing.newtonRaphsonIterate = function(x,t,x1,x2) {
var _g = 0;
while(_g < 4) {
var i = _g++;
var currentSlope = BezierEasing.getSlope(t,x1,x2);
if(currentSlope == 0.0) {
return t;
}
var currentX = BezierEasing.calcBezier(t,x1,x2) - x;
t -= currentX / currentSlope;
}
return t;
}
BezierEasing.linearEasing = function(ratio) {
return ratio;
}
BezierEasing.NEWTON_ITERATIONS = 4
BezierEasing.NEWTON_MIN_SLOPE = 0.001
BezierEasing.SUBDIVISION_PRECISION = 0.0000001
BezierEasing.SUBDIVISION_MAX_ITERATIONS = 10
BezierEasing.SPLINE_TABLE_SIZE = 11
BezierEasing.SAMPLE_STEP_SIZE = 0.1
// Export
exports.default = BezierEasing;