@aarsteinmedia/dotlottie-player 5.0.0 → 5.0.2
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.
- package/CHANGELOG.md +13 -0
- package/custom-elements.json +242 -2327
- package/dist/index.d.ts +137 -198
- package/dist/index.js +1329 -1218
- package/dist/unpkg.js +2 -0
- package/package.json +40 -45
- package/dist/unpkg/index.js +0 -2
package/dist/index.js
CHANGED
|
@@ -1,12 +1,72 @@
|
|
|
1
|
+
import { isServer as isServer$1, createElementID, PreserveAspectRatio as PreserveAspectRatio$1 } from '@aarsteinmedia/lottie-web/utils';
|
|
2
|
+
import Lottie from 'lottie-web';
|
|
1
3
|
import { strToU8, strFromU8, zip, unzip as unzip$1 } from 'fflate';
|
|
2
|
-
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Credit to: Leonardo Favre https://github.com/leofavre/observed-properties.
|
|
7
|
+
*/ const updateOnConnected = Symbol('UPDATE_ON_CONNECTED');
|
|
8
|
+
if (isServer$1()) {
|
|
9
|
+
// Mock HTMLElement for server-side rendering
|
|
10
|
+
global.HTMLElement = // eslint-disable-next-line @typescript-eslint/no-extraneous-class
|
|
11
|
+
class EmptyHTMLElement {
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* HTMLElement enhanced to track property changes.
|
|
16
|
+
*/ class PropertyCallbackElement extends HTMLElement {
|
|
17
|
+
constructor(){
|
|
18
|
+
super();
|
|
19
|
+
if (updateOnConnected in this) {
|
|
20
|
+
this[updateOnConnected] = [];
|
|
21
|
+
}
|
|
22
|
+
const { observedProperties = [] } = this.constructor;
|
|
23
|
+
const { length } = observedProperties;
|
|
24
|
+
for(let i = 0; i < length; i++){
|
|
25
|
+
const initialValue = this[observedProperties[i]], cachedValue = Symbol(observedProperties[i]);
|
|
26
|
+
this[cachedValue] = initialValue;
|
|
27
|
+
Object.defineProperty(this, observedProperties[i], {
|
|
28
|
+
get () {
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
|
|
30
|
+
return this[cachedValue];
|
|
31
|
+
},
|
|
32
|
+
set (value) {
|
|
33
|
+
const oldValue = this[cachedValue];
|
|
34
|
+
this[cachedValue] = value;
|
|
35
|
+
this.propertyChangedCallback(observedProperties[i], oldValue, value);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (typeof initialValue !== 'undefined' && updateOnConnected in this && Array.isArray(this[updateOnConnected])) {
|
|
39
|
+
this[updateOnConnected].push(observedProperties[i]);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// eslint-disable-next-line @typescript-eslint/require-await
|
|
44
|
+
async connectedCallback() {
|
|
45
|
+
let arr = [];
|
|
46
|
+
if (updateOnConnected in this && Array.isArray(this[updateOnConnected])) {
|
|
47
|
+
arr = this[updateOnConnected];
|
|
48
|
+
}
|
|
49
|
+
const { length } = arr;
|
|
50
|
+
for(let i = 0; i < length; i++){
|
|
51
|
+
if (!('propertyChangedCallback' in this) || typeof this.propertyChangedCallback !== 'function') {
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (arr[i] in this) {
|
|
55
|
+
this.propertyChangedCallback(arr[i], undefined, this[arr[i]]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
propertyChangedCallback(_name, _oldValue, _value) {
|
|
60
|
+
throw new Error(`${this.constructor.name}: Method propertyChangedCallback is not implemented`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
3
63
|
|
|
4
64
|
var ObjectFit = /*#__PURE__*/ function(ObjectFit) {
|
|
5
65
|
ObjectFit["Contain"] = "contain";
|
|
6
66
|
ObjectFit["Cover"] = "cover";
|
|
7
67
|
ObjectFit["Fill"] = "fill";
|
|
8
|
-
ObjectFit["ScaleDown"] = "scale-down";
|
|
9
68
|
ObjectFit["None"] = "none";
|
|
69
|
+
ObjectFit["ScaleDown"] = "scale-down";
|
|
10
70
|
return ObjectFit;
|
|
11
71
|
}({});
|
|
12
72
|
var PlayerState = /*#__PURE__*/ function(PlayerState) {
|
|
@@ -45,14 +105,298 @@ var PlayerEvents = /*#__PURE__*/ function(PlayerEvents) {
|
|
|
45
105
|
var PreserveAspectRatio = /*#__PURE__*/ function(PreserveAspectRatio) {
|
|
46
106
|
PreserveAspectRatio["Contain"] = "xMidYMid meet";
|
|
47
107
|
PreserveAspectRatio["Cover"] = "xMidYMid slice";
|
|
48
|
-
PreserveAspectRatio["None"] = "xMinYMin slice";
|
|
49
108
|
PreserveAspectRatio["Initial"] = "none";
|
|
109
|
+
PreserveAspectRatio["None"] = "xMinYMin slice";
|
|
50
110
|
return PreserveAspectRatio;
|
|
51
111
|
}({});
|
|
112
|
+
var RendererType = /*#__PURE__*/ function(RendererType) {
|
|
113
|
+
RendererType["Canvas"] = "canvas";
|
|
114
|
+
RendererType["HTML"] = "html";
|
|
115
|
+
RendererType["SVG"] = "svg";
|
|
116
|
+
return RendererType;
|
|
117
|
+
}({});
|
|
118
|
+
|
|
119
|
+
var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-toolbar-height: 35px;\n --lottie-player-toolbar-background-color: #fff;\n --lottie-player-toolbar-icon-color: #000;\n --lottie-player-toolbar-icon-hover-color: #000;\n --lottie-player-toolbar-icon-active-color: #4285f4;\n --lottie-player-seeker-track-color: rgb(0 0 0 / 20%);\n --lottie-player-seeker-thumb-color: #4285f4;\n --lottie-player-seeker-display: block;\n\n width: 100%;\n height: 100%;\n\n &:not([hidden]) {\n display: block;\n }\n\n .main {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n margin: 0;\n padding: 0;\n }\n\n .animation {\n width: 100%;\n height: 100%;\n display: flex;\n margin: 0;\n padding: 0;\n }\n\n [data-controls='true'] .animation {\n height: calc(100% - 35px);\n }\n\n .animation-container {\n position: relative;\n }\n\n .popover {\n position: absolute;\n right: 5px;\n bottom: 40px;\n background-color: var(--lottie-player-toolbar-background-color);\n border-radius: 5px;\n padding: 10px 15px;\n border: solid 2px var(--lottie-player-toolbar-icon-color);\n animation: fade-in 0.2s ease-in-out;\n\n &::before {\n content: '';\n right: 10px;\n border: 7px solid transparent;\n margin-right: -7px;\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n top: 100%;\n border-top-color: var(--lottie-player-toolbar-icon-color);\n }\n }\n\n .error {\n display: flex;\n margin: auto;\n justify-content: center;\n height: 100%;\n align-items: center;\n\n & svg {\n width: 100%;\n height: auto;\n }\n }\n\n .toolbar {\n display: flex;\n place-items: center center;\n background: var(--lottie-player-toolbar-background-color);\n margin: 0;\n height: 35px;\n padding: 5px;\n border-radius: 5px;\n gap: 5px;\n\n &.has-error {\n pointer-events: none;\n opacity: 0.5;\n }\n\n & button {\n cursor: pointer;\n fill: var(--lottie-player-toolbar-icon-color);\n color: var(--lottie-player-toolbar-icon-color);\n background: none;\n border: 0;\n padding: 0;\n outline: 0;\n height: 100%;\n margin: 0;\n align-items: center;\n gap: 5px;\n opacity: 0.9;\n\n &:not([hidden]) {\n display: flex;\n }\n\n &:hover {\n opacity: 1;\n }\n\n &[data-active='true'] {\n opacity: 1;\n fill: var(--lottie-player-toolbar-icon-active-color);\n }\n\n &:disabled {\n opacity: 0.5;\n }\n\n &:focus {\n outline: 0;\n }\n\n & svg {\n pointer-events: none;\n\n & > * {\n fill: inherit;\n }\n }\n\n &.disabled svg {\n display: none;\n }\n }\n }\n\n .progress-container {\n position: relative;\n width: 100%;\n\n &.simple {\n margin-right: 12px;\n }\n }\n\n .seeker {\n appearance: none;\n outline: none;\n width: 100%;\n height: 20px;\n border-radius: 3px;\n border: 0;\n cursor: pointer;\n background-color: transparent;\n\n display: var(--lottie-player-seeker-display);\n color: var(--lottie-player-seeker-thumb-color);\n margin: 0;\n padding: 7.5px 0;\n position: relative;\n z-index: 1;\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n appearance: none;\n outline: none;\n }\n\n &::-webkit-slider-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n border: 0;\n background-color: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -webkit-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-webkit-slider-thumb,\n &:focus::-webkit-slider-thumb {\n transform: scale(1);\n }\n\n &::-moz-range-progress {\n background-color: var(--lottie-player-seeker-thumb-color);\n height: 5px;\n border-radius: 3px;\n }\n\n &::-moz-range-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background-color: var(--lottie-player-seeker-thumb-color);\n border: 0;\n cursor: pointer;\n -moz-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-moz-range-thumb,\n &:focus::-moz-range-thumb {\n transform: scale(1);\n }\n\n &::-ms-track {\n width: 100%;\n height: 5px;\n cursor: pointer;\n background: transparent;\n border-color: transparent;\n color: transparent;\n }\n\n &::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n border-radius: 3px;\n }\n\n &::-ms-fill-lower {\n background-color: var(--lottie-player-seeker-thumb-color);\n border-radius: 3px;\n }\n\n &::-ms-thumb {\n border: 0;\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -ms-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-ms-thumb {\n transform: scale(1);\n }\n\n &:focus {\n &::-ms-thumb {\n transform: scale(1);\n }\n\n &::-ms-fill-lower,\n &::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n }\n }\n }\n\n & progress {\n appearance: none;\n outline: none;\n position: absolute;\n width: 100%;\n height: 5px;\n border-radius: 3px;\n border: 0;\n top: 0;\n left: 0;\n margin: 7.5px 0;\n background-color: var(--lottie-player-seeker-track-color);\n pointer-events: none;\n\n &::-webkit-progress-inner-element {\n border-radius: 3px;\n overflow: hidden;\n }\n\n &::-webkit-slider-runnable-track {\n background-color: transparent;\n }\n\n &::-webkit-progress-value {\n background-color: var(--lottie-player-seeker-thumb-color);\n }\n }\n\n & *::-moz-progress-bar {\n background-color: var(--lottie-player-seeker-thumb-color);\n }\n}\n\n@keyframes fade-in {\n 0% {\n opacity: 0;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n :host {\n --lottie-player-toolbar-background-color: #000;\n --lottie-player-toolbar-icon-color: #fff;\n --lottie-player-toolbar-icon-hover-color: #fff;\n --lottie-player-seeker-track-color: rgb(255 255 255 / 60%);\n }\n}\n";
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Render Controls.
|
|
123
|
+
*/ function renderControls() {
|
|
124
|
+
if (!this.shadow) {
|
|
125
|
+
throw new Error('No Shadow Element');
|
|
126
|
+
}
|
|
127
|
+
const slot = this.shadow.querySelector('slot[name=controls]');
|
|
128
|
+
if (!slot) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (!this.controls) {
|
|
132
|
+
slot.innerHTML = '';
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
slot.innerHTML = /* HTML */ `<div class="lottie-controls toolbar ${this.playerState === PlayerState.Error ? 'has-error' : ''}" aria-label="Lottie Animation controls"><button class="togglePlay" data-active="false" aria-label="Toggle Play/Pause"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg></button> <button class="stop" data-active="true" aria-label="Stop"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M6 6h12v12H6V6z"/></svg></button> <button class="prev" aria-label="Previous animation" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.9 18.2 8.1 12l9.8-6.2v12.4zm-10.3 0H6.1V5.8h1.5v12.4z"/></svg></button> <button class="next" aria-label="Next animation" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="m6.1 5.8 9.8 6.2-9.8 6.2V5.8zM16.4 5.8h1.5v12.4h-1.5z"/></svg></button><form class="progress-container${this.simple ? ' simple' : ''}"><input class="seeker" type="range" min="0" max="100" step="1" value="${this._seeker.toString()}" aria-valuemin="0" aria-valuemax="100" role="slider" aria-valuenow="${this._seeker.toString()}" tabindex="0" aria-label="Slider for search"><progress max="100" value="${this._seeker}"></progress></form>${this.simple ? '' : /* HTML */ `<button class="toggleLoop" data-active="${this.loop}" tabindex="0" aria-label="Toggle loop"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"/></svg></button> <button class="toggleBoomerang" data-active="${this.mode === PlayMode.Bounce}" aria-label="Toggle boomerang" tabindex="0"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="m11.8 13.2-.3.3c-.5.5-1.1 1.1-1.7 1.5-.5.4-1 .6-1.5.8-.5.2-1.1.3-1.6.3s-1-.1-1.5-.3c-.6-.2-1-.5-1.4-1-.5-.6-.8-1.2-.9-1.9-.2-.9-.1-1.8.3-2.6.3-.7.8-1.2 1.3-1.6.3-.2.6-.4 1-.5.2-.2.5-.2.8-.3.3 0 .7-.1 1 0 .3 0 .6.1.9.2.9.3 1.7.9 2.4 1.5.4.4.8.7 1.1 1.1l.1.1.4-.4c.6-.6 1.2-1.2 1.9-1.6.5-.3 1-.6 1.5-.7.4-.1.7-.2 1-.2h.9c1 .1 1.9.5 2.6 1.4.4.5.7 1.1.8 1.8.2.9.1 1.7-.2 2.5-.4.9-1 1.5-1.8 2-.4.2-.7.4-1.1.4-.4.1-.8.1-1.2.1-.5 0-.9-.1-1.3-.3-.8-.3-1.5-.9-2.1-1.5-.4-.4-.8-.7-1.1-1.1h-.3zm-1.1-1.1c-.1-.1-.1-.1 0 0-.3-.3-.6-.6-.8-.9-.5-.5-1-.9-1.6-1.2-.4-.3-.8-.4-1.3-.4-.4 0-.8 0-1.1.2-.5.2-.9.6-1.1 1-.2.3-.3.7-.3 1.1 0 .3 0 .6.1.9.1.5.4.9.8 1.2.5.4 1.1.5 1.7.5.5 0 1-.2 1.5-.5.6-.4 1.1-.8 1.6-1.3.1-.3.3-.5.5-.6zM13 12c.5.5 1 1 1.5 1.4.5.5 1.1.9 1.9 1 .4.1.8 0 1.2-.1.3-.1.6-.3.9-.5.4-.4.7-.9.8-1.4.1-.5 0-.9-.1-1.4-.3-.8-.8-1.2-1.7-1.4-.4-.1-.8-.1-1.2 0-.5.1-1 .4-1.4.7-.5.4-1 .8-1.4 1.2-.2.2-.4.3-.5.5z"/></svg></button> <button class="toggleSettings" aria-label="Settings" aria-haspopup="true" aria-expanded="${Boolean(this._isSettingsOpen)}" aria-controls="${this._identifier}-settings"><svg width="24" height="24" aria-hidden="true" focusable="false"><circle cx="12" cy="5.4" r="2.5"/><circle cx="12" cy="12" r="2.5"/><circle cx="12" cy="18.6" r="2.5"/></svg></button><div id="${this._identifier}-settings" class="popover" hidden><button class="convert" aria-label="Convert JSON animation to dotLottie format" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"/></svg> Convert to dotLottie</button> <button class="snapshot" aria-label="Download still image"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M16.8 10.8 12 15.6l-4.8-4.8h3V3.6h3.6v7.2h3zM12 15.6H3v4.8h18v-4.8h-9zm7.8 2.4h-2.4v-1.2h2.4V18z"/></svg> Download still image</button></div>`}</div>`;
|
|
136
|
+
const togglePlay = this.shadow.querySelector('.togglePlay');
|
|
137
|
+
if (togglePlay instanceof HTMLButtonElement) {
|
|
138
|
+
togglePlay.onclick = this.togglePlay;
|
|
139
|
+
}
|
|
140
|
+
const stop = this.shadow.querySelector('.stop');
|
|
141
|
+
if (stop instanceof HTMLButtonElement) {
|
|
142
|
+
stop.onclick = this.stop;
|
|
143
|
+
}
|
|
144
|
+
const prev = this.shadow.querySelector('.prev');
|
|
145
|
+
if (prev instanceof HTMLButtonElement) {
|
|
146
|
+
prev.onclick = this.prev;
|
|
147
|
+
}
|
|
148
|
+
const next = this.shadow.querySelector('.next');
|
|
149
|
+
if (next instanceof HTMLButtonElement) {
|
|
150
|
+
next.onclick = this.next;
|
|
151
|
+
}
|
|
152
|
+
const seeker = this.shadow.querySelector('.seeker');
|
|
153
|
+
if (seeker instanceof HTMLInputElement) {
|
|
154
|
+
seeker.onchange = this._handleSeekChange;
|
|
155
|
+
seeker.onmousedown = this._freeze;
|
|
156
|
+
}
|
|
157
|
+
if (!this.simple) {
|
|
158
|
+
const toggleLoop = this.shadow.querySelector('.toggleLoop');
|
|
159
|
+
if (toggleLoop instanceof HTMLButtonElement) {
|
|
160
|
+
toggleLoop.onclick = this.toggleLoop;
|
|
161
|
+
}
|
|
162
|
+
const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
|
|
163
|
+
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
164
|
+
toggleBoomerang.onclick = this.toggleBoomerang;
|
|
165
|
+
}
|
|
166
|
+
const convert = this.shadow.querySelector('.convert');
|
|
167
|
+
if (convert instanceof HTMLButtonElement) {
|
|
168
|
+
convert.onclick = this.convert;
|
|
169
|
+
}
|
|
170
|
+
const snapshot = this.shadow.querySelector('.snapshot');
|
|
171
|
+
if (snapshot instanceof HTMLButtonElement) {
|
|
172
|
+
snapshot.onclick = ()=>this.snapshot(true);
|
|
173
|
+
}
|
|
174
|
+
const toggleSettings = this.shadow.querySelector('.toggleSettings');
|
|
175
|
+
if (toggleSettings instanceof HTMLButtonElement) {
|
|
176
|
+
toggleSettings.onclick = this._handleSettingsClick;
|
|
177
|
+
toggleSettings.onblur = this._handleBlur;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Render Player.
|
|
184
|
+
*/ async function renderPlayer() {
|
|
185
|
+
if (!this.shadow) {
|
|
186
|
+
throw new Error('No Shadow Element');
|
|
187
|
+
}
|
|
188
|
+
this.template.innerHTML = /* HTML */ `<div class="animation-container main" data-controls="${this.controls ?? false}" lang="${this.description ? document.documentElement.lang : 'en'}" aria-label="${this.description ?? 'Lottie animation'}" data-loaded="${this._playerState.loaded}"><figure class="animation" style="background:${this.background}">${this.playerState === PlayerState.Error ? /* HTML */ `<div class="error"><svg preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1920" height="1080" viewBox="0 0 1920 1080"><path fill="#fff" d="M0 0h1920v1080H0z"/><path fill="#3a6d8b" d="M1190.2 531 1007 212.4c-22-38.2-77.2-38-98.8.5L729.5 531.3c-21.3 37.9 6.1 84.6 49.5 84.6l361.9.3c43.7 0 71.1-47.3 49.3-85.2zM937.3 288.7c.2-7.5 3.3-23.9 23.2-23.9 16.3 0 23 16.1 23 23.5 0 55.3-10.7 197.2-12.2 214.5-.1 1-.9 1.7-1.9 1.7h-18.3c-1 0-1.8-.7-1.9-1.7-1.4-17.5-13.4-162.9-11.9-214.1zm24.2 283.8c-13.1 0-23.7-10.6-23.7-23.7s10.6-23.7 23.7-23.7 23.7 10.6 23.7 23.7-10.6 23.7-23.7 23.7zM722.1 644h112.6v34.4h-70.4V698h58.8v31.7h-58.8v22.6h72.4v36.2H722.1V644zm162 57.1h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6zm78.9 0h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5H963v15.6zm39.5 36.2c0-31.3 22.2-54.8 56.6-54.8 34.4 0 56.2 23.5 56.2 54.8s-21.8 54.6-56.2 54.6c-34.4-.1-56.6-23.3-56.6-54.6zm74 0c0-17.4-6.1-29.1-17.8-29.1-11.7 0-17.4 11.7-17.4 29.1 0 17.4 5.7 29.1 17.4 29.1s17.8-11.8 17.8-29.1zm83.1-36.2h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6z"/><path fill="none" d="M718.9 807.7h645v285.4h-645z"/><text fill="#3a6d8b" style="text-align:center;position:absolute;left:100%;font-size:47px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'.SFNSText-Regular',sans-serif" x="50%" y="848.017" text-anchor="middle">${this._errorMessage}</text></svg></div>` : ''}</figure><slot name="controls"></slot></div>`;
|
|
189
|
+
this.shadow.adoptedStyleSheets = [
|
|
190
|
+
await DotLottiePlayer.styles()
|
|
191
|
+
];
|
|
192
|
+
this.shadow.appendChild(this.template.content.cloneNode(true));
|
|
193
|
+
}
|
|
52
194
|
|
|
53
195
|
class CustomError extends Error {
|
|
54
196
|
}
|
|
55
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Methods used locally and exported.
|
|
199
|
+
*/ const getManifest = (unzipped)=>{
|
|
200
|
+
const file = strFromU8(unzipped['manifest.json'], false), manifest = JSON.parse(file);
|
|
201
|
+
if (!('animations' in manifest)) {
|
|
202
|
+
throw new Error('Manifest not found');
|
|
203
|
+
}
|
|
204
|
+
if (manifest.animations.length === 0) {
|
|
205
|
+
throw new Error('No animations listed in manifest');
|
|
206
|
+
}
|
|
207
|
+
return manifest;
|
|
208
|
+
}, isServer = ()=>!(typeof window !== 'undefined' && window.document);
|
|
209
|
+
/**
|
|
210
|
+
* Methods used only locally.
|
|
211
|
+
*/ const hasExt = (path)=>{
|
|
212
|
+
const lastDotIndex = path?.split('/').pop()?.lastIndexOf('.');
|
|
213
|
+
return (lastDotIndex ?? 0) > 1 && path && path.length - 1 > (lastDotIndex ?? 0);
|
|
214
|
+
};
|
|
215
|
+
/**
|
|
216
|
+
* Get extension from filename, URL or path.
|
|
217
|
+
*/ const getExt = (str)=>{
|
|
218
|
+
if (typeof str !== 'string' || !str || !hasExt(str)) {
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
return str.split('.').pop()?.toLowerCase();
|
|
222
|
+
};
|
|
223
|
+
const unzip = async (resp)=>{
|
|
224
|
+
const u8 = new Uint8Array(await resp.arrayBuffer()), unzipped = await new Promise((resolve, reject)=>{
|
|
225
|
+
unzip$1(u8, (err, file)=>{
|
|
226
|
+
if (err) {
|
|
227
|
+
reject(err);
|
|
228
|
+
}
|
|
229
|
+
resolve(file);
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
return unzipped;
|
|
233
|
+
}, getArrayBuffer = async (zippable)=>{
|
|
234
|
+
const arrayBuffer = await new Promise((resolve, reject)=>{
|
|
235
|
+
zip(zippable, {
|
|
236
|
+
level: 9
|
|
237
|
+
}, (err, data)=>{
|
|
238
|
+
if (err) {
|
|
239
|
+
reject(err);
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
if (!(data.buffer instanceof ArrayBuffer)) {
|
|
243
|
+
reject(new Error('Data is not transferable'));
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
resolve(data.buffer);
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
return arrayBuffer;
|
|
250
|
+
}, getMimeFromExt = (ext)=>{
|
|
251
|
+
switch(ext){
|
|
252
|
+
case 'svg':
|
|
253
|
+
case 'svg+xml':
|
|
254
|
+
{
|
|
255
|
+
return 'image/svg+xml';
|
|
256
|
+
}
|
|
257
|
+
case 'jpg':
|
|
258
|
+
case 'jpeg':
|
|
259
|
+
{
|
|
260
|
+
return 'image/jpeg';
|
|
261
|
+
}
|
|
262
|
+
case 'png':
|
|
263
|
+
case 'gif':
|
|
264
|
+
case 'webp':
|
|
265
|
+
case 'avif':
|
|
266
|
+
{
|
|
267
|
+
return `image/${ext}`;
|
|
268
|
+
}
|
|
269
|
+
case 'mp3':
|
|
270
|
+
case 'mpeg':
|
|
271
|
+
case 'wav':
|
|
272
|
+
{
|
|
273
|
+
return `audio/${ext}`;
|
|
274
|
+
}
|
|
275
|
+
default:
|
|
276
|
+
{
|
|
277
|
+
return '';
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}, isAudio = (asset)=>!('h' in asset) && !('w' in asset) && 'p' in asset && 'e' in asset && 'u' in asset && 'id' in asset, isImage = (asset)=>'w' in asset && 'h' in asset && !('xt' in asset) && 'p' in asset, parseBase64 = (str)=>str.slice(Math.max(0, str.indexOf(',') + 1)), isBase64 = (str)=>{
|
|
281
|
+
if (!str) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
const regex = /^(?:[0-9a-z+/]{4})*(?:[0-9a-z+/]{2}==|[0-9a-z+/]{3}=)?$/i;
|
|
285
|
+
return regex.test(parseBase64(str));
|
|
286
|
+
}, resolveAssets = async (unzipped, assets)=>{
|
|
287
|
+
if (!Array.isArray(assets)) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const toResolve = [], { length } = assets;
|
|
291
|
+
for(let i = 0; i < length; i++){
|
|
292
|
+
if (!isAudio(assets[i]) && !isImage(assets[i])) {
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
const type = isImage(assets[i]) ? 'images' : 'audio', u8 = unzipped?.[`${type}/${assets[i].p}`];
|
|
296
|
+
if (!u8) {
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
toResolve.push(new Promise((resolveAsset)=>{
|
|
300
|
+
let assetB64;
|
|
301
|
+
if (isServer()) {
|
|
302
|
+
assetB64 = Buffer.from(u8).toString('base64');
|
|
303
|
+
} else {
|
|
304
|
+
let result = '';
|
|
305
|
+
const { length: jLen } = u8;
|
|
306
|
+
for(let j = 0; j < jLen; j++){
|
|
307
|
+
result += String.fromCharCode(u8[j]);
|
|
308
|
+
}
|
|
309
|
+
assetB64 = btoa(result);
|
|
310
|
+
}
|
|
311
|
+
assets[i].p = assets[i].p?.startsWith('data:') || isBase64(assets[i].p) ? assets[i].p : `data:${getMimeFromExt(getExt(assets[i].p))};base64,${assetB64}`;
|
|
312
|
+
assets[i].e = 1;
|
|
313
|
+
assets[i].u = '';
|
|
314
|
+
resolveAsset();
|
|
315
|
+
}));
|
|
316
|
+
}
|
|
317
|
+
await Promise.all(toResolve);
|
|
318
|
+
}, prepareString = (str)=>str.replaceAll(new RegExp(/"""/, 'g'), '""').replaceAll(/(["'])(.*?)\1/g, (_match, quote, content)=>{
|
|
319
|
+
const replacedContent = content.replaceAll(/[^\w\s.#]/g, '');
|
|
320
|
+
return `${quote}${replacedContent}${quote}`;
|
|
321
|
+
}), fileToBase64 = async (url)=>{
|
|
322
|
+
const response = await fetch(url), blob = await response.blob();
|
|
323
|
+
return new Promise((resolve, reject)=>{
|
|
324
|
+
try {
|
|
325
|
+
const reader = new FileReader();
|
|
326
|
+
reader.onload = ()=>{
|
|
327
|
+
if (typeof reader.result === 'string') {
|
|
328
|
+
resolve(reader.result);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
reject(new Error('Could not create bas64'));
|
|
332
|
+
};
|
|
333
|
+
reader.readAsDataURL(blob);
|
|
334
|
+
} catch (error) {
|
|
335
|
+
reject(error);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}, getLottieJSON = async (resp)=>{
|
|
339
|
+
const unzipped = await unzip(resp), manifest = getManifest(unzipped), data = [], toResolve = [], { length } = manifest.animations;
|
|
340
|
+
/**
|
|
341
|
+
* Check whether Lottie animations folder is abbreviated.
|
|
342
|
+
*/ let animationsFolder = 'animations';
|
|
343
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
344
|
+
if (unzipped[`a/${manifest.animations[0].id}.json`]) {
|
|
345
|
+
animationsFolder = 'a';
|
|
346
|
+
}
|
|
347
|
+
for(let i = 0; i < length; i++){
|
|
348
|
+
const str = strFromU8(unzipped[`${animationsFolder}/${manifest.animations[i].id}.json`]), lottie = JSON.parse(prepareString(str));
|
|
349
|
+
// Handle Expressions
|
|
350
|
+
const { length: jLen } = lottie.layers;
|
|
351
|
+
for(let j = 0; j < jLen; j++){
|
|
352
|
+
const { ks: shape } = lottie.layers[j], props = Object.keys(shape), { length: pLen } = props;
|
|
353
|
+
for(let p = 0; p < pLen; p++){
|
|
354
|
+
const { e: isEncoded, x: expression } = shape[props[p]];
|
|
355
|
+
if (!expression || !isEncoded) {
|
|
356
|
+
continue;
|
|
357
|
+
}
|
|
358
|
+
// Base64 Decode to handle compression
|
|
359
|
+
// @ts-expect-error
|
|
360
|
+
lottie.layers[j].ks[props[p]].x = atob(expression);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
toResolve.push(resolveAssets(unzipped, lottie.assets));
|
|
364
|
+
data.push(lottie);
|
|
365
|
+
}
|
|
366
|
+
await Promise.all(toResolve);
|
|
367
|
+
return {
|
|
368
|
+
data,
|
|
369
|
+
manifest
|
|
370
|
+
};
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* Download file, either SVG or dotLottie.
|
|
374
|
+
*/ const download = (data, options)=>{
|
|
375
|
+
const blob = new Blob([
|
|
376
|
+
data
|
|
377
|
+
], {
|
|
378
|
+
type: options?.mimeType
|
|
379
|
+
}), fileName = options?.name || createElementID(), dataURL = URL.createObjectURL(blob), link = document.createElement('a');
|
|
380
|
+
link.href = dataURL;
|
|
381
|
+
link.download = fileName;
|
|
382
|
+
link.hidden = true;
|
|
383
|
+
document.body.appendChild(link);
|
|
384
|
+
link.click();
|
|
385
|
+
setTimeout(()=>{
|
|
386
|
+
link.remove();
|
|
387
|
+
URL.revokeObjectURL(dataURL);
|
|
388
|
+
}, 1000);
|
|
389
|
+
}, /**
|
|
390
|
+
* Parse URL to get filename.
|
|
391
|
+
*
|
|
392
|
+
* @param src - The url string.
|
|
393
|
+
* @param keepExt - Whether to include file extension.
|
|
394
|
+
* @returns Filename, in lowercase.
|
|
395
|
+
*/ getFilename = (src, keepExt)=>{
|
|
396
|
+
// Because the regex strips all special characters, we need to extract the file extension, so we can add it later if we need it
|
|
397
|
+
getExt(src);
|
|
398
|
+
return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replaceAll(/\W+/g, '-')}${''}`;
|
|
399
|
+
}, addExt = (ext, str)=>{
|
|
56
400
|
if (!str) {
|
|
57
401
|
return;
|
|
58
402
|
}
|
|
@@ -67,30 +411,59 @@ const addExt = (ext, str)=>{
|
|
|
67
411
|
switch(objectFit){
|
|
68
412
|
case ObjectFit.Contain:
|
|
69
413
|
case ObjectFit.ScaleDown:
|
|
70
|
-
|
|
414
|
+
{
|
|
415
|
+
return PreserveAspectRatio$1.Contain;
|
|
416
|
+
}
|
|
71
417
|
case ObjectFit.Cover:
|
|
72
|
-
|
|
418
|
+
{
|
|
419
|
+
return PreserveAspectRatio$1.Cover;
|
|
420
|
+
}
|
|
73
421
|
case ObjectFit.Fill:
|
|
74
|
-
|
|
422
|
+
{
|
|
423
|
+
return PreserveAspectRatio$1.Initial;
|
|
424
|
+
}
|
|
75
425
|
case ObjectFit.None:
|
|
76
|
-
|
|
426
|
+
{
|
|
427
|
+
return PreserveAspectRatio$1.None;
|
|
428
|
+
}
|
|
77
429
|
default:
|
|
78
|
-
|
|
430
|
+
{
|
|
431
|
+
return PreserveAspectRatio$1.Contain;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}, /**
|
|
435
|
+
* Convert Base64 encoded string to Uint8Array.
|
|
436
|
+
*
|
|
437
|
+
* @param str - Base64 encoded string.
|
|
438
|
+
* @returns UTF-8/Latin-1 binary.
|
|
439
|
+
*/ base64ToU8 = (str)=>strToU8(isServer() ? Buffer.from(parseBase64(str), 'base64').toString('binary') : atob(parseBase64(str)), true), getExtFromB64 = (str)=>{
|
|
440
|
+
const mime = str.split(':')[1].split(';')[0], ext = mime.split('/')[1].split('+')[0];
|
|
441
|
+
return ext;
|
|
442
|
+
}, handleErrors = (err)=>{
|
|
443
|
+
const res = {
|
|
444
|
+
message: 'Unknown error',
|
|
445
|
+
status: isServer() ? 500 : 400
|
|
446
|
+
};
|
|
447
|
+
if (err && typeof err === 'object') {
|
|
448
|
+
if ('message' in err && typeof err.message === 'string') {
|
|
449
|
+
res.message = err.message;
|
|
450
|
+
}
|
|
451
|
+
if ('status' in err) {
|
|
452
|
+
res.status = Number(err.status);
|
|
453
|
+
}
|
|
79
454
|
}
|
|
455
|
+
return res;
|
|
80
456
|
}, /**
|
|
81
|
-
* Convert Base64 encoded string to Uint8Array
|
|
82
|
-
* @param { string } str Base64 encoded string
|
|
83
|
-
* @returns { Uint8Array } UTF-8/Latin-1 binary
|
|
84
|
-
*/ base64ToU8 = (str)=>strToU8(isServer() ? Buffer.from(parseBase64(str), 'base64').toString('binary') : atob(parseBase64(str)), true), /**
|
|
85
457
|
* Convert a JSON Lottie to dotLottie or combine several animations and download new dotLottie file in your browser.
|
|
86
|
-
*/ createDotLottie = async ({ animations, fileName, manifest, shouldDownload = true })=>{
|
|
458
|
+
*/ createDotLottie = async ({ animations = [], fileName, manifest, shouldDownload = true })=>{
|
|
87
459
|
try {
|
|
88
460
|
// Input validation
|
|
89
|
-
if (
|
|
90
|
-
throw new Error(`Missing or malformed required parameter(s):\n ${animations
|
|
461
|
+
if (animations.length === 0 || !manifest) {
|
|
462
|
+
throw new Error(`Missing or malformed required parameter(s):\n ${animations.length > 0 ? '- manifest\n' : ''} ${manifest ? '- animations\n' : ''}`);
|
|
91
463
|
}
|
|
92
|
-
const manifestCompressionLevel = 0, animationCompressionLevel = 9,
|
|
93
|
-
|
|
464
|
+
const manifestCompressionLevel = 0, animationCompressionLevel = 9, /**
|
|
465
|
+
* Prepare the dotLottie file.
|
|
466
|
+
*/ name = addExt('lottie', fileName) || `${createElementID()}.lottie`, dotlottie = {
|
|
94
467
|
'manifest.json': [
|
|
95
468
|
strToU8(JSON.stringify(manifest), true),
|
|
96
469
|
{
|
|
@@ -99,19 +472,31 @@ const addExt = (ext, str)=>{
|
|
|
99
472
|
]
|
|
100
473
|
};
|
|
101
474
|
// Add animations and assets to the dotLottie file
|
|
102
|
-
|
|
103
|
-
|
|
475
|
+
const { length } = animations;
|
|
476
|
+
for(let i = 0; i < length; i++){
|
|
477
|
+
const { length: jLen } = animations[i].assets;
|
|
478
|
+
// Prepare assets
|
|
479
|
+
for(let j = 0; j < jLen; j++){
|
|
480
|
+
const asset = animations[i].assets[j];
|
|
104
481
|
if (!asset.p || !isImage(asset) && !isAudio(asset)) {
|
|
105
482
|
continue;
|
|
106
483
|
}
|
|
107
|
-
const { p: file, u: path } = asset
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
//
|
|
112
|
-
|
|
484
|
+
const { p: file, u: path } = asset;
|
|
485
|
+
if (!file) {
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
// Original asset.id caused issues with multianimations
|
|
489
|
+
const assetId = createElementID(), isEncoded = file.startsWith('data:'), ext = isEncoded ? getExtFromB64(file) : getExt(file), /**
|
|
490
|
+
* Check if the asset is already base64-encoded. If not, get path, fetch it, and encode it.
|
|
491
|
+
*/ dataURL = isEncoded ? file : await fileToBase64(path ? path.endsWith('/') && `${path}${file}` || `${path}/${file}` : file);
|
|
113
492
|
// Asset is encoded
|
|
114
|
-
|
|
493
|
+
// eslint-disable-next-line require-atomic-updates
|
|
494
|
+
animations[i].assets[j].e = 1;
|
|
495
|
+
// eslint-disable-next-line require-atomic-updates
|
|
496
|
+
animations[i].assets[j].p = `${assetId}.${ext}`;
|
|
497
|
+
// Asset is embedded, so path empty string
|
|
498
|
+
// eslint-disable-next-line require-atomic-updates
|
|
499
|
+
animations[i].assets[j].u = '';
|
|
115
500
|
dotlottie[`${isAudio(asset) ? 'audio' : 'images'}/${assetId}.${ext}`] = [
|
|
116
501
|
base64ToU8(dataURL),
|
|
117
502
|
{
|
|
@@ -119,70 +504,59 @@ const addExt = (ext, str)=>{
|
|
|
119
504
|
}
|
|
120
505
|
];
|
|
121
506
|
}
|
|
122
|
-
|
|
123
|
-
|
|
507
|
+
// Prepare expressions
|
|
508
|
+
const { length: kLen } = animations[i].layers;
|
|
509
|
+
for(let k = 0; k < kLen; k++){
|
|
510
|
+
const { ks: shape } = animations[i].layers[k], props = Object.keys(shape), { length: pLen } = props;
|
|
511
|
+
for(let p = 0; p < pLen; p++){
|
|
512
|
+
const { x: expression } = shape[props[p]];
|
|
513
|
+
if (!expression) {
|
|
514
|
+
continue;
|
|
515
|
+
}
|
|
516
|
+
// Base64 Encode to handle compression
|
|
517
|
+
// @ts-expect-error: We have checked this property is set
|
|
518
|
+
animations[i].layers[k].ks[props[p]].x = btoa(expression);
|
|
519
|
+
// Set e (encoded) to 1
|
|
520
|
+
// @ts-expect-error: We have checked this property is set
|
|
521
|
+
animations[i].layers[k].ks[props[p]].e = 1;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
dotlottie[`a/${manifest.animations[i].id}.json`] = [
|
|
525
|
+
strToU8(JSON.stringify(animations[i]), true),
|
|
124
526
|
{
|
|
125
527
|
level: animationCompressionLevel
|
|
126
528
|
}
|
|
127
529
|
];
|
|
128
530
|
}
|
|
129
531
|
const buffer = await getArrayBuffer(dotlottie);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
532
|
+
if (shouldDownload) {
|
|
533
|
+
download(buffer, {
|
|
534
|
+
mimeType: 'application/zip',
|
|
535
|
+
name
|
|
536
|
+
});
|
|
537
|
+
return null;
|
|
538
|
+
}
|
|
539
|
+
return buffer;
|
|
540
|
+
} catch (error) {
|
|
541
|
+
console.error(`❌ ${handleErrors(error).message}`);
|
|
542
|
+
return null;
|
|
543
|
+
}
|
|
544
|
+
}, createJSON = ({ animation, fileName, shouldDownload })=>{
|
|
138
545
|
try {
|
|
139
546
|
if (!animation) {
|
|
140
|
-
throw new Error(
|
|
547
|
+
throw new Error('createJSON: Missing or malformed required parameter(s):\n - animation\n\'');
|
|
141
548
|
}
|
|
142
|
-
const name = addExt('json', fileName) || `${
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
console.error(`❌ ${handleErrors(err).message}`);
|
|
149
|
-
}
|
|
150
|
-
}, /**
|
|
151
|
-
* Download file, either SVG or dotLottie.
|
|
152
|
-
* @param { string } data The data to be downloaded
|
|
153
|
-
* @param { string } name Don't include file extension in the filename
|
|
154
|
-
*/ download = (data, options)=>{
|
|
155
|
-
const blob = new Blob([
|
|
156
|
-
data
|
|
157
|
-
], {
|
|
158
|
-
type: options?.mimeType
|
|
159
|
-
}), fileName = options?.name || useId(), dataURL = URL.createObjectURL(blob), link = document.createElement('a');
|
|
160
|
-
link.href = dataURL;
|
|
161
|
-
link.download = fileName;
|
|
162
|
-
link.hidden = true;
|
|
163
|
-
document.body.appendChild(link);
|
|
164
|
-
link.click();
|
|
165
|
-
setTimeout(()=>{
|
|
166
|
-
link.remove();
|
|
167
|
-
URL.revokeObjectURL(dataURL);
|
|
168
|
-
}, 1000);
|
|
169
|
-
}, fileToBase64 = async (url)=>{
|
|
170
|
-
const response = await fetch(url), blob = await response.blob();
|
|
171
|
-
return new Promise((resolve, reject)=>{
|
|
172
|
-
try {
|
|
173
|
-
const reader = new FileReader();
|
|
174
|
-
reader.onload = ()=>{
|
|
175
|
-
if (typeof reader.result === 'string') {
|
|
176
|
-
resolve(reader.result);
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
reject();
|
|
180
|
-
};
|
|
181
|
-
reader.readAsDataURL(blob);
|
|
182
|
-
} catch (e) {
|
|
183
|
-
reject(e);
|
|
549
|
+
const name = addExt('json', fileName) || `${createElementID()}.json`, jsonString = JSON.stringify(animation);
|
|
550
|
+
if (shouldDownload) {
|
|
551
|
+
download(jsonString, {
|
|
552
|
+
mimeType: 'application/json',
|
|
553
|
+
name
|
|
554
|
+
});
|
|
184
555
|
}
|
|
185
|
-
|
|
556
|
+
return;
|
|
557
|
+
} catch (error) {
|
|
558
|
+
console.error(`❌ ${handleErrors(error).message}`);
|
|
559
|
+
}
|
|
186
560
|
}, frameOutput = (frame)=>((frame ?? 0) + 1).toString().padStart(3, '0'), getAnimationData = async (input)=>{
|
|
187
561
|
try {
|
|
188
562
|
if (!input || typeof input !== 'string' && typeof input !== 'object') {
|
|
@@ -195,7 +569,7 @@ const addExt = (ext, str)=>{
|
|
|
195
569
|
return {
|
|
196
570
|
animations,
|
|
197
571
|
isDotLottie: false,
|
|
198
|
-
manifest:
|
|
572
|
+
manifest: null
|
|
199
573
|
};
|
|
200
574
|
}
|
|
201
575
|
const result = await fetch(input, {
|
|
@@ -209,19 +583,24 @@ const addExt = (ext, str)=>{
|
|
|
209
583
|
throw error;
|
|
210
584
|
}
|
|
211
585
|
/**
|
|
212
|
-
* Check if file is JSON, first by parsing
|
|
213
|
-
* then – if filename has no extension – by
|
|
214
|
-
* and parsing
|
|
215
|
-
*/
|
|
216
|
-
|
|
217
|
-
|
|
586
|
+
* Check if file is JSON, first by parsing headers for content-type,
|
|
587
|
+
* than by parsing filename, then – if filename has no extension – by
|
|
588
|
+
* cloning the response and parsing response for content.
|
|
589
|
+
*/ let isJSON = true;
|
|
590
|
+
const contentType = result.headers.get('content-type');
|
|
591
|
+
if (contentType === 'application/zip+dotlottie') {
|
|
592
|
+
isJSON = false;
|
|
593
|
+
}
|
|
594
|
+
if (isJSON) {
|
|
595
|
+
const ext = getExt(input);
|
|
596
|
+
if (ext === 'json') {
|
|
218
597
|
const lottie = await result.json();
|
|
219
598
|
return {
|
|
220
599
|
animations: [
|
|
221
600
|
lottie
|
|
222
601
|
],
|
|
223
602
|
isDotLottie: false,
|
|
224
|
-
manifest:
|
|
603
|
+
manifest: null
|
|
225
604
|
};
|
|
226
605
|
}
|
|
227
606
|
const text = await result.clone().text();
|
|
@@ -232,9 +611,9 @@ const addExt = (ext, str)=>{
|
|
|
232
611
|
lottie
|
|
233
612
|
],
|
|
234
613
|
isDotLottie: false,
|
|
235
|
-
manifest:
|
|
614
|
+
manifest: null
|
|
236
615
|
};
|
|
237
|
-
} catch (
|
|
616
|
+
} catch (error) {
|
|
238
617
|
/* empty */ }
|
|
239
618
|
}
|
|
240
619
|
const { data, manifest } = await getLottieJSON(result);
|
|
@@ -243,321 +622,264 @@ const addExt = (ext, str)=>{
|
|
|
243
622
|
isDotLottie: true,
|
|
244
623
|
manifest
|
|
245
624
|
};
|
|
246
|
-
} catch (
|
|
247
|
-
console.error(`❌ ${handleErrors(
|
|
625
|
+
} catch (error) {
|
|
626
|
+
console.error(`❌ ${handleErrors(error).message}`);
|
|
248
627
|
return {
|
|
249
628
|
animations: undefined,
|
|
250
629
|
isDotLottie: false,
|
|
251
|
-
manifest:
|
|
630
|
+
manifest: null
|
|
252
631
|
};
|
|
253
632
|
}
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
*/ getExt = (str)=>{
|
|
275
|
-
if (typeof str !== 'string' || !str || !hasExt(str)) {
|
|
276
|
-
return;
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* DotLottie Player Web Component.
|
|
637
|
+
*/ class DotLottiePlayer extends PropertyCallbackElement {
|
|
638
|
+
/**
|
|
639
|
+
* Attributes to observe.
|
|
640
|
+
*/ static get observedAttributes() {
|
|
641
|
+
return [
|
|
642
|
+
'animateOnScroll',
|
|
643
|
+
'autoplay',
|
|
644
|
+
'controls',
|
|
645
|
+
'direction',
|
|
646
|
+
'hover',
|
|
647
|
+
'loop',
|
|
648
|
+
'mode',
|
|
649
|
+
'speed',
|
|
650
|
+
'src',
|
|
651
|
+
'subframe'
|
|
652
|
+
];
|
|
277
653
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
* @returns { string } Filename, in lowercase
|
|
287
|
-
*/ getFilename = (src, keepExt)=>{
|
|
288
|
-
// Because the regex strips all special characters, we need to extract the file extension, so we can add it later if we need it
|
|
289
|
-
getExt(src);
|
|
290
|
-
return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replace(/\W+/g, '-')}${''}` // .toLowerCase()
|
|
291
|
-
;
|
|
292
|
-
}, getLottieJSON = async (resp)=>{
|
|
293
|
-
const unzipped = await unzip(resp), manifest = getManifest(unzipped), data = [], toResolve = [];
|
|
294
|
-
for (const { id } of manifest.animations){
|
|
295
|
-
const str = strFromU8(unzipped[`animations/${id}.json`]), lottie = JSON.parse(prepareString(str));
|
|
296
|
-
toResolve.push(resolveAssets(unzipped, lottie.assets));
|
|
297
|
-
data.push(lottie);
|
|
654
|
+
static get observedProperties() {
|
|
655
|
+
return [
|
|
656
|
+
'playerState',
|
|
657
|
+
'_isSettingsOpen',
|
|
658
|
+
'_seeker',
|
|
659
|
+
'_currentAnimation',
|
|
660
|
+
'_animations'
|
|
661
|
+
];
|
|
298
662
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
throw new Error('Manifest not found');
|
|
663
|
+
/**
|
|
664
|
+
* Return the styles for the component.
|
|
665
|
+
*/ static get styles() {
|
|
666
|
+
return async ()=>{
|
|
667
|
+
const styleSheet = new CSSStyleSheet();
|
|
668
|
+
await styleSheet.replace(css_248z);
|
|
669
|
+
return styleSheet;
|
|
670
|
+
};
|
|
308
671
|
}
|
|
309
|
-
|
|
310
|
-
|
|
672
|
+
/**
|
|
673
|
+
* Whether to trigger next frame with scroll.
|
|
674
|
+
*/ set animateOnScroll(value) {
|
|
675
|
+
this.setAttribute('animateOnScroll', Boolean(value).toString());
|
|
311
676
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
case 'svg':
|
|
316
|
-
case 'svg+xml':
|
|
317
|
-
return 'image/svg+xml';
|
|
318
|
-
case 'jpg':
|
|
319
|
-
case 'jpeg':
|
|
320
|
-
return 'image/jpeg';
|
|
321
|
-
case 'png':
|
|
322
|
-
case 'gif':
|
|
323
|
-
case 'webp':
|
|
324
|
-
case 'avif':
|
|
325
|
-
return `image/${ext}`;
|
|
326
|
-
case 'mp3':
|
|
327
|
-
case 'mpeg':
|
|
328
|
-
case 'wav':
|
|
329
|
-
return `audio/${ext}`;
|
|
330
|
-
default:
|
|
331
|
-
return '';
|
|
677
|
+
get animateOnScroll() {
|
|
678
|
+
const val = this.getAttribute('animateOnScroll');
|
|
679
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
332
680
|
}
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
681
|
+
/**
|
|
682
|
+
* Autoplay.
|
|
683
|
+
*/ set autoplay(value) {
|
|
684
|
+
this.setAttribute('autoplay', Boolean(value).toString());
|
|
685
|
+
}
|
|
686
|
+
get autoplay() {
|
|
687
|
+
const val = this.getAttribute('autoplay');
|
|
688
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
689
|
+
}
|
|
690
|
+
/**
|
|
691
|
+
* Background color.
|
|
692
|
+
*/ set background(value) {
|
|
693
|
+
this.setAttribute('background', value);
|
|
694
|
+
}
|
|
695
|
+
get background() {
|
|
696
|
+
return this.getAttribute('background') || 'transparent';
|
|
697
|
+
}
|
|
698
|
+
/**
|
|
699
|
+
* Show controls.
|
|
700
|
+
*/ set controls(value) {
|
|
701
|
+
this.setAttribute('controls', Boolean(value).toString());
|
|
702
|
+
}
|
|
703
|
+
get controls() {
|
|
704
|
+
const val = this.getAttribute('controls');
|
|
705
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
706
|
+
}
|
|
707
|
+
/**
|
|
708
|
+
* Number of times to loop.
|
|
709
|
+
*/ set count(value) {
|
|
710
|
+
this.setAttribute('count', value.toString());
|
|
711
|
+
}
|
|
712
|
+
get count() {
|
|
713
|
+
const val = this.getAttribute('count');
|
|
714
|
+
if (val) {
|
|
715
|
+
return Number(val);
|
|
341
716
|
}
|
|
342
|
-
|
|
343
|
-
|
|
717
|
+
return 0;
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Description for screen readers.
|
|
721
|
+
*/ set description(value) {
|
|
722
|
+
if (value) {
|
|
723
|
+
this.setAttribute('description', value);
|
|
344
724
|
}
|
|
345
725
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const lastDotIndex = path?.split('/').pop()?.lastIndexOf('.');
|
|
349
|
-
return (lastDotIndex ?? 0) > 1 && path && path.length - 1 > (lastDotIndex ?? 0);
|
|
350
|
-
}, isAudio = (asset)=>!('h' in asset) && !('w' in asset) && 'p' in asset && 'e' in asset && 'u' in asset && 'id' in asset, isBase64 = (str)=>{
|
|
351
|
-
if (!str) {
|
|
352
|
-
return false;
|
|
726
|
+
get description() {
|
|
727
|
+
return this.getAttribute('description');
|
|
353
728
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
return `${quote}${replacedContent}${quote}`;
|
|
359
|
-
}), resolveAssets = async (unzipped, assets)=>{
|
|
360
|
-
if (!Array.isArray(assets)) {
|
|
361
|
-
return;
|
|
729
|
+
/**
|
|
730
|
+
* Direction of animation.
|
|
731
|
+
*/ set direction(value) {
|
|
732
|
+
this.setAttribute('direction', value.toString());
|
|
362
733
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
if (
|
|
366
|
-
|
|
367
|
-
}
|
|
368
|
-
const type = isImage(asset) ? 'images' : 'audio', u8 = unzipped?.[`${type}/${asset.p}`];
|
|
369
|
-
if (!u8) {
|
|
370
|
-
continue;
|
|
734
|
+
get direction() {
|
|
735
|
+
const val = Number(this.getAttribute('direction'));
|
|
736
|
+
if (val === -1) {
|
|
737
|
+
return val;
|
|
371
738
|
}
|
|
372
|
-
|
|
373
|
-
const assetB64 = isServer() ? Buffer.from(u8).toString('base64') : btoa(u8.reduce((dat, byte)=>`${dat}${String.fromCharCode(byte)}`, ''));
|
|
374
|
-
asset.p = asset.p?.startsWith('data:') || isBase64(asset.p) ? asset.p : `data:${getMimeFromExt(getExt(asset.p))};base64,${assetB64}`;
|
|
375
|
-
asset.e = 1;
|
|
376
|
-
asset.u = '';
|
|
377
|
-
resolveAsset();
|
|
378
|
-
}));
|
|
739
|
+
return 1;
|
|
379
740
|
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (err) {
|
|
385
|
-
reject(err);
|
|
386
|
-
}
|
|
387
|
-
resolve(file);
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
return unzipped;
|
|
391
|
-
}, useId = (prefix)=>{
|
|
392
|
-
const s4 = ()=>((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1);
|
|
393
|
-
return `${prefix ?? `:${s4()}`}_${s4()}`;
|
|
394
|
-
};
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Render Player
|
|
398
|
-
*/ function renderPlayer() {
|
|
399
|
-
this.template.innerHTML = /* HTML */ `<div class="animation-container main" data-controls="${this.controls ?? false}" lang="${this.description ? document?.documentElement?.lang : 'en'}" aria-label="${this.description ?? 'Lottie animation'}" data-loaded="${this._playerState.loaded}"><figure class="animation" style="background:${this.background}">${this.playerState === PlayerState.Error ? /* HTML */ `<div class="error"><svg preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1920" height="1080" viewBox="0 0 1920 1080"><path fill="#fff" d="M0 0h1920v1080H0z"/><path fill="#3a6d8b" d="M1190.2 531 1007 212.4c-22-38.2-77.2-38-98.8.5L729.5 531.3c-21.3 37.9 6.1 84.6 49.5 84.6l361.9.3c43.7 0 71.1-47.3 49.3-85.2zM937.3 288.7c.2-7.5 3.3-23.9 23.2-23.9 16.3 0 23 16.1 23 23.5 0 55.3-10.7 197.2-12.2 214.5-.1 1-.9 1.7-1.9 1.7h-18.3c-1 0-1.8-.7-1.9-1.7-1.4-17.5-13.4-162.9-11.9-214.1zm24.2 283.8c-13.1 0-23.7-10.6-23.7-23.7s10.6-23.7 23.7-23.7 23.7 10.6 23.7 23.7-10.6 23.7-23.7 23.7zM722.1 644h112.6v34.4h-70.4V698h58.8v31.7h-58.8v22.6h72.4v36.2H722.1V644zm162 57.1h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6zm78.9 0h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5H963v15.6zm39.5 36.2c0-31.3 22.2-54.8 56.6-54.8 34.4 0 56.2 23.5 56.2 54.8s-21.8 54.6-56.2 54.6c-34.4-.1-56.6-23.3-56.6-54.6zm74 0c0-17.4-6.1-29.1-17.8-29.1-11.7 0-17.4 11.7-17.4 29.1 0 17.4 5.7 29.1 17.4 29.1s17.8-11.8 17.8-29.1zm83.1-36.2h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6z"/><path fill="none" d="M718.9 807.7h645v285.4h-645z"/><text fill="#3a6d8b" style="text-align:center;position:absolute;left:100%;font-size:47px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'.SFNSText-Regular',sans-serif" x="50%" y="848.017" text-anchor="middle">${this._errorMessage}</text></svg></div>` : ''}</figure><slot name="controls"></slot></div>`;
|
|
400
|
-
this.shadow.adoptedStyleSheets = [
|
|
401
|
-
DotLottiePlayer.styles
|
|
402
|
-
];
|
|
403
|
-
this.shadow.appendChild(this.template.content.cloneNode(true));
|
|
404
|
-
}
|
|
405
|
-
|
|
406
|
-
/**
|
|
407
|
-
* Render Controls
|
|
408
|
-
*/ function renderControls() {
|
|
409
|
-
const slot = this.shadow.querySelector('slot[name=controls]');
|
|
410
|
-
if (!slot) {
|
|
411
|
-
return;
|
|
741
|
+
/**
|
|
742
|
+
* Whether to play on mouseover.
|
|
743
|
+
*/ set hover(value) {
|
|
744
|
+
this.setAttribute('hover', value.toString());
|
|
412
745
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
return;
|
|
746
|
+
get hover() {
|
|
747
|
+
const val = this.getAttribute('hover');
|
|
748
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
416
749
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
750
|
+
/**
|
|
751
|
+
* Pause between loop intrations, in miliseconds.
|
|
752
|
+
*/ set intermission(value) {
|
|
753
|
+
this.setAttribute('intermission', value.toString());
|
|
421
754
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
755
|
+
get intermission() {
|
|
756
|
+
const val = Number(this.getAttribute('intermission'));
|
|
757
|
+
if (!isNaN(val)) {
|
|
758
|
+
return val;
|
|
759
|
+
}
|
|
760
|
+
return 0;
|
|
425
761
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
762
|
+
/**
|
|
763
|
+
* Loop animation.
|
|
764
|
+
*/ set loop(value) {
|
|
765
|
+
this.setAttribute('loop', Boolean(value).toString());
|
|
429
766
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
767
|
+
get loop() {
|
|
768
|
+
const val = this.getAttribute('loop');
|
|
769
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
433
770
|
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
771
|
+
/**
|
|
772
|
+
* Play mode.
|
|
773
|
+
*/ set mode(value) {
|
|
774
|
+
this.setAttribute('mode', value.toString());
|
|
438
775
|
}
|
|
439
|
-
|
|
440
|
-
const
|
|
441
|
-
if (
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
|
|
445
|
-
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
446
|
-
toggleBoomerang.onclick = this.toggleBoomerang;
|
|
447
|
-
}
|
|
448
|
-
const convert = this.shadow.querySelector('.convert');
|
|
449
|
-
if (convert instanceof HTMLButtonElement) {
|
|
450
|
-
convert.onclick = this.convert;
|
|
451
|
-
}
|
|
452
|
-
const snapshot = this.shadow.querySelector('.snapshot');
|
|
453
|
-
if (snapshot instanceof HTMLButtonElement) {
|
|
454
|
-
snapshot.onclick = ()=>this.snapshot(true);
|
|
776
|
+
get mode() {
|
|
777
|
+
const val = this.getAttribute('mode');
|
|
778
|
+
if (val === PlayMode.Bounce) {
|
|
779
|
+
return val;
|
|
455
780
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
781
|
+
return PlayMode.Normal;
|
|
782
|
+
}
|
|
783
|
+
/**
|
|
784
|
+
* Resizing to container.
|
|
785
|
+
*/ set objectfit(value) {
|
|
786
|
+
this.setAttribute('objectfit', value);
|
|
787
|
+
}
|
|
788
|
+
get objectfit() {
|
|
789
|
+
const val = this.getAttribute('objectfit');
|
|
790
|
+
if (val && Object.values(ObjectFit).includes(val)) {
|
|
791
|
+
return val;
|
|
460
792
|
}
|
|
793
|
+
return ObjectFit.Contain;
|
|
461
794
|
}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
if (
|
|
470
|
-
|
|
471
|
-
// @ts-ignore
|
|
472
|
-
global.HTMLElement = class EmptyHTMLElement {
|
|
473
|
-
};
|
|
474
|
-
}
|
|
475
|
-
/**
|
|
476
|
-
* HTMLElement enhanced to track property changes
|
|
477
|
-
*/ class EnhancedElement extends HTMLElement {
|
|
478
|
-
constructor(){
|
|
479
|
-
super();
|
|
480
|
-
// @ts-ignore
|
|
481
|
-
const { observedProperties = [] } = this.constructor;
|
|
482
|
-
if (UPDATE_ON_CONNECTED in this) {
|
|
483
|
-
this[UPDATE_ON_CONNECTED] = [];
|
|
484
|
-
}
|
|
485
|
-
if ('propertyChangedCallback' in this && typeof this.propertyChangedCallback === 'function') {
|
|
486
|
-
for (const propName of observedProperties){
|
|
487
|
-
const initialValue = this[propName], CACHED_VALUE = Symbol(propName);
|
|
488
|
-
// @ts-ignore
|
|
489
|
-
this[CACHED_VALUE] = initialValue;
|
|
490
|
-
Object.defineProperty(this, propName, {
|
|
491
|
-
get () {
|
|
492
|
-
return this[CACHED_VALUE];
|
|
493
|
-
},
|
|
494
|
-
set (value) {
|
|
495
|
-
const oldValue = this[CACHED_VALUE];
|
|
496
|
-
this[CACHED_VALUE] = value;
|
|
497
|
-
this.propertyChangedCallback(propName, oldValue, value);
|
|
498
|
-
}
|
|
499
|
-
});
|
|
500
|
-
if (typeof initialValue !== 'undefined') {
|
|
501
|
-
if (UPDATE_ON_CONNECTED in this && Array.isArray(this[UPDATE_ON_CONNECTED])) {
|
|
502
|
-
this[UPDATE_ON_CONNECTED].push(propName);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
}
|
|
795
|
+
/**
|
|
796
|
+
* Resizing to container (Deprecated).
|
|
797
|
+
*/ set preserveAspectRatio(value) {
|
|
798
|
+
this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
|
|
799
|
+
}
|
|
800
|
+
get preserveAspectRatio() {
|
|
801
|
+
const val = this.getAttribute('preserveAspectRatio');
|
|
802
|
+
if (val && Object.values(PreserveAspectRatio).includes(val)) {
|
|
803
|
+
return val;
|
|
506
804
|
}
|
|
805
|
+
return null;
|
|
507
806
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
807
|
+
/**
|
|
808
|
+
* Renderer to use: svg, canvas or html.
|
|
809
|
+
*/ set renderer(value) {
|
|
810
|
+
this.setAttribute('renderer', value);
|
|
811
|
+
}
|
|
812
|
+
get renderer() {
|
|
813
|
+
const val = this.getAttribute('renderer');
|
|
814
|
+
if (val === RendererType.Canvas || val === RendererType.HTML) {
|
|
815
|
+
return val;
|
|
512
816
|
}
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
817
|
+
return RendererType.SVG;
|
|
818
|
+
}
|
|
819
|
+
/**
|
|
820
|
+
* Hide advanced controls.
|
|
821
|
+
*/ set simple(value) {
|
|
822
|
+
this.setAttribute('simple', value.toString());
|
|
823
|
+
}
|
|
824
|
+
get simple() {
|
|
825
|
+
const val = this.getAttribute('simple');
|
|
826
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Speed.
|
|
830
|
+
*/ set speed(value) {
|
|
831
|
+
this.setAttribute('speed', value.toString());
|
|
832
|
+
}
|
|
833
|
+
get speed() {
|
|
834
|
+
const val = this.getAttribute('speed');
|
|
835
|
+
if (val !== null && !isNaN(Number(val))) {
|
|
836
|
+
return Number(val);
|
|
520
837
|
}
|
|
838
|
+
return 1;
|
|
839
|
+
}
|
|
840
|
+
/**
|
|
841
|
+
* Source, either path or JSON string.
|
|
842
|
+
*/ set src(value) {
|
|
843
|
+
this.setAttribute('src', value || '');
|
|
844
|
+
}
|
|
845
|
+
get src() {
|
|
846
|
+
return this.getAttribute('src');
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Subframe.
|
|
850
|
+
*/ set subframe(value) {
|
|
851
|
+
this.setAttribute('subframe', Boolean(value).toString());
|
|
852
|
+
}
|
|
853
|
+
get subframe() {
|
|
854
|
+
const val = this.getAttribute('subframe');
|
|
855
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
521
856
|
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
var name="@aarsteinmedia/dotlottie-player";var version="5.0.0";var description="Web Component for playing Lottie animations in your web app. Previously @johanaarstein/dotlottie-player";var exports={".":{"import":"./dist/index.js",node:"./dist/index.js",types:"./dist/index.d.ts"}};var main="./dist/index.js";var unpkg="./dist/unpkg/index.js";var module="./dist/index.js";var types="./dist/index.d.ts";var type="module";var homepage="https://www.aarstein.media/en/dotlottie-player";var repository={url:"git+https://github.com/aarsteinmedia/dotlottie-player.git",type:"git"};var bugs="https://github.com/aarsteinmedia/dotlottie-player/issues";var author={name:"Johan Martin Aarstein",email:"johan@aarstein.media",url:"https://www.aarstein.media",organization:"Aarstein Media"};var contributors=[{name:"Anthony Colpron",email:"anthonycolpron@gmail.com",url:"https://github.com/anthony-colpron"}];var license="GPL-2.0-or-later";var scripts={test:"wtr",prebuild:"rimraf ./dist",build:"rollup -c","prebuild:types":"rimraf ./types","build:types":"tsc -p ./tsconfig.prod.json && tsc-alias","build:cem":"npx cem analyze --config cem.config.js",prod:"pnpm build:types && pnpm build && pnpm build:cem",dev:"rollup -c -w --environment NODE_ENV:development","lint:js":"eslint","lint:js:fix":"eslint --fix","lint:css":"npx stylelint **/*.css","lint:css:fix":"npx stylelint **/*.css --fix","lint:pkg":"npmPkgJsonLint .","lint:pkg:fix":"npmPkgJsonLint . --fix"};var dependencies={fflate:"^0.8.2","lottie-web":"^5.12.2"};var peerDependencies={"@types/react":">= 16.0.0"};var devDependencies={"@custom-elements-manifest/analyzer":"^0.10.4","@eslint/compat":"^1.2.7","@eslint/js":"^9.21.0","@esm-bundle/chai":"4.3.4-fix.0","@open-wc/testing":"^4.0.0","@rollup/plugin-commonjs":"^28.0.2","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.0","@rollup/plugin-typescript":"^12.1.2","@swc/core":"^1.11.1","@types/mocha":"^10.0.10","@types/node":"^22.13.5","@types/path-browserify":"^1.0.3","@types/react":"^19.0.10","@web/dev-server-esbuild":"^1.0.4","@web/dev-server-import-maps":"^0.2.1","@web/dev-server-rollup":"^0.6.4","@web/test-runner":"^0.20.0","@web/test-runner-playwright":"^0.11.0",autoprefixer:"^10.4.20",esbuild:"^0.25.0",eslint:"^9.21.0","eslint-config-prettier":"^10.0.1","eslint-import-resolver-typescript":"^3.8.3","eslint-plugin-import":"^2.31.0","eslint-plugin-jsdoc":"^50.6.3","eslint-plugin-perfectionist":"^4.9.0","eslint-plugin-prettier":"^5.2.3",globals:"^16.0.0","npm-package-json-lint":"^8.0.0","npm-package-json-lint-config-default":"^7.0.1","postcss-flexbugs-fixes":"^5.0.2",prettier:"^3.5.2",react:"^19.0.0",rimraf:"^6.0.1",rollup:"^4.34.8","rollup-plugin-dts":"^6.1.1","rollup-plugin-html-literals":"^1.1.8","rollup-plugin-livereload":"^2.0.5","rollup-plugin-postcss":"^4.0.2","rollup-plugin-serve":"^3.0.0","rollup-plugin-summary":"^3.0.0","rollup-plugin-swc3":"^0.12.1","rollup-plugin-typescript-paths":"^1.5.0",stylelint:"^16.14.1","stylelint-config-recommended":"^15.0.0","tsc-alias":"^1.8.10",tslib:"^2.8.1",typescript:"^5.7.3","typescript-eslint":"^8.25.0"};var pnpm={onlyBuiltDependencies:["@parcel/watcher","@swc/core","esbuild"]};var browserslist={production:[">0.3%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]};var customElements$1="custom-elements.json";var files=["CHANGELOG.md","custom-elements.json","dist","README.md"];var keywords=["lottie","dotlottie","animation","web component","svg","vector","player"];var publishConfig={access:"public"};var engines={node:">= 12.17.0"};var funding={type:"paypal",url:"https://www.paypal.com/donate/?hosted_button_id=E7C7DMN8KSQ6A"};var pkg = {name:name,version:version,description:description,exports:exports,main:main,unpkg:unpkg,module:module,types:types,type:type,homepage:homepage,repository:repository,bugs:bugs,author:author,contributors:contributors,license:license,scripts:scripts,dependencies:dependencies,peerDependencies:peerDependencies,devDependencies:devDependencies,pnpm:pnpm,browserslist:browserslist,customElements:customElements$1,files:files,keywords:keywords,publishConfig:publishConfig,engines:engines,funding:funding};
|
|
525
|
-
|
|
526
|
-
var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-toolbar-height: 35px;\n --lottie-player-toolbar-background-color: #fff;\n --lottie-player-toolbar-icon-color: #000;\n --lottie-player-toolbar-icon-hover-color: #000;\n --lottie-player-toolbar-icon-active-color: #4285f4;\n --lottie-player-seeker-track-color: rgb(0 0 0 / 20%);\n --lottie-player-seeker-thumb-color: #4285f4;\n --lottie-player-seeker-display: block;\n\n width: 100%;\n height: 100%;\n\n &:not([hidden]) {\n display: block;\n }\n\n .main {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n margin: 0;\n padding: 0;\n }\n\n .animation {\n width: 100%;\n height: 100%;\n display: flex;\n margin: 0;\n padding: 0;\n }\n\n [data-controls='true'] .animation {\n height: calc(100% - 35px);\n }\n\n .animation-container {\n position: relative;\n }\n\n .popover {\n position: absolute;\n right: 5px;\n bottom: 40px;\n background-color: var(--lottie-player-toolbar-background-color);\n border-radius: 5px;\n padding: 10px 15px;\n border: solid 2px var(--lottie-player-toolbar-icon-color);\n animation: fade-in 0.2s ease-in-out;\n\n &::before {\n content: '';\n right: 10px;\n border: 7px solid transparent;\n margin-right: -7px;\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n top: 100%;\n border-top-color: var(--lottie-player-toolbar-icon-color);\n }\n }\n\n .error {\n display: flex;\n margin: auto;\n justify-content: center;\n height: 100%;\n align-items: center;\n\n & svg {\n width: 100%;\n height: auto;\n }\n }\n\n .toolbar {\n display: flex;\n place-items: center center;\n background: var(--lottie-player-toolbar-background-color);\n margin: 0;\n height: 35px;\n padding: 5px;\n border-radius: 5px;\n gap: 5px;\n\n &.has-error {\n pointer-events: none;\n opacity: 0.5;\n }\n\n & button {\n cursor: pointer;\n fill: var(--lottie-player-toolbar-icon-color);\n color: var(--lottie-player-toolbar-icon-color);\n background: none;\n border: 0;\n padding: 0;\n outline: 0;\n height: 100%;\n margin: 0;\n align-items: center;\n gap: 5px;\n opacity: 0.9;\n\n &:not([hidden]) {\n display: flex;\n }\n\n &:hover {\n opacity: 1;\n }\n\n &[data-active='true'] {\n opacity: 1;\n fill: var(--lottie-player-toolbar-icon-active-color);\n }\n\n &:disabled {\n opacity: 0.5;\n }\n\n &:focus {\n outline: 0;\n }\n\n & svg {\n pointer-events: none;\n\n & > * {\n fill: inherit;\n }\n }\n\n &.disabled svg {\n display: none;\n }\n }\n }\n\n .progress-container {\n position: relative;\n width: 100%;\n\n &.simple {\n margin-right: 12px;\n }\n }\n\n .seeker {\n appearance: none;\n outline: none;\n width: 100%;\n height: 20px;\n border-radius: 3px;\n border: 0;\n cursor: pointer;\n background-color: transparent;\n\n display: var(--lottie-player-seeker-display);\n color: var(--lottie-player-seeker-thumb-color);\n margin: 0;\n padding: 7.5px 0;\n position: relative;\n z-index: 1;\n\n &::-webkit-slider-runnable-track,\n &::-webkit-slider-thumb {\n appearance: none;\n outline: none;\n }\n\n &::-webkit-slider-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n border: 0;\n background-color: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -webkit-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-webkit-slider-thumb,\n &:focus::-webkit-slider-thumb {\n transform: scale(1);\n }\n\n &::-moz-range-progress {\n background-color: var(--lottie-player-seeker-thumb-color);\n height: 5px;\n border-radius: 3px;\n }\n\n &::-moz-range-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background-color: var(--lottie-player-seeker-thumb-color);\n border: 0;\n cursor: pointer;\n -moz-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-moz-range-thumb,\n &:focus::-moz-range-thumb {\n transform: scale(1);\n }\n\n &::-ms-track {\n width: 100%;\n height: 5px;\n cursor: pointer;\n background: transparent;\n border-color: transparent;\n color: transparent;\n }\n\n &::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n border-radius: 3px;\n }\n\n &::-ms-fill-lower {\n background-color: var(--lottie-player-seeker-thumb-color);\n border-radius: 3px;\n }\n\n &::-ms-thumb {\n border: 0;\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -ms-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n }\n\n &:hover::-ms-thumb {\n transform: scale(1);\n }\n\n &:focus {\n &::-ms-thumb {\n transform: scale(1);\n }\n\n &::-ms-fill-lower,\n &::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n }\n }\n }\n\n & progress {\n appearance: none;\n outline: none;\n position: absolute;\n width: 100%;\n height: 5px;\n border-radius: 3px;\n border: 0;\n top: 0;\n left: 0;\n margin: 7.5px 0;\n background-color: var(--lottie-player-seeker-track-color);\n pointer-events: none;\n\n &::-webkit-progress-inner-element {\n border-radius: 3px;\n overflow: hidden;\n }\n\n &::-webkit-slider-runnable-track {\n background-color: transparent;\n }\n\n &::-webkit-progress-value {\n background-color: var(--lottie-player-seeker-thumb-color);\n }\n }\n\n & *::-moz-progress-bar {\n background-color: var(--lottie-player-seeker-thumb-color);\n }\n}\n\n@keyframes fade-in {\n 0% {\n opacity: 0;\n }\n\n 100% {\n opacity: 1;\n }\n}\n\n@media (prefers-color-scheme: dark) {\n :host {\n --lottie-player-toolbar-background-color: #000;\n --lottie-player-toolbar-icon-color: #fff;\n --lottie-player-toolbar-icon-hover-color: #fff;\n --lottie-player-seeker-track-color: rgb(255 255 255 / 60%);\n }\n}\n";
|
|
527
|
-
|
|
528
|
-
/**
|
|
529
|
-
* dotLottie Player Web Component
|
|
530
|
-
* @export
|
|
531
|
-
* @class DotLottiePlayer
|
|
532
|
-
* @extends { EnhancedElement }
|
|
533
|
-
* @description Web Component for playing Lottie animations in your web app.
|
|
534
|
-
*/ class DotLottiePlayer extends EnhancedElement {
|
|
535
857
|
constructor(){
|
|
536
|
-
super(),
|
|
537
|
-
*
|
|
538
|
-
*/ this._multiAnimationSettings = [], /**
|
|
539
|
-
* Animation Container
|
|
540
|
-
*/ this._container = null, /**
|
|
541
|
-
* @state
|
|
542
|
-
* Player state
|
|
858
|
+
super(), /**
|
|
859
|
+
* Player state.
|
|
543
860
|
*/ this.playerState = PlayerState.Loading, /**
|
|
544
|
-
*
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
* Seeker
|
|
549
|
-
*/ this._seeker = 0, /**
|
|
550
|
-
* @state
|
|
551
|
-
* Which animation to show, if several
|
|
552
|
-
*/ this._currentAnimation = 0, this._lottieInstance = null, this._identifier = this.id || useId('dotlottie'), this._errorMessage = 'Something went wrong', this._isBounce = false, this._isDotLottie = false, this._playerState = {
|
|
861
|
+
* Animation Container.
|
|
862
|
+
*/ this._container = null, this._errorMessage = 'Something went wrong', this._identifier = this.id || createElementID(), /**
|
|
863
|
+
* Whether settings toolbar is open.
|
|
864
|
+
*/ this._isSettingsOpen = false, this._playerState = {
|
|
553
865
|
count: 0,
|
|
554
866
|
loaded: false,
|
|
555
867
|
prev: PlayerState.Loading,
|
|
556
868
|
scrollTimeout: null,
|
|
557
869
|
scrollY: 0,
|
|
558
870
|
visible: false
|
|
559
|
-
}, /**
|
|
560
|
-
*
|
|
871
|
+
}, this._render = renderPlayer, this._renderControls = renderControls, /**
|
|
872
|
+
* Seeker.
|
|
873
|
+
*/ this._seeker = 0, /**
|
|
874
|
+
* This is included in watched properties,
|
|
875
|
+
* so that next-button will show up
|
|
876
|
+
* on load, if controls are visible.
|
|
877
|
+
*/ this._animations = [], /**
|
|
878
|
+
* Which animation to show, if several.
|
|
879
|
+
*/ this._currentAnimation = 0, this._isBounce = false, this._isDotLottie = false, this._lottieInstance = null, /**
|
|
880
|
+
* Multi-animation settings.
|
|
881
|
+
*/ this._multiAnimationSettings = [], /**
|
|
882
|
+
* Handle settings click event.
|
|
561
883
|
*/ this._handleSettingsClick = ({ target })=>{
|
|
562
884
|
this._toggleSettings();
|
|
563
885
|
// Because Safari does not add focus on click, we need to add it manually, so the onblur event will fire
|
|
@@ -596,55 +918,58 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
596
918
|
});
|
|
597
919
|
}
|
|
598
920
|
/**
|
|
599
|
-
*
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
this.
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
921
|
+
* Creates a new dotLottie file, by combinig several animations.
|
|
922
|
+
* If set to false the function returns an ArrayBuffer. Defaults to true.
|
|
923
|
+
*/ async addAnimation(configs, fileName, shouldDownload = true) {
|
|
924
|
+
// Initialize meta object for animation, with fallbacks for
|
|
925
|
+
// when the method is called indepenently
|
|
926
|
+
const { animations = [], manifest = {
|
|
927
|
+
animations: this.src ? [
|
|
928
|
+
{
|
|
929
|
+
id: this._identifier
|
|
930
|
+
}
|
|
931
|
+
] : []
|
|
932
|
+
} } = this.src ? await getAnimationData(this.src) : {};
|
|
933
|
+
try {
|
|
934
|
+
if (!manifest) {
|
|
935
|
+
throw new Error('Manifest is not set');
|
|
936
|
+
}
|
|
937
|
+
manifest.generator = '@aarsteinmedia/dotlottie-player';
|
|
938
|
+
const { length } = configs;
|
|
939
|
+
for(let i = 0; i < length; i++){
|
|
940
|
+
const { url } = configs[i], { animations: animationsToAdd } = await getAnimationData(url);
|
|
941
|
+
if (!animationsToAdd) {
|
|
942
|
+
throw new Error('No animation loaded');
|
|
943
|
+
}
|
|
944
|
+
if (manifest.animations.some(({ id })=>id === configs[i].id)) {
|
|
945
|
+
throw new Error('Duplicate id for animation');
|
|
946
|
+
}
|
|
947
|
+
manifest.animations = [
|
|
948
|
+
...manifest.animations,
|
|
949
|
+
{
|
|
950
|
+
id: configs[i].id
|
|
951
|
+
}
|
|
952
|
+
];
|
|
953
|
+
animations.push(...animationsToAdd);
|
|
954
|
+
}
|
|
955
|
+
return {
|
|
956
|
+
result: await createDotLottie({
|
|
957
|
+
animations,
|
|
958
|
+
fileName,
|
|
959
|
+
manifest,
|
|
960
|
+
shouldDownload
|
|
961
|
+
}),
|
|
962
|
+
success: true
|
|
963
|
+
};
|
|
964
|
+
} catch (error) {
|
|
965
|
+
return {
|
|
966
|
+
error: handleErrors(error).message,
|
|
967
|
+
success: false
|
|
968
|
+
};
|
|
626
969
|
}
|
|
627
|
-
// Remove the attached Visibility API's change event listener
|
|
628
|
-
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Attributes to observe
|
|
632
|
-
*/ static get observedAttributes() {
|
|
633
|
-
return [
|
|
634
|
-
'animateOnScroll',
|
|
635
|
-
'autoplay',
|
|
636
|
-
'controls',
|
|
637
|
-
'direction',
|
|
638
|
-
'hover',
|
|
639
|
-
'loop',
|
|
640
|
-
'mode',
|
|
641
|
-
'speed',
|
|
642
|
-
'src',
|
|
643
|
-
'subframe'
|
|
644
|
-
];
|
|
645
970
|
}
|
|
646
971
|
/**
|
|
647
|
-
* Runs when the value of an attribute is changed on the component
|
|
972
|
+
* Runs when the value of an attribute is changed on the component.
|
|
648
973
|
*/ async attributeChangedCallback(name, _oldValue, value) {
|
|
649
974
|
if (!this._lottieInstance) {
|
|
650
975
|
return;
|
|
@@ -675,7 +1000,8 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
675
1000
|
}
|
|
676
1001
|
if (name === 'direction') {
|
|
677
1002
|
if (Number(value) === -1) {
|
|
678
|
-
|
|
1003
|
+
this.setDirection(-1);
|
|
1004
|
+
return;
|
|
679
1005
|
}
|
|
680
1006
|
this.setDirection(1);
|
|
681
1007
|
}
|
|
@@ -689,14 +1015,14 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
689
1015
|
this._container.removeEventListener('mouseleave', this._mouseLeave);
|
|
690
1016
|
}
|
|
691
1017
|
if (name === 'loop') {
|
|
692
|
-
const toggleLoop = this.shadow
|
|
1018
|
+
const toggleLoop = this.shadow?.querySelector('.toggleLoop');
|
|
693
1019
|
if (toggleLoop instanceof HTMLButtonElement) {
|
|
694
1020
|
toggleLoop.dataset.active = value;
|
|
695
1021
|
}
|
|
696
1022
|
this.setLoop(value === '' || Boolean(value));
|
|
697
1023
|
}
|
|
698
1024
|
if (name === 'mode') {
|
|
699
|
-
const toggleBoomerang = this.shadow
|
|
1025
|
+
const toggleBoomerang = this.shadow?.querySelector('.toggleBoomerang');
|
|
700
1026
|
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
701
1027
|
toggleBoomerang.dataset.active = (value === PlayMode.Bounce).toString();
|
|
702
1028
|
}
|
|
@@ -715,395 +1041,112 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
715
1041
|
this.setSubframe(value === '' || Boolean(value));
|
|
716
1042
|
}
|
|
717
1043
|
}
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
'_currentAnimation',
|
|
724
|
-
'_animations'
|
|
725
|
-
];
|
|
726
|
-
}
|
|
727
|
-
// name: string, oldValue: string, newValue: string
|
|
728
|
-
propertyChangedCallback(name, _oldValue, value) {
|
|
1044
|
+
/**
|
|
1045
|
+
* Initialize everything on component first render.
|
|
1046
|
+
*/ async connectedCallback() {
|
|
1047
|
+
await super.connectedCallback();
|
|
1048
|
+
await this._render();
|
|
729
1049
|
if (!this.shadow) {
|
|
730
|
-
|
|
731
|
-
}
|
|
732
|
-
const togglePlay = this.shadow.querySelector('.togglePlay'), stop = this.shadow.querySelector('.stop'), prev = this.shadow.querySelector('.prev'), next = this.shadow.querySelector('.next'), seeker = this.shadow.querySelector('.seeker'), progress = this.shadow.querySelector('progress'), popover = this.shadow.querySelector('.popover'), convert = this.shadow.querySelector('.convert');
|
|
733
|
-
if (!(togglePlay instanceof HTMLButtonElement) || !(stop instanceof HTMLButtonElement) || !(next instanceof HTMLButtonElement) || !(prev instanceof HTMLButtonElement) || !(seeker instanceof HTMLInputElement) || !(progress instanceof HTMLProgressElement)) {
|
|
734
|
-
return;
|
|
735
|
-
}
|
|
736
|
-
if (name === 'playerState') {
|
|
737
|
-
togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
|
|
738
|
-
stop.dataset.active = (value === PlayerState.Stopped).toString();
|
|
739
|
-
if (value === PlayerState.Playing) {
|
|
740
|
-
togglePlay.innerHTML = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M14.016 5.016H18v13.969h-3.984V5.016zM6 18.984V5.015h3.984v13.969H6z"/></svg>`;
|
|
741
|
-
} else {
|
|
742
|
-
togglePlay.innerHTML = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg>`;
|
|
743
|
-
}
|
|
1050
|
+
throw new Error('Missing Shadow element');
|
|
744
1051
|
}
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
1052
|
+
this._container = this.shadow.querySelector('.animation');
|
|
1053
|
+
this._renderControls();
|
|
1054
|
+
// Add listener for Visibility API's change event.
|
|
1055
|
+
if (typeof document.hidden !== 'undefined') {
|
|
1056
|
+
document.addEventListener('visibilitychange', this._onVisibilityChange);
|
|
749
1057
|
}
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
1058
|
+
// Add intersection observer for detecting component being out-of-view.
|
|
1059
|
+
this._addIntersectionObserver();
|
|
1060
|
+
// Setup lottie player
|
|
1061
|
+
await this.load(this.src);
|
|
1062
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Rendered));
|
|
1063
|
+
}
|
|
1064
|
+
async convert({ animations: animationsFromProps, fileName, manifest, shouldDownload = true, src: srcFromProps, typeCheck }) {
|
|
1065
|
+
const src = srcFromProps || this.src || this.source;
|
|
1066
|
+
if (!src) {
|
|
1067
|
+
throw new Error('No animation to convert');
|
|
754
1068
|
}
|
|
755
|
-
if (
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
} else {
|
|
764
|
-
prev.hidden = true;
|
|
765
|
-
}
|
|
1069
|
+
if (typeCheck || this._isDotLottie) {
|
|
1070
|
+
const animationData = await getAnimationData(src);
|
|
1071
|
+
createJSON({
|
|
1072
|
+
animation: animationData.animations?.[0],
|
|
1073
|
+
fileName: `${getFilename(fileName || src || 'converted')}.json`,
|
|
1074
|
+
shouldDownload
|
|
1075
|
+
});
|
|
1076
|
+
return;
|
|
766
1077
|
}
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
1078
|
+
let animations = animationsFromProps;
|
|
1079
|
+
if (!animations) {
|
|
1080
|
+
const animationData = await getAnimationData(src);
|
|
1081
|
+
animations = animationData.animations;
|
|
770
1082
|
}
|
|
1083
|
+
return createDotLottie({
|
|
1084
|
+
animations,
|
|
1085
|
+
fileName: `${getFilename(fileName || src || 'converted')}.lottie`,
|
|
1086
|
+
manifest: {
|
|
1087
|
+
...manifest ?? this._manifest,
|
|
1088
|
+
generator: '[[GENERATOR]]'
|
|
1089
|
+
},
|
|
1090
|
+
shouldDownload
|
|
1091
|
+
});
|
|
771
1092
|
}
|
|
772
1093
|
/**
|
|
773
|
-
*
|
|
774
|
-
*/
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
get animateOnScroll() {
|
|
778
|
-
const val = this.getAttribute('animateOnScroll');
|
|
779
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
780
|
-
return true;
|
|
1094
|
+
* Destroy animation and element.
|
|
1095
|
+
*/ destroy() {
|
|
1096
|
+
if (!this._lottieInstance) {
|
|
1097
|
+
return;
|
|
781
1098
|
}
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
}
|
|
789
|
-
get autoplay() {
|
|
790
|
-
const val = this.getAttribute('autoplay');
|
|
791
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
792
|
-
return true;
|
|
793
|
-
}
|
|
794
|
-
return false;
|
|
795
|
-
}
|
|
796
|
-
/**
|
|
797
|
-
* Background color
|
|
798
|
-
*/ set background(value) {
|
|
799
|
-
this.setAttribute('background', value);
|
|
800
|
-
}
|
|
801
|
-
get background() {
|
|
802
|
-
return this.getAttribute('background') || 'transparent';
|
|
803
|
-
}
|
|
804
|
-
/**
|
|
805
|
-
* Show controls
|
|
806
|
-
*/ set controls(value) {
|
|
807
|
-
this.setAttribute('controls', (!!value).toString());
|
|
808
|
-
}
|
|
809
|
-
get controls() {
|
|
810
|
-
const val = this.getAttribute('controls');
|
|
811
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
812
|
-
return true;
|
|
813
|
-
}
|
|
814
|
-
return false;
|
|
815
|
-
}
|
|
816
|
-
/**
|
|
817
|
-
* Number of times to loop
|
|
818
|
-
*/ set count(value) {
|
|
819
|
-
this.setAttribute('count', value.toString());
|
|
820
|
-
}
|
|
821
|
-
get count() {
|
|
822
|
-
const val = this.getAttribute('count');
|
|
823
|
-
if (val) {
|
|
824
|
-
return Number(val);
|
|
825
|
-
}
|
|
826
|
-
return 0;
|
|
827
|
-
}
|
|
828
|
-
/**
|
|
829
|
-
* Description for screen readers
|
|
830
|
-
*/ set description(value) {
|
|
831
|
-
if (value) {
|
|
832
|
-
this.setAttribute('description', value);
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
get description() {
|
|
836
|
-
return this.getAttribute('description');
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* Direction of animation
|
|
840
|
-
*/ set direction(value) {
|
|
841
|
-
this.setAttribute('direction', value.toString());
|
|
842
|
-
}
|
|
843
|
-
get direction() {
|
|
844
|
-
const val = Number(this.getAttribute('direction'));
|
|
845
|
-
if (val === -1) {
|
|
846
|
-
return val;
|
|
847
|
-
}
|
|
848
|
-
return 1;
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Whether to play on mouseover
|
|
852
|
-
*/ set hover(value) {
|
|
853
|
-
this.setAttribute('hover', value.toString());
|
|
854
|
-
}
|
|
855
|
-
get hover() {
|
|
856
|
-
const val = this.getAttribute('hover');
|
|
857
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
858
|
-
return true;
|
|
859
|
-
}
|
|
860
|
-
return false;
|
|
861
|
-
}
|
|
862
|
-
/**
|
|
863
|
-
* Pause between loop intrations, in miliseconds
|
|
864
|
-
*/ set intermission(value) {
|
|
865
|
-
this.setAttribute('intermission', value.toString());
|
|
866
|
-
}
|
|
867
|
-
get intermission() {
|
|
868
|
-
const val = Number(this.getAttribute('intermission'));
|
|
869
|
-
if (!isNaN(val)) {
|
|
870
|
-
return val;
|
|
871
|
-
}
|
|
872
|
-
return 0;
|
|
873
|
-
}
|
|
874
|
-
/**
|
|
875
|
-
* Loop animation
|
|
876
|
-
*/ set loop(value) {
|
|
877
|
-
this.setAttribute('loop', (!!value).toString());
|
|
878
|
-
}
|
|
879
|
-
get loop() {
|
|
880
|
-
const val = this.getAttribute('loop');
|
|
881
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
882
|
-
return true;
|
|
883
|
-
}
|
|
884
|
-
return false;
|
|
885
|
-
}
|
|
886
|
-
/**
|
|
887
|
-
* Play mode
|
|
888
|
-
*/ set mode(value) {
|
|
889
|
-
this.setAttribute('mode', value.toString());
|
|
890
|
-
}
|
|
891
|
-
get mode() {
|
|
892
|
-
const val = this.getAttribute('mode');
|
|
893
|
-
if (val === PlayMode.Bounce) {
|
|
894
|
-
return val;
|
|
895
|
-
}
|
|
896
|
-
return PlayMode.Normal;
|
|
897
|
-
}
|
|
898
|
-
/**
|
|
899
|
-
* Resizing to container
|
|
900
|
-
*/ set objectfit(value) {
|
|
901
|
-
this.setAttribute('objectfit', value);
|
|
902
|
-
}
|
|
903
|
-
get objectfit() {
|
|
904
|
-
const val = this.getAttribute('objectfit');
|
|
905
|
-
if (val && Object.values(ObjectFit).includes(val)) {
|
|
906
|
-
return val;
|
|
907
|
-
}
|
|
908
|
-
return ObjectFit.Contain;
|
|
909
|
-
}
|
|
910
|
-
/**
|
|
911
|
-
* Resizing to container (Deprecated)
|
|
912
|
-
*/ set preserveAspectRatio(value) {
|
|
913
|
-
this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
|
|
914
|
-
}
|
|
915
|
-
get preserveAspectRatio() {
|
|
916
|
-
const val = this.getAttribute('preserveAspectRatio');
|
|
917
|
-
if (val && Object.values(PreserveAspectRatio).includes(val)) {
|
|
918
|
-
return val;
|
|
919
|
-
}
|
|
920
|
-
return null;
|
|
921
|
-
}
|
|
922
|
-
/**
|
|
923
|
-
* Renderer to use: svg, canvas or html
|
|
924
|
-
*/ set renderer(value) {
|
|
925
|
-
this.setAttribute('renderer', value);
|
|
926
|
-
}
|
|
927
|
-
get renderer() {
|
|
928
|
-
const val = this.getAttribute('renderer');
|
|
929
|
-
if (val === 'canvas' || val === 'html') {
|
|
930
|
-
return val;
|
|
931
|
-
}
|
|
932
|
-
return 'svg';
|
|
1099
|
+
this.playerState = PlayerState.Destroyed;
|
|
1100
|
+
this._lottieInstance.destroy();
|
|
1101
|
+
this._lottieInstance = null;
|
|
1102
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Destroyed));
|
|
1103
|
+
this.remove();
|
|
1104
|
+
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
933
1105
|
}
|
|
934
1106
|
/**
|
|
935
|
-
*
|
|
936
|
-
*/
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
942
|
-
return true;
|
|
1107
|
+
* Cleanup on component destroy.
|
|
1108
|
+
*/ disconnectedCallback() {
|
|
1109
|
+
// Remove intersection observer for detecting component being out-of-view
|
|
1110
|
+
if (this._intersectionObserver) {
|
|
1111
|
+
this._intersectionObserver.disconnect();
|
|
1112
|
+
this._intersectionObserver = undefined;
|
|
943
1113
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
* Speed
|
|
948
|
-
*/ set speed(value) {
|
|
949
|
-
this.setAttribute('speed', value?.toString());
|
|
950
|
-
}
|
|
951
|
-
get speed() {
|
|
952
|
-
const val = this.getAttribute('speed');
|
|
953
|
-
if (val !== null && !isNaN(Number(val))) {
|
|
954
|
-
return Number(val);
|
|
1114
|
+
// Destroy the animation instance
|
|
1115
|
+
if (this._lottieInstance) {
|
|
1116
|
+
this._lottieInstance.destroy();
|
|
955
1117
|
}
|
|
956
|
-
|
|
1118
|
+
// Remove the attached Visibility API's change event listener
|
|
1119
|
+
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
957
1120
|
}
|
|
958
1121
|
/**
|
|
959
|
-
*
|
|
960
|
-
*/
|
|
961
|
-
this.
|
|
962
|
-
}
|
|
963
|
-
get src() {
|
|
964
|
-
return this.getAttribute('src');
|
|
1122
|
+
* Returns the lottie-web instance used in the component.
|
|
1123
|
+
*/ getLottie() {
|
|
1124
|
+
return this._lottieInstance;
|
|
965
1125
|
}
|
|
966
1126
|
/**
|
|
967
|
-
*
|
|
968
|
-
*/
|
|
969
|
-
this.
|
|
970
|
-
}
|
|
971
|
-
get subframe() {
|
|
972
|
-
const val = this.getAttribute('subframe');
|
|
973
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
974
|
-
return true;
|
|
975
|
-
}
|
|
976
|
-
return false;
|
|
1127
|
+
* Get Lottie Manifest.
|
|
1128
|
+
*/ getManifest() {
|
|
1129
|
+
return this._manifest;
|
|
977
1130
|
}
|
|
978
1131
|
/**
|
|
979
|
-
* Get Multi-animation settings
|
|
980
|
-
*
|
|
1132
|
+
* Get Multi-animation settings.
|
|
1133
|
+
*
|
|
981
1134
|
*/ getMultiAnimationSettings() {
|
|
982
1135
|
return this._multiAnimationSettings;
|
|
983
1136
|
}
|
|
984
1137
|
/**
|
|
985
|
-
*
|
|
986
|
-
*
|
|
987
|
-
*/ setMultiAnimationSettings(settings) {
|
|
988
|
-
this._multiAnimationSettings = settings;
|
|
989
|
-
}
|
|
990
|
-
/**
|
|
991
|
-
* Set playback segment
|
|
992
|
-
* @param { AnimationSegment } settings
|
|
993
|
-
*/ setSegment(segment) {
|
|
994
|
-
this._segment = segment;
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Get playback segment
|
|
998
|
-
* @returns { AnimationSegment }
|
|
1138
|
+
* Get playback segment.
|
|
1139
|
+
*
|
|
999
1140
|
*/ getSegment() {
|
|
1000
1141
|
return this._segment;
|
|
1001
1142
|
}
|
|
1002
1143
|
/**
|
|
1003
|
-
*
|
|
1004
|
-
* @returns { AnimationConfig }
|
|
1005
|
-
*/ _getOptions() {
|
|
1006
|
-
if (!this._container) {
|
|
1007
|
-
throw new Error('Container not rendered');
|
|
1008
|
-
}
|
|
1009
|
-
const preserveAspectRatio = this.preserveAspectRatio ?? (this.objectfit && aspectRatio(this.objectfit)), currentAnimationSettings = this._multiAnimationSettings?.length ? this._multiAnimationSettings?.[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest.animations?.[this._currentAnimation];
|
|
1010
|
-
// Loop
|
|
1011
|
-
let loop = !!this.loop;
|
|
1012
|
-
if (currentAnimationManifest.loop !== undefined && this.loop === undefined) {
|
|
1013
|
-
loop = !!currentAnimationManifest.loop;
|
|
1014
|
-
}
|
|
1015
|
-
if (currentAnimationSettings?.loop !== undefined) {
|
|
1016
|
-
loop = !!currentAnimationSettings.loop;
|
|
1017
|
-
}
|
|
1018
|
-
// Autoplay
|
|
1019
|
-
let autoplay = !!this.autoplay;
|
|
1020
|
-
if (currentAnimationManifest.autoplay !== undefined && this.autoplay === undefined) {
|
|
1021
|
-
autoplay = !!currentAnimationManifest.autoplay;
|
|
1022
|
-
}
|
|
1023
|
-
if (currentAnimationSettings?.autoplay !== undefined) {
|
|
1024
|
-
autoplay = !!currentAnimationSettings.autoplay;
|
|
1025
|
-
}
|
|
1026
|
-
if (this.animateOnScroll) {
|
|
1027
|
-
autoplay = false;
|
|
1028
|
-
}
|
|
1029
|
-
// Segment
|
|
1030
|
-
let initialSegment = this._segment;
|
|
1031
|
-
if (this._segment?.every((val)=>val > 0)) {
|
|
1032
|
-
initialSegment = [
|
|
1033
|
-
this._segment[0] - 1,
|
|
1034
|
-
this._segment[1] - 1
|
|
1035
|
-
];
|
|
1036
|
-
}
|
|
1037
|
-
if (this._segment?.some((val)=>val < 0)) {
|
|
1038
|
-
initialSegment = undefined;
|
|
1039
|
-
}
|
|
1040
|
-
const options = {
|
|
1041
|
-
autoplay,
|
|
1042
|
-
container: this._container,
|
|
1043
|
-
initialSegment,
|
|
1044
|
-
loop,
|
|
1045
|
-
renderer: this.renderer,
|
|
1046
|
-
rendererSettings: {
|
|
1047
|
-
imagePreserveAspectRatio: preserveAspectRatio
|
|
1048
|
-
}
|
|
1049
|
-
};
|
|
1050
|
-
switch(this.renderer){
|
|
1051
|
-
case 'svg':
|
|
1052
|
-
options.rendererSettings = {
|
|
1053
|
-
...options.rendererSettings,
|
|
1054
|
-
hideOnTransparent: true,
|
|
1055
|
-
preserveAspectRatio,
|
|
1056
|
-
progressiveLoad: true
|
|
1057
|
-
};
|
|
1058
|
-
break;
|
|
1059
|
-
case 'canvas':
|
|
1060
|
-
options.rendererSettings = {
|
|
1061
|
-
...options.rendererSettings,
|
|
1062
|
-
clearCanvas: true,
|
|
1063
|
-
preserveAspectRatio,
|
|
1064
|
-
progressiveLoad: true
|
|
1065
|
-
};
|
|
1066
|
-
break;
|
|
1067
|
-
case 'html':
|
|
1068
|
-
options.rendererSettings = {
|
|
1069
|
-
...options.rendererSettings,
|
|
1070
|
-
hideOnTransparent: true
|
|
1071
|
-
};
|
|
1072
|
-
}
|
|
1073
|
-
return options;
|
|
1074
|
-
}
|
|
1075
|
-
/**
|
|
1076
|
-
* Add IntersectionObserver
|
|
1077
|
-
*/ _addIntersectionObserver() {
|
|
1078
|
-
if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
|
|
1079
|
-
return;
|
|
1080
|
-
}
|
|
1081
|
-
this._intersectionObserver = new IntersectionObserver((entries)=>{
|
|
1082
|
-
for (const entry of entries){
|
|
1083
|
-
if (!entry.isIntersecting || document.hidden) {
|
|
1084
|
-
if (this.playerState === PlayerState.Playing) {
|
|
1085
|
-
this._freeze();
|
|
1086
|
-
}
|
|
1087
|
-
this._playerState.visible = false;
|
|
1088
|
-
continue;
|
|
1089
|
-
}
|
|
1090
|
-
if (!this.animateOnScroll && this.playerState === PlayerState.Frozen) {
|
|
1091
|
-
this.play();
|
|
1092
|
-
}
|
|
1093
|
-
if (!this._playerState.scrollY) {
|
|
1094
|
-
this._playerState.scrollY = scrollY;
|
|
1095
|
-
}
|
|
1096
|
-
this._playerState.visible = true;
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
this._intersectionObserver.observe(this._container);
|
|
1100
|
-
}
|
|
1101
|
-
/**
|
|
1102
|
-
* Initialize Lottie Web player
|
|
1144
|
+
* Initialize Lottie Web player.
|
|
1103
1145
|
*/ async load(src) {
|
|
1104
1146
|
if (!this.shadowRoot || !src) {
|
|
1105
1147
|
return;
|
|
1106
1148
|
}
|
|
1149
|
+
this.source = src;
|
|
1107
1150
|
// Load the resource
|
|
1108
1151
|
try {
|
|
1109
1152
|
const { animations, isDotLottie, manifest } = await getAnimationData(src);
|
|
@@ -1111,19 +1154,17 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1111
1154
|
throw new Error('Broken or corrupted file');
|
|
1112
1155
|
}
|
|
1113
1156
|
this._isBounce = this.mode === PlayMode.Bounce;
|
|
1114
|
-
if (this._multiAnimationSettings?.
|
|
1115
|
-
|
|
1116
|
-
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1117
|
-
}
|
|
1157
|
+
if (this._multiAnimationSettings.length > 0 && this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1158
|
+
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1118
1159
|
}
|
|
1119
|
-
this._isDotLottie =
|
|
1160
|
+
this._isDotLottie = Boolean(isDotLottie);
|
|
1120
1161
|
this._animations = animations;
|
|
1121
1162
|
this._manifest = manifest ?? {
|
|
1122
1163
|
animations: [
|
|
1123
1164
|
{
|
|
1124
1165
|
autoplay: !this.animateOnScroll && this.autoplay,
|
|
1125
1166
|
direction: this.direction,
|
|
1126
|
-
id:
|
|
1167
|
+
id: createElementID(),
|
|
1127
1168
|
loop: this.loop,
|
|
1128
1169
|
mode: this.mode,
|
|
1129
1170
|
speed: this.speed
|
|
@@ -1135,26 +1176,27 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1135
1176
|
this._lottieInstance.destroy();
|
|
1136
1177
|
}
|
|
1137
1178
|
this.playerState = PlayerState.Stopped;
|
|
1138
|
-
if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings
|
|
1179
|
+
if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings[this._currentAnimation]?.autoplay)) {
|
|
1139
1180
|
this.playerState = PlayerState.Playing;
|
|
1140
1181
|
}
|
|
1141
1182
|
// Initialize lottie player and load animation
|
|
1142
|
-
|
|
1183
|
+
// @ts-expect-error TODO:
|
|
1184
|
+
this._lottieInstance = Lottie.loadAnimation({
|
|
1143
1185
|
...this._getOptions(),
|
|
1144
1186
|
animationData: animations[this._currentAnimation]
|
|
1145
1187
|
});
|
|
1146
|
-
} catch (
|
|
1147
|
-
this._errorMessage = handleErrors(
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
this._errorMessage = handleErrors(error).message;
|
|
1148
1190
|
this.playerState = PlayerState.Error;
|
|
1149
1191
|
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1150
1192
|
return;
|
|
1151
1193
|
}
|
|
1152
1194
|
this._addEventListeners();
|
|
1153
|
-
const speed = this._multiAnimationSettings
|
|
1195
|
+
const speed = this._multiAnimationSettings[this._currentAnimation]?.speed ?? this.speed, direction = this._multiAnimationSettings[this._currentAnimation]?.direction ?? this.direction;
|
|
1154
1196
|
// Set initial playback speed and direction
|
|
1155
1197
|
this._lottieInstance.setSpeed(speed);
|
|
1156
1198
|
this._lottieInstance.setDirection(direction);
|
|
1157
|
-
this._lottieInstance.setSubframe(
|
|
1199
|
+
this._lottieInstance.setSubframe(Boolean(this.subframe));
|
|
1158
1200
|
// Start playing if autoplay is enabled
|
|
1159
1201
|
if (this.autoplay || this.animateOnScroll) {
|
|
1160
1202
|
if (this.direction === -1) {
|
|
@@ -1170,313 +1212,215 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1170
1212
|
}
|
|
1171
1213
|
}
|
|
1172
1214
|
/**
|
|
1173
|
-
*
|
|
1174
|
-
*/
|
|
1175
|
-
|
|
1215
|
+
* Skip to next animation.
|
|
1216
|
+
*/ next() {
|
|
1217
|
+
this._currentAnimation++;
|
|
1218
|
+
this._switchInstance();
|
|
1176
1219
|
}
|
|
1177
1220
|
/**
|
|
1178
|
-
*
|
|
1179
|
-
*/
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
this._lottieInstance[method]('enterFrame', this._enterFrame);
|
|
1183
|
-
this._lottieInstance[method]('complete', this._complete);
|
|
1184
|
-
this._lottieInstance[method]('loopComplete', this._loopComplete);
|
|
1185
|
-
this._lottieInstance[method]('DOMLoaded', this._DOMLoaded);
|
|
1186
|
-
this._lottieInstance[method]('data_ready', this._dataReady);
|
|
1187
|
-
this._lottieInstance[method]('data_failed', this._dataFailed);
|
|
1188
|
-
}
|
|
1189
|
-
if (this._container && this.hover) {
|
|
1190
|
-
this._container[method]('mouseenter', this._mouseEnter);
|
|
1191
|
-
this._container[method]('mouseleave', this._mouseLeave);
|
|
1221
|
+
* Pause.
|
|
1222
|
+
*/ pause() {
|
|
1223
|
+
if (!this._lottieInstance) {
|
|
1224
|
+
return;
|
|
1192
1225
|
}
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
passive: true
|
|
1200
|
-
});
|
|
1201
|
-
if (this.animateOnScroll) {
|
|
1202
|
-
window[method]('scroll', this._handleScroll, {
|
|
1203
|
-
capture: true,
|
|
1204
|
-
passive: true
|
|
1205
|
-
});
|
|
1226
|
+
this._playerState.prev = this.playerState;
|
|
1227
|
+
try {
|
|
1228
|
+
this._lottieInstance.pause();
|
|
1229
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Pause));
|
|
1230
|
+
} finally{
|
|
1231
|
+
this.playerState = PlayerState.Paused;
|
|
1206
1232
|
}
|
|
1207
1233
|
}
|
|
1208
1234
|
/**
|
|
1209
|
-
*
|
|
1210
|
-
*/
|
|
1211
|
-
this._toggleEventListeners('add');
|
|
1212
|
-
}
|
|
1213
|
-
/**
|
|
1214
|
-
* Remove event listeners
|
|
1215
|
-
*/ _removeEventListeners() {
|
|
1216
|
-
this._toggleEventListeners('remove');
|
|
1217
|
-
}
|
|
1218
|
-
_loopComplete() {
|
|
1235
|
+
* Play.
|
|
1236
|
+
*/ play() {
|
|
1219
1237
|
if (!this._lottieInstance) {
|
|
1220
1238
|
return;
|
|
1221
1239
|
}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
this._playerState.count += 1;
|
|
1229
|
-
}
|
|
1230
|
-
if (this._playerState.count >= this.count) {
|
|
1231
|
-
this.setLoop(false);
|
|
1232
|
-
this.playerState = PlayerState.Completed;
|
|
1233
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete));
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Loop));
|
|
1238
|
-
if (this._isBounce) {
|
|
1239
|
-
this._lottieInstance.goToAndStop(playDirection === -1 ? inPoint : outPoint * 0.99, true);
|
|
1240
|
-
this._lottieInstance.setDirection(playDirection * -1);
|
|
1241
|
-
return setTimeout(()=>{
|
|
1242
|
-
if (!this.animateOnScroll) {
|
|
1243
|
-
this._lottieInstance?.play();
|
|
1244
|
-
}
|
|
1245
|
-
}, this.intermission);
|
|
1240
|
+
this._playerState.prev = this.playerState;
|
|
1241
|
+
try {
|
|
1242
|
+
this._lottieInstance.play();
|
|
1243
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Play));
|
|
1244
|
+
} finally{
|
|
1245
|
+
this.playerState = PlayerState.Playing;
|
|
1246
1246
|
}
|
|
1247
|
-
this._lottieInstance.goToAndStop(playDirection === -1 ? outPoint * 0.99 : inPoint, true);
|
|
1248
|
-
return setTimeout(()=>{
|
|
1249
|
-
if (!this.animateOnScroll) {
|
|
1250
|
-
this._lottieInstance?.play();
|
|
1251
|
-
}
|
|
1252
|
-
}, this.intermission);
|
|
1253
1247
|
}
|
|
1254
|
-
|
|
1255
|
-
|
|
1248
|
+
/**
|
|
1249
|
+
* Skip to previous animation.
|
|
1250
|
+
*/ prev() {
|
|
1251
|
+
this._currentAnimation--;
|
|
1252
|
+
this._switchInstance(true);
|
|
1253
|
+
}
|
|
1254
|
+
/**
|
|
1255
|
+
* Name: string, oldValue: string, newValue: string.
|
|
1256
|
+
*/ propertyChangedCallback(name, _oldValue, value) {
|
|
1257
|
+
if (!this.shadow) {
|
|
1256
1258
|
return;
|
|
1257
1259
|
}
|
|
1258
|
-
const
|
|
1259
|
-
|
|
1260
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Frame, {
|
|
1261
|
-
detail: {
|
|
1262
|
-
frame: currentFrame,
|
|
1263
|
-
seeker: this._seeker
|
|
1264
|
-
}
|
|
1265
|
-
}));
|
|
1266
|
-
}
|
|
1267
|
-
_complete() {
|
|
1268
|
-
if (!this._lottieInstance) {
|
|
1260
|
+
const togglePlay = this.shadow.querySelector('.togglePlay'), stop = this.shadow.querySelector('.stop'), prev = this.shadow.querySelector('.prev'), next = this.shadow.querySelector('.next'), seeker = this.shadow.querySelector('.seeker'), progress = this.shadow.querySelector('progress'), popover = this.shadow.querySelector('.popover'), convert = this.shadow.querySelector('.convert');
|
|
1261
|
+
if (!(togglePlay instanceof HTMLButtonElement) || !(stop instanceof HTMLButtonElement) || !(next instanceof HTMLButtonElement) || !(prev instanceof HTMLButtonElement) || !(seeker instanceof HTMLInputElement) || !(progress instanceof HTMLProgressElement)) {
|
|
1269
1262
|
return;
|
|
1270
1263
|
}
|
|
1271
|
-
if (
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1264
|
+
if (name === 'playerState') {
|
|
1265
|
+
togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
|
|
1266
|
+
stop.dataset.active = (value === PlayerState.Stopped).toString();
|
|
1267
|
+
if (value === PlayerState.Playing) {
|
|
1268
|
+
togglePlay.innerHTML = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M14.016 5.016H18v13.969h-3.984V5.016zM6 18.984V5.015h3.984v13.969H6z"/></svg>`;
|
|
1269
|
+
} else {
|
|
1270
|
+
togglePlay.innerHTML = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg>`;
|
|
1278
1271
|
}
|
|
1279
1272
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
detail: {
|
|
1285
|
-
frame: currentFrame,
|
|
1286
|
-
seeker: this._seeker
|
|
1287
|
-
}
|
|
1288
|
-
}));
|
|
1289
|
-
}
|
|
1290
|
-
_DOMLoaded() {
|
|
1291
|
-
this._playerState.loaded = true;
|
|
1292
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Ready));
|
|
1293
|
-
}
|
|
1294
|
-
_dataReady() {
|
|
1295
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Load));
|
|
1296
|
-
}
|
|
1297
|
-
_dataFailed() {
|
|
1298
|
-
this.playerState = PlayerState.Error;
|
|
1299
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1300
|
-
}
|
|
1301
|
-
_handleWindowBlur({ type }) {
|
|
1302
|
-
if (this.playerState === PlayerState.Playing && type === 'blur') {
|
|
1303
|
-
this._freeze();
|
|
1273
|
+
if (name === '_seeker' && typeof value === 'number') {
|
|
1274
|
+
seeker.value = value.toString();
|
|
1275
|
+
seeker.ariaValueNow = value.toString();
|
|
1276
|
+
progress.value = value;
|
|
1304
1277
|
}
|
|
1305
|
-
if (
|
|
1306
|
-
|
|
1278
|
+
if (name === '_animations' && Array.isArray(value) && this._currentAnimation + 1 < value.length) {
|
|
1279
|
+
next.hidden = false;
|
|
1307
1280
|
}
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1281
|
+
if (name === '_currentAnimation' && typeof value === 'number') {
|
|
1282
|
+
if (value + 1 >= this._animations.length) {
|
|
1283
|
+
next.hidden = true;
|
|
1284
|
+
} else {
|
|
1285
|
+
next.hidden = false;
|
|
1286
|
+
}
|
|
1287
|
+
if (value) {
|
|
1288
|
+
prev.hidden = false;
|
|
1289
|
+
} else {
|
|
1290
|
+
prev.hidden = true;
|
|
1291
|
+
}
|
|
1314
1292
|
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
*/ _mouseLeave() {
|
|
1319
|
-
if (this.hover && this.playerState === PlayerState.Playing) {
|
|
1320
|
-
this.stop();
|
|
1293
|
+
if (name === '_isSettingsOpen' && typeof value === 'boolean' && popover instanceof HTMLDivElement && convert instanceof HTMLButtonElement) {
|
|
1294
|
+
popover.hidden = !value;
|
|
1295
|
+
convert.hidden = this._isDotLottie;
|
|
1321
1296
|
}
|
|
1322
1297
|
}
|
|
1323
1298
|
/**
|
|
1324
|
-
*
|
|
1325
|
-
*/
|
|
1326
|
-
if (
|
|
1327
|
-
this._freeze();
|
|
1299
|
+
* Reload animation.
|
|
1300
|
+
*/ async reload() {
|
|
1301
|
+
if (!this._lottieInstance || !this.src) {
|
|
1328
1302
|
return;
|
|
1329
1303
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
}
|
|
1304
|
+
this._lottieInstance.destroy();
|
|
1305
|
+
await this.load(this.src);
|
|
1333
1306
|
}
|
|
1334
1307
|
/**
|
|
1335
|
-
*
|
|
1336
|
-
|
|
1337
|
-
|
|
1308
|
+
* Seek to a given frame.
|
|
1309
|
+
*
|
|
1310
|
+
* @param value - Frame to seek to.
|
|
1311
|
+
*/ seek(value) {
|
|
1312
|
+
if (!this._lottieInstance) {
|
|
1338
1313
|
return;
|
|
1339
1314
|
}
|
|
1340
|
-
|
|
1341
|
-
|
|
1315
|
+
// Extract frame number from either number or percentage value
|
|
1316
|
+
const matches = value.toString().match(/^(\d+)(%?)$/);
|
|
1317
|
+
if (!matches) {
|
|
1342
1318
|
return;
|
|
1343
1319
|
}
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
if (roundedScroll < (this._lottieInstance?.totalFrames ?? 0)) {
|
|
1354
|
-
this.playerState = PlayerState.Playing;
|
|
1355
|
-
this._lottieInstance?.goToAndStop(roundedScroll, true);
|
|
1356
|
-
} else {
|
|
1357
|
-
this.playerState = PlayerState.Paused;
|
|
1358
|
-
}
|
|
1359
|
-
});
|
|
1320
|
+
// Calculate and set the frame number
|
|
1321
|
+
const frame = Math.round(matches[2] === '%' ? this._lottieInstance.totalFrames * Number(matches[1]) / 100 : Number(matches[1]));
|
|
1322
|
+
// Set seeker to new frame number
|
|
1323
|
+
this._seeker = frame;
|
|
1324
|
+
// Send lottie player to the new frame
|
|
1325
|
+
if (this.playerState === PlayerState.Playing || this.playerState === PlayerState.Frozen && this._playerState.prev === PlayerState.Playing) {
|
|
1326
|
+
this._lottieInstance.goToAndPlay(frame, true);
|
|
1327
|
+
this.playerState = PlayerState.Playing;
|
|
1328
|
+
return;
|
|
1360
1329
|
}
|
|
1330
|
+
this._lottieInstance.goToAndStop(frame, true);
|
|
1331
|
+
this._lottieInstance.pause();
|
|
1361
1332
|
}
|
|
1362
1333
|
/**
|
|
1363
|
-
*
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1334
|
+
* Dynamically set count for loops.
|
|
1335
|
+
*/ setCount(value) {
|
|
1336
|
+
this.count = value;
|
|
1337
|
+
}
|
|
1338
|
+
/**
|
|
1339
|
+
* Animation play direction.
|
|
1340
|
+
*
|
|
1341
|
+
* @param value - Animation direction.
|
|
1342
|
+
*/ setDirection(value) {
|
|
1343
|
+
if (!this._lottieInstance) {
|
|
1367
1344
|
return;
|
|
1368
1345
|
}
|
|
1369
|
-
this.
|
|
1370
|
-
}
|
|
1371
|
-
_isLottie(json) {
|
|
1372
|
-
const mandatory = [
|
|
1373
|
-
'v',
|
|
1374
|
-
'ip',
|
|
1375
|
-
'op',
|
|
1376
|
-
'layers',
|
|
1377
|
-
'fr',
|
|
1378
|
-
'w',
|
|
1379
|
-
'h'
|
|
1380
|
-
];
|
|
1381
|
-
return mandatory.every((field)=>Object.prototype.hasOwnProperty.call(json, field));
|
|
1346
|
+
this._lottieInstance.setDirection(value);
|
|
1382
1347
|
}
|
|
1383
1348
|
/**
|
|
1384
|
-
*
|
|
1385
|
-
* @param { [ AnimationConfig ] } configs
|
|
1386
|
-
* @param { string } fileName
|
|
1387
|
-
* @param { boolean } shouldDownload Whether to trigger a download in the browser.
|
|
1388
|
-
* If set to false the function returns an ArrayBuffer. Defaults to true.
|
|
1349
|
+
* Set loop.
|
|
1389
1350
|
*
|
|
1390
|
-
*/
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
const { animations = [], manifest = {
|
|
1394
|
-
animations: this.src ? [
|
|
1395
|
-
{
|
|
1396
|
-
id: this._identifier
|
|
1397
|
-
}
|
|
1398
|
-
] : []
|
|
1399
|
-
} } = this.src ? await getAnimationData(this.src) : {};
|
|
1400
|
-
try {
|
|
1401
|
-
manifest.generator = pkg.name;
|
|
1402
|
-
for (const config of configs){
|
|
1403
|
-
const { url } = config, { animations: animationsToAdd } = await getAnimationData(url);
|
|
1404
|
-
if (!animationsToAdd) {
|
|
1405
|
-
throw new Error('No animation loaded');
|
|
1406
|
-
}
|
|
1407
|
-
if (manifest.animations.some(({ id })=>id === config.id)) {
|
|
1408
|
-
throw new Error('Duplicate id for animation');
|
|
1409
|
-
}
|
|
1410
|
-
manifest.animations = [
|
|
1411
|
-
...manifest.animations,
|
|
1412
|
-
{
|
|
1413
|
-
id: config.id
|
|
1414
|
-
}
|
|
1415
|
-
];
|
|
1416
|
-
animations?.push(...animationsToAdd);
|
|
1417
|
-
}
|
|
1418
|
-
return {
|
|
1419
|
-
result: await createDotLottie({
|
|
1420
|
-
animations,
|
|
1421
|
-
fileName,
|
|
1422
|
-
manifest,
|
|
1423
|
-
shouldDownload
|
|
1424
|
-
}),
|
|
1425
|
-
success: true
|
|
1426
|
-
};
|
|
1427
|
-
} catch (err) {
|
|
1428
|
-
return {
|
|
1429
|
-
error: handleErrors(err).message,
|
|
1430
|
-
success: false
|
|
1431
|
-
};
|
|
1351
|
+
*/ setLoop(value) {
|
|
1352
|
+
if (!this._lottieInstance) {
|
|
1353
|
+
return;
|
|
1432
1354
|
}
|
|
1355
|
+
this._lottieInstance.setLoop(value);
|
|
1433
1356
|
}
|
|
1434
1357
|
/**
|
|
1435
|
-
*
|
|
1436
|
-
|
|
1437
|
-
|
|
1358
|
+
* Set Multi-animation settings.
|
|
1359
|
+
*
|
|
1360
|
+
*/ setMultiAnimationSettings(settings) {
|
|
1361
|
+
this._multiAnimationSettings = settings;
|
|
1438
1362
|
}
|
|
1439
1363
|
/**
|
|
1440
|
-
*
|
|
1441
|
-
|
|
1364
|
+
* Set playback segment.
|
|
1365
|
+
*
|
|
1366
|
+
*/ setSegment(segment) {
|
|
1367
|
+
this._segment = segment;
|
|
1368
|
+
}
|
|
1369
|
+
/**
|
|
1370
|
+
* Set animation playback speed.
|
|
1371
|
+
*
|
|
1372
|
+
* @param value - Playback speed.
|
|
1373
|
+
*/ setSpeed(value = 1) {
|
|
1442
1374
|
if (!this._lottieInstance) {
|
|
1443
1375
|
return;
|
|
1444
1376
|
}
|
|
1445
|
-
|
|
1446
|
-
this._playerState.prev = this.playerState;
|
|
1447
|
-
}
|
|
1448
|
-
try {
|
|
1449
|
-
this._lottieInstance.play();
|
|
1450
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Play));
|
|
1451
|
-
} finally{
|
|
1452
|
-
this.playerState = PlayerState.Playing;
|
|
1453
|
-
}
|
|
1377
|
+
this._lottieInstance.setSpeed(value);
|
|
1454
1378
|
}
|
|
1455
1379
|
/**
|
|
1456
|
-
*
|
|
1457
|
-
|
|
1380
|
+
* Toggles subframe, for more smooth animations.
|
|
1381
|
+
*
|
|
1382
|
+
* @param value - Whether animation uses subframe.
|
|
1383
|
+
*/ setSubframe(value) {
|
|
1458
1384
|
if (!this._lottieInstance) {
|
|
1459
1385
|
return;
|
|
1460
1386
|
}
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1387
|
+
this._lottieInstance.setSubframe(value);
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Snapshot and download the current frame as SVG.
|
|
1391
|
+
*/ snapshot(shouldDownload = true, name = 'AM Lottie') {
|
|
1464
1392
|
try {
|
|
1465
|
-
this.
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1393
|
+
if (!this.shadowRoot) {
|
|
1394
|
+
throw new Error('Unknown error');
|
|
1395
|
+
}
|
|
1396
|
+
// Get SVG element and serialize markup
|
|
1397
|
+
const svgElement = this.shadowRoot.querySelector('.animation svg');
|
|
1398
|
+
if (!svgElement) {
|
|
1399
|
+
throw new Error('Could not retrieve animation from DOM');
|
|
1400
|
+
}
|
|
1401
|
+
const data = svgElement instanceof Node ? new XMLSerializer().serializeToString(svgElement) : null;
|
|
1402
|
+
if (!data) {
|
|
1403
|
+
throw new Error('Could not serialize SVG element');
|
|
1404
|
+
}
|
|
1405
|
+
if (shouldDownload) {
|
|
1406
|
+
download(data, {
|
|
1407
|
+
mimeType: 'image/svg+xml',
|
|
1408
|
+
name: `${getFilename(this.src || name)}-${frameOutput(this._seeker)}.svg`
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
return data;
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
console.error(error);
|
|
1414
|
+
return null;
|
|
1469
1415
|
}
|
|
1470
1416
|
}
|
|
1471
1417
|
/**
|
|
1472
|
-
* Stop
|
|
1418
|
+
* Stop.
|
|
1473
1419
|
*/ stop() {
|
|
1474
1420
|
if (!this._lottieInstance) {
|
|
1475
1421
|
return;
|
|
1476
1422
|
}
|
|
1477
|
-
|
|
1478
|
-
this._playerState.prev = this.playerState;
|
|
1479
|
-
}
|
|
1423
|
+
this._playerState.prev = this.playerState;
|
|
1480
1424
|
this._playerState.count = 0;
|
|
1481
1425
|
try {
|
|
1482
1426
|
this._lottieInstance.stop();
|
|
@@ -1486,204 +1430,367 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1486
1430
|
}
|
|
1487
1431
|
}
|
|
1488
1432
|
/**
|
|
1489
|
-
*
|
|
1490
|
-
*/
|
|
1491
|
-
|
|
1433
|
+
* Toggle Boomerang.
|
|
1434
|
+
*/ toggleBoomerang() {
|
|
1435
|
+
const curr = this._multiAnimationSettings[this._currentAnimation];
|
|
1436
|
+
if (curr.mode !== undefined) {
|
|
1437
|
+
if (curr.mode === PlayMode.Normal) {
|
|
1438
|
+
curr.mode = PlayMode.Bounce;
|
|
1439
|
+
this._isBounce = true;
|
|
1440
|
+
return;
|
|
1441
|
+
}
|
|
1442
|
+
curr.mode = PlayMode.Normal;
|
|
1443
|
+
this._isBounce = false;
|
|
1492
1444
|
return;
|
|
1493
1445
|
}
|
|
1494
|
-
this.
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1446
|
+
if (this.mode === PlayMode.Normal) {
|
|
1447
|
+
this.mode = PlayMode.Bounce;
|
|
1448
|
+
this._isBounce = true;
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
this.mode = PlayMode.Normal;
|
|
1452
|
+
this._isBounce = false;
|
|
1500
1453
|
}
|
|
1501
1454
|
/**
|
|
1502
|
-
*
|
|
1503
|
-
|
|
1504
|
-
|
|
1455
|
+
* Toggle loop.
|
|
1456
|
+
*/ toggleLoop() {
|
|
1457
|
+
const hasLoop = !this.loop;
|
|
1458
|
+
this.loop = hasLoop;
|
|
1459
|
+
this.setLoop(hasLoop);
|
|
1460
|
+
}
|
|
1461
|
+
/**
|
|
1462
|
+
* Toggle playing state.
|
|
1463
|
+
*/ togglePlay() {
|
|
1505
1464
|
if (!this._lottieInstance) {
|
|
1506
1465
|
return;
|
|
1507
1466
|
}
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1467
|
+
const { currentFrame, playDirection, totalFrames } = this._lottieInstance;
|
|
1468
|
+
if (this.playerState === PlayerState.Playing) {
|
|
1469
|
+
this.pause();
|
|
1511
1470
|
return;
|
|
1512
1471
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
// Set seeker to new frame number
|
|
1516
|
-
this._seeker = frame;
|
|
1517
|
-
// Send lottie player to the new frame
|
|
1518
|
-
if (this.playerState === PlayerState.Playing || this.playerState === PlayerState.Frozen && this._playerState.prev === PlayerState.Playing) {
|
|
1519
|
-
this._lottieInstance.goToAndPlay(frame, true);
|
|
1520
|
-
this.playerState = PlayerState.Playing;
|
|
1472
|
+
if (this.playerState !== PlayerState.Completed) {
|
|
1473
|
+
this.play();
|
|
1521
1474
|
return;
|
|
1522
1475
|
}
|
|
1523
|
-
this.
|
|
1524
|
-
this.
|
|
1476
|
+
this.playerState = PlayerState.Playing;
|
|
1477
|
+
if (this._isBounce) {
|
|
1478
|
+
this.setDirection(playDirection * -1);
|
|
1479
|
+
this._lottieInstance.goToAndPlay(currentFrame, true);
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
if (playDirection === -1) {
|
|
1483
|
+
this._lottieInstance.goToAndPlay(totalFrames, true);
|
|
1484
|
+
return;
|
|
1485
|
+
}
|
|
1486
|
+
this._lottieInstance.goToAndPlay(0, true);
|
|
1525
1487
|
}
|
|
1526
1488
|
/**
|
|
1527
|
-
*
|
|
1528
|
-
|
|
1489
|
+
* Freeze animation.
|
|
1490
|
+
* This internal state pauses animation and is used to differentiate between
|
|
1491
|
+
* user requested pauses and component instigated pauses.
|
|
1492
|
+
*/ _freeze() {
|
|
1493
|
+
if (!this._lottieInstance) {
|
|
1494
|
+
return;
|
|
1495
|
+
}
|
|
1496
|
+
this._playerState.prev = this.playerState;
|
|
1529
1497
|
try {
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1498
|
+
this._lottieInstance.pause();
|
|
1499
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Freeze));
|
|
1500
|
+
} finally{
|
|
1501
|
+
this.playerState = PlayerState.Frozen;
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Handle blur.
|
|
1506
|
+
*/ _handleBlur() {
|
|
1507
|
+
setTimeout(()=>{
|
|
1508
|
+
this._toggleSettings(false);
|
|
1509
|
+
}, 200);
|
|
1510
|
+
}
|
|
1511
|
+
/**
|
|
1512
|
+
* Handles click and drag actions on the progress track.
|
|
1513
|
+
*
|
|
1514
|
+
*/ _handleSeekChange({ target }) {
|
|
1515
|
+
if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
|
|
1516
|
+
return;
|
|
1517
|
+
}
|
|
1518
|
+
this.seek(Math.round(Number(target.value) / 100 * this._lottieInstance.totalFrames));
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Add event listeners.
|
|
1522
|
+
*/ _addEventListeners() {
|
|
1523
|
+
this._toggleEventListeners('add');
|
|
1524
|
+
}
|
|
1525
|
+
/**
|
|
1526
|
+
* Add IntersectionObserver.
|
|
1527
|
+
*/ _addIntersectionObserver() {
|
|
1528
|
+
if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1531
|
+
this._intersectionObserver = new IntersectionObserver((entries)=>{
|
|
1532
|
+
const { length } = entries;
|
|
1533
|
+
for(let i = 0; i < length; i++){
|
|
1534
|
+
if (!entries[i].isIntersecting || document.hidden) {
|
|
1535
|
+
if (this.playerState === PlayerState.Playing) {
|
|
1536
|
+
this._freeze();
|
|
1537
|
+
}
|
|
1538
|
+
this._playerState.visible = false;
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1541
|
+
if (!this.animateOnScroll && this.playerState === PlayerState.Frozen) {
|
|
1542
|
+
this.play();
|
|
1543
|
+
}
|
|
1544
|
+
if (!this._playerState.scrollY) {
|
|
1545
|
+
this._playerState.scrollY = scrollY;
|
|
1546
|
+
}
|
|
1547
|
+
this._playerState.visible = true;
|
|
1537
1548
|
}
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1549
|
+
});
|
|
1550
|
+
this._intersectionObserver.observe(this._container);
|
|
1551
|
+
}
|
|
1552
|
+
_complete() {
|
|
1553
|
+
if (!this._lottieInstance) {
|
|
1554
|
+
return;
|
|
1555
|
+
}
|
|
1556
|
+
if (this._animations.length > 1) {
|
|
1557
|
+
if (this._multiAnimationSettings[this._currentAnimation + 1]?.autoplay) {
|
|
1558
|
+
this.next();
|
|
1559
|
+
return;
|
|
1541
1560
|
}
|
|
1542
|
-
if (
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
});
|
|
1561
|
+
if (this.loop && this._currentAnimation === this._animations.length - 1) {
|
|
1562
|
+
this._currentAnimation = 0;
|
|
1563
|
+
this._switchInstance();
|
|
1564
|
+
return;
|
|
1547
1565
|
}
|
|
1548
|
-
return data;
|
|
1549
|
-
} catch (err) {
|
|
1550
|
-
console.error(err);
|
|
1551
|
-
return null;
|
|
1552
1566
|
}
|
|
1567
|
+
const { currentFrame, totalFrames } = this._lottieInstance;
|
|
1568
|
+
this._seeker = Math.round(currentFrame / totalFrames * 100);
|
|
1569
|
+
this.playerState = PlayerState.Completed;
|
|
1570
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete, {
|
|
1571
|
+
detail: {
|
|
1572
|
+
frame: currentFrame,
|
|
1573
|
+
seeker: this._seeker
|
|
1574
|
+
}
|
|
1575
|
+
}));
|
|
1576
|
+
}
|
|
1577
|
+
_dataFailed() {
|
|
1578
|
+
this.playerState = PlayerState.Error;
|
|
1579
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1553
1580
|
}
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1581
|
+
_dataReady() {
|
|
1582
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Load));
|
|
1583
|
+
}
|
|
1584
|
+
_DOMLoaded() {
|
|
1585
|
+
this._playerState.loaded = true;
|
|
1586
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Ready));
|
|
1587
|
+
}
|
|
1588
|
+
_enterFrame() {
|
|
1558
1589
|
if (!this._lottieInstance) {
|
|
1559
1590
|
return;
|
|
1560
1591
|
}
|
|
1561
|
-
this._lottieInstance
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1592
|
+
const { currentFrame, totalFrames } = this._lottieInstance;
|
|
1593
|
+
this._seeker = Math.round(currentFrame / totalFrames * 100);
|
|
1594
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Frame, {
|
|
1595
|
+
detail: {
|
|
1596
|
+
frame: currentFrame,
|
|
1597
|
+
seeker: this._seeker
|
|
1598
|
+
}
|
|
1599
|
+
}));
|
|
1567
1600
|
}
|
|
1568
1601
|
/**
|
|
1569
|
-
*
|
|
1570
|
-
*
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
return;
|
|
1602
|
+
* Get options from props.
|
|
1603
|
+
*
|
|
1604
|
+
*/ _getOptions() {
|
|
1605
|
+
if (!this._container) {
|
|
1606
|
+
throw new Error('Container not rendered');
|
|
1575
1607
|
}
|
|
1576
|
-
|
|
1577
|
-
|
|
1608
|
+
const preserveAspectRatio = this.preserveAspectRatio ?? aspectRatio(this.objectfit), currentAnimationSettings = this._multiAnimationSettings.length > 0 ? this._multiAnimationSettings[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest?.animations[this._currentAnimation];
|
|
1609
|
+
// Loop
|
|
1610
|
+
let hasLoop = Boolean(this.loop);
|
|
1611
|
+
if (currentAnimationManifest?.loop !== undefined) {
|
|
1612
|
+
hasLoop = Boolean(currentAnimationManifest.loop);
|
|
1578
1613
|
}
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Freeze));
|
|
1582
|
-
} finally{
|
|
1583
|
-
this.playerState = PlayerState.Frozen;
|
|
1614
|
+
if (currentAnimationSettings?.loop !== undefined) {
|
|
1615
|
+
hasLoop = Boolean(currentAnimationSettings.loop);
|
|
1584
1616
|
}
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
if (!this._lottieInstance || !this.src) {
|
|
1590
|
-
return;
|
|
1617
|
+
// Autoplay
|
|
1618
|
+
let hasAutoplay = Boolean(this.autoplay);
|
|
1619
|
+
if (currentAnimationManifest?.autoplay !== undefined) {
|
|
1620
|
+
hasAutoplay = Boolean(currentAnimationManifest.autoplay);
|
|
1591
1621
|
}
|
|
1592
|
-
|
|
1593
|
-
|
|
1622
|
+
if (currentAnimationSettings?.autoplay !== undefined) {
|
|
1623
|
+
hasAutoplay = Boolean(currentAnimationSettings.autoplay);
|
|
1624
|
+
}
|
|
1625
|
+
if (this.animateOnScroll) {
|
|
1626
|
+
hasAutoplay = false;
|
|
1627
|
+
}
|
|
1628
|
+
// Segment
|
|
1629
|
+
let initialSegment = this._segment;
|
|
1630
|
+
if (this._segment?.every((val)=>val > 0)) {
|
|
1631
|
+
initialSegment = [
|
|
1632
|
+
this._segment[0] - 1,
|
|
1633
|
+
this._segment[1] - 1
|
|
1634
|
+
];
|
|
1635
|
+
}
|
|
1636
|
+
if (this._segment?.some((val)=>val < 0)) {
|
|
1637
|
+
initialSegment = undefined;
|
|
1638
|
+
}
|
|
1639
|
+
const options = {
|
|
1640
|
+
autoplay: hasAutoplay,
|
|
1641
|
+
container: this._container,
|
|
1642
|
+
initialSegment,
|
|
1643
|
+
loop: hasLoop,
|
|
1644
|
+
renderer: this.renderer,
|
|
1645
|
+
rendererSettings: {
|
|
1646
|
+
imagePreserveAspectRatio: preserveAspectRatio
|
|
1647
|
+
}
|
|
1648
|
+
};
|
|
1649
|
+
switch(this.renderer){
|
|
1650
|
+
case RendererType.SVG:
|
|
1651
|
+
{
|
|
1652
|
+
options.rendererSettings = {
|
|
1653
|
+
...options.rendererSettings,
|
|
1654
|
+
hideOnTransparent: true,
|
|
1655
|
+
preserveAspectRatio,
|
|
1656
|
+
progressiveLoad: true
|
|
1657
|
+
};
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
case RendererType.Canvas:
|
|
1661
|
+
{
|
|
1662
|
+
options.rendererSettings = {
|
|
1663
|
+
...options.rendererSettings,
|
|
1664
|
+
// @ts-expect-error TODO:
|
|
1665
|
+
clearCanvas: true,
|
|
1666
|
+
preserveAspectRatio,
|
|
1667
|
+
progressiveLoad: true
|
|
1668
|
+
};
|
|
1669
|
+
break;
|
|
1670
|
+
}
|
|
1671
|
+
case RendererType.HTML:
|
|
1672
|
+
{
|
|
1673
|
+
options.rendererSettings = {
|
|
1674
|
+
...options.rendererSettings,
|
|
1675
|
+
hideOnTransparent: true
|
|
1676
|
+
};
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
return options;
|
|
1594
1680
|
}
|
|
1595
1681
|
/**
|
|
1596
|
-
*
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
if (!this._lottieInstance) {
|
|
1682
|
+
* Handle scroll.
|
|
1683
|
+
*/ _handleScroll() {
|
|
1684
|
+
if (!this.animateOnScroll || !this._lottieInstance) {
|
|
1600
1685
|
return;
|
|
1601
1686
|
}
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
/**
|
|
1605
|
-
* Animation play direction
|
|
1606
|
-
* @param { AnimationDirection } value Animation direction
|
|
1607
|
-
*/ setDirection(value) {
|
|
1608
|
-
if (!this._lottieInstance) {
|
|
1687
|
+
if (isServer()) {
|
|
1688
|
+
console.warn('DotLottie: Scroll animations might not work properly in a Server Side Rendering context. Try to wrap this in a client component.');
|
|
1609
1689
|
return;
|
|
1610
1690
|
}
|
|
1611
|
-
this.
|
|
1691
|
+
if (this._playerState.visible) {
|
|
1692
|
+
if (this._playerState.scrollTimeout) {
|
|
1693
|
+
clearTimeout(this._playerState.scrollTimeout);
|
|
1694
|
+
}
|
|
1695
|
+
this._playerState.scrollTimeout = setTimeout(()=>{
|
|
1696
|
+
this.playerState = PlayerState.Paused;
|
|
1697
|
+
}, 400);
|
|
1698
|
+
const adjustedScroll = scrollY > this._playerState.scrollY ? scrollY - this._playerState.scrollY : this._playerState.scrollY - scrollY, clampedScroll = Math.min(Math.max(adjustedScroll / 3, 1), this._lottieInstance.totalFrames * 3), roundedScroll = clampedScroll / 3;
|
|
1699
|
+
requestAnimationFrame(()=>{
|
|
1700
|
+
if (roundedScroll < (this._lottieInstance?.totalFrames ?? 0)) {
|
|
1701
|
+
this.playerState = PlayerState.Playing;
|
|
1702
|
+
this._lottieInstance?.goToAndStop(roundedScroll, true);
|
|
1703
|
+
} else {
|
|
1704
|
+
this.playerState = PlayerState.Paused;
|
|
1705
|
+
}
|
|
1706
|
+
});
|
|
1707
|
+
}
|
|
1612
1708
|
}
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
if (
|
|
1618
|
-
|
|
1709
|
+
_handleWindowBlur({ type }) {
|
|
1710
|
+
if (this.playerState === PlayerState.Playing && type === 'blur') {
|
|
1711
|
+
this._freeze();
|
|
1712
|
+
}
|
|
1713
|
+
if (this.playerState === PlayerState.Frozen && type === 'focus') {
|
|
1714
|
+
this.play();
|
|
1619
1715
|
}
|
|
1620
|
-
this._lottieInstance.setLoop(value);
|
|
1621
1716
|
}
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1717
|
+
_isLottie(json) {
|
|
1718
|
+
const mandatory = [
|
|
1719
|
+
'v',
|
|
1720
|
+
'ip',
|
|
1721
|
+
'op',
|
|
1722
|
+
'layers',
|
|
1723
|
+
'fr',
|
|
1724
|
+
'w',
|
|
1725
|
+
'h'
|
|
1726
|
+
];
|
|
1727
|
+
return mandatory.every((field)=>Object.hasOwn(json, field));
|
|
1728
|
+
}
|
|
1729
|
+
_loopComplete() {
|
|
1625
1730
|
if (!this._lottieInstance) {
|
|
1626
1731
|
return;
|
|
1627
1732
|
}
|
|
1628
|
-
const {
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1733
|
+
const { playDirection, // firstFrame,
|
|
1734
|
+
totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
|
|
1735
|
+
if (this.count) {
|
|
1736
|
+
if (this._isBounce) {
|
|
1737
|
+
this._playerState.count += 0.5;
|
|
1738
|
+
} else {
|
|
1739
|
+
this._playerState.count += 1;
|
|
1740
|
+
}
|
|
1741
|
+
if (this._playerState.count >= this.count) {
|
|
1742
|
+
this.setLoop(false);
|
|
1743
|
+
this.playerState = PlayerState.Completed;
|
|
1744
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete));
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1634
1747
|
}
|
|
1635
|
-
this.
|
|
1748
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Loop));
|
|
1636
1749
|
if (this._isBounce) {
|
|
1637
|
-
this.
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1750
|
+
this._lottieInstance.goToAndStop(playDirection === -1 ? inPoint : outPoint * 0.99, true);
|
|
1751
|
+
this._lottieInstance.setDirection(playDirection * -1);
|
|
1752
|
+
return setTimeout(()=>{
|
|
1753
|
+
if (!this.animateOnScroll) {
|
|
1754
|
+
this._lottieInstance?.play();
|
|
1755
|
+
}
|
|
1756
|
+
}, this.intermission);
|
|
1642
1757
|
}
|
|
1643
|
-
|
|
1758
|
+
this._lottieInstance.goToAndStop(playDirection === -1 ? outPoint * 0.99 : inPoint, true);
|
|
1759
|
+
return setTimeout(()=>{
|
|
1760
|
+
if (!this.animateOnScroll) {
|
|
1761
|
+
this._lottieInstance?.play();
|
|
1762
|
+
}
|
|
1763
|
+
}, this.intermission);
|
|
1644
1764
|
}
|
|
1645
1765
|
/**
|
|
1646
|
-
*
|
|
1647
|
-
*/
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1766
|
+
* Handle MouseEnter.
|
|
1767
|
+
*/ _mouseEnter() {
|
|
1768
|
+
if (this.hover && this.playerState !== PlayerState.Playing) {
|
|
1769
|
+
this.play();
|
|
1770
|
+
}
|
|
1651
1771
|
}
|
|
1652
1772
|
/**
|
|
1653
|
-
*
|
|
1654
|
-
*/
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
if (curr.mode === PlayMode.Normal) {
|
|
1658
|
-
curr.mode = PlayMode.Bounce;
|
|
1659
|
-
this._isBounce = true;
|
|
1660
|
-
return;
|
|
1661
|
-
}
|
|
1662
|
-
curr.mode = PlayMode.Normal;
|
|
1663
|
-
this._isBounce = false;
|
|
1664
|
-
return;
|
|
1665
|
-
}
|
|
1666
|
-
if (this.mode === PlayMode.Normal) {
|
|
1667
|
-
this.mode = PlayMode.Bounce;
|
|
1668
|
-
this._isBounce = true;
|
|
1669
|
-
return;
|
|
1773
|
+
* Handle MouseLeave.
|
|
1774
|
+
*/ _mouseLeave() {
|
|
1775
|
+
if (this.hover && this.playerState === PlayerState.Playing) {
|
|
1776
|
+
this.stop();
|
|
1670
1777
|
}
|
|
1671
|
-
this.mode = PlayMode.Normal;
|
|
1672
|
-
this._isBounce = false;
|
|
1673
1778
|
}
|
|
1674
1779
|
/**
|
|
1675
|
-
*
|
|
1676
|
-
*/
|
|
1677
|
-
if (
|
|
1678
|
-
this.
|
|
1780
|
+
* Handle visibility change events.
|
|
1781
|
+
*/ _onVisibilityChange() {
|
|
1782
|
+
if (document.hidden && this.playerState === PlayerState.Playing) {
|
|
1783
|
+
this._freeze();
|
|
1679
1784
|
return;
|
|
1680
1785
|
}
|
|
1681
|
-
this.
|
|
1786
|
+
if (this.playerState === PlayerState.Frozen) {
|
|
1787
|
+
this.play();
|
|
1788
|
+
}
|
|
1682
1789
|
}
|
|
1683
1790
|
/**
|
|
1684
|
-
*
|
|
1685
|
-
*/
|
|
1686
|
-
|
|
1791
|
+
* Remove event listeners.
|
|
1792
|
+
*/ _removeEventListeners() {
|
|
1793
|
+
this._toggleEventListeners('remove');
|
|
1687
1794
|
}
|
|
1688
1795
|
_switchInstance(isPrevious = false) {
|
|
1689
1796
|
// Bail early if there is not animation to play
|
|
@@ -1696,82 +1803,86 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1696
1803
|
this._lottieInstance.destroy();
|
|
1697
1804
|
}
|
|
1698
1805
|
// Re-initialize lottie player
|
|
1699
|
-
|
|
1806
|
+
// @ts-expect-error TODO:
|
|
1807
|
+
this._lottieInstance = Lottie.loadAnimation({
|
|
1700
1808
|
...this._getOptions(),
|
|
1701
1809
|
animationData: this._animations[this._currentAnimation]
|
|
1702
1810
|
});
|
|
1703
1811
|
// Check play mode for current animation
|
|
1704
|
-
if (this._multiAnimationSettings
|
|
1812
|
+
if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1705
1813
|
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1706
1814
|
}
|
|
1707
1815
|
// Remove event listeners to new Lottie instance, and add new
|
|
1708
1816
|
this._removeEventListeners();
|
|
1709
1817
|
this._addEventListeners();
|
|
1710
1818
|
this.dispatchEvent(new CustomEvent(isPrevious ? PlayerEvents.Previous : PlayerEvents.Next));
|
|
1711
|
-
if (this._multiAnimationSettings
|
|
1819
|
+
if (this._multiAnimationSettings[this._currentAnimation]?.autoplay ?? this.autoplay) {
|
|
1712
1820
|
if (this.animateOnScroll) {
|
|
1713
|
-
this._lottieInstance
|
|
1821
|
+
this._lottieInstance.goToAndStop(0, true);
|
|
1714
1822
|
this.playerState = PlayerState.Paused;
|
|
1715
1823
|
return;
|
|
1716
1824
|
}
|
|
1717
|
-
this._lottieInstance
|
|
1825
|
+
this._lottieInstance.goToAndPlay(0, true);
|
|
1718
1826
|
this.playerState = PlayerState.Playing;
|
|
1719
1827
|
return;
|
|
1720
1828
|
}
|
|
1721
|
-
this._lottieInstance
|
|
1829
|
+
this._lottieInstance.goToAndStop(0, true);
|
|
1722
1830
|
this.playerState = PlayerState.Stopped;
|
|
1723
|
-
} catch (
|
|
1724
|
-
this._errorMessage = handleErrors(
|
|
1831
|
+
} catch (error) {
|
|
1832
|
+
this._errorMessage = handleErrors(error).message;
|
|
1725
1833
|
this.playerState = PlayerState.Error;
|
|
1726
1834
|
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1727
1835
|
}
|
|
1728
1836
|
}
|
|
1729
1837
|
/**
|
|
1730
|
-
*
|
|
1731
|
-
*/
|
|
1732
|
-
|
|
1733
|
-
this.
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
}
|
|
1741
|
-
async convert({ animations, fileName, manifest, shouldDownload = true, src, typeCheck }) {
|
|
1742
|
-
if (typeCheck || this._isDotLottie) {
|
|
1743
|
-
return createJSON({
|
|
1744
|
-
animation: (await getAnimationData(src || this.src))?.animations?.[0],
|
|
1745
|
-
fileName: `${getFilename(fileName || this.src || 'converted')}.json`,
|
|
1746
|
-
shouldDownload
|
|
1747
|
-
});
|
|
1838
|
+
* Toggle event listeners.
|
|
1839
|
+
*/ _toggleEventListeners(action) {
|
|
1840
|
+
const method = action === 'add' ? 'addEventListener' : 'removeEventListener';
|
|
1841
|
+
if (this._lottieInstance) {
|
|
1842
|
+
this._lottieInstance[method]('enterFrame', this._enterFrame);
|
|
1843
|
+
this._lottieInstance[method]('complete', this._complete);
|
|
1844
|
+
this._lottieInstance[method]('loopComplete', this._loopComplete);
|
|
1845
|
+
this._lottieInstance[method]('DOMLoaded', this._DOMLoaded);
|
|
1846
|
+
this._lottieInstance[method]('data_ready', this._dataReady);
|
|
1847
|
+
this._lottieInstance[method]('data_failed', this._dataFailed);
|
|
1748
1848
|
}
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1849
|
+
if (this._container && this.hover) {
|
|
1850
|
+
this._container[method]('mouseenter', this._mouseEnter);
|
|
1851
|
+
this._container[method]('mouseleave', this._mouseLeave);
|
|
1852
|
+
}
|
|
1853
|
+
window[method]('focus', this._handleWindowBlur, {
|
|
1854
|
+
capture: false,
|
|
1855
|
+
passive: true
|
|
1856
|
+
});
|
|
1857
|
+
window[method]('blur', this._handleWindowBlur, {
|
|
1858
|
+
capture: false,
|
|
1859
|
+
passive: true
|
|
1757
1860
|
});
|
|
1861
|
+
if (this.animateOnScroll) {
|
|
1862
|
+
window[method]('scroll', this._handleScroll, {
|
|
1863
|
+
capture: true,
|
|
1864
|
+
passive: true
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1758
1867
|
}
|
|
1759
1868
|
/**
|
|
1760
|
-
*
|
|
1761
|
-
*/
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1869
|
+
* Toggle show Settings.
|
|
1870
|
+
*/ _toggleSettings(flag) {
|
|
1871
|
+
if (flag === undefined) {
|
|
1872
|
+
this._isSettingsOpen = !this._isSettingsOpen;
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
this._isSettingsOpen = flag;
|
|
1765
1876
|
}
|
|
1766
1877
|
}
|
|
1767
1878
|
|
|
1768
1879
|
/**
|
|
1769
|
-
* Expose DotLottiePlayer class as global variable
|
|
1770
|
-
*
|
|
1880
|
+
* Expose DotLottiePlayer class as global variable.
|
|
1881
|
+
*
|
|
1771
1882
|
*/ globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
|
|
1772
1883
|
const tagName = 'dotlottie-player';
|
|
1773
1884
|
if (!isServer()) {
|
|
1774
|
-
customElements.define(
|
|
1885
|
+
customElements.define(tagName, DotLottiePlayer);
|
|
1775
1886
|
}
|
|
1776
1887
|
|
|
1777
1888
|
export { PlayMode, PlayerEvents, PlayerState, DotLottiePlayer as default, tagName };
|