animate_it 0.4.0 → 0.5.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 +4 -4
- data/CHANGELOG.md +29 -1
- data/README.md +84 -4
- data/app/controllers/animate_it/embed_assets_controller.rb +25 -0
- data/app/controllers/animate_it/frames_controller.rb +3 -0
- data/app/controllers/animate_it/public_players_controller.rb +5 -1
- data/app/views/animate_it/frames/player.html.haml +12 -1
- data/config/routes.rb +5 -0
- data/lib/animate_it/chapter_navigation.rb +160 -0
- data/lib/animate_it/chapters.rb +95 -0
- data/lib/animate_it/composition.rb +15 -0
- data/lib/animate_it/embed_helper.rb +200 -8
- data/lib/animate_it/embed_runtime/embed.js +338 -0
- data/lib/animate_it/embed_runtime.rb +13 -0
- data/lib/animate_it/embed_styles.rb +126 -0
- data/lib/animate_it/engine.rb +4 -1
- data/lib/animate_it/player_manifest.rb +29 -0
- data/lib/animate_it/runtime/runtime.js +138 -5
- data/lib/animate_it/version.rb +1 -1
- data/lib/animate_it.rb +8 -0
- metadata +13 -6
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
module AnimateIt
|
|
2
|
+
module EmbedStyles
|
|
3
|
+
module_function
|
|
4
|
+
|
|
5
|
+
def chapter_source
|
|
6
|
+
@chapter_source ||= <<~CSS.freeze
|
|
7
|
+
.animate-it-chapters {
|
|
8
|
+
--animate-it-progress-color: #28d2bc;
|
|
9
|
+
--animate-it-progress-width: 2.5px;
|
|
10
|
+
--animate-it-active-glow: 0 0 10px 2px rgb(40 210 188 / 42%);
|
|
11
|
+
--animate-it-chapter-color: #414b57;
|
|
12
|
+
--animate-it-chapter-background: #fff;
|
|
13
|
+
--animate-it-chapter-shadow: 0 4px 12px rgb(39 47 57 / 8%);
|
|
14
|
+
--animate-it-chapter-font: 700 14px/1 system-ui, sans-serif;
|
|
15
|
+
--animate-it-chapter-gap: 14px;
|
|
16
|
+
--animate-it-chapter-height: 44px;
|
|
17
|
+
--animate-it-carousel-distance: 108%;
|
|
18
|
+
--animate-it-carousel-scale: .84;
|
|
19
|
+
--animate-it-carousel-opacity: .68;
|
|
20
|
+
--animate-it-carousel-duration: 180ms;
|
|
21
|
+
display: grid;
|
|
22
|
+
grid-template-columns: repeat(var(--animate-it-chapter-count, 4), minmax(0, 1fr));
|
|
23
|
+
gap: var(--animate-it-chapter-gap);
|
|
24
|
+
}
|
|
25
|
+
.animate-it-chapter--pills {
|
|
26
|
+
--animate-it-chapter-progress: 0;
|
|
27
|
+
--animate-it-chapter-active: 0;
|
|
28
|
+
--animate-it-chapter-complete: 0;
|
|
29
|
+
position: relative;
|
|
30
|
+
min-width: 0;
|
|
31
|
+
min-height: 44px;
|
|
32
|
+
height: var(--animate-it-chapter-height);
|
|
33
|
+
padding: 2px;
|
|
34
|
+
border: 0;
|
|
35
|
+
border-radius: 999px;
|
|
36
|
+
appearance: none;
|
|
37
|
+
color: var(--animate-it-chapter-color);
|
|
38
|
+
background: var(--animate-it-chapter-background);
|
|
39
|
+
box-shadow: var(--animate-it-chapter-shadow);
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
}
|
|
42
|
+
.animate-it-chapter--pills[data-chapter-state="current"] { box-shadow: var(--animate-it-active-glow); }
|
|
43
|
+
.animate-it-chapter--pills:focus-visible { outline: 3px solid var(--animate-it-progress-color); outline-offset: 3px; }
|
|
44
|
+
.animate-it-chapter__progress { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
|
|
45
|
+
.animate-it-chapter__progress rect {
|
|
46
|
+
fill: none;
|
|
47
|
+
stroke: var(--animate-it-progress-color);
|
|
48
|
+
stroke-width: var(--animate-it-progress-width);
|
|
49
|
+
stroke-dasharray: var(--animate-it-chapter-progress) 1;
|
|
50
|
+
stroke-opacity: clamp(0, calc(var(--animate-it-chapter-progress) * 1000), 1);
|
|
51
|
+
stroke-linecap: round;
|
|
52
|
+
vector-effect: non-scaling-stroke;
|
|
53
|
+
}
|
|
54
|
+
.animate-it-chapter__label {
|
|
55
|
+
position: relative;
|
|
56
|
+
display: flex;
|
|
57
|
+
height: 100%;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
opacity: calc(.58 + (var(--animate-it-chapter-active) * .42));
|
|
61
|
+
font: var(--animate-it-chapter-font);
|
|
62
|
+
}
|
|
63
|
+
@media (max-width: 767px) {
|
|
64
|
+
.animate-it-chapters--mobile-carousel { position: relative; display: block; height: var(--animate-it-chapter-height); overflow: clip; }
|
|
65
|
+
.animate-it-chapters--mobile-carousel .animate-it-chapter--pills {
|
|
66
|
+
position: absolute;
|
|
67
|
+
left: 50%;
|
|
68
|
+
width: min(31.25%, 122px);
|
|
69
|
+
transition: transform var(--animate-it-carousel-duration) ease, opacity var(--animate-it-carousel-duration) ease;
|
|
70
|
+
}
|
|
71
|
+
.animate-it-chapters--mobile-carousel .animate-it-chapter--pills[data-chapter-position="previous"] { transform: translateX(calc(-50% - var(--animate-it-carousel-distance))) scale(var(--animate-it-carousel-scale)); opacity: var(--animate-it-carousel-opacity); }
|
|
72
|
+
.animate-it-chapters--mobile-carousel .animate-it-chapter--pills[data-chapter-position="current"] { transform: translateX(-50%); opacity: 1; }
|
|
73
|
+
.animate-it-chapters--mobile-carousel .animate-it-chapter--pills[data-chapter-position="next"] { transform: translateX(calc(-50% + var(--animate-it-carousel-distance))) scale(var(--animate-it-carousel-scale)); opacity: var(--animate-it-carousel-opacity); }
|
|
74
|
+
.animate-it-chapters--mobile-carousel .animate-it-chapter--pills[data-chapter-position="hidden"] { visibility: hidden; pointer-events: none; opacity: 0; }
|
|
75
|
+
}
|
|
76
|
+
@media (prefers-reduced-motion: reduce) {
|
|
77
|
+
.animate-it-chapter--pills { transition: none !important; }
|
|
78
|
+
}
|
|
79
|
+
CSS
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def source
|
|
83
|
+
@source ||= <<~CSS.freeze
|
|
84
|
+
#{chapter_source}
|
|
85
|
+
animate-it-embed {
|
|
86
|
+
--animate-it-crossfade-duration: 120ms;
|
|
87
|
+
position: relative;
|
|
88
|
+
display: block;
|
|
89
|
+
width: 100%;
|
|
90
|
+
background: transparent;
|
|
91
|
+
}
|
|
92
|
+
.animate-it-embed__navigation { margin-bottom: 14px; }
|
|
93
|
+
.animate-it-embed__viewport { position: relative; width: 100%; background: transparent; }
|
|
94
|
+
.animate-it-embed__poster, .animate-it-embed__shell { position: absolute; inset: 0; width: 100%; height: 100%; }
|
|
95
|
+
.animate-it-embed__poster { z-index: 2; margin: 0; opacity: 1; transition: opacity var(--animate-it-crossfade-duration) ease; pointer-events: none; }
|
|
96
|
+
.animate-it-embed__poster img { display: block; width: 100%; height: 100%; object-fit: contain; }
|
|
97
|
+
.animate-it-embed__shell { z-index: 1; overflow: hidden; opacity: 0; transition: opacity var(--animate-it-crossfade-duration) ease; background: transparent; }
|
|
98
|
+
.animate-it-embed__frame { position: absolute; top: 0; left: 0; transform-origin: top left; background: transparent; }
|
|
99
|
+
.animate-it-embed__frame iframe { display: block; border: 0; background: transparent; pointer-events: none; }
|
|
100
|
+
animate-it-embed[data-player-ready="true"] .animate-it-embed__poster { opacity: 0; }
|
|
101
|
+
animate-it-embed[data-player-ready="true"] .animate-it-embed__shell { opacity: 1; }
|
|
102
|
+
.animate-it-embed__control {
|
|
103
|
+
position: absolute;
|
|
104
|
+
z-index: 4;
|
|
105
|
+
right: 12px;
|
|
106
|
+
bottom: 12px;
|
|
107
|
+
width: 44px;
|
|
108
|
+
height: 44px;
|
|
109
|
+
padding: 0;
|
|
110
|
+
border: 0;
|
|
111
|
+
border-radius: 999px;
|
|
112
|
+
color: #fff;
|
|
113
|
+
background: rgb(18 24 29 / 84%);
|
|
114
|
+
font: 700 13px/1 system-ui, sans-serif;
|
|
115
|
+
cursor: pointer;
|
|
116
|
+
}
|
|
117
|
+
.animate-it-embed__control:focus-visible { outline: 3px solid var(--animate-it-progress-color, #28d2bc); outline-offset: 3px; }
|
|
118
|
+
animate-it-embed[data-reduced-motion="true"] .animate-it-embed__navigation,
|
|
119
|
+
animate-it-embed[data-reduced-motion="true"] .animate-it-embed__control { display: none; }
|
|
120
|
+
@media (prefers-reduced-motion: reduce) {
|
|
121
|
+
.animate-it-embed__poster, .animate-it-embed__shell { transition: none; }
|
|
122
|
+
}
|
|
123
|
+
CSS
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
data/lib/animate_it/engine.rb
CHANGED
|
@@ -29,7 +29,10 @@ module AnimateIt
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
initializer "animate_it.embed_helper" do
|
|
32
|
-
ActiveSupport.on_load(:action_view)
|
|
32
|
+
ActiveSupport.on_load(:action_view) do
|
|
33
|
+
include AnimateIt::EmbedHelper
|
|
34
|
+
include AnimateIt::ChapterNavigationHelper
|
|
35
|
+
end
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module AnimateIt
|
|
2
|
+
class PlayerManifest
|
|
3
|
+
VERSION = 1
|
|
4
|
+
|
|
5
|
+
def initialize(composition)
|
|
6
|
+
@composition = composition
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def as_json(*)
|
|
10
|
+
@composition.chapters.validate!
|
|
11
|
+
{
|
|
12
|
+
"version" => VERSION,
|
|
13
|
+
"id" => @composition.id,
|
|
14
|
+
"width" => @composition.width,
|
|
15
|
+
"height" => @composition.height,
|
|
16
|
+
"fps" => @composition.fps,
|
|
17
|
+
"duration" => @composition.duration_in_frames,
|
|
18
|
+
"chapters" => @composition.chapters.as_json,
|
|
19
|
+
"playback" => @composition.public_player_options.transform_keys { |key| camelize(key) }
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def camelize(key)
|
|
26
|
+
key.to_s.gsub(/_([a-z])/) { Regexp.last_match(1).upcase }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -74,6 +74,51 @@
|
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
function clamp(value, min, max) {
|
|
78
|
+
return Math.max(min, Math.min(max, value));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function createChapterState(manifest, root) {
|
|
82
|
+
var chapters = (manifest && manifest.chapters) || [];
|
|
83
|
+
var elements = chapters.length ? Array.prototype.slice.call(root.querySelectorAll("[data-animate-it-chapter]")) : [];
|
|
84
|
+
var lastName = null;
|
|
85
|
+
|
|
86
|
+
function setElementState(el, chapter, index, currentIndex, progress) {
|
|
87
|
+
var state = currentIndex < 0 || index > currentIndex ? "upcoming" : (index < currentIndex ? "completed" : "current");
|
|
88
|
+
var position = currentIndex < 0 ? "hidden" :
|
|
89
|
+
(index === currentIndex ? "current" : (index === currentIndex - 1 ? "previous" : (index === currentIndex + 1 ? "next" : "hidden")));
|
|
90
|
+
var chapterProgress = state === "completed" ? 1 : (state === "current" ? progress : 0);
|
|
91
|
+
el.dataset.chapterState = state;
|
|
92
|
+
el.dataset.chapterPosition = position;
|
|
93
|
+
el.style.setProperty("--animate-it-chapter-progress", String(chapterProgress));
|
|
94
|
+
el.style.setProperty("--animate-it-chapter-active", state === "current" ? "1" : "0");
|
|
95
|
+
el.style.setProperty("--animate-it-chapter-complete", state === "completed" ? "1" : "0");
|
|
96
|
+
if (el.tagName === "BUTTON") {
|
|
97
|
+
if (state === "current") el.setAttribute("aria-current", "step");
|
|
98
|
+
else el.removeAttribute("aria-current");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function update(frame) {
|
|
103
|
+
var currentIndex = -1;
|
|
104
|
+
for (var i = chapters.length - 1; i >= 0; i -= 1) {
|
|
105
|
+
if (frame >= chapters[i].startFrame) { currentIndex = i; break; }
|
|
106
|
+
}
|
|
107
|
+
var current = currentIndex >= 0 ? chapters[currentIndex] : null;
|
|
108
|
+
var progress = current ? (current.durationFrames === 1 ? 1 :
|
|
109
|
+
clamp((frame - current.startFrame) / (current.durationFrames - 1), 0, 1)) : 0;
|
|
110
|
+
elements.forEach(function (el) {
|
|
111
|
+
var index = chapters.findIndex(function (chapter) { return chapter.name === el.dataset.animateItChapter; });
|
|
112
|
+
if (index >= 0) setElementState(el, chapters[index], index, currentIndex, progress);
|
|
113
|
+
});
|
|
114
|
+
var changed = (current && current.name) !== lastName;
|
|
115
|
+
lastName = current && current.name;
|
|
116
|
+
return { chapter: current, index: currentIndex, progress: progress, changed: changed };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return { update: update, chapters: chapters };
|
|
120
|
+
}
|
|
121
|
+
|
|
77
122
|
// Pause native CSS/Web Animations and seek them to deterministic frame
|
|
78
123
|
// time. Layers use scene-local time so delayed scenes start at zero.
|
|
79
124
|
var animationCache = typeof WeakMap === "undefined" ? null : new WeakMap();
|
|
@@ -100,7 +145,8 @@
|
|
|
100
145
|
return animations;
|
|
101
146
|
}
|
|
102
147
|
|
|
103
|
-
function createPlayer(doc, root) {
|
|
148
|
+
function createPlayer(doc, root, options) {
|
|
149
|
+
var settings = options || {};
|
|
104
150
|
var duration = doc.duration;
|
|
105
151
|
var varBindings = [];
|
|
106
152
|
var group;
|
|
@@ -140,9 +186,12 @@
|
|
|
140
186
|
});
|
|
141
187
|
|
|
142
188
|
var current = -1;
|
|
189
|
+
var chapterState = createChapterState(settings.manifest, root);
|
|
190
|
+
var currentChapter = null;
|
|
143
191
|
|
|
144
192
|
function setFrame(n) {
|
|
145
193
|
var frame = Math.max(0, Math.min(duration - 1, Math.round(Number(n) || 0)));
|
|
194
|
+
var frameChanged = frame !== current;
|
|
146
195
|
current = frame;
|
|
147
196
|
|
|
148
197
|
layers.forEach(function (layer) {
|
|
@@ -180,6 +229,8 @@
|
|
|
180
229
|
} else {
|
|
181
230
|
seekAnimations(root, frame, doc.fps);
|
|
182
231
|
}
|
|
232
|
+
currentChapter = chapterState.update(frame);
|
|
233
|
+
if (frameChanged && typeof settings.onFrame === "function") settings.onFrame(frame, currentChapter);
|
|
183
234
|
return frame;
|
|
184
235
|
}
|
|
185
236
|
|
|
@@ -187,7 +238,8 @@
|
|
|
187
238
|
duration: duration,
|
|
188
239
|
fps: doc.fps,
|
|
189
240
|
setFrame: setFrame,
|
|
190
|
-
currentFrame: function () { return current; }
|
|
241
|
+
currentFrame: function () { return current; },
|
|
242
|
+
currentChapter: function () { return currentChapter; }
|
|
191
243
|
};
|
|
192
244
|
}
|
|
193
245
|
|
|
@@ -204,6 +256,7 @@
|
|
|
204
256
|
var animationFrame = null;
|
|
205
257
|
var startedAt = 0;
|
|
206
258
|
var startedFrame = frame;
|
|
259
|
+
var emit = typeof settings.onEvent === "function" ? settings.onEvent : function () {};
|
|
207
260
|
|
|
208
261
|
audios.forEach(function (el) {
|
|
209
262
|
var gain = Number(el.dataset.gain);
|
|
@@ -269,10 +322,12 @@
|
|
|
269
322
|
}
|
|
270
323
|
|
|
271
324
|
function pause() {
|
|
325
|
+
var wasPlaying = animationFrame !== null;
|
|
272
326
|
if (animationFrame !== null) global.cancelAnimationFrame(animationFrame);
|
|
273
327
|
animationFrame = null;
|
|
274
328
|
syncAudio(frame, false);
|
|
275
329
|
updateButton(false);
|
|
330
|
+
if (wasPlaying) emit("pause", { frame: frame });
|
|
276
331
|
}
|
|
277
332
|
|
|
278
333
|
function seek(nextFrame) {
|
|
@@ -294,6 +349,7 @@
|
|
|
294
349
|
if (next >= duration) {
|
|
295
350
|
if (!shouldLoop) {
|
|
296
351
|
frame = player.setFrame(duration - 1);
|
|
352
|
+
emit("ended", { frame: frame });
|
|
297
353
|
pause();
|
|
298
354
|
return;
|
|
299
355
|
}
|
|
@@ -316,8 +372,10 @@
|
|
|
316
372
|
startedFrame = frame;
|
|
317
373
|
updateButton(true);
|
|
318
374
|
animationFrame = global.requestAnimationFrame(tick);
|
|
375
|
+
emit("play", { frame: frame });
|
|
319
376
|
return syncAudio(frame, true).catch(function (error) {
|
|
320
377
|
pause();
|
|
378
|
+
emit("error", { message: error && error.message ? error.message : "AnimateIt playback failed" });
|
|
321
379
|
throw error;
|
|
322
380
|
});
|
|
323
381
|
}
|
|
@@ -339,10 +397,56 @@
|
|
|
339
397
|
};
|
|
340
398
|
}
|
|
341
399
|
|
|
400
|
+
function waitForReady(root) {
|
|
401
|
+
var fonts = root.fonts && root.fonts.ready ? root.fonts.ready.catch(function () {}) : Promise.resolve();
|
|
402
|
+
var images = Array.prototype.slice.call(root.images || []).filter(function (image) {
|
|
403
|
+
if (image.hidden) return false;
|
|
404
|
+
if (typeof image.getBoundingClientRect !== "function") return true;
|
|
405
|
+
var rect = image.getBoundingClientRect();
|
|
406
|
+
return rect.width > 0 && rect.height > 0;
|
|
407
|
+
}).map(function (image) {
|
|
408
|
+
if (image.complete) {
|
|
409
|
+
if (image.naturalWidth === 0) return Promise.reject(new Error("AnimateIt visible image failed to load"));
|
|
410
|
+
return typeof image.decode === "function" ? image.decode() : Promise.resolve();
|
|
411
|
+
}
|
|
412
|
+
return new Promise(function (resolve, reject) {
|
|
413
|
+
image.addEventListener("load", resolve, { once: true });
|
|
414
|
+
image.addEventListener("error", function () {
|
|
415
|
+
reject(new Error("AnimateIt visible image failed to load"));
|
|
416
|
+
}, { once: true });
|
|
417
|
+
});
|
|
418
|
+
});
|
|
419
|
+
return Promise.all([fonts, Promise.all(images)]).then(function () {
|
|
420
|
+
return new Promise(function (resolve) {
|
|
421
|
+
global.requestAnimationFrame(function () { global.requestAnimationFrame(resolve); });
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
|
|
342
426
|
function boot() {
|
|
343
427
|
var script = document.querySelector("script[data-animate-it-tracks]");
|
|
344
428
|
if (!script) return;
|
|
345
|
-
var
|
|
429
|
+
var manifestScript = document.querySelector("script[data-animate-it-manifest]");
|
|
430
|
+
var manifest = manifestScript ? JSON.parse(manifestScript.textContent) : { chapters: [] };
|
|
431
|
+
var currentChapterName = null;
|
|
432
|
+
function emit(name, detail) {
|
|
433
|
+
var payload = Object.assign({ frame: player ? player.currentFrame() : 0 }, detail || {});
|
|
434
|
+
if (typeof global.CustomEvent === "function") global.dispatchEvent(new CustomEvent("animateit:" + name, { detail: payload }));
|
|
435
|
+
if (global.parent && global.parent !== global && global.location) {
|
|
436
|
+
global.parent.postMessage({ namespace: "animate-it", event: name, detail: payload }, global.location.origin);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
var player = createPlayer(JSON.parse(script.textContent), document, {
|
|
440
|
+
manifest: manifest,
|
|
441
|
+
onFrame: function (frame, chapterState) {
|
|
442
|
+
var chapter = chapterState.chapter;
|
|
443
|
+
emit("framechange", { frame: frame, chapter: chapter && chapter.name, progress: chapterState.progress });
|
|
444
|
+
if (chapterState.changed) {
|
|
445
|
+
currentChapterName = chapter && chapter.name;
|
|
446
|
+
emit("chapterchange", { frame: frame, chapter: currentChapterName, progress: chapterState.progress });
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
});
|
|
346
450
|
player.setFrame(0);
|
|
347
451
|
global.__animateIt = { totalFrames: player.duration, setFrame: player.setFrame };
|
|
348
452
|
global.AnimateItRuntime = player;
|
|
@@ -352,13 +456,41 @@
|
|
|
352
456
|
Array.prototype.slice.call(document.querySelectorAll("audio[data-from-frame]")),
|
|
353
457
|
{
|
|
354
458
|
loop: script.dataset.animateItLoop === "true",
|
|
355
|
-
button: document.querySelector("[data-animate-it-play]")
|
|
459
|
+
button: document.querySelector("[data-animate-it-play]"),
|
|
460
|
+
onEvent: emit
|
|
356
461
|
}
|
|
357
462
|
);
|
|
463
|
+
transport.seekChapter = function (name) {
|
|
464
|
+
var chapter = (manifest.chapters || []).find(function (item) { return item.name === String(name); });
|
|
465
|
+
if (!chapter) throw new Error("Unknown AnimateIt chapter: " + name);
|
|
466
|
+
return transport.seek(chapter.startFrame);
|
|
467
|
+
};
|
|
358
468
|
global.AnimateItTransport = transport;
|
|
469
|
+
global.AnimateItPlayer = transport;
|
|
470
|
+
global.addEventListener("message", function (event) {
|
|
471
|
+
if (event.source !== global.parent || !global.location || event.origin !== global.location.origin) return;
|
|
472
|
+
var data = event.data || {};
|
|
473
|
+
if (data.namespace !== "animate-it" || data.command === undefined) return;
|
|
474
|
+
try {
|
|
475
|
+
if (data.command === "play") transport.play().catch(function () {});
|
|
476
|
+
else if (data.command === "pause") transport.pause();
|
|
477
|
+
else if (data.command === "toggle") transport.toggle().catch(function () {});
|
|
478
|
+
else if (data.command === "seek") transport.seek(data.frame);
|
|
479
|
+
else if (data.command === "seekChapter") transport.seekChapter(data.chapter);
|
|
480
|
+
} catch (error) {
|
|
481
|
+
emit("error", { message: error.message });
|
|
482
|
+
}
|
|
483
|
+
});
|
|
359
484
|
if (script.dataset.animateItAutoplay === "true") transport.play().catch(function () {});
|
|
360
485
|
}
|
|
361
|
-
document
|
|
486
|
+
waitForReady(document)
|
|
487
|
+
.then(function () {
|
|
488
|
+
document.documentElement.dataset.animateItReady = "1";
|
|
489
|
+
emit("ready", { manifest: manifest, chapter: currentChapterName });
|
|
490
|
+
})
|
|
491
|
+
.catch(function (error) {
|
|
492
|
+
emit("error", { message: error && error.message ? error.message : "AnimateIt player failed readiness" });
|
|
493
|
+
});
|
|
362
494
|
}
|
|
363
495
|
|
|
364
496
|
var api = {
|
|
@@ -367,6 +499,7 @@
|
|
|
367
499
|
formatComputed: formatComputed,
|
|
368
500
|
interpolate: interpolate,
|
|
369
501
|
compileTrack: compileTrack,
|
|
502
|
+
createChapterState: createChapterState,
|
|
370
503
|
seekAnimations: seekAnimations,
|
|
371
504
|
createPlayer: createPlayer,
|
|
372
505
|
createTransport: createTransport
|
data/lib/animate_it/version.rb
CHANGED
data/lib/animate_it.rb
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
require "active_support"
|
|
2
|
+
require "active_support/core_ext"
|
|
3
|
+
|
|
1
4
|
require_relative "animate_it/version"
|
|
2
5
|
require_relative "animate_it/errors"
|
|
3
6
|
require_relative "animate_it/frame_duration"
|
|
@@ -13,6 +16,7 @@ require_relative "animate_it/timeline"
|
|
|
13
16
|
require_relative "animate_it/registry"
|
|
14
17
|
require_relative "animate_it/render_store"
|
|
15
18
|
require_relative "animate_it/beats"
|
|
19
|
+
require_relative "animate_it/chapters"
|
|
16
20
|
require_relative "animate_it/animation"
|
|
17
21
|
require_relative "animate_it/text_effects"
|
|
18
22
|
require_relative "animate_it/scene"
|
|
@@ -22,6 +26,10 @@ require_relative "animate_it/tracks/layer"
|
|
|
22
26
|
require_relative "animate_it/tracks/document"
|
|
23
27
|
require_relative "animate_it/tracks/recorder"
|
|
24
28
|
require_relative "animate_it/track_document_schema"
|
|
29
|
+
require_relative "animate_it/player_manifest"
|
|
30
|
+
require_relative "animate_it/embed_styles"
|
|
31
|
+
require_relative "animate_it/chapter_navigation"
|
|
32
|
+
require_relative "animate_it/embed_runtime"
|
|
25
33
|
require_relative "animate_it/runtime"
|
|
26
34
|
require_relative "animate_it/embed_helper"
|
|
27
35
|
require_relative "animate_it/output"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: animate_it
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- growth-constant
|
|
@@ -58,6 +58,7 @@ files:
|
|
|
58
58
|
- README.md
|
|
59
59
|
- app/controllers/animate_it/application_controller.rb
|
|
60
60
|
- app/controllers/animate_it/audio_controller.rb
|
|
61
|
+
- app/controllers/animate_it/embed_assets_controller.rb
|
|
61
62
|
- app/controllers/animate_it/frames_controller.rb
|
|
62
63
|
- app/controllers/animate_it/props_controller.rb
|
|
63
64
|
- app/controllers/animate_it/public_players_controller.rb
|
|
@@ -90,15 +91,21 @@ files:
|
|
|
90
91
|
- lib/animate_it/asset_manifest.rb
|
|
91
92
|
- lib/animate_it/asset_renderer.rb
|
|
92
93
|
- lib/animate_it/beats.rb
|
|
94
|
+
- lib/animate_it/chapter_navigation.rb
|
|
95
|
+
- lib/animate_it/chapters.rb
|
|
93
96
|
- lib/animate_it/composition.rb
|
|
94
97
|
- lib/animate_it/configuration.rb
|
|
95
98
|
- lib/animate_it/easing.rb
|
|
96
99
|
- lib/animate_it/embed_helper.rb
|
|
100
|
+
- lib/animate_it/embed_runtime.rb
|
|
101
|
+
- lib/animate_it/embed_runtime/embed.js
|
|
102
|
+
- lib/animate_it/embed_styles.rb
|
|
97
103
|
- lib/animate_it/engine.rb
|
|
98
104
|
- lib/animate_it/errors.rb
|
|
99
105
|
- lib/animate_it/frame_context.rb
|
|
100
106
|
- lib/animate_it/frame_duration.rb
|
|
101
107
|
- lib/animate_it/output.rb
|
|
108
|
+
- lib/animate_it/player_manifest.rb
|
|
102
109
|
- lib/animate_it/props_schema.rb
|
|
103
110
|
- lib/animate_it/registry.rb
|
|
104
111
|
- lib/animate_it/render_store.rb
|
|
@@ -121,14 +128,14 @@ files:
|
|
|
121
128
|
- lib/generators/animate_it/install/install_generator.rb
|
|
122
129
|
- lib/generators/animate_it/install/templates/animate_it.rb
|
|
123
130
|
- lib/tasks/animate_it_tasks.rake
|
|
124
|
-
homepage: https://github.com/
|
|
131
|
+
homepage: https://github.com/joinbuildit/animate_it
|
|
125
132
|
licenses:
|
|
126
133
|
- MIT
|
|
127
134
|
metadata:
|
|
128
|
-
homepage_uri: https://github.com/
|
|
129
|
-
source_code_uri: https://github.com/
|
|
130
|
-
changelog_uri: https://github.com/
|
|
131
|
-
bug_tracker_uri: https://github.com/
|
|
135
|
+
homepage_uri: https://github.com/joinbuildit/animate_it
|
|
136
|
+
source_code_uri: https://github.com/joinbuildit/animate_it
|
|
137
|
+
changelog_uri: https://github.com/joinbuildit/animate_it/blob/main/CHANGELOG.md
|
|
138
|
+
bug_tracker_uri: https://github.com/joinbuildit/animate_it/issues
|
|
132
139
|
rubygems_mfa_required: 'true'
|
|
133
140
|
rdoc_options: []
|
|
134
141
|
require_paths:
|