-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathweb-animations-api-shiv.js
130 lines (108 loc) · 4.88 KB
/
web-animations-api-shiv.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/* WEB ANIMATIONS API SHIV :: https://github.com/wnda/web-animations-api-shiv */
;(function (win, doc) {
'use strict';
if ('animate' in HTMLElement.prototype) { return; }
HTMLElement.prototype.animate = function (js_keyframes, options) {
var _element = this;
var _animation_name = options.id ? options.id.toString() : createAnimationName(win.Date.now(), _element);
doc.head.insertAdjacentHTML('beforeEnd',
'<style data-waapiid="' + _animation_name + '">' +
'@' + getVendorPrefix(_element, 'animationName', true) + 'keyframes ' + _animation_name + '{' +
generateCSSKeyframes(_element, js_keyframes) +
'}' +
'[data-waapiel="' + _animation_name + '"] {' +
getAnimationCSS(_element, {
'animationDuration': options.duration ? options.duration + 'ms' : options + 'ms' || '0s',
'animationIterationCount': options.iterations === Infinity ? 'infinite' : options.iterations || '1',
'animationTimingFunction': options.easing || 'linear',
'animationDirection': options.direction || 'normal',
'animationFillMode': options.fill || '',
'animationDelay': options.delay || '0s',
'animationName': _animation_name || ''
}) + getCSSProperty(_element, 'animationPlayState') + ': running;' +
'}' +
'</style>'
);
_element.setAttribute('data-waapiel', _animation_name);
_element.playState = (function () {
return win.getComputedStyle(this)[getJSProperty(this, 'animationPlayState')];
}).call(_element);
_element.play = function () {
_element.style[getJSProperty(_element, 'animationPlayState')] = 'running';
};
_element.pause = function () {
_element.style[getJSProperty(_element, 'animationPlayState')] = 'paused';
};
_element.cancel = function () {
var _stylesheet = doc.querySelector('[data-waapiid="' + _animation_name + '"]');
_stylesheet.parentNode.removeChild(_stylesheet);
_element.removeAttribute('data-waapiel');
delete(_element.playState);
delete(_element.play);
delete(_element.pause);
delete(_element.cancel);
};
return _element;
};
function generateCSSKeyframes (element, js_keyframes) {
return js_keyframes.map(function (keyframe, idx, arr) {
var _offset = keyframe.offset || null;
var _easing = keyframe.easing || null;
var _keys = win.Object.keys(keyframe).filter(function (key) { return key !== 'offset' && key !== 'easing'; });
var _effects = getCSSProperty(element, _keys[0]) + ': ' + keyframe[_keys[0]] + '; ' +
(!!_easing ? getCSSProperty(element, 'animationTimingFunction') + ':' + _easing + ';' : '');
return buildKeyframeString(_effects, _offset, idx, arr.length);
}).join('');
}
function buildKeyframeString (effects, offset, idx, len) {
switch (!0) {
case !!(!!offset && (offset < 0 || offset > 1)):
return '';
case !!(idx === 0 && idx === (len - 1)):
return '0%, 100% {' + effects + '}';
case !!(idx === 0):
case !!(!!offset && offset === 0):
return '0% {' + effects + '}';
case !!(idx === (len - 1)):
case !!(!!offset && offset === 1):
return '100% {' + effects + '}';
case !!(!!offset && offset > 0 && offset < 1):
return (offset * 1e2).toFixed(2) + '% {' + effects + '}';
default:
return (((idx + 1) / len) * 1e2).toFixed(2) + '% {' + effects + '}';
}
}
function getCSSProperty (element, prop) {
return getVendorPrefix(element, prop, true) + convertToCSSProp(prop);
}
function getJSProperty(element, prop) {
return getVendorPrefix(element, prop, false) + prop;
}
function getVendorPrefix (element, prop, css) {
var _js_props = element.style;
var _js_prop = prop.substr(0,1).toUpperCase() + prop.substr(1);
var _prefix = (prop in _js_props ? '' :
'webkit' + _js_prop in _js_props ? 'webkit' :
'moz' + _js_prop in _js_props ? 'moz' :
'ms' + _js_prop in _js_props ? 'ms' :
'o' + _js_prop in _js_props ? 'o' :
'') || '';
return !!css && !!_prefix ? '-' + _prefix + '-' : _prefix;
}
function convertToCSSProp (str) {
return str.split('').map(function (char) {
if (char === char.toLowerCase()) { return char; }
else { return '-' + char.toLowerCase() }
}).join('');
}
function getAnimationCSS (element, css) {
return win.Object.keys(css).filter(function (pair) {
return !!css[pair];
}).map(function (pair) {
return getCSSProperty(element, pair) + ': ' + css[pair] + '; ';
}).join('');
}
function createAnimationName (current_time, element) {
return 'WAAPI-' + current_time.toString() + ([].slice.call(doc.getElementsByTagName('*')).indexOf(element)).toString();
}
})(window, document);