anime_js_rails 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +58 -0
- data/Rakefile +2 -0
- data/anime_js_rails.gemspec +25 -0
- data/lib/anime_js_rails.rb +9 -0
- data/lib/anime_js_rails/version.rb +3 -0
- data/vendor/assets/javascripts/anime.js +634 -0
- metadata +97 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4475bff5d8cd4d3fcfbfe2bbcab4256586c2fbc7
|
4
|
+
data.tar.gz: 2b9526c177aeac9f6402e25edd4597eebb4e8a64
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d302052b4448652f9d81dea7d441ca8fb682689ac76a369218e98fae82b38c4aa150708be72a9e2368cc67e4491d1ab1288f5edc853f220ccfff9c4477f6da28
|
7
|
+
data.tar.gz: c266fcb69f347271a105b842fd8029a07f4620328414e2520819afa359ef650be1dafd6d4f0527d254e9077f3f04a368f0e64ac8d158488d6650b93f3c91129b
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2016 Guinsly Mondesir
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# AnimeJsRails
|
2
|
+
|
3
|
+
Makes it simple to include the [anime.js](https://github.com/juliangarnier/anime) library in the Rails asset pipeline.
|
4
|
+
|
5
|
+
|
6
|
+
### Animation example
|
7
|
+
|
8
|
+
```javascript
|
9
|
+
var myAnimation = anime({
|
10
|
+
targets: ['.blue', '.green'],
|
11
|
+
translateX: '13rem',
|
12
|
+
rotate: 180,
|
13
|
+
borderRadius: 8,
|
14
|
+
duration: 2000,
|
15
|
+
loop: true
|
16
|
+
});
|
17
|
+
```
|
18
|
+
|
19
|
+

|
20
|
+
|
21
|
+
[Live example on CodePen](http://codepen.io/juliangarnier/pen/42673ea42700509510c80dcf83d5fc22?editors=0010)
|
22
|
+
|
23
|
+
## Installation
|
24
|
+
|
25
|
+
Add this line to your application's Gemfile:
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
gem 'anime_js_rails'
|
29
|
+
```
|
30
|
+
|
31
|
+
And then execute:
|
32
|
+
|
33
|
+
$ bundle
|
34
|
+
|
35
|
+
Or install it yourself as:
|
36
|
+
|
37
|
+
$ gem install anime_js_rails
|
38
|
+
|
39
|
+
|
40
|
+
### Configuration Ruby on Rails
|
41
|
+
```ruby
|
42
|
+
#app/assets/javascript/application.js
|
43
|
+
//= require anime
|
44
|
+
#config/initializers/assets.rb
|
45
|
+
Rails.application.config.assets.precompile += %w( anime.js )
|
46
|
+
#or
|
47
|
+
Rails.application.config.assets.precompile += [/.*\.js/,/.*\.css/]
|
48
|
+
```
|
49
|
+
|
50
|
+
|
51
|
+
## Contributing
|
52
|
+
|
53
|
+
1. Star it
|
54
|
+
2. Fork it ( https://github.com/guinslym/anime_js_rails )
|
55
|
+
3. Create your feature branch (`git checkout -b my-new-feature`)
|
56
|
+
4. Commit your changes (`git commit -am 'Add some feature'`)
|
57
|
+
5. Push to the branch (`git push origin my-new-feature`)
|
58
|
+
6. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'anime_js_rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "anime_js_rails"
|
8
|
+
spec.version = AnimeJsRails::VERSION
|
9
|
+
spec.authors = ["Guinsly Mondesir"]
|
10
|
+
spec.email = ["guinslym@users.noreply.github.com"]
|
11
|
+
spec.description = %q{Makes it simple to include the anime.js library (by Guinsly Mondesir) in the Rails asset pipeline.}
|
12
|
+
spec.summary = %q{Anime (/ˈæn.ə.meɪ/) is a flexible yet lightweight JavaScript animation library.
|
13
|
+
It works with CSS, Individual Transforms, SVG, DOM attributes and JS Objects}
|
14
|
+
spec.homepage = "https://github.com/guinslym/anime_js_rails"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
23
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
24
|
+
spec.add_development_dependency "rails", "> 3.1.0"
|
25
|
+
end
|
@@ -0,0 +1,634 @@
|
|
1
|
+
/*
|
2
|
+
* Anime v1.1.0
|
3
|
+
* http://anime-js.com
|
4
|
+
* JavaScript animation engine
|
5
|
+
* Copyright (c) 2016 Julian Garnier
|
6
|
+
* http://juliangarnier.com
|
7
|
+
* Released under the MIT license
|
8
|
+
*/
|
9
|
+
|
10
|
+
(function (root, factory) {
|
11
|
+
if (typeof define === 'function' && define.amd) {
|
12
|
+
// AMD. Register as an anonymous module.
|
13
|
+
define([], factory);
|
14
|
+
} else if (typeof module === 'object' && module.exports) {
|
15
|
+
// Node. Does not work with strict CommonJS, but
|
16
|
+
// only CommonJS-like environments that support module.exports,
|
17
|
+
// like Node.
|
18
|
+
module.exports = factory();
|
19
|
+
} else {
|
20
|
+
// Browser globals (root is window)
|
21
|
+
root.anime = factory();
|
22
|
+
}
|
23
|
+
}(this, function () {
|
24
|
+
|
25
|
+
var version = '1.1.0';
|
26
|
+
|
27
|
+
// Defaults
|
28
|
+
|
29
|
+
var defaultSettings = {
|
30
|
+
duration: 1000,
|
31
|
+
delay: 0,
|
32
|
+
loop: false,
|
33
|
+
autoplay: true,
|
34
|
+
direction: 'normal',
|
35
|
+
easing: 'easeOutElastic',
|
36
|
+
elasticity: 400,
|
37
|
+
round: false,
|
38
|
+
begin: undefined,
|
39
|
+
update: undefined,
|
40
|
+
complete: undefined
|
41
|
+
}
|
42
|
+
|
43
|
+
// Transforms
|
44
|
+
|
45
|
+
var validTransforms = ['translateX', 'translateY', 'translateZ', 'rotate', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scaleX', 'scaleY', 'scaleZ', 'skewX', 'skewY'];
|
46
|
+
var transform, transformStr = 'transform';
|
47
|
+
|
48
|
+
// Utils
|
49
|
+
|
50
|
+
var is = (function() {
|
51
|
+
return {
|
52
|
+
array: function(a) { return Array.isArray(a) },
|
53
|
+
object: function(a) { return Object.prototype.toString.call(a).indexOf('Object') > -1 },
|
54
|
+
svg: function(a) { return a instanceof SVGElement },
|
55
|
+
dom: function(a) { return a.nodeType || is.svg(a) },
|
56
|
+
number: function(a) { return !isNaN(parseInt(a)) },
|
57
|
+
string: function(a) { return typeof a === 'string' },
|
58
|
+
func: function(a) { return typeof a === 'function' },
|
59
|
+
undef: function(a) { return typeof a === 'undefined' },
|
60
|
+
null: function(a) { return typeof a === 'null' },
|
61
|
+
hex: function(a) { return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(a) },
|
62
|
+
rgb: function(a) { return /^rgb/.test(a) },
|
63
|
+
rgba: function(a) { return /^rgba/.test(a) },
|
64
|
+
hsl: function(a) { return /^hsl/.test(a) },
|
65
|
+
color: function(a) { return (is.hex(a) || is.rgb(a) || is.rgba(a) || is.hsl(a))}
|
66
|
+
}
|
67
|
+
})();
|
68
|
+
|
69
|
+
// Easings functions adapted from http://jqueryui.com/
|
70
|
+
|
71
|
+
var easings = (function() {
|
72
|
+
var eases = {};
|
73
|
+
var names = ['Quad', 'Cubic', 'Quart', 'Quint', 'Expo'];
|
74
|
+
var functions = {
|
75
|
+
Sine: function(t) { return 1 - Math.cos( t * Math.PI / 2 ); },
|
76
|
+
Circ: function(t) { return 1 - Math.sqrt( 1 - t * t ); },
|
77
|
+
Elastic: function(t, m) {
|
78
|
+
if( t === 0 || t === 1 ) return t;
|
79
|
+
var p = (1 - Math.min(m, 998) / 1000), st = t / 1, st1 = st - 1, s = p / ( 2 * Math.PI ) * Math.asin( 1 );
|
80
|
+
return -( Math.pow( 2, 10 * st1 ) * Math.sin( ( st1 - s ) * ( 2 * Math.PI ) / p ) );
|
81
|
+
},
|
82
|
+
Back: function(t) { return t * t * ( 3 * t - 2 ); },
|
83
|
+
Bounce: function(t) {
|
84
|
+
var pow2, bounce = 4;
|
85
|
+
while ( t < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
|
86
|
+
return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - t, 2 );
|
87
|
+
}
|
88
|
+
}
|
89
|
+
names.forEach(function(name, i) {
|
90
|
+
functions[name] = function(t) {
|
91
|
+
return Math.pow( t, i + 2 );
|
92
|
+
}
|
93
|
+
});
|
94
|
+
Object.keys(functions).forEach(function(name) {
|
95
|
+
var easeIn = functions[name];
|
96
|
+
eases['easeIn' + name] = easeIn;
|
97
|
+
eases['easeOut' + name] = function(t, m) { return 1 - easeIn(1 - t, m); };
|
98
|
+
eases['easeInOut' + name] = function(t, m) { return t < 0.5 ? easeIn(t * 2, m) / 2 : 1 - easeIn(t * -2 + 2, m) / 2; };
|
99
|
+
});
|
100
|
+
eases.linear = function(t) { return t; };
|
101
|
+
return eases;
|
102
|
+
})();
|
103
|
+
|
104
|
+
// Strings
|
105
|
+
|
106
|
+
var numberToString = function(val) {
|
107
|
+
return (is.string(val)) ? val : val + '';
|
108
|
+
}
|
109
|
+
|
110
|
+
var stringToHyphens = function(str) {
|
111
|
+
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
112
|
+
}
|
113
|
+
|
114
|
+
var selectString = function(str) {
|
115
|
+
if (is.color(str)) return false;
|
116
|
+
try {
|
117
|
+
var nodes = document.querySelectorAll(str);
|
118
|
+
return nodes;
|
119
|
+
} catch(e) {
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
// Numbers
|
125
|
+
|
126
|
+
var random = function(min, max) {
|
127
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
128
|
+
}
|
129
|
+
|
130
|
+
// Arrays
|
131
|
+
|
132
|
+
var flattenArray = function(arr) {
|
133
|
+
return arr.reduce(function(a, b) {
|
134
|
+
return a.concat(is.array(b) ? flattenArray(b) : b);
|
135
|
+
}, []);
|
136
|
+
}
|
137
|
+
|
138
|
+
var toArray = function(o) {
|
139
|
+
if (is.array(o)) return o;
|
140
|
+
if (is.string(o)) o = selectString(o) || o;
|
141
|
+
if (o instanceof NodeList || o instanceof HTMLCollection) return [].slice.call(o);
|
142
|
+
return [o];
|
143
|
+
}
|
144
|
+
|
145
|
+
var arrayContains = function(arr, val) {
|
146
|
+
return arr.some(function(a) { return a === val; });
|
147
|
+
}
|
148
|
+
|
149
|
+
var groupArrayByProps = function(arr, propsArr) {
|
150
|
+
var groups = {};
|
151
|
+
arr.forEach(function(o) {
|
152
|
+
var group = JSON.stringify(propsArr.map(function(p) { return o[p]; }));
|
153
|
+
groups[group] = groups[group] || [];
|
154
|
+
groups[group].push(o);
|
155
|
+
});
|
156
|
+
return Object.keys(groups).map(function(group) {
|
157
|
+
return groups[group];
|
158
|
+
});
|
159
|
+
}
|
160
|
+
|
161
|
+
var removeArrayDuplicates = function(arr) {
|
162
|
+
return arr.filter(function(item, pos, self) {
|
163
|
+
return self.indexOf(item) === pos;
|
164
|
+
});
|
165
|
+
}
|
166
|
+
|
167
|
+
// Objects
|
168
|
+
|
169
|
+
var cloneObject = function(o) {
|
170
|
+
var newObject = {};
|
171
|
+
for (var p in o) newObject[p] = o[p];
|
172
|
+
return newObject;
|
173
|
+
}
|
174
|
+
|
175
|
+
var mergeObjects = function(o1, o2) {
|
176
|
+
for (var p in o2) o1[p] = !is.undef(o1[p]) ? o1[p] : o2[p];
|
177
|
+
return o1;
|
178
|
+
}
|
179
|
+
|
180
|
+
// Colors
|
181
|
+
|
182
|
+
var hexToRgb = function(hex) {
|
183
|
+
var rgx = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
184
|
+
var hex = hex.replace(rgx, function(m, r, g, b) { return r + r + g + g + b + b; });
|
185
|
+
var rgb = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
186
|
+
var r = parseInt(rgb[1], 16);
|
187
|
+
var g = parseInt(rgb[2], 16);
|
188
|
+
var b = parseInt(rgb[3], 16);
|
189
|
+
return 'rgb(' + r + ',' + g + ',' + b + ')';
|
190
|
+
}
|
191
|
+
|
192
|
+
var hslToRgb = function(hsl) {
|
193
|
+
var hsl = /hsl\((\d+),\s*([\d.]+)%,\s*([\d.]+)%\)/g.exec(hsl);
|
194
|
+
var h = parseInt(hsl[1]) / 360;
|
195
|
+
var s = parseInt(hsl[2]) / 100;
|
196
|
+
var l = parseInt(hsl[3]) / 100;
|
197
|
+
var hue2rgb = function(p, q, t) {
|
198
|
+
if (t < 0) t += 1;
|
199
|
+
if (t > 1) t -= 1;
|
200
|
+
if (t < 1/6) return p + (q - p) * 6 * t;
|
201
|
+
if (t < 1/2) return q;
|
202
|
+
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
203
|
+
return p;
|
204
|
+
}
|
205
|
+
var r, g, b;
|
206
|
+
if (s == 0) {
|
207
|
+
r = g = b = l;
|
208
|
+
} else {
|
209
|
+
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
210
|
+
var p = 2 * l - q;
|
211
|
+
r = hue2rgb(p, q, h + 1/3);
|
212
|
+
g = hue2rgb(p, q, h);
|
213
|
+
b = hue2rgb(p, q, h - 1/3);
|
214
|
+
}
|
215
|
+
return 'rgb(' + r * 255 + ',' + g * 255 + ',' + b * 255 + ')';
|
216
|
+
}
|
217
|
+
|
218
|
+
var colorToRgb = function(val) {
|
219
|
+
if (is.rgb(val) || is.rgba(val)) return val;
|
220
|
+
if (is.hex(val)) return hexToRgb(val);
|
221
|
+
if (is.hsl(val)) return hslToRgb(val);
|
222
|
+
}
|
223
|
+
|
224
|
+
// Units
|
225
|
+
|
226
|
+
var getUnit = function(val) {
|
227
|
+
return /([\+\-]?[0-9|auto\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg)?/.exec(val)[2];
|
228
|
+
}
|
229
|
+
|
230
|
+
var addDefaultTransformUnit = function(prop, val, intialVal) {
|
231
|
+
if (getUnit(val)) return val;
|
232
|
+
if (prop.indexOf('translate') > -1) return getUnit(intialVal) ? val + getUnit(intialVal) : val + 'px';
|
233
|
+
if (prop.indexOf('rotate') > -1 || prop.indexOf('skew') > -1) return val + 'deg';
|
234
|
+
return val;
|
235
|
+
}
|
236
|
+
|
237
|
+
// Values
|
238
|
+
|
239
|
+
var getCSSValue = function(el, prop) {
|
240
|
+
// First check if prop is a valid CSS property
|
241
|
+
if (prop in el.style) {
|
242
|
+
// Then return the property value or fallback to '0' when getPropertyValue fails
|
243
|
+
return getComputedStyle(el).getPropertyValue(stringToHyphens(prop)) || '0';
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
var getTransformValue = function(el, prop) {
|
248
|
+
var defaultVal = prop.indexOf('scale') > -1 ? 1 : 0;
|
249
|
+
var str = el.style.transform;
|
250
|
+
if (!str) return defaultVal;
|
251
|
+
var rgx = /(\w+)\((.+?)\)/g;
|
252
|
+
var match = [];
|
253
|
+
var props = [];
|
254
|
+
var values = [];
|
255
|
+
while (match = rgx.exec(str)) {
|
256
|
+
props.push(match[1]);
|
257
|
+
values.push(match[2]);
|
258
|
+
}
|
259
|
+
var val = values.filter(function(f, i) { return props[i] === prop; });
|
260
|
+
return val.length ? val[0] : defaultVal;
|
261
|
+
}
|
262
|
+
|
263
|
+
var getAnimationType = function(el, prop) {
|
264
|
+
if ( is.dom(el) && arrayContains(validTransforms, prop)) return 'transform';
|
265
|
+
if ( is.dom(el) && (prop !== 'transform' && getCSSValue(el, prop))) return 'css';
|
266
|
+
if ( is.dom(el) && (el.getAttribute(prop) || (is.svg(el) && el[prop]))) return 'attribute';
|
267
|
+
if (!is.null(el[prop]) && !is.undef(el[prop])) return 'object';
|
268
|
+
}
|
269
|
+
|
270
|
+
var getInitialTargetValue = function(target, prop) {
|
271
|
+
switch (getAnimationType(target, prop)) {
|
272
|
+
case 'transform': return getTransformValue(target, prop);
|
273
|
+
case 'css': return getCSSValue(target, prop);
|
274
|
+
case 'attribute': return target.getAttribute(prop);
|
275
|
+
}
|
276
|
+
return target[prop] || 0;
|
277
|
+
}
|
278
|
+
|
279
|
+
var getValidValue = function(values, val, originalCSS) {
|
280
|
+
if (is.color(val)) return colorToRgb(val);
|
281
|
+
if (getUnit(val)) return val;
|
282
|
+
var unit = getUnit(values.to) ? getUnit(values.to) : getUnit(values.from);
|
283
|
+
if (!unit && originalCSS) unit = getUnit(originalCSS);
|
284
|
+
return unit ? val + unit : val;
|
285
|
+
}
|
286
|
+
|
287
|
+
var decomposeValue = function(val) {
|
288
|
+
var rgx = /-?\d*\.?\d+/g;
|
289
|
+
return {
|
290
|
+
original: val,
|
291
|
+
numbers: numberToString(val).match(rgx) ? numberToString(val).match(rgx).map(Number) : [0],
|
292
|
+
strings: numberToString(val).split(rgx)
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
var recomposeValue = function(numbers, strings, initialStrings) {
|
297
|
+
return strings.reduce(function(a, b, i) {
|
298
|
+
var b = (b ? b : initialStrings[i - 1]);
|
299
|
+
return a + numbers[i - 1] + b;
|
300
|
+
});
|
301
|
+
}
|
302
|
+
|
303
|
+
// Animatables
|
304
|
+
|
305
|
+
var getAnimatables = function(targets) {
|
306
|
+
var targets = targets ? (flattenArray(is.array(targets) ? targets.map(toArray) : toArray(targets))) : [];
|
307
|
+
return targets.map(function(t, i) {
|
308
|
+
return { target: t, id: i };
|
309
|
+
});
|
310
|
+
}
|
311
|
+
|
312
|
+
// Properties
|
313
|
+
|
314
|
+
var getProperties = function(params, settings) {
|
315
|
+
var props = [];
|
316
|
+
for (var p in params) {
|
317
|
+
if (!defaultSettings.hasOwnProperty(p) && p !== 'targets') {
|
318
|
+
var prop = is.object(params[p]) ? cloneObject(params[p]) : {value: params[p]};
|
319
|
+
prop.name = p;
|
320
|
+
props.push(mergeObjects(prop, settings));
|
321
|
+
}
|
322
|
+
}
|
323
|
+
return props;
|
324
|
+
}
|
325
|
+
|
326
|
+
var getPropertiesValues = function(target, prop, value, i) {
|
327
|
+
var values = toArray( is.func(value) ? value(target, i) : value);
|
328
|
+
return {
|
329
|
+
from: (values.length > 1) ? values[0] : getInitialTargetValue(target, prop),
|
330
|
+
to: (values.length > 1) ? values[1] : values[0]
|
331
|
+
}
|
332
|
+
}
|
333
|
+
|
334
|
+
// Tweens
|
335
|
+
|
336
|
+
var getTweenValues = function(prop, values, type, target) {
|
337
|
+
var valid = {};
|
338
|
+
if (type === 'transform') {
|
339
|
+
valid.from = prop + '(' + addDefaultTransformUnit(prop, values.from, values.to) + ')';
|
340
|
+
valid.to = prop + '(' + addDefaultTransformUnit(prop, values.to) + ')';
|
341
|
+
} else {
|
342
|
+
var originalCSS = (type === 'css') ? getCSSValue(target, prop) : undefined;
|
343
|
+
valid.from = getValidValue(values, values.from, originalCSS);
|
344
|
+
valid.to = getValidValue(values, values.to, originalCSS);
|
345
|
+
}
|
346
|
+
return { from: decomposeValue(valid.from), to: decomposeValue(valid.to) };
|
347
|
+
}
|
348
|
+
|
349
|
+
var getTweensProps = function(animatables, props) {
|
350
|
+
var tweensProps = [];
|
351
|
+
animatables.forEach(function(animatable, i) {
|
352
|
+
var target = animatable.target;
|
353
|
+
return props.forEach(function(prop) {
|
354
|
+
var animType = getAnimationType(target, prop.name);
|
355
|
+
if (animType) {
|
356
|
+
var values = getPropertiesValues(target, prop.name, prop.value, i);
|
357
|
+
var tween = cloneObject(prop);
|
358
|
+
tween.animatables = animatable;
|
359
|
+
tween.type = animType;
|
360
|
+
tween.from = getTweenValues(prop.name, values, tween.type, target).from;
|
361
|
+
tween.to = getTweenValues(prop.name, values, tween.type, target).to;
|
362
|
+
tween.round = (is.color(values.from) || tween.round) ? 1 : 0;
|
363
|
+
tween.delay = (is.func(tween.delay) ? tween.delay(target, i, animatables.length) : tween.delay) / animation.speed;
|
364
|
+
tween.duration = (is.func(tween.duration) ? tween.duration(target, i, animatables.length) : tween.duration) / animation.speed;
|
365
|
+
tweensProps.push(tween);
|
366
|
+
}
|
367
|
+
});
|
368
|
+
});
|
369
|
+
return tweensProps;
|
370
|
+
}
|
371
|
+
|
372
|
+
var getTweens = function(animatables, props) {
|
373
|
+
var tweensProps = getTweensProps(animatables, props);
|
374
|
+
var splittedProps = groupArrayByProps(tweensProps, ['name', 'from', 'to', 'delay', 'duration']);
|
375
|
+
return splittedProps.map(function(tweenProps) {
|
376
|
+
var tween = cloneObject(tweenProps[0]);
|
377
|
+
tween.animatables = tweenProps.map(function(p) { return p.animatables });
|
378
|
+
tween.totalDuration = tween.delay + tween.duration;
|
379
|
+
return tween;
|
380
|
+
});
|
381
|
+
}
|
382
|
+
|
383
|
+
var reverseTweens = function(anim, delays) {
|
384
|
+
anim.tweens.forEach(function(tween) {
|
385
|
+
var toVal = tween.to;
|
386
|
+
var fromVal = tween.from;
|
387
|
+
var delayVal = anim.duration - (tween.delay + tween.duration);
|
388
|
+
tween.from = toVal;
|
389
|
+
tween.to = fromVal;
|
390
|
+
if (delays) tween.delay = delayVal;
|
391
|
+
});
|
392
|
+
anim.reversed = anim.reversed ? false : true;
|
393
|
+
}
|
394
|
+
|
395
|
+
var getTweensDuration = function(tweens) {
|
396
|
+
if (tweens.length) return Math.max.apply(Math, tweens.map(function(tween){ return tween.totalDuration; }));
|
397
|
+
}
|
398
|
+
|
399
|
+
// will-change
|
400
|
+
|
401
|
+
var getWillChange = function(anim) {
|
402
|
+
var props = [];
|
403
|
+
var els = [];
|
404
|
+
anim.tweens.forEach(function(tween) {
|
405
|
+
if (tween.type === 'css' || tween.type === 'transform' ) {
|
406
|
+
props.push(tween.type === 'css' ? stringToHyphens(tween.name) : 'transform');
|
407
|
+
tween.animatables.forEach(function(animatable) { els.push(animatable.target); });
|
408
|
+
}
|
409
|
+
});
|
410
|
+
return {
|
411
|
+
properties: removeArrayDuplicates(props).join(', '),
|
412
|
+
elements: removeArrayDuplicates(els)
|
413
|
+
}
|
414
|
+
}
|
415
|
+
|
416
|
+
var setWillChange = function(anim) {
|
417
|
+
var willChange = getWillChange(anim);
|
418
|
+
willChange.elements.forEach(function(element) {
|
419
|
+
element.style.willChange = willChange.properties;
|
420
|
+
});
|
421
|
+
}
|
422
|
+
|
423
|
+
var removeWillChange = function(anim) {
|
424
|
+
var willChange = getWillChange(anim);
|
425
|
+
willChange.elements.forEach(function(element) {
|
426
|
+
element.style.removeProperty('will-change');
|
427
|
+
});
|
428
|
+
}
|
429
|
+
|
430
|
+
/* Svg path */
|
431
|
+
|
432
|
+
var getPathProps = function(path) {
|
433
|
+
var el = is.string(path) ? selectString(path)[0] : path;
|
434
|
+
return {
|
435
|
+
path: el,
|
436
|
+
value: el.getTotalLength()
|
437
|
+
}
|
438
|
+
}
|
439
|
+
|
440
|
+
var snapProgressToPath = function(tween, progress) {
|
441
|
+
var pathEl = tween.path;
|
442
|
+
var pathProgress = tween.value * progress;
|
443
|
+
var point = function(offset) {
|
444
|
+
var o = offset || 0;
|
445
|
+
var p = progress > 1 ? tween.value + o : pathProgress + o;
|
446
|
+
return pathEl.getPointAtLength(p);
|
447
|
+
}
|
448
|
+
var p = point();
|
449
|
+
var p0 = point(-1);
|
450
|
+
var p1 = point(+1);
|
451
|
+
switch (tween.name) {
|
452
|
+
case 'translateX': return p.x;
|
453
|
+
case 'translateY': return p.y;
|
454
|
+
case 'rotate': return Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
// Progress
|
459
|
+
|
460
|
+
var getTweenProgress = function(tween, time) {
|
461
|
+
var elapsed = Math.min(Math.max(time - tween.delay, 0), tween.duration);
|
462
|
+
var percent = elapsed / tween.duration;
|
463
|
+
var progress = tween.to.numbers.map(function(number, p) {
|
464
|
+
var start = tween.from.numbers[p];
|
465
|
+
var eased = easings[tween.easing](percent, tween.elasticity);
|
466
|
+
var val = tween.path ? snapProgressToPath(tween, eased) : start + eased * (number - start);
|
467
|
+
val = tween.round ? Math.round(val * tween.round) / tween.round : val;
|
468
|
+
return val;
|
469
|
+
});
|
470
|
+
return recomposeValue(progress, tween.to.strings, tween.from.strings);
|
471
|
+
}
|
472
|
+
|
473
|
+
var setAnimationProgress = function(anim, time) {
|
474
|
+
var transforms;
|
475
|
+
anim.currentTime = time;
|
476
|
+
anim.progress = (time / anim.duration) * 100;
|
477
|
+
for (var t = 0; t < anim.tweens.length; t++) {
|
478
|
+
var tween = anim.tweens[t];
|
479
|
+
tween.currentValue = getTweenProgress(tween, time);
|
480
|
+
var progress = tween.currentValue;
|
481
|
+
for (var a = 0; a < tween.animatables.length; a++) {
|
482
|
+
var animatable = tween.animatables[a];
|
483
|
+
var id = animatable.id;
|
484
|
+
var target = animatable.target;
|
485
|
+
var name = tween.name;
|
486
|
+
switch (tween.type) {
|
487
|
+
case 'css': target.style[name] = progress; break;
|
488
|
+
case 'attribute': target.setAttribute(name, progress); break;
|
489
|
+
case 'object': target[name] = progress; break;
|
490
|
+
case 'transform':
|
491
|
+
if (!transforms) transforms = {};
|
492
|
+
if (!transforms[id]) transforms[id] = [];
|
493
|
+
transforms[id].push(progress);
|
494
|
+
break;
|
495
|
+
}
|
496
|
+
}
|
497
|
+
}
|
498
|
+
if (transforms) {
|
499
|
+
if (!transform) transform = (getCSSValue(document.body, transformStr) ? '' : '-webkit-') + transformStr;
|
500
|
+
for (var t in transforms) {
|
501
|
+
anim.animatables[t].target.style[transform] = transforms[t].join(' ');
|
502
|
+
}
|
503
|
+
}
|
504
|
+
if (anim.settings.update) anim.settings.update(anim);
|
505
|
+
}
|
506
|
+
|
507
|
+
// Animation
|
508
|
+
|
509
|
+
var createAnimation = function(params) {
|
510
|
+
var anim = {};
|
511
|
+
anim.animatables = getAnimatables(params.targets);
|
512
|
+
anim.settings = mergeObjects(params, defaultSettings);
|
513
|
+
anim.properties = getProperties(params, anim.settings);
|
514
|
+
anim.tweens = getTweens(anim.animatables, anim.properties);
|
515
|
+
anim.duration = getTweensDuration(anim.tweens) || params.duration;
|
516
|
+
anim.currentTime = 0;
|
517
|
+
anim.progress = 0;
|
518
|
+
anim.ended = false;
|
519
|
+
return anim;
|
520
|
+
}
|
521
|
+
|
522
|
+
// Public
|
523
|
+
|
524
|
+
var animations = [];
|
525
|
+
var raf = 0;
|
526
|
+
|
527
|
+
var engine = (function() {
|
528
|
+
var play = function() { raf = requestAnimationFrame(step); };
|
529
|
+
var step = function(t) {
|
530
|
+
if (animations.length) {
|
531
|
+
for (var i = 0; i < animations.length; i++) animations[i].tick(t);
|
532
|
+
play();
|
533
|
+
} else {
|
534
|
+
cancelAnimationFrame(raf);
|
535
|
+
raf = 0;
|
536
|
+
}
|
537
|
+
}
|
538
|
+
return play;
|
539
|
+
})();
|
540
|
+
|
541
|
+
var animation = function(params) {
|
542
|
+
|
543
|
+
var anim = createAnimation(params);
|
544
|
+
var time = {};
|
545
|
+
|
546
|
+
anim.tick = function(now) {
|
547
|
+
anim.ended = false;
|
548
|
+
if (!time.start) time.start = now;
|
549
|
+
time.current = Math.min(Math.max(time.last + now - time.start, 0), anim.duration);
|
550
|
+
setAnimationProgress(anim, time.current);
|
551
|
+
var s = anim.settings;
|
552
|
+
if (s.begin && time.current >= s.delay) { s.begin(anim); s.begin = undefined; };
|
553
|
+
if (time.current >= anim.duration) {
|
554
|
+
if (s.loop) {
|
555
|
+
time.start = now;
|
556
|
+
if (s.direction === 'alternate') reverseTweens(anim, true);
|
557
|
+
if (is.number(s.loop)) s.loop--;
|
558
|
+
} else {
|
559
|
+
anim.ended = true;
|
560
|
+
anim.pause();
|
561
|
+
if (s.complete) s.complete(anim);
|
562
|
+
}
|
563
|
+
time.last = 0;
|
564
|
+
}
|
565
|
+
}
|
566
|
+
|
567
|
+
anim.seek = function(progress) {
|
568
|
+
setAnimationProgress(anim, (progress / 100) * anim.duration);
|
569
|
+
}
|
570
|
+
|
571
|
+
anim.pause = function() {
|
572
|
+
removeWillChange(anim);
|
573
|
+
var i = animations.indexOf(anim);
|
574
|
+
if (i > -1) animations.splice(i, 1);
|
575
|
+
}
|
576
|
+
|
577
|
+
anim.play = function(params) {
|
578
|
+
anim.pause();
|
579
|
+
if (params) anim = mergeObjects(createAnimation(mergeObjects(params, anim.settings)), anim);
|
580
|
+
time.start = 0;
|
581
|
+
time.last = anim.ended ? 0 : anim.currentTime;
|
582
|
+
var s = anim.settings;
|
583
|
+
if (s.direction === 'reverse') reverseTweens(anim);
|
584
|
+
if (s.direction === 'alternate' && !s.loop) s.loop = 1;
|
585
|
+
setWillChange(anim);
|
586
|
+
animations.push(anim);
|
587
|
+
if (!raf) engine();
|
588
|
+
}
|
589
|
+
|
590
|
+
anim.restart = function() {
|
591
|
+
if (anim.reversed) reverseTweens(anim);
|
592
|
+
anim.pause();
|
593
|
+
anim.seek(0);
|
594
|
+
anim.play();
|
595
|
+
}
|
596
|
+
|
597
|
+
if (anim.settings.autoplay) anim.play();
|
598
|
+
|
599
|
+
return anim;
|
600
|
+
|
601
|
+
}
|
602
|
+
|
603
|
+
// Remove one or multiple targets from all active animations.
|
604
|
+
|
605
|
+
var remove = function(elements) {
|
606
|
+
var targets = flattenArray(is.array(elements) ? elements.map(toArray) : toArray(elements));
|
607
|
+
for (var i = animations.length-1; i >= 0; i--) {
|
608
|
+
var animation = animations[i];
|
609
|
+
var tweens = animation.tweens;
|
610
|
+
for (var t = tweens.length-1; t >= 0; t--) {
|
611
|
+
var animatables = tweens[t].animatables;
|
612
|
+
for (var a = animatables.length-1; a >= 0; a--) {
|
613
|
+
if (arrayContains(targets, animatables[a].target)) {
|
614
|
+
animatables.splice(a, 1);
|
615
|
+
if (!animatables.length) tweens.splice(t, 1);
|
616
|
+
if (!tweens.length) animation.pause();
|
617
|
+
}
|
618
|
+
}
|
619
|
+
}
|
620
|
+
}
|
621
|
+
}
|
622
|
+
|
623
|
+
animation.version = version;
|
624
|
+
animation.speed = 1;
|
625
|
+
animation.list = animations;
|
626
|
+
animation.remove = remove;
|
627
|
+
animation.easings = easings;
|
628
|
+
animation.getValue = getInitialTargetValue;
|
629
|
+
animation.path = getPathProps;
|
630
|
+
animation.random = random;
|
631
|
+
|
632
|
+
return animation;
|
633
|
+
|
634
|
+
}));
|
metadata
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: anime_js_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guinsly Mondesir
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-07-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.7'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rails
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 3.1.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 3.1.0
|
55
|
+
description: Makes it simple to include the anime.js library (by Guinsly Mondesir)
|
56
|
+
in the Rails asset pipeline.
|
57
|
+
email:
|
58
|
+
- guinslym@users.noreply.github.com
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
64
|
+
- Gemfile
|
65
|
+
- LICENSE.txt
|
66
|
+
- README.md
|
67
|
+
- Rakefile
|
68
|
+
- anime_js_rails.gemspec
|
69
|
+
- lib/anime_js_rails.rb
|
70
|
+
- lib/anime_js_rails/version.rb
|
71
|
+
- vendor/assets/javascripts/anime.js
|
72
|
+
homepage: https://github.com/guinslym/anime_js_rails
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.2.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Anime (/ˈæn.ə.meɪ/) is a flexible yet lightweight JavaScript animation library.
|
96
|
+
It works with CSS, Individual Transforms, SVG, DOM attributes and JS Objects
|
97
|
+
test_files: []
|