@aarsteinmedia/dotlottie-player 5.0.1 → 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 +6 -0
- package/custom-elements.json +237 -284
- package/dist/index.d.ts +134 -125
- package/dist/index.js +1364 -1287
- package/dist/unpkg.js +2 -0
- package/package.json +20 -23
- package/dist/unpkg/index.js +0 -2
package/dist/index.js
CHANGED
|
@@ -1,13 +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
|
-
|
|
3
|
-
|
|
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
|
+
}
|
|
4
63
|
|
|
5
64
|
var ObjectFit = /*#__PURE__*/ function(ObjectFit) {
|
|
6
65
|
ObjectFit["Contain"] = "contain";
|
|
7
66
|
ObjectFit["Cover"] = "cover";
|
|
8
67
|
ObjectFit["Fill"] = "fill";
|
|
9
|
-
ObjectFit["ScaleDown"] = "scale-down";
|
|
10
68
|
ObjectFit["None"] = "none";
|
|
69
|
+
ObjectFit["ScaleDown"] = "scale-down";
|
|
11
70
|
return ObjectFit;
|
|
12
71
|
}({});
|
|
13
72
|
var PlayerState = /*#__PURE__*/ function(PlayerState) {
|
|
@@ -46,20 +105,298 @@ var PlayerEvents = /*#__PURE__*/ function(PlayerEvents) {
|
|
|
46
105
|
var PreserveAspectRatio = /*#__PURE__*/ function(PreserveAspectRatio) {
|
|
47
106
|
PreserveAspectRatio["Contain"] = "xMidYMid meet";
|
|
48
107
|
PreserveAspectRatio["Cover"] = "xMidYMid slice";
|
|
49
|
-
PreserveAspectRatio["None"] = "xMinYMin slice";
|
|
50
108
|
PreserveAspectRatio["Initial"] = "none";
|
|
109
|
+
PreserveAspectRatio["None"] = "xMinYMin slice";
|
|
51
110
|
return PreserveAspectRatio;
|
|
52
111
|
}({});
|
|
53
112
|
var RendererType = /*#__PURE__*/ function(RendererType) {
|
|
54
|
-
RendererType["SVG"] = "svg";
|
|
55
|
-
RendererType["HTML"] = "html";
|
|
56
113
|
RendererType["Canvas"] = "canvas";
|
|
114
|
+
RendererType["HTML"] = "html";
|
|
115
|
+
RendererType["SVG"] = "svg";
|
|
57
116
|
return RendererType;
|
|
58
117
|
}({});
|
|
59
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
|
+
}
|
|
194
|
+
|
|
60
195
|
class CustomError extends Error {
|
|
61
196
|
}
|
|
62
|
-
|
|
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)=>{
|
|
63
400
|
if (!str) {
|
|
64
401
|
return;
|
|
65
402
|
}
|
|
@@ -74,30 +411,59 @@ const addExt = (ext, str)=>{
|
|
|
74
411
|
switch(objectFit){
|
|
75
412
|
case ObjectFit.Contain:
|
|
76
413
|
case ObjectFit.ScaleDown:
|
|
77
|
-
|
|
414
|
+
{
|
|
415
|
+
return PreserveAspectRatio$1.Contain;
|
|
416
|
+
}
|
|
78
417
|
case ObjectFit.Cover:
|
|
79
|
-
|
|
418
|
+
{
|
|
419
|
+
return PreserveAspectRatio$1.Cover;
|
|
420
|
+
}
|
|
80
421
|
case ObjectFit.Fill:
|
|
81
|
-
|
|
422
|
+
{
|
|
423
|
+
return PreserveAspectRatio$1.Initial;
|
|
424
|
+
}
|
|
82
425
|
case ObjectFit.None:
|
|
83
|
-
|
|
426
|
+
{
|
|
427
|
+
return PreserveAspectRatio$1.None;
|
|
428
|
+
}
|
|
84
429
|
default:
|
|
85
|
-
|
|
430
|
+
{
|
|
431
|
+
return PreserveAspectRatio$1.Contain;
|
|
432
|
+
}
|
|
86
433
|
}
|
|
87
434
|
}, /**
|
|
88
|
-
* Convert Base64 encoded string to Uint8Array
|
|
89
|
-
*
|
|
90
|
-
* @
|
|
91
|
-
|
|
92
|
-
|
|
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
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return res;
|
|
456
|
+
}, /**
|
|
457
|
+
* Convert a JSON Lottie to dotLottie or combine several animations and download new dotLottie file in your browser.
|
|
93
458
|
*/ createDotLottie = async ({ animations = [], fileName, manifest, shouldDownload = true })=>{
|
|
94
459
|
try {
|
|
95
460
|
// Input validation
|
|
96
|
-
if (
|
|
97
|
-
throw new Error(`Missing or malformed required parameter(s):\n ${animations.length ? '- manifest\n' : ''} ${manifest ? '- animations\n' : ''}`);
|
|
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' : ''}`);
|
|
98
463
|
}
|
|
99
|
-
const manifestCompressionLevel = 0, animationCompressionLevel = 9,
|
|
100
|
-
|
|
464
|
+
const manifestCompressionLevel = 0, animationCompressionLevel = 9, /**
|
|
465
|
+
* Prepare the dotLottie file.
|
|
466
|
+
*/ name = addExt('lottie', fileName) || `${createElementID()}.lottie`, dotlottie = {
|
|
101
467
|
'manifest.json': [
|
|
102
468
|
strToU8(JSON.stringify(manifest), true),
|
|
103
469
|
{
|
|
@@ -109,30 +475,53 @@ const addExt = (ext, str)=>{
|
|
|
109
475
|
const { length } = animations;
|
|
110
476
|
for(let i = 0; i < length; i++){
|
|
111
477
|
const { length: jLen } = animations[i].assets;
|
|
478
|
+
// Prepare assets
|
|
112
479
|
for(let j = 0; j < jLen; j++){
|
|
113
|
-
|
|
480
|
+
const asset = animations[i].assets[j];
|
|
481
|
+
if (!asset.p || !isImage(asset) && !isAudio(asset)) {
|
|
114
482
|
continue;
|
|
115
483
|
}
|
|
116
|
-
const { p: file, u: path } =
|
|
484
|
+
const { p: file, u: path } = asset;
|
|
117
485
|
if (!file) {
|
|
118
486
|
continue;
|
|
119
487
|
}
|
|
120
488
|
// Original asset.id caused issues with multianimations
|
|
121
|
-
const assetId = createElementID(), isEncoded = file.startsWith('data:'), ext = isEncoded ? getExtFromB64(file) : getExt(file),
|
|
122
|
-
|
|
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);
|
|
492
|
+
// Asset is encoded
|
|
493
|
+
// eslint-disable-next-line require-atomic-updates
|
|
494
|
+
animations[i].assets[j].e = 1;
|
|
495
|
+
// eslint-disable-next-line require-atomic-updates
|
|
123
496
|
animations[i].assets[j].p = `${assetId}.${ext}`;
|
|
124
497
|
// Asset is embedded, so path empty string
|
|
498
|
+
// eslint-disable-next-line require-atomic-updates
|
|
125
499
|
animations[i].assets[j].u = '';
|
|
126
|
-
|
|
127
|
-
animations[i].assets[j].e = 1;
|
|
128
|
-
dotlottie[`${isAudio(animations[i].assets[j]) ? 'audio' : 'images'}/${assetId}.${ext}`] = [
|
|
500
|
+
dotlottie[`${isAudio(asset) ? 'audio' : 'images'}/${assetId}.${ext}`] = [
|
|
129
501
|
base64ToU8(dataURL),
|
|
130
502
|
{
|
|
131
503
|
level: animationCompressionLevel
|
|
132
504
|
}
|
|
133
505
|
];
|
|
134
506
|
}
|
|
135
|
-
|
|
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`] = [
|
|
136
525
|
strToU8(JSON.stringify(animations[i]), true),
|
|
137
526
|
{
|
|
138
527
|
level: animationCompressionLevel
|
|
@@ -140,62 +529,34 @@ const addExt = (ext, str)=>{
|
|
|
140
529
|
];
|
|
141
530
|
}
|
|
142
531
|
const buffer = await getArrayBuffer(dotlottie);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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;
|
|
149
543
|
}
|
|
150
544
|
}, createJSON = ({ animation, fileName, shouldDownload })=>{
|
|
151
545
|
try {
|
|
152
546
|
if (!animation) {
|
|
153
|
-
throw new Error(
|
|
547
|
+
throw new Error('createJSON: Missing or malformed required parameter(s):\n - animation\n\'');
|
|
154
548
|
}
|
|
155
549
|
const name = addExt('json', fileName) || `${createElementID()}.json`, jsonString = JSON.stringify(animation);
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
console.error(`❌ ${handleErrors(err).message}`);
|
|
162
|
-
}
|
|
163
|
-
}, /**
|
|
164
|
-
* Download file, either SVG or dotLottie.
|
|
165
|
-
* @param { string } data The data to be downloaded
|
|
166
|
-
* @param { string } name Don't include file extension in the filename
|
|
167
|
-
*/ download = (data, options)=>{
|
|
168
|
-
const blob = new Blob([
|
|
169
|
-
data
|
|
170
|
-
], {
|
|
171
|
-
type: options?.mimeType
|
|
172
|
-
}), fileName = options?.name || createElementID(), dataURL = URL.createObjectURL(blob), link = document.createElement('a');
|
|
173
|
-
link.href = dataURL;
|
|
174
|
-
link.download = fileName;
|
|
175
|
-
link.hidden = true;
|
|
176
|
-
document.body.appendChild(link);
|
|
177
|
-
link.click();
|
|
178
|
-
setTimeout(()=>{
|
|
179
|
-
link.remove();
|
|
180
|
-
URL.revokeObjectURL(dataURL);
|
|
181
|
-
}, 1000);
|
|
182
|
-
}, fileToBase64 = async (url)=>{
|
|
183
|
-
const response = await fetch(url), blob = await response.blob();
|
|
184
|
-
return new Promise((resolve, reject)=>{
|
|
185
|
-
try {
|
|
186
|
-
const reader = new FileReader();
|
|
187
|
-
reader.onload = ()=>{
|
|
188
|
-
if (typeof reader.result === 'string') {
|
|
189
|
-
resolve(reader.result);
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
reject();
|
|
193
|
-
};
|
|
194
|
-
reader.readAsDataURL(blob);
|
|
195
|
-
} catch (e) {
|
|
196
|
-
reject(e);
|
|
550
|
+
if (shouldDownload) {
|
|
551
|
+
download(jsonString, {
|
|
552
|
+
mimeType: 'application/json',
|
|
553
|
+
name
|
|
554
|
+
});
|
|
197
555
|
}
|
|
198
|
-
|
|
556
|
+
return;
|
|
557
|
+
} catch (error) {
|
|
558
|
+
console.error(`❌ ${handleErrors(error).message}`);
|
|
559
|
+
}
|
|
199
560
|
}, frameOutput = (frame)=>((frame ?? 0) + 1).toString().padStart(3, '0'), getAnimationData = async (input)=>{
|
|
200
561
|
try {
|
|
201
562
|
if (!input || typeof input !== 'string' && typeof input !== 'object') {
|
|
@@ -261,329 +622,264 @@ const addExt = (ext, str)=>{
|
|
|
261
622
|
isDotLottie: true,
|
|
262
623
|
manifest
|
|
263
624
|
};
|
|
264
|
-
} catch (
|
|
265
|
-
console.error(`❌ ${handleErrors(
|
|
625
|
+
} catch (error) {
|
|
626
|
+
console.error(`❌ ${handleErrors(error).message}`);
|
|
266
627
|
return {
|
|
267
628
|
animations: undefined,
|
|
268
629
|
isDotLottie: false,
|
|
269
630
|
manifest: null
|
|
270
631
|
};
|
|
271
632
|
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
if (err) {
|
|
278
|
-
reject(err);
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
if (!(data.buffer instanceof ArrayBuffer)) {
|
|
282
|
-
reject('Data is not transferable');
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
resolve(data.buffer);
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
return arrayBuffer;
|
|
289
|
-
}, /**
|
|
290
|
-
* Get extension from filename, URL or path
|
|
291
|
-
* @param { string } str Filename, URL or path
|
|
292
|
-
*/ getExt = (str)=>{
|
|
293
|
-
if (typeof str !== 'string' || !str || !hasExt(str)) {
|
|
294
|
-
return;
|
|
295
|
-
}
|
|
296
|
-
return str.split('.').pop()?.toLowerCase();
|
|
297
|
-
}, getExtFromB64 = (str)=>{
|
|
298
|
-
const mime = str.split(':')[1].split(';')[0], ext = mime.split('/')[1].split('+')[0];
|
|
299
|
-
return ext;
|
|
300
|
-
}, /**
|
|
301
|
-
* Parse URL to get filename
|
|
302
|
-
* @param { string } src The url string
|
|
303
|
-
* @param { boolean } keepExt Whether to include file extension
|
|
304
|
-
* @returns { string } Filename, in lowercase
|
|
305
|
-
*/ getFilename = (src, keepExt)=>{
|
|
306
|
-
// Because the regex strips all special characters, we need to extract the file extension, so we can add it later if we need it
|
|
307
|
-
getExt(src);
|
|
308
|
-
return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replace(/\W+/g, '-')}${''}` // .toLowerCase()
|
|
309
|
-
;
|
|
310
|
-
}, getLottieJSON = async (resp)=>{
|
|
311
|
-
const unzipped = await unzip(resp), manifest = getManifest(unzipped), data = [], toResolve = [], { length } = manifest.animations;
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* DotLottie Player Web Component.
|
|
637
|
+
*/ class DotLottiePlayer extends PropertyCallbackElement {
|
|
312
638
|
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
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
|
+
];
|
|
318
653
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
654
|
+
static get observedProperties() {
|
|
655
|
+
return [
|
|
656
|
+
'playerState',
|
|
657
|
+
'_isSettingsOpen',
|
|
658
|
+
'_seeker',
|
|
659
|
+
'_currentAnimation',
|
|
660
|
+
'_animations'
|
|
661
|
+
];
|
|
323
662
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
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
|
+
};
|
|
333
671
|
}
|
|
334
|
-
|
|
335
|
-
|
|
672
|
+
/**
|
|
673
|
+
* Whether to trigger next frame with scroll.
|
|
674
|
+
*/ set animateOnScroll(value) {
|
|
675
|
+
this.setAttribute('animateOnScroll', Boolean(value).toString());
|
|
336
676
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
case 'svg':
|
|
341
|
-
case 'svg+xml':
|
|
342
|
-
return 'image/svg+xml';
|
|
343
|
-
case 'jpg':
|
|
344
|
-
case 'jpeg':
|
|
345
|
-
return 'image/jpeg';
|
|
346
|
-
case 'png':
|
|
347
|
-
case 'gif':
|
|
348
|
-
case 'webp':
|
|
349
|
-
case 'avif':
|
|
350
|
-
return `image/${ext}`;
|
|
351
|
-
case 'mp3':
|
|
352
|
-
case 'mpeg':
|
|
353
|
-
case 'wav':
|
|
354
|
-
return `audio/${ext}`;
|
|
355
|
-
default:
|
|
356
|
-
return '';
|
|
677
|
+
get animateOnScroll() {
|
|
678
|
+
const val = this.getAttribute('animateOnScroll');
|
|
679
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
357
680
|
}
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
};
|
|
363
|
-
if (err && typeof err === 'object') {
|
|
364
|
-
if ('message' in err && typeof err.message === 'string') {
|
|
365
|
-
res.message = err.message;
|
|
366
|
-
}
|
|
367
|
-
if ('status' in err) {
|
|
368
|
-
res.status = Number(err.status);
|
|
369
|
-
}
|
|
681
|
+
/**
|
|
682
|
+
* Autoplay.
|
|
683
|
+
*/ set autoplay(value) {
|
|
684
|
+
this.setAttribute('autoplay', Boolean(value).toString());
|
|
370
685
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
return (lastDotIndex ?? 0) > 1 && path && path.length - 1 > (lastDotIndex ?? 0);
|
|
375
|
-
}, isAudio = (asset)=>!('h' in asset) && !('w' in asset) && 'p' in asset && 'e' in asset && 'u' in asset && 'id' in asset, isBase64 = (str)=>{
|
|
376
|
-
if (!str) {
|
|
377
|
-
return false;
|
|
686
|
+
get autoplay() {
|
|
687
|
+
const val = this.getAttribute('autoplay');
|
|
688
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
378
689
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return `${quote}${replacedContent}${quote}`;
|
|
384
|
-
}), resolveAssets = async (unzipped, assets)=>{
|
|
385
|
-
if (!Array.isArray(assets)) {
|
|
386
|
-
return;
|
|
690
|
+
/**
|
|
691
|
+
* Background color.
|
|
692
|
+
*/ set background(value) {
|
|
693
|
+
this.setAttribute('background', value);
|
|
387
694
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
if (!isAudio(assets[i]) && !isImage(assets[i])) {
|
|
391
|
-
continue;
|
|
392
|
-
}
|
|
393
|
-
const type = isImage(assets[i]) ? 'images' : 'audio', u8 = unzipped?.[`${type}/${assets[i].p}`];
|
|
394
|
-
if (!u8) {
|
|
395
|
-
continue;
|
|
396
|
-
}
|
|
397
|
-
toResolve.push(new Promise((resolveAsset)=>{
|
|
398
|
-
const assetB64 = isServer() ? Buffer.from(u8).toString('base64') : btoa(u8.reduce((dat, byte)=>`${dat}${String.fromCharCode(byte)}`, ''));
|
|
399
|
-
assets[i].p = assets[i].p?.startsWith('data:') || isBase64(assets[i].p) ? assets[i].p : `data:${getMimeFromExt(getExt(assets[i].p))};base64,${assetB64}`;
|
|
400
|
-
assets[i].e = 1;
|
|
401
|
-
assets[i].u = '';
|
|
402
|
-
resolveAsset();
|
|
403
|
-
}));
|
|
695
|
+
get background() {
|
|
696
|
+
return this.getAttribute('background') || 'transparent';
|
|
404
697
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (err) {
|
|
410
|
-
reject(err);
|
|
411
|
-
}
|
|
412
|
-
resolve(file);
|
|
413
|
-
});
|
|
414
|
-
});
|
|
415
|
-
return unzipped;
|
|
416
|
-
};
|
|
417
|
-
|
|
418
|
-
/**
|
|
419
|
-
* Render Player
|
|
420
|
-
*/ function renderPlayer() {
|
|
421
|
-
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>`;
|
|
422
|
-
this.shadow.adoptedStyleSheets = [
|
|
423
|
-
DotLottiePlayer.styles
|
|
424
|
-
];
|
|
425
|
-
this.shadow.appendChild(this.template.content.cloneNode(true));
|
|
426
|
-
}
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* Render Controls
|
|
430
|
-
*/ function renderControls() {
|
|
431
|
-
const slot = this.shadow.querySelector('slot[name=controls]');
|
|
432
|
-
if (!slot) {
|
|
433
|
-
return;
|
|
698
|
+
/**
|
|
699
|
+
* Show controls.
|
|
700
|
+
*/ set controls(value) {
|
|
701
|
+
this.setAttribute('controls', Boolean(value).toString());
|
|
434
702
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
return;
|
|
703
|
+
get controls() {
|
|
704
|
+
const val = this.getAttribute('controls');
|
|
705
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
438
706
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
707
|
+
/**
|
|
708
|
+
* Number of times to loop.
|
|
709
|
+
*/ set count(value) {
|
|
710
|
+
this.setAttribute('count', value.toString());
|
|
443
711
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
712
|
+
get count() {
|
|
713
|
+
const val = this.getAttribute('count');
|
|
714
|
+
if (val) {
|
|
715
|
+
return Number(val);
|
|
716
|
+
}
|
|
717
|
+
return 0;
|
|
447
718
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
719
|
+
/**
|
|
720
|
+
* Description for screen readers.
|
|
721
|
+
*/ set description(value) {
|
|
722
|
+
if (value) {
|
|
723
|
+
this.setAttribute('description', value);
|
|
724
|
+
}
|
|
451
725
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
next.onclick = this.next;
|
|
726
|
+
get description() {
|
|
727
|
+
return this.getAttribute('description');
|
|
455
728
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
729
|
+
/**
|
|
730
|
+
* Direction of animation.
|
|
731
|
+
*/ set direction(value) {
|
|
732
|
+
this.setAttribute('direction', value.toString());
|
|
460
733
|
}
|
|
461
|
-
|
|
462
|
-
const
|
|
463
|
-
if (
|
|
464
|
-
|
|
465
|
-
}
|
|
466
|
-
const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
|
|
467
|
-
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
468
|
-
toggleBoomerang.onclick = this.toggleBoomerang;
|
|
469
|
-
}
|
|
470
|
-
const convert = this.shadow.querySelector('.convert');
|
|
471
|
-
if (convert instanceof HTMLButtonElement) {
|
|
472
|
-
convert.onclick = this.convert;
|
|
734
|
+
get direction() {
|
|
735
|
+
const val = Number(this.getAttribute('direction'));
|
|
736
|
+
if (val === -1) {
|
|
737
|
+
return val;
|
|
473
738
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
739
|
+
return 1;
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Whether to play on mouseover.
|
|
743
|
+
*/ set hover(value) {
|
|
744
|
+
this.setAttribute('hover', value.toString());
|
|
745
|
+
}
|
|
746
|
+
get hover() {
|
|
747
|
+
const val = this.getAttribute('hover');
|
|
748
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Pause between loop intrations, in miliseconds.
|
|
752
|
+
*/ set intermission(value) {
|
|
753
|
+
this.setAttribute('intermission', value.toString());
|
|
754
|
+
}
|
|
755
|
+
get intermission() {
|
|
756
|
+
const val = Number(this.getAttribute('intermission'));
|
|
757
|
+
if (!isNaN(val)) {
|
|
758
|
+
return val;
|
|
477
759
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
760
|
+
return 0;
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Loop animation.
|
|
764
|
+
*/ set loop(value) {
|
|
765
|
+
this.setAttribute('loop', Boolean(value).toString());
|
|
766
|
+
}
|
|
767
|
+
get loop() {
|
|
768
|
+
const val = this.getAttribute('loop');
|
|
769
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
770
|
+
}
|
|
771
|
+
/**
|
|
772
|
+
* Play mode.
|
|
773
|
+
*/ set mode(value) {
|
|
774
|
+
this.setAttribute('mode', value.toString());
|
|
775
|
+
}
|
|
776
|
+
get mode() {
|
|
777
|
+
const val = this.getAttribute('mode');
|
|
778
|
+
if (val === PlayMode.Bounce) {
|
|
779
|
+
return val;
|
|
482
780
|
}
|
|
781
|
+
return PlayMode.Normal;
|
|
483
782
|
}
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
/**
|
|
496
|
-
* HTMLElement enhanced to track property changes
|
|
497
|
-
*/ class PropertyCallbackElement extends HTMLElement {
|
|
498
|
-
constructor(){
|
|
499
|
-
super();
|
|
500
|
-
const { observedProperties = [] } = this.constructor;
|
|
501
|
-
if (UPDATE_ON_CONNECTED in this) {
|
|
502
|
-
this[UPDATE_ON_CONNECTED] = [];
|
|
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;
|
|
503
792
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
const oldValue = this[CACHED_VALUE];
|
|
516
|
-
this[CACHED_VALUE] = value;
|
|
517
|
-
this.propertyChangedCallback(observedProperties[i], oldValue, value);
|
|
518
|
-
}
|
|
519
|
-
});
|
|
520
|
-
if (typeof initialValue !== 'undefined') {
|
|
521
|
-
if (UPDATE_ON_CONNECTED in this && Array.isArray(this[UPDATE_ON_CONNECTED])) {
|
|
522
|
-
this[UPDATE_ON_CONNECTED].push(observedProperties[i]);
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
|
-
}
|
|
793
|
+
return ObjectFit.Contain;
|
|
794
|
+
}
|
|
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;
|
|
526
804
|
}
|
|
805
|
+
return null;
|
|
527
806
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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;
|
|
532
816
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
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);
|
|
541
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');
|
|
542
856
|
}
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
var name="@aarsteinmedia/dotlottie-player";var version="5.0.1";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"};var dependencies={"@aarsteinmedia/lottie-web":"^0.2.21",fflate:"^0.8.2","lottie-web":"^5.13.0"};var peerDependencies={"@types/react":">= 16.0.0"};var devDependencies={"@custom-elements-manifest/analyzer":"^0.10.4","@eslint/compat":"^1.2.9","@eslint/js":"^9.27.0","@esm-bundle/chai":"4.3.4-fix.0","@open-wc/testing":"^4.0.0","@rollup/plugin-commonjs":"^28.0.3","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^16.0.1","@rollup/plugin-typescript":"^12.1.2","@swc/core":"^1.11.29","@types/mocha":"^10.0.10","@types/node":"^22.15.21","@types/path-browserify":"^1.0.3","@types/react":"^19.1.5","@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.2","@web/test-runner-playwright":"^0.11.0",autoprefixer:"^10.4.21",esbuild:"^0.25.4",eslint:"^9.27.0","eslint-config-prettier":"^10.1.5","eslint-import-resolver-typescript":"^4.3.5","eslint-plugin-import":"^2.31.0","eslint-plugin-jsdoc":"^50.6.17","eslint-plugin-perfectionist":"^4.13.0","eslint-plugin-prettier":"^5.4.0",globals:"^16.1.0","postcss-flexbugs-fixes":"^5.0.2",prettier:"^3.5.3",react:"^19.1.0",rimraf:"^6.0.1",rollup:"^4.41.0","rollup-plugin-dts":"^6.2.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.1","rollup-plugin-swc3":"^0.12.1","rollup-plugin-typescript-paths":"^1.5.0",stylelint:"^16.19.1","stylelint-config-recommended":"^16.0.0","tsc-alias":"^1.8.16",tslib:"^2.8.1",typescript:"^5.8.3","typescript-eslint":"^8.32.1"};var pnpm={onlyBuiltDependencies:["@parcel/watcher","@swc/core","esbuild","unrs-resolver"]};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};
|
|
546
|
-
|
|
547
|
-
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";
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
* dotLottie Player Web Component
|
|
551
|
-
* @export
|
|
552
|
-
* @class DotLottiePlayer
|
|
553
|
-
* @extends { EnhancedElement }
|
|
554
|
-
* @description Web Component for playing Lottie animations in your web app.
|
|
555
|
-
*/ class DotLottiePlayer extends PropertyCallbackElement {
|
|
556
857
|
constructor(){
|
|
557
|
-
super(),
|
|
558
|
-
*
|
|
559
|
-
*/ this._multiAnimationSettings = [], /**
|
|
560
|
-
* Animation Container
|
|
561
|
-
*/ this._container = null, /**
|
|
562
|
-
* @state
|
|
563
|
-
* Player state
|
|
858
|
+
super(), /**
|
|
859
|
+
* Player state.
|
|
564
860
|
*/ this.playerState = PlayerState.Loading, /**
|
|
565
|
-
*
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
* Seeker
|
|
570
|
-
*/ this._seeker = 0, /**
|
|
571
|
-
* @state
|
|
572
|
-
* Which animation to show, if several
|
|
573
|
-
*/ this._currentAnimation = 0, /**
|
|
574
|
-
* @state
|
|
575
|
-
* This is included in watched properties,
|
|
576
|
-
* so that next-button will show up
|
|
577
|
-
* on load, if controls are visible
|
|
578
|
-
*/ this._animations = [], this._lottieInstance = null, this._identifier = this.id || createElementID(), 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 = {
|
|
579
865
|
count: 0,
|
|
580
866
|
loaded: false,
|
|
581
867
|
prev: PlayerState.Loading,
|
|
582
868
|
scrollTimeout: null,
|
|
583
869
|
scrollY: 0,
|
|
584
870
|
visible: false
|
|
585
|
-
}, /**
|
|
586
|
-
*
|
|
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.
|
|
587
883
|
*/ this._handleSettingsClick = ({ target })=>{
|
|
588
884
|
this._toggleSettings();
|
|
589
885
|
// Because Safari does not add focus on click, we need to add it manually, so the onblur event will fire
|
|
@@ -622,55 +918,58 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
622
918
|
});
|
|
623
919
|
}
|
|
624
920
|
/**
|
|
625
|
-
*
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
this.
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
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
|
+
};
|
|
652
969
|
}
|
|
653
|
-
// Remove the attached Visibility API's change event listener
|
|
654
|
-
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
655
|
-
}
|
|
656
|
-
/**
|
|
657
|
-
* Attributes to observe
|
|
658
|
-
*/ static get observedAttributes() {
|
|
659
|
-
return [
|
|
660
|
-
'animateOnScroll',
|
|
661
|
-
'autoplay',
|
|
662
|
-
'controls',
|
|
663
|
-
'direction',
|
|
664
|
-
'hover',
|
|
665
|
-
'loop',
|
|
666
|
-
'mode',
|
|
667
|
-
'speed',
|
|
668
|
-
'src',
|
|
669
|
-
'subframe'
|
|
670
|
-
];
|
|
671
970
|
}
|
|
672
971
|
/**
|
|
673
|
-
* 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.
|
|
674
973
|
*/ async attributeChangedCallback(name, _oldValue, value) {
|
|
675
974
|
if (!this._lottieInstance) {
|
|
676
975
|
return;
|
|
@@ -701,7 +1000,8 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
701
1000
|
}
|
|
702
1001
|
if (name === 'direction') {
|
|
703
1002
|
if (Number(value) === -1) {
|
|
704
|
-
|
|
1003
|
+
this.setDirection(-1);
|
|
1004
|
+
return;
|
|
705
1005
|
}
|
|
706
1006
|
this.setDirection(1);
|
|
707
1007
|
}
|
|
@@ -715,14 +1015,14 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
715
1015
|
this._container.removeEventListener('mouseleave', this._mouseLeave);
|
|
716
1016
|
}
|
|
717
1017
|
if (name === 'loop') {
|
|
718
|
-
const toggleLoop = this.shadow
|
|
1018
|
+
const toggleLoop = this.shadow?.querySelector('.toggleLoop');
|
|
719
1019
|
if (toggleLoop instanceof HTMLButtonElement) {
|
|
720
1020
|
toggleLoop.dataset.active = value;
|
|
721
1021
|
}
|
|
722
1022
|
this.setLoop(value === '' || Boolean(value));
|
|
723
1023
|
}
|
|
724
1024
|
if (name === 'mode') {
|
|
725
|
-
const toggleBoomerang = this.shadow
|
|
1025
|
+
const toggleBoomerang = this.shadow?.querySelector('.toggleBoomerang');
|
|
726
1026
|
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
727
1027
|
toggleBoomerang.dataset.active = (value === PlayMode.Bounce).toString();
|
|
728
1028
|
}
|
|
@@ -741,759 +1041,189 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
741
1041
|
this.setSubframe(value === '' || Boolean(value));
|
|
742
1042
|
}
|
|
743
1043
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
'_currentAnimation',
|
|
750
|
-
'_animations'
|
|
751
|
-
];
|
|
752
|
-
}
|
|
753
|
-
// name: string, oldValue: string, newValue: string
|
|
754
|
-
propertyChangedCallback(name, _oldValue, value) {
|
|
1044
|
+
/**
|
|
1045
|
+
* Initialize everything on component first render.
|
|
1046
|
+
*/ async connectedCallback() {
|
|
1047
|
+
await super.connectedCallback();
|
|
1048
|
+
await this._render();
|
|
755
1049
|
if (!this.shadow) {
|
|
756
|
-
|
|
1050
|
+
throw new Error('Missing Shadow element');
|
|
757
1051
|
}
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
|
|
764
|
-
stop.dataset.active = (value === PlayerState.Stopped).toString();
|
|
765
|
-
if (value === PlayerState.Playing) {
|
|
766
|
-
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>`;
|
|
767
|
-
} else {
|
|
768
|
-
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>`;
|
|
769
|
-
}
|
|
770
|
-
}
|
|
771
|
-
if (name === '_seeker' && typeof value === 'number') {
|
|
772
|
-
seeker.value = value.toString();
|
|
773
|
-
seeker.ariaValueNow = value.toString();
|
|
774
|
-
progress.value = value;
|
|
775
|
-
}
|
|
776
|
-
if (name === '_animations' && Array.isArray(value)) {
|
|
777
|
-
if (this._currentAnimation + 1 < value.length) {
|
|
778
|
-
next.hidden = false;
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
if (name === '_currentAnimation' && typeof value === 'number') {
|
|
782
|
-
if (value + 1 >= this._animations.length) {
|
|
783
|
-
next.hidden = true;
|
|
784
|
-
} else {
|
|
785
|
-
next.hidden = false;
|
|
786
|
-
}
|
|
787
|
-
if (value) {
|
|
788
|
-
prev.hidden = false;
|
|
789
|
-
} else {
|
|
790
|
-
prev.hidden = true;
|
|
791
|
-
}
|
|
792
|
-
}
|
|
793
|
-
if (name === '_isSettingsOpen' && typeof value === 'boolean' && popover instanceof HTMLDivElement && convert instanceof HTMLButtonElement) {
|
|
794
|
-
popover.hidden = !value;
|
|
795
|
-
convert.hidden = this._isDotLottie;
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
/**
|
|
799
|
-
* Whether to trigger next frame with scroll
|
|
800
|
-
*/ set animateOnScroll(value) {
|
|
801
|
-
this.setAttribute('animateOnScroll', (!!value).toString());
|
|
802
|
-
}
|
|
803
|
-
get animateOnScroll() {
|
|
804
|
-
const val = this.getAttribute('animateOnScroll');
|
|
805
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
806
|
-
return true;
|
|
807
|
-
}
|
|
808
|
-
return false;
|
|
809
|
-
}
|
|
810
|
-
/**
|
|
811
|
-
* Autoplay
|
|
812
|
-
*/ set autoplay(value) {
|
|
813
|
-
this.setAttribute('autoplay', (!!value).toString());
|
|
814
|
-
}
|
|
815
|
-
get autoplay() {
|
|
816
|
-
const val = this.getAttribute('autoplay');
|
|
817
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
818
|
-
return true;
|
|
819
|
-
}
|
|
820
|
-
return false;
|
|
821
|
-
}
|
|
822
|
-
/**
|
|
823
|
-
* Background color
|
|
824
|
-
*/ set background(value) {
|
|
825
|
-
this.setAttribute('background', value);
|
|
826
|
-
}
|
|
827
|
-
get background() {
|
|
828
|
-
return this.getAttribute('background') || 'transparent';
|
|
829
|
-
}
|
|
830
|
-
/**
|
|
831
|
-
* Show controls
|
|
832
|
-
*/ set controls(value) {
|
|
833
|
-
this.setAttribute('controls', (!!value).toString());
|
|
834
|
-
}
|
|
835
|
-
get controls() {
|
|
836
|
-
const val = this.getAttribute('controls');
|
|
837
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
838
|
-
return true;
|
|
839
|
-
}
|
|
840
|
-
return false;
|
|
841
|
-
}
|
|
842
|
-
/**
|
|
843
|
-
* Number of times to loop
|
|
844
|
-
*/ set count(value) {
|
|
845
|
-
this.setAttribute('count', value.toString());
|
|
846
|
-
}
|
|
847
|
-
get count() {
|
|
848
|
-
const val = this.getAttribute('count');
|
|
849
|
-
if (val) {
|
|
850
|
-
return Number(val);
|
|
851
|
-
}
|
|
852
|
-
return 0;
|
|
853
|
-
}
|
|
854
|
-
/**
|
|
855
|
-
* Description for screen readers
|
|
856
|
-
*/ set description(value) {
|
|
857
|
-
if (value) {
|
|
858
|
-
this.setAttribute('description', value);
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
get description() {
|
|
862
|
-
return this.getAttribute('description');
|
|
863
|
-
}
|
|
864
|
-
/**
|
|
865
|
-
* Direction of animation
|
|
866
|
-
*/ set direction(value) {
|
|
867
|
-
this.setAttribute('direction', value.toString());
|
|
868
|
-
}
|
|
869
|
-
get direction() {
|
|
870
|
-
const val = Number(this.getAttribute('direction'));
|
|
871
|
-
if (val === -1) {
|
|
872
|
-
return val;
|
|
873
|
-
}
|
|
874
|
-
return 1;
|
|
875
|
-
}
|
|
876
|
-
/**
|
|
877
|
-
* Whether to play on mouseover
|
|
878
|
-
*/ set hover(value) {
|
|
879
|
-
this.setAttribute('hover', value.toString());
|
|
880
|
-
}
|
|
881
|
-
get hover() {
|
|
882
|
-
const val = this.getAttribute('hover');
|
|
883
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
884
|
-
return true;
|
|
885
|
-
}
|
|
886
|
-
return false;
|
|
887
|
-
}
|
|
888
|
-
/**
|
|
889
|
-
* Pause between loop intrations, in miliseconds
|
|
890
|
-
*/ set intermission(value) {
|
|
891
|
-
this.setAttribute('intermission', value.toString());
|
|
892
|
-
}
|
|
893
|
-
get intermission() {
|
|
894
|
-
const val = Number(this.getAttribute('intermission'));
|
|
895
|
-
if (!isNaN(val)) {
|
|
896
|
-
return val;
|
|
897
|
-
}
|
|
898
|
-
return 0;
|
|
899
|
-
}
|
|
900
|
-
/**
|
|
901
|
-
* Loop animation
|
|
902
|
-
*/ set loop(value) {
|
|
903
|
-
this.setAttribute('loop', (!!value).toString());
|
|
904
|
-
}
|
|
905
|
-
get loop() {
|
|
906
|
-
const val = this.getAttribute('loop');
|
|
907
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
908
|
-
return true;
|
|
909
|
-
}
|
|
910
|
-
return false;
|
|
911
|
-
}
|
|
912
|
-
/**
|
|
913
|
-
* Play mode
|
|
914
|
-
*/ set mode(value) {
|
|
915
|
-
this.setAttribute('mode', value.toString());
|
|
916
|
-
}
|
|
917
|
-
get mode() {
|
|
918
|
-
const val = this.getAttribute('mode');
|
|
919
|
-
if (val === PlayMode.Bounce) {
|
|
920
|
-
return val;
|
|
921
|
-
}
|
|
922
|
-
return PlayMode.Normal;
|
|
923
|
-
}
|
|
924
|
-
/**
|
|
925
|
-
* Resizing to container
|
|
926
|
-
*/ set objectfit(value) {
|
|
927
|
-
this.setAttribute('objectfit', value);
|
|
928
|
-
}
|
|
929
|
-
get objectfit() {
|
|
930
|
-
const val = this.getAttribute('objectfit');
|
|
931
|
-
if (val && Object.values(ObjectFit).includes(val)) {
|
|
932
|
-
return val;
|
|
933
|
-
}
|
|
934
|
-
return ObjectFit.Contain;
|
|
935
|
-
}
|
|
936
|
-
/**
|
|
937
|
-
* Resizing to container (Deprecated)
|
|
938
|
-
*/ set preserveAspectRatio(value) {
|
|
939
|
-
this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
|
|
940
|
-
}
|
|
941
|
-
get preserveAspectRatio() {
|
|
942
|
-
const val = this.getAttribute('preserveAspectRatio');
|
|
943
|
-
if (val && Object.values(PreserveAspectRatio).includes(val)) {
|
|
944
|
-
return val;
|
|
945
|
-
}
|
|
946
|
-
return null;
|
|
947
|
-
}
|
|
948
|
-
/**
|
|
949
|
-
* Renderer to use: svg, canvas or html
|
|
950
|
-
*/ set renderer(value) {
|
|
951
|
-
this.setAttribute('renderer', value);
|
|
952
|
-
}
|
|
953
|
-
get renderer() {
|
|
954
|
-
const val = this.getAttribute('renderer');
|
|
955
|
-
if (val === RendererType.Canvas || val === RendererType.HTML) {
|
|
956
|
-
return val;
|
|
957
|
-
}
|
|
958
|
-
return RendererType.SVG;
|
|
959
|
-
}
|
|
960
|
-
/**
|
|
961
|
-
* Hide advanced controls
|
|
962
|
-
*/ set simple(value) {
|
|
963
|
-
this.setAttribute('simple', value.toString());
|
|
964
|
-
}
|
|
965
|
-
get simple() {
|
|
966
|
-
const val = this.getAttribute('simple');
|
|
967
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
968
|
-
return true;
|
|
969
|
-
}
|
|
970
|
-
return false;
|
|
971
|
-
}
|
|
972
|
-
/**
|
|
973
|
-
* Speed
|
|
974
|
-
*/ set speed(value) {
|
|
975
|
-
this.setAttribute('speed', value?.toString());
|
|
976
|
-
}
|
|
977
|
-
get speed() {
|
|
978
|
-
const val = this.getAttribute('speed');
|
|
979
|
-
if (val !== null && !isNaN(Number(val))) {
|
|
980
|
-
return Number(val);
|
|
981
|
-
}
|
|
982
|
-
return 1;
|
|
983
|
-
}
|
|
984
|
-
/**
|
|
985
|
-
* Source, either path or JSON string
|
|
986
|
-
*/ set src(value) {
|
|
987
|
-
this.setAttribute('src', value || '');
|
|
988
|
-
}
|
|
989
|
-
get src() {
|
|
990
|
-
return this.getAttribute('src');
|
|
991
|
-
}
|
|
992
|
-
/**
|
|
993
|
-
* Subframe
|
|
994
|
-
*/ set subframe(value) {
|
|
995
|
-
this.setAttribute('subframe', (!!value).toString());
|
|
996
|
-
}
|
|
997
|
-
get subframe() {
|
|
998
|
-
const val = this.getAttribute('subframe');
|
|
999
|
-
if (val === 'true' || val === '' || val === '1') {
|
|
1000
|
-
return true;
|
|
1001
|
-
}
|
|
1002
|
-
return false;
|
|
1003
|
-
}
|
|
1004
|
-
/**
|
|
1005
|
-
* Get Multi-animation settings
|
|
1006
|
-
* @returns { AnimationSettings[] }
|
|
1007
|
-
*/ getMultiAnimationSettings() {
|
|
1008
|
-
return this._multiAnimationSettings;
|
|
1009
|
-
}
|
|
1010
|
-
/**
|
|
1011
|
-
* Set Multi-animation settings
|
|
1012
|
-
* @param { AnimationSettings[] } settings
|
|
1013
|
-
*/ setMultiAnimationSettings(settings) {
|
|
1014
|
-
this._multiAnimationSettings = settings;
|
|
1015
|
-
}
|
|
1016
|
-
/**
|
|
1017
|
-
* Set playback segment
|
|
1018
|
-
* @param { Vector2 } segment
|
|
1019
|
-
*/ setSegment(segment) {
|
|
1020
|
-
this._segment = segment;
|
|
1021
|
-
}
|
|
1022
|
-
/**
|
|
1023
|
-
* Get playback segment
|
|
1024
|
-
* @returns { Vector2 }
|
|
1025
|
-
*/ getSegment() {
|
|
1026
|
-
return this._segment;
|
|
1027
|
-
}
|
|
1028
|
-
/**
|
|
1029
|
-
* Get options from props
|
|
1030
|
-
* @returns { AnimationConfig }
|
|
1031
|
-
*/ _getOptions() {
|
|
1032
|
-
if (!this._container) {
|
|
1033
|
-
throw new Error('Container not rendered');
|
|
1034
|
-
}
|
|
1035
|
-
const preserveAspectRatio = this.preserveAspectRatio ?? (this.objectfit && aspectRatio(this.objectfit)), currentAnimationSettings = this._multiAnimationSettings?.length ? this._multiAnimationSettings?.[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest?.animations[this._currentAnimation];
|
|
1036
|
-
// Loop
|
|
1037
|
-
let loop = !!this.loop;
|
|
1038
|
-
if (currentAnimationManifest?.loop !== undefined && this.loop === undefined) {
|
|
1039
|
-
loop = !!currentAnimationManifest.loop;
|
|
1040
|
-
}
|
|
1041
|
-
if (currentAnimationSettings?.loop !== undefined) {
|
|
1042
|
-
loop = !!currentAnimationSettings.loop;
|
|
1043
|
-
}
|
|
1044
|
-
// Autoplay
|
|
1045
|
-
let autoplay = !!this.autoplay;
|
|
1046
|
-
if (currentAnimationManifest?.autoplay !== undefined && this.autoplay === undefined) {
|
|
1047
|
-
autoplay = !!currentAnimationManifest.autoplay;
|
|
1048
|
-
}
|
|
1049
|
-
if (currentAnimationSettings?.autoplay !== undefined) {
|
|
1050
|
-
autoplay = !!currentAnimationSettings.autoplay;
|
|
1051
|
-
}
|
|
1052
|
-
if (this.animateOnScroll) {
|
|
1053
|
-
autoplay = false;
|
|
1054
|
-
}
|
|
1055
|
-
// Segment
|
|
1056
|
-
let initialSegment = this._segment;
|
|
1057
|
-
if (this._segment?.every((val)=>val > 0)) {
|
|
1058
|
-
initialSegment = [
|
|
1059
|
-
this._segment[0] - 1,
|
|
1060
|
-
this._segment[1] - 1
|
|
1061
|
-
];
|
|
1062
|
-
}
|
|
1063
|
-
if (this._segment?.some((val)=>val < 0)) {
|
|
1064
|
-
initialSegment = undefined;
|
|
1065
|
-
}
|
|
1066
|
-
const options = {
|
|
1067
|
-
autoplay,
|
|
1068
|
-
container: this._container,
|
|
1069
|
-
initialSegment,
|
|
1070
|
-
loop,
|
|
1071
|
-
renderer: this.renderer,
|
|
1072
|
-
rendererSettings: {
|
|
1073
|
-
imagePreserveAspectRatio: preserveAspectRatio
|
|
1074
|
-
}
|
|
1075
|
-
};
|
|
1076
|
-
switch(this.renderer){
|
|
1077
|
-
case 'svg':
|
|
1078
|
-
options.rendererSettings = {
|
|
1079
|
-
...options.rendererSettings,
|
|
1080
|
-
hideOnTransparent: true,
|
|
1081
|
-
preserveAspectRatio,
|
|
1082
|
-
progressiveLoad: true
|
|
1083
|
-
};
|
|
1084
|
-
break;
|
|
1085
|
-
case 'canvas':
|
|
1086
|
-
options.rendererSettings = {
|
|
1087
|
-
...options.rendererSettings,
|
|
1088
|
-
clearCanvas: true,
|
|
1089
|
-
// @ts-expect-error TODO:
|
|
1090
|
-
preserveAspectRatio,
|
|
1091
|
-
progressiveLoad: true
|
|
1092
|
-
};
|
|
1093
|
-
break;
|
|
1094
|
-
case 'html':
|
|
1095
|
-
options.rendererSettings = {
|
|
1096
|
-
...options.rendererSettings,
|
|
1097
|
-
hideOnTransparent: true
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
return options;
|
|
1101
|
-
}
|
|
1102
|
-
/**
|
|
1103
|
-
* Add IntersectionObserver
|
|
1104
|
-
*/ _addIntersectionObserver() {
|
|
1105
|
-
if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
|
|
1106
|
-
return;
|
|
1107
|
-
}
|
|
1108
|
-
this._intersectionObserver = new IntersectionObserver((entries)=>{
|
|
1109
|
-
const { length } = entries;
|
|
1110
|
-
for(let i = 0; i < length; i++){
|
|
1111
|
-
if (!entries[i].isIntersecting || document.hidden) {
|
|
1112
|
-
if (this.playerState === PlayerState.Playing) {
|
|
1113
|
-
this._freeze();
|
|
1114
|
-
}
|
|
1115
|
-
this._playerState.visible = false;
|
|
1116
|
-
continue;
|
|
1117
|
-
}
|
|
1118
|
-
if (!this.animateOnScroll && this.playerState === PlayerState.Frozen) {
|
|
1119
|
-
this.play();
|
|
1120
|
-
}
|
|
1121
|
-
if (!this._playerState.scrollY) {
|
|
1122
|
-
this._playerState.scrollY = scrollY;
|
|
1123
|
-
}
|
|
1124
|
-
this._playerState.visible = true;
|
|
1125
|
-
}
|
|
1126
|
-
});
|
|
1127
|
-
this._intersectionObserver.observe(this._container);
|
|
1128
|
-
}
|
|
1129
|
-
/**
|
|
1130
|
-
* Initialize Lottie Web player
|
|
1131
|
-
*/ async load(src) {
|
|
1132
|
-
if (!this.shadowRoot || !src) {
|
|
1133
|
-
return;
|
|
1134
|
-
}
|
|
1135
|
-
// Load the resource
|
|
1136
|
-
try {
|
|
1137
|
-
const { animations, isDotLottie, manifest } = await getAnimationData(src);
|
|
1138
|
-
if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
|
|
1139
|
-
throw new Error('Broken or corrupted file');
|
|
1140
|
-
}
|
|
1141
|
-
this._isBounce = this.mode === PlayMode.Bounce;
|
|
1142
|
-
if (this._multiAnimationSettings?.length) {
|
|
1143
|
-
if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1144
|
-
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
this._isDotLottie = !!isDotLottie;
|
|
1148
|
-
this._animations = animations;
|
|
1149
|
-
this._manifest = manifest ?? {
|
|
1150
|
-
animations: [
|
|
1151
|
-
{
|
|
1152
|
-
autoplay: !this.animateOnScroll && this.autoplay,
|
|
1153
|
-
direction: this.direction,
|
|
1154
|
-
id: createElementID(),
|
|
1155
|
-
loop: this.loop,
|
|
1156
|
-
mode: this.mode,
|
|
1157
|
-
speed: this.speed
|
|
1158
|
-
}
|
|
1159
|
-
]
|
|
1160
|
-
};
|
|
1161
|
-
// Clear previous animation, if any
|
|
1162
|
-
if (this._lottieInstance) {
|
|
1163
|
-
this._lottieInstance.destroy();
|
|
1164
|
-
}
|
|
1165
|
-
this.playerState = PlayerState.Stopped;
|
|
1166
|
-
if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings?.[this._currentAnimation]?.autoplay)) {
|
|
1167
|
-
this.playerState = PlayerState.Playing;
|
|
1168
|
-
}
|
|
1169
|
-
// Initialize lottie player and load animation
|
|
1170
|
-
// @ts-expect-error TODO:
|
|
1171
|
-
this._lottieInstance = Lottie.default.loadAnimation({
|
|
1172
|
-
...this._getOptions(),
|
|
1173
|
-
animationData: animations[this._currentAnimation]
|
|
1174
|
-
});
|
|
1175
|
-
} catch (err) {
|
|
1176
|
-
this._errorMessage = handleErrors(err).message;
|
|
1177
|
-
this.playerState = PlayerState.Error;
|
|
1178
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1179
|
-
return;
|
|
1180
|
-
}
|
|
1181
|
-
this._addEventListeners();
|
|
1182
|
-
const speed = this._multiAnimationSettings?.[this._currentAnimation]?.speed ?? this.speed ?? this._manifest?.animations[this._currentAnimation].speed, direction = this._multiAnimationSettings?.[this._currentAnimation]?.direction ?? this.direction ?? this._manifest?.animations[this._currentAnimation].direction ?? 1;
|
|
1183
|
-
// Set initial playback speed and direction
|
|
1184
|
-
this._lottieInstance.setSpeed(speed);
|
|
1185
|
-
this._lottieInstance.setDirection(direction);
|
|
1186
|
-
this._lottieInstance.setSubframe(!!this.subframe);
|
|
1187
|
-
// Start playing if autoplay is enabled
|
|
1188
|
-
if (this.autoplay || this.animateOnScroll) {
|
|
1189
|
-
if (this.direction === -1) {
|
|
1190
|
-
this.seek('99%');
|
|
1191
|
-
}
|
|
1192
|
-
if (!('IntersectionObserver' in window)) {
|
|
1193
|
-
if (!this.animateOnScroll) {
|
|
1194
|
-
this.play();
|
|
1195
|
-
}
|
|
1196
|
-
this._playerState.visible = true;
|
|
1197
|
-
}
|
|
1198
|
-
this._addIntersectionObserver();
|
|
1199
|
-
}
|
|
1200
|
-
}
|
|
1201
|
-
/**
|
|
1202
|
-
* Get Lottie Manifest
|
|
1203
|
-
*/ getManifest() {
|
|
1204
|
-
return this._manifest;
|
|
1205
|
-
}
|
|
1206
|
-
/**
|
|
1207
|
-
* Toggle event listeners
|
|
1208
|
-
*/ _toggleEventListeners(action) {
|
|
1209
|
-
const method = action === 'add' ? 'addEventListener' : 'removeEventListener';
|
|
1210
|
-
if (this._lottieInstance) {
|
|
1211
|
-
this._lottieInstance[method]('enterFrame', this._enterFrame);
|
|
1212
|
-
this._lottieInstance[method]('complete', this._complete);
|
|
1213
|
-
this._lottieInstance[method]('loopComplete', this._loopComplete);
|
|
1214
|
-
this._lottieInstance[method]('DOMLoaded', this._DOMLoaded);
|
|
1215
|
-
this._lottieInstance[method]('data_ready', this._dataReady);
|
|
1216
|
-
this._lottieInstance[method]('data_failed', this._dataFailed);
|
|
1217
|
-
}
|
|
1218
|
-
if (this._container && this.hover) {
|
|
1219
|
-
this._container[method]('mouseenter', this._mouseEnter);
|
|
1220
|
-
this._container[method]('mouseleave', this._mouseLeave);
|
|
1221
|
-
}
|
|
1222
|
-
window[method]('focus', this._handleWindowBlur, {
|
|
1223
|
-
capture: false,
|
|
1224
|
-
passive: true
|
|
1225
|
-
});
|
|
1226
|
-
window[method]('blur', this._handleWindowBlur, {
|
|
1227
|
-
capture: false,
|
|
1228
|
-
passive: true
|
|
1229
|
-
});
|
|
1230
|
-
if (this.animateOnScroll) {
|
|
1231
|
-
window[method]('scroll', this._handleScroll, {
|
|
1232
|
-
capture: true,
|
|
1233
|
-
passive: true
|
|
1234
|
-
});
|
|
1235
|
-
}
|
|
1236
|
-
}
|
|
1237
|
-
/**
|
|
1238
|
-
* Add event listeners
|
|
1239
|
-
*/ _addEventListeners() {
|
|
1240
|
-
this._toggleEventListeners('add');
|
|
1241
|
-
}
|
|
1242
|
-
/**
|
|
1243
|
-
* Remove event listeners
|
|
1244
|
-
*/ _removeEventListeners() {
|
|
1245
|
-
this._toggleEventListeners('remove');
|
|
1246
|
-
}
|
|
1247
|
-
_loopComplete() {
|
|
1248
|
-
if (!this._lottieInstance) {
|
|
1249
|
-
return;
|
|
1250
|
-
}
|
|
1251
|
-
const { playDirection, // firstFrame,
|
|
1252
|
-
totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
|
|
1253
|
-
if (this.count) {
|
|
1254
|
-
if (this._isBounce) {
|
|
1255
|
-
this._playerState.count += 0.5;
|
|
1256
|
-
} else {
|
|
1257
|
-
this._playerState.count += 1;
|
|
1258
|
-
}
|
|
1259
|
-
if (this._playerState.count >= this.count) {
|
|
1260
|
-
this.setLoop(false);
|
|
1261
|
-
this.playerState = PlayerState.Completed;
|
|
1262
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete));
|
|
1263
|
-
return;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Loop));
|
|
1267
|
-
if (this._isBounce) {
|
|
1268
|
-
this._lottieInstance.goToAndStop(playDirection === -1 ? inPoint : outPoint * 0.99, true);
|
|
1269
|
-
this._lottieInstance.setDirection(playDirection * -1);
|
|
1270
|
-
return setTimeout(()=>{
|
|
1271
|
-
if (!this.animateOnScroll) {
|
|
1272
|
-
this._lottieInstance?.play();
|
|
1273
|
-
}
|
|
1274
|
-
}, this.intermission);
|
|
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);
|
|
1275
1057
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
}, this.intermission);
|
|
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));
|
|
1282
1063
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
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');
|
|
1068
|
+
}
|
|
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
|
+
});
|
|
1285
1076
|
return;
|
|
1286
1077
|
}
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1078
|
+
let animations = animationsFromProps;
|
|
1079
|
+
if (!animations) {
|
|
1080
|
+
const animationData = await getAnimationData(src);
|
|
1081
|
+
animations = animationData.animations;
|
|
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
|
+
});
|
|
1295
1092
|
}
|
|
1296
|
-
|
|
1093
|
+
/**
|
|
1094
|
+
* Destroy animation and element.
|
|
1095
|
+
*/ destroy() {
|
|
1297
1096
|
if (!this._lottieInstance) {
|
|
1298
1097
|
return;
|
|
1299
1098
|
}
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
return this._switchInstance();
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
const { currentFrame, totalFrames } = this._lottieInstance;
|
|
1310
|
-
this._seeker = Math.round(currentFrame / totalFrames * 100);
|
|
1311
|
-
this.playerState = PlayerState.Completed;
|
|
1312
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete, {
|
|
1313
|
-
detail: {
|
|
1314
|
-
frame: currentFrame,
|
|
1315
|
-
seeker: this._seeker
|
|
1316
|
-
}
|
|
1317
|
-
}));
|
|
1318
|
-
}
|
|
1319
|
-
_DOMLoaded() {
|
|
1320
|
-
this._playerState.loaded = true;
|
|
1321
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Ready));
|
|
1322
|
-
}
|
|
1323
|
-
_dataReady() {
|
|
1324
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Load));
|
|
1325
|
-
}
|
|
1326
|
-
_dataFailed() {
|
|
1327
|
-
this.playerState = PlayerState.Error;
|
|
1328
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
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);
|
|
1329
1105
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1106
|
+
/**
|
|
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;
|
|
1333
1113
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1114
|
+
// Destroy the animation instance
|
|
1115
|
+
if (this._lottieInstance) {
|
|
1116
|
+
this._lottieInstance.destroy();
|
|
1336
1117
|
}
|
|
1118
|
+
// Remove the attached Visibility API's change event listener
|
|
1119
|
+
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
1337
1120
|
}
|
|
1338
1121
|
/**
|
|
1339
|
-
*
|
|
1340
|
-
*/
|
|
1341
|
-
|
|
1342
|
-
this.play();
|
|
1343
|
-
}
|
|
1122
|
+
* Returns the lottie-web instance used in the component.
|
|
1123
|
+
*/ getLottie() {
|
|
1124
|
+
return this._lottieInstance;
|
|
1344
1125
|
}
|
|
1345
1126
|
/**
|
|
1346
|
-
*
|
|
1347
|
-
*/
|
|
1348
|
-
|
|
1349
|
-
this.stop();
|
|
1350
|
-
}
|
|
1127
|
+
* Get Lottie Manifest.
|
|
1128
|
+
*/ getManifest() {
|
|
1129
|
+
return this._manifest;
|
|
1351
1130
|
}
|
|
1352
1131
|
/**
|
|
1353
|
-
*
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
if (this.playerState === PlayerState.Frozen) {
|
|
1360
|
-
this.play();
|
|
1361
|
-
}
|
|
1132
|
+
* Get Multi-animation settings.
|
|
1133
|
+
*
|
|
1134
|
+
*/ getMultiAnimationSettings() {
|
|
1135
|
+
return this._multiAnimationSettings;
|
|
1362
1136
|
}
|
|
1363
1137
|
/**
|
|
1364
|
-
*
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
}
|
|
1369
|
-
if (isServer()) {
|
|
1370
|
-
console.warn('DotLottie: Scroll animations might not work properly in a Server Side Rendering context. Try to wrap this in a client component.');
|
|
1371
|
-
return;
|
|
1372
|
-
}
|
|
1373
|
-
if (this._playerState.visible) {
|
|
1374
|
-
if (this._playerState.scrollTimeout) {
|
|
1375
|
-
clearTimeout(this._playerState.scrollTimeout);
|
|
1376
|
-
}
|
|
1377
|
-
this._playerState.scrollTimeout = setTimeout(()=>{
|
|
1378
|
-
this.playerState = PlayerState.Paused;
|
|
1379
|
-
}, 400);
|
|
1380
|
-
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;
|
|
1381
|
-
requestAnimationFrame(()=>{
|
|
1382
|
-
if (roundedScroll < (this._lottieInstance?.totalFrames ?? 0)) {
|
|
1383
|
-
this.playerState = PlayerState.Playing;
|
|
1384
|
-
this._lottieInstance?.goToAndStop(roundedScroll, true);
|
|
1385
|
-
} else {
|
|
1386
|
-
this.playerState = PlayerState.Paused;
|
|
1387
|
-
}
|
|
1388
|
-
});
|
|
1389
|
-
}
|
|
1138
|
+
* Get playback segment.
|
|
1139
|
+
*
|
|
1140
|
+
*/ getSegment() {
|
|
1141
|
+
return this._segment;
|
|
1390
1142
|
}
|
|
1391
1143
|
/**
|
|
1392
|
-
*
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
|
|
1144
|
+
* Initialize Lottie Web player.
|
|
1145
|
+
*/ async load(src) {
|
|
1146
|
+
if (!this.shadowRoot || !src) {
|
|
1396
1147
|
return;
|
|
1397
1148
|
}
|
|
1398
|
-
this.
|
|
1399
|
-
|
|
1400
|
-
_isLottie(json) {
|
|
1401
|
-
const mandatory = [
|
|
1402
|
-
'v',
|
|
1403
|
-
'ip',
|
|
1404
|
-
'op',
|
|
1405
|
-
'layers',
|
|
1406
|
-
'fr',
|
|
1407
|
-
'w',
|
|
1408
|
-
'h'
|
|
1409
|
-
];
|
|
1410
|
-
return mandatory.every((field)=>Object.prototype.hasOwnProperty.call(json, field));
|
|
1411
|
-
}
|
|
1412
|
-
/**
|
|
1413
|
-
* Creates a new dotLottie file, by combinig several animations
|
|
1414
|
-
* @param { [ AnimationConfig ] } configs
|
|
1415
|
-
* @param { string } fileName
|
|
1416
|
-
* @param { boolean } shouldDownload Whether to trigger a download in the browser.
|
|
1417
|
-
* If set to false the function returns an ArrayBuffer. Defaults to true.
|
|
1418
|
-
*
|
|
1419
|
-
*/ async addAnimation(configs, fileName, shouldDownload = true) {
|
|
1420
|
-
// Initialize meta object for animation, with fallbacks for
|
|
1421
|
-
// when the method is called indepenently
|
|
1422
|
-
const { animations = [], manifest = {
|
|
1423
|
-
animations: this.src ? [
|
|
1424
|
-
{
|
|
1425
|
-
id: this._identifier
|
|
1426
|
-
}
|
|
1427
|
-
] : []
|
|
1428
|
-
} } = this.src ? await getAnimationData(this.src) : {};
|
|
1149
|
+
this.source = src;
|
|
1150
|
+
// Load the resource
|
|
1429
1151
|
try {
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
manifest.animations = [
|
|
1443
|
-
...manifest.animations,
|
|
1152
|
+
const { animations, isDotLottie, manifest } = await getAnimationData(src);
|
|
1153
|
+
if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
|
|
1154
|
+
throw new Error('Broken or corrupted file');
|
|
1155
|
+
}
|
|
1156
|
+
this._isBounce = this.mode === PlayMode.Bounce;
|
|
1157
|
+
if (this._multiAnimationSettings.length > 0 && this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1158
|
+
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1159
|
+
}
|
|
1160
|
+
this._isDotLottie = Boolean(isDotLottie);
|
|
1161
|
+
this._animations = animations;
|
|
1162
|
+
this._manifest = manifest ?? {
|
|
1163
|
+
animations: [
|
|
1444
1164
|
{
|
|
1445
|
-
|
|
1165
|
+
autoplay: !this.animateOnScroll && this.autoplay,
|
|
1166
|
+
direction: this.direction,
|
|
1167
|
+
id: createElementID(),
|
|
1168
|
+
loop: this.loop,
|
|
1169
|
+
mode: this.mode,
|
|
1170
|
+
speed: this.speed
|
|
1446
1171
|
}
|
|
1447
|
-
]
|
|
1448
|
-
animations.push(...animationsToAdd);
|
|
1449
|
-
}
|
|
1450
|
-
return {
|
|
1451
|
-
result: await createDotLottie({
|
|
1452
|
-
animations,
|
|
1453
|
-
fileName,
|
|
1454
|
-
// @ts-expect-error TODO:
|
|
1455
|
-
manifest,
|
|
1456
|
-
shouldDownload
|
|
1457
|
-
}),
|
|
1458
|
-
success: true
|
|
1459
|
-
};
|
|
1460
|
-
} catch (err) {
|
|
1461
|
-
return {
|
|
1462
|
-
error: handleErrors(err).message,
|
|
1463
|
-
success: false
|
|
1172
|
+
]
|
|
1464
1173
|
};
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1174
|
+
// Clear previous animation, if any
|
|
1175
|
+
if (this._lottieInstance) {
|
|
1176
|
+
this._lottieInstance.destroy();
|
|
1177
|
+
}
|
|
1178
|
+
this.playerState = PlayerState.Stopped;
|
|
1179
|
+
if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings[this._currentAnimation]?.autoplay)) {
|
|
1180
|
+
this.playerState = PlayerState.Playing;
|
|
1181
|
+
}
|
|
1182
|
+
// Initialize lottie player and load animation
|
|
1183
|
+
// @ts-expect-error TODO:
|
|
1184
|
+
this._lottieInstance = Lottie.loadAnimation({
|
|
1185
|
+
...this._getOptions(),
|
|
1186
|
+
animationData: animations[this._currentAnimation]
|
|
1187
|
+
});
|
|
1188
|
+
} catch (error) {
|
|
1189
|
+
this._errorMessage = handleErrors(error).message;
|
|
1190
|
+
this.playerState = PlayerState.Error;
|
|
1191
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1476
1192
|
return;
|
|
1477
1193
|
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1194
|
+
this._addEventListeners();
|
|
1195
|
+
const speed = this._multiAnimationSettings[this._currentAnimation]?.speed ?? this.speed, direction = this._multiAnimationSettings[this._currentAnimation]?.direction ?? this.direction;
|
|
1196
|
+
// Set initial playback speed and direction
|
|
1197
|
+
this._lottieInstance.setSpeed(speed);
|
|
1198
|
+
this._lottieInstance.setDirection(direction);
|
|
1199
|
+
this._lottieInstance.setSubframe(Boolean(this.subframe));
|
|
1200
|
+
// Start playing if autoplay is enabled
|
|
1201
|
+
if (this.autoplay || this.animateOnScroll) {
|
|
1202
|
+
if (this.direction === -1) {
|
|
1203
|
+
this.seek('99%');
|
|
1204
|
+
}
|
|
1205
|
+
if (!('IntersectionObserver' in window)) {
|
|
1206
|
+
if (!this.animateOnScroll) {
|
|
1207
|
+
this.play();
|
|
1208
|
+
}
|
|
1209
|
+
this._playerState.visible = true;
|
|
1210
|
+
}
|
|
1211
|
+
this._addIntersectionObserver();
|
|
1486
1212
|
}
|
|
1487
1213
|
}
|
|
1488
1214
|
/**
|
|
1489
|
-
*
|
|
1215
|
+
* Skip to next animation.
|
|
1216
|
+
*/ next() {
|
|
1217
|
+
this._currentAnimation++;
|
|
1218
|
+
this._switchInstance();
|
|
1219
|
+
}
|
|
1220
|
+
/**
|
|
1221
|
+
* Pause.
|
|
1490
1222
|
*/ pause() {
|
|
1491
1223
|
if (!this._lottieInstance) {
|
|
1492
1224
|
return;
|
|
1493
1225
|
}
|
|
1494
|
-
|
|
1495
|
-
this._playerState.prev = this.playerState;
|
|
1496
|
-
}
|
|
1226
|
+
this._playerState.prev = this.playerState;
|
|
1497
1227
|
try {
|
|
1498
1228
|
this._lottieInstance.pause();
|
|
1499
1229
|
this.dispatchEvent(new CustomEvent(PlayerEvents.Pause));
|
|
@@ -1502,44 +1232,88 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1502
1232
|
}
|
|
1503
1233
|
}
|
|
1504
1234
|
/**
|
|
1505
|
-
*
|
|
1506
|
-
*/
|
|
1235
|
+
* Play.
|
|
1236
|
+
*/ play() {
|
|
1507
1237
|
if (!this._lottieInstance) {
|
|
1508
1238
|
return;
|
|
1509
1239
|
}
|
|
1510
|
-
|
|
1511
|
-
this._playerState.prev = this.playerState;
|
|
1512
|
-
}
|
|
1513
|
-
this._playerState.count = 0;
|
|
1240
|
+
this._playerState.prev = this.playerState;
|
|
1514
1241
|
try {
|
|
1515
|
-
this._lottieInstance.
|
|
1516
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.
|
|
1242
|
+
this._lottieInstance.play();
|
|
1243
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Play));
|
|
1517
1244
|
} finally{
|
|
1518
|
-
this.playerState = PlayerState.
|
|
1245
|
+
this.playerState = PlayerState.Playing;
|
|
1519
1246
|
}
|
|
1520
1247
|
}
|
|
1521
1248
|
/**
|
|
1522
|
-
*
|
|
1523
|
-
*/
|
|
1524
|
-
|
|
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) {
|
|
1258
|
+
return;
|
|
1259
|
+
}
|
|
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)) {
|
|
1262
|
+
return;
|
|
1263
|
+
}
|
|
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>`;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
if (name === '_seeker' && typeof value === 'number') {
|
|
1274
|
+
seeker.value = value.toString();
|
|
1275
|
+
seeker.ariaValueNow = value.toString();
|
|
1276
|
+
progress.value = value;
|
|
1277
|
+
}
|
|
1278
|
+
if (name === '_animations' && Array.isArray(value) && this._currentAnimation + 1 < value.length) {
|
|
1279
|
+
next.hidden = false;
|
|
1280
|
+
}
|
|
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
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
if (name === '_isSettingsOpen' && typeof value === 'boolean' && popover instanceof HTMLDivElement && convert instanceof HTMLButtonElement) {
|
|
1294
|
+
popover.hidden = !value;
|
|
1295
|
+
convert.hidden = this._isDotLottie;
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
/**
|
|
1299
|
+
* Reload animation.
|
|
1300
|
+
*/ async reload() {
|
|
1301
|
+
if (!this._lottieInstance || !this.src) {
|
|
1525
1302
|
return;
|
|
1526
1303
|
}
|
|
1527
|
-
this.playerState = PlayerState.Destroyed;
|
|
1528
1304
|
this._lottieInstance.destroy();
|
|
1529
|
-
this.
|
|
1530
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Destroyed));
|
|
1531
|
-
this.remove();
|
|
1532
|
-
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
1305
|
+
await this.load(this.src);
|
|
1533
1306
|
}
|
|
1534
1307
|
/**
|
|
1535
|
-
* Seek to a given frame
|
|
1536
|
-
*
|
|
1308
|
+
* Seek to a given frame.
|
|
1309
|
+
*
|
|
1310
|
+
* @param value - Frame to seek to.
|
|
1537
1311
|
*/ seek(value) {
|
|
1538
1312
|
if (!this._lottieInstance) {
|
|
1539
1313
|
return;
|
|
1540
1314
|
}
|
|
1541
1315
|
// Extract frame number from either number or percentage value
|
|
1542
|
-
const matches = value.toString().match(/^(
|
|
1316
|
+
const matches = value.toString().match(/^(\d+)(%?)$/);
|
|
1543
1317
|
if (!matches) {
|
|
1544
1318
|
return;
|
|
1545
1319
|
}
|
|
@@ -1557,7 +1331,63 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1557
1331
|
this._lottieInstance.pause();
|
|
1558
1332
|
}
|
|
1559
1333
|
/**
|
|
1560
|
-
*
|
|
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) {
|
|
1344
|
+
return;
|
|
1345
|
+
}
|
|
1346
|
+
this._lottieInstance.setDirection(value);
|
|
1347
|
+
}
|
|
1348
|
+
/**
|
|
1349
|
+
* Set loop.
|
|
1350
|
+
*
|
|
1351
|
+
*/ setLoop(value) {
|
|
1352
|
+
if (!this._lottieInstance) {
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
this._lottieInstance.setLoop(value);
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Set Multi-animation settings.
|
|
1359
|
+
*
|
|
1360
|
+
*/ setMultiAnimationSettings(settings) {
|
|
1361
|
+
this._multiAnimationSettings = settings;
|
|
1362
|
+
}
|
|
1363
|
+
/**
|
|
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) {
|
|
1374
|
+
if (!this._lottieInstance) {
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
this._lottieInstance.setSpeed(value);
|
|
1378
|
+
}
|
|
1379
|
+
/**
|
|
1380
|
+
* Toggles subframe, for more smooth animations.
|
|
1381
|
+
*
|
|
1382
|
+
* @param value - Whether animation uses subframe.
|
|
1383
|
+
*/ setSubframe(value) {
|
|
1384
|
+
if (!this._lottieInstance) {
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
this._lottieInstance.setSubframe(value);
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Snapshot and download the current frame as SVG.
|
|
1561
1391
|
*/ snapshot(shouldDownload = true, name = 'AM Lottie') {
|
|
1562
1392
|
try {
|
|
1563
1393
|
if (!this.shadowRoot) {
|
|
@@ -1579,144 +1409,388 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1579
1409
|
});
|
|
1580
1410
|
}
|
|
1581
1411
|
return data;
|
|
1582
|
-
} catch (
|
|
1583
|
-
console.error(
|
|
1412
|
+
} catch (error) {
|
|
1413
|
+
console.error(error);
|
|
1584
1414
|
return null;
|
|
1585
1415
|
}
|
|
1586
1416
|
}
|
|
1587
|
-
/**
|
|
1588
|
-
*
|
|
1589
|
-
|
|
1590
|
-
|
|
1417
|
+
/**
|
|
1418
|
+
* Stop.
|
|
1419
|
+
*/ stop() {
|
|
1420
|
+
if (!this._lottieInstance) {
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
this._playerState.prev = this.playerState;
|
|
1424
|
+
this._playerState.count = 0;
|
|
1425
|
+
try {
|
|
1426
|
+
this._lottieInstance.stop();
|
|
1427
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Stop));
|
|
1428
|
+
} finally{
|
|
1429
|
+
this.playerState = PlayerState.Stopped;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
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;
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
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;
|
|
1453
|
+
}
|
|
1454
|
+
/**
|
|
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() {
|
|
1464
|
+
if (!this._lottieInstance) {
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1467
|
+
const { currentFrame, playDirection, totalFrames } = this._lottieInstance;
|
|
1468
|
+
if (this.playerState === PlayerState.Playing) {
|
|
1469
|
+
this.pause();
|
|
1470
|
+
return;
|
|
1471
|
+
}
|
|
1472
|
+
if (this.playerState !== PlayerState.Completed) {
|
|
1473
|
+
this.play();
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
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);
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
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;
|
|
1497
|
+
try {
|
|
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;
|
|
1548
|
+
}
|
|
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;
|
|
1560
|
+
}
|
|
1561
|
+
if (this.loop && this._currentAnimation === this._animations.length - 1) {
|
|
1562
|
+
this._currentAnimation = 0;
|
|
1563
|
+
this._switchInstance();
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
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));
|
|
1580
|
+
}
|
|
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() {
|
|
1591
1589
|
if (!this._lottieInstance) {
|
|
1592
1590
|
return;
|
|
1593
1591
|
}
|
|
1594
|
-
this._lottieInstance
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
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
|
+
}));
|
|
1600
1600
|
}
|
|
1601
1601
|
/**
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
return;
|
|
1602
|
+
* Get options from props.
|
|
1603
|
+
*
|
|
1604
|
+
*/ _getOptions() {
|
|
1605
|
+
if (!this._container) {
|
|
1606
|
+
throw new Error('Container not rendered');
|
|
1608
1607
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
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);
|
|
1611
1613
|
}
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Freeze));
|
|
1615
|
-
} finally{
|
|
1616
|
-
this.playerState = PlayerState.Frozen;
|
|
1614
|
+
if (currentAnimationSettings?.loop !== undefined) {
|
|
1615
|
+
hasLoop = Boolean(currentAnimationSettings.loop);
|
|
1617
1616
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
if (!this._lottieInstance || !this.src) {
|
|
1623
|
-
return;
|
|
1617
|
+
// Autoplay
|
|
1618
|
+
let hasAutoplay = Boolean(this.autoplay);
|
|
1619
|
+
if (currentAnimationManifest?.autoplay !== undefined) {
|
|
1620
|
+
hasAutoplay = Boolean(currentAnimationManifest.autoplay);
|
|
1624
1621
|
}
|
|
1625
|
-
|
|
1626
|
-
|
|
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;
|
|
1627
1680
|
}
|
|
1628
1681
|
/**
|
|
1629
|
-
*
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
if (!this._lottieInstance) {
|
|
1682
|
+
* Handle scroll.
|
|
1683
|
+
*/ _handleScroll() {
|
|
1684
|
+
if (!this.animateOnScroll || !this._lottieInstance) {
|
|
1633
1685
|
return;
|
|
1634
1686
|
}
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
/**
|
|
1638
|
-
* Animation play direction
|
|
1639
|
-
* @param { AnimationDirection } value Animation direction
|
|
1640
|
-
*/ setDirection(value) {
|
|
1641
|
-
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.');
|
|
1642
1689
|
return;
|
|
1643
1690
|
}
|
|
1644
|
-
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
|
+
}
|
|
1645
1708
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
if (
|
|
1651
|
-
|
|
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();
|
|
1652
1715
|
}
|
|
1653
|
-
this._lottieInstance.setLoop(value);
|
|
1654
1716
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
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() {
|
|
1658
1730
|
if (!this._lottieInstance) {
|
|
1659
1731
|
return;
|
|
1660
1732
|
}
|
|
1661
|
-
const {
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
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
|
+
}
|
|
1667
1747
|
}
|
|
1668
|
-
this.
|
|
1748
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Loop));
|
|
1669
1749
|
if (this._isBounce) {
|
|
1670
|
-
this.
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
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);
|
|
1675
1757
|
}
|
|
1676
|
-
|
|
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);
|
|
1677
1764
|
}
|
|
1678
1765
|
/**
|
|
1679
|
-
*
|
|
1680
|
-
*/
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1766
|
+
* Handle MouseEnter.
|
|
1767
|
+
*/ _mouseEnter() {
|
|
1768
|
+
if (this.hover && this.playerState !== PlayerState.Playing) {
|
|
1769
|
+
this.play();
|
|
1770
|
+
}
|
|
1684
1771
|
}
|
|
1685
1772
|
/**
|
|
1686
|
-
*
|
|
1687
|
-
*/
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
if (curr.mode === PlayMode.Normal) {
|
|
1691
|
-
curr.mode = PlayMode.Bounce;
|
|
1692
|
-
this._isBounce = true;
|
|
1693
|
-
return;
|
|
1694
|
-
}
|
|
1695
|
-
curr.mode = PlayMode.Normal;
|
|
1696
|
-
this._isBounce = false;
|
|
1697
|
-
return;
|
|
1698
|
-
}
|
|
1699
|
-
if (this.mode === PlayMode.Normal) {
|
|
1700
|
-
this.mode = PlayMode.Bounce;
|
|
1701
|
-
this._isBounce = true;
|
|
1702
|
-
return;
|
|
1773
|
+
* Handle MouseLeave.
|
|
1774
|
+
*/ _mouseLeave() {
|
|
1775
|
+
if (this.hover && this.playerState === PlayerState.Playing) {
|
|
1776
|
+
this.stop();
|
|
1703
1777
|
}
|
|
1704
|
-
this.mode = PlayMode.Normal;
|
|
1705
|
-
this._isBounce = false;
|
|
1706
1778
|
}
|
|
1707
1779
|
/**
|
|
1708
|
-
*
|
|
1709
|
-
*/
|
|
1710
|
-
if (
|
|
1711
|
-
this.
|
|
1780
|
+
* Handle visibility change events.
|
|
1781
|
+
*/ _onVisibilityChange() {
|
|
1782
|
+
if (document.hidden && this.playerState === PlayerState.Playing) {
|
|
1783
|
+
this._freeze();
|
|
1712
1784
|
return;
|
|
1713
1785
|
}
|
|
1714
|
-
this.
|
|
1786
|
+
if (this.playerState === PlayerState.Frozen) {
|
|
1787
|
+
this.play();
|
|
1788
|
+
}
|
|
1715
1789
|
}
|
|
1716
1790
|
/**
|
|
1717
|
-
*
|
|
1718
|
-
*/
|
|
1719
|
-
|
|
1791
|
+
* Remove event listeners.
|
|
1792
|
+
*/ _removeEventListeners() {
|
|
1793
|
+
this._toggleEventListeners('remove');
|
|
1720
1794
|
}
|
|
1721
1795
|
_switchInstance(isPrevious = false) {
|
|
1722
1796
|
// Bail early if there is not animation to play
|
|
@@ -1730,82 +1804,85 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1730
1804
|
}
|
|
1731
1805
|
// Re-initialize lottie player
|
|
1732
1806
|
// @ts-expect-error TODO:
|
|
1733
|
-
this._lottieInstance = Lottie.
|
|
1807
|
+
this._lottieInstance = Lottie.loadAnimation({
|
|
1734
1808
|
...this._getOptions(),
|
|
1735
1809
|
animationData: this._animations[this._currentAnimation]
|
|
1736
1810
|
});
|
|
1737
1811
|
// Check play mode for current animation
|
|
1738
|
-
if (this._multiAnimationSettings
|
|
1812
|
+
if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1739
1813
|
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1740
1814
|
}
|
|
1741
1815
|
// Remove event listeners to new Lottie instance, and add new
|
|
1742
1816
|
this._removeEventListeners();
|
|
1743
1817
|
this._addEventListeners();
|
|
1744
1818
|
this.dispatchEvent(new CustomEvent(isPrevious ? PlayerEvents.Previous : PlayerEvents.Next));
|
|
1745
|
-
if (this._multiAnimationSettings
|
|
1819
|
+
if (this._multiAnimationSettings[this._currentAnimation]?.autoplay ?? this.autoplay) {
|
|
1746
1820
|
if (this.animateOnScroll) {
|
|
1747
|
-
this._lottieInstance
|
|
1821
|
+
this._lottieInstance.goToAndStop(0, true);
|
|
1748
1822
|
this.playerState = PlayerState.Paused;
|
|
1749
1823
|
return;
|
|
1750
1824
|
}
|
|
1751
|
-
this._lottieInstance
|
|
1825
|
+
this._lottieInstance.goToAndPlay(0, true);
|
|
1752
1826
|
this.playerState = PlayerState.Playing;
|
|
1753
1827
|
return;
|
|
1754
1828
|
}
|
|
1755
|
-
this._lottieInstance
|
|
1829
|
+
this._lottieInstance.goToAndStop(0, true);
|
|
1756
1830
|
this.playerState = PlayerState.Stopped;
|
|
1757
|
-
} catch (
|
|
1758
|
-
this._errorMessage = handleErrors(
|
|
1831
|
+
} catch (error) {
|
|
1832
|
+
this._errorMessage = handleErrors(error).message;
|
|
1759
1833
|
this.playerState = PlayerState.Error;
|
|
1760
1834
|
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1761
1835
|
}
|
|
1762
1836
|
}
|
|
1763
1837
|
/**
|
|
1764
|
-
*
|
|
1765
|
-
*/
|
|
1766
|
-
|
|
1767
|
-
this.
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
}
|
|
1775
|
-
async convert({ animations, fileName, manifest, shouldDownload = true, src, typeCheck }) {
|
|
1776
|
-
if (typeCheck || this._isDotLottie) {
|
|
1777
|
-
return createJSON({
|
|
1778
|
-
animation: (await getAnimationData(src || this.src))?.animations?.[0],
|
|
1779
|
-
fileName: `${getFilename(fileName || this.src || 'converted')}.json`,
|
|
1780
|
-
shouldDownload
|
|
1781
|
-
});
|
|
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);
|
|
1782
1848
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
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
|
|
1791
1860
|
});
|
|
1861
|
+
if (this.animateOnScroll) {
|
|
1862
|
+
window[method]('scroll', this._handleScroll, {
|
|
1863
|
+
capture: true,
|
|
1864
|
+
passive: true
|
|
1865
|
+
});
|
|
1866
|
+
}
|
|
1792
1867
|
}
|
|
1793
1868
|
/**
|
|
1794
|
-
*
|
|
1795
|
-
*/
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1869
|
+
* Toggle show Settings.
|
|
1870
|
+
*/ _toggleSettings(flag) {
|
|
1871
|
+
if (flag === undefined) {
|
|
1872
|
+
this._isSettingsOpen = !this._isSettingsOpen;
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
this._isSettingsOpen = flag;
|
|
1799
1876
|
}
|
|
1800
1877
|
}
|
|
1801
1878
|
|
|
1802
1879
|
/**
|
|
1803
|
-
* Expose DotLottiePlayer class as global variable
|
|
1804
|
-
*
|
|
1880
|
+
* Expose DotLottiePlayer class as global variable.
|
|
1881
|
+
*
|
|
1805
1882
|
*/ globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
|
|
1806
1883
|
const tagName = 'dotlottie-player';
|
|
1807
1884
|
if (!isServer()) {
|
|
1808
|
-
customElements.define(
|
|
1885
|
+
customElements.define(tagName, DotLottiePlayer);
|
|
1809
1886
|
}
|
|
1810
1887
|
|
|
1811
1888
|
export { PlayMode, PlayerEvents, PlayerState, DotLottiePlayer as default, tagName };
|