-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
74 lines (61 loc) · 2.32 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Tween a given t value based on a bezier curve specified
// in SVG path data format.
//
// * Use Illustrator/Sketch to create easing functions,
// ala https://github.com/legomushroom/copy-path-coordinates
// * Use your easing curves to create delay, allowing
// you to easily understand and coordinate multiple
// animations by keeping their durations the same.
// * Easily combine easing curves.
//
// Options:
//
// * sampleCount - default: 300
// The number of samples to generate. The larger the
// number the more accurate the easing, at the expense
// of initialization time.
// * height - default: 100
// The height of the assumed viewBox.
// * width - default: 100
// The width of the assumed viewBox.
//
// Inspired by Oleg Solomka’s work on http://mojs.io/
function pathEasing(pathData, options, window = window) {
options = options || {};
var sampleCount = (options.samples === undefined) ? 300 : options.samples;
var height = (options.height === undefined) ? 100 : options.height;
var width = (options.width === undefined) ? 100 : options.width;
var path = window.document.createElementNS('http://www.w3.org/2000/svg', 'path');
path.setAttribute('d', pathData);
var pathLength = path.getTotalLength();
var sampleCountPct = 1 / sampleCount;
var xSamples = new Float64Array(sampleCount);
var ySamples = new Float64Array(sampleCount);
var preComputeStart = window.performance.now();
for (var i = 0; i < sampleCount; i++) {
var point = path.getPointAtLength(sampleCountPct * i * pathLength);
xSamples[i] = point.x / width;
ySamples[i] = 1 - point.y / height;
}
var preComputeEnd = window.performance.now();
// Takes a value t between 0 and 1 and returns
// the value of t eased based on the given bezier
// path’s y value.
function tween(t) {
// A simple search that loops over every sample
// each time until it finds a sample for the given
// t x value. No doubt this could be optimized.
for (var n = 0; n < xSamples.length; n++) {
if (xSamples[n] == t || (xSamples[n] < t && xSamples[n + 1] > t)) {
return ySamples[n];
}
}
return t;
}
// Expose some handy properties.
tween.path = path;
tween.preComputeTime = preComputeEnd - preComputeStart;
tween.sampleCount = sampleCount;
return tween;
}
module.exports = pathEasing;