@aarsteinmedia/dotlottie-player 5.0.1 → 5.0.3
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 +7 -0
- package/custom-elements.json +237 -284
- package/dist/index.d.ts +134 -125
- package/dist/index.js +1365 -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,265 @@ 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
|
-
|
|
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
|
+
const generator = '@aarsteinmedia/dotlottie-player';
|
|
636
|
+
/**
|
|
637
|
+
* DotLottie Player Web Component.
|
|
638
|
+
*/ class DotLottiePlayer extends PropertyCallbackElement {
|
|
312
639
|
/**
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
640
|
+
* Attributes to observe.
|
|
641
|
+
*/ static get observedAttributes() {
|
|
642
|
+
return [
|
|
643
|
+
'animateOnScroll',
|
|
644
|
+
'autoplay',
|
|
645
|
+
'controls',
|
|
646
|
+
'direction',
|
|
647
|
+
'hover',
|
|
648
|
+
'loop',
|
|
649
|
+
'mode',
|
|
650
|
+
'speed',
|
|
651
|
+
'src',
|
|
652
|
+
'subframe'
|
|
653
|
+
];
|
|
318
654
|
}
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
655
|
+
static get observedProperties() {
|
|
656
|
+
return [
|
|
657
|
+
'playerState',
|
|
658
|
+
'_isSettingsOpen',
|
|
659
|
+
'_seeker',
|
|
660
|
+
'_currentAnimation',
|
|
661
|
+
'_animations'
|
|
662
|
+
];
|
|
323
663
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
throw new Error('Manifest not found');
|
|
664
|
+
/**
|
|
665
|
+
* Return the styles for the component.
|
|
666
|
+
*/ static get styles() {
|
|
667
|
+
return async ()=>{
|
|
668
|
+
const styleSheet = new CSSStyleSheet();
|
|
669
|
+
await styleSheet.replace(css_248z);
|
|
670
|
+
return styleSheet;
|
|
671
|
+
};
|
|
333
672
|
}
|
|
334
|
-
|
|
335
|
-
|
|
673
|
+
/**
|
|
674
|
+
* Whether to trigger next frame with scroll.
|
|
675
|
+
*/ set animateOnScroll(value) {
|
|
676
|
+
this.setAttribute('animateOnScroll', Boolean(value).toString());
|
|
336
677
|
}
|
|
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 '';
|
|
678
|
+
get animateOnScroll() {
|
|
679
|
+
const val = this.getAttribute('animateOnScroll');
|
|
680
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
357
681
|
}
|
|
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
|
-
}
|
|
682
|
+
/**
|
|
683
|
+
* Autoplay.
|
|
684
|
+
*/ set autoplay(value) {
|
|
685
|
+
this.setAttribute('autoplay', Boolean(value).toString());
|
|
370
686
|
}
|
|
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;
|
|
687
|
+
get autoplay() {
|
|
688
|
+
const val = this.getAttribute('autoplay');
|
|
689
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
378
690
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
return `${quote}${replacedContent}${quote}`;
|
|
384
|
-
}), resolveAssets = async (unzipped, assets)=>{
|
|
385
|
-
if (!Array.isArray(assets)) {
|
|
386
|
-
return;
|
|
691
|
+
/**
|
|
692
|
+
* Background color.
|
|
693
|
+
*/ set background(value) {
|
|
694
|
+
this.setAttribute('background', value);
|
|
387
695
|
}
|
|
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
|
-
}));
|
|
696
|
+
get background() {
|
|
697
|
+
return this.getAttribute('background') || 'transparent';
|
|
404
698
|
}
|
|
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;
|
|
699
|
+
/**
|
|
700
|
+
* Show controls.
|
|
701
|
+
*/ set controls(value) {
|
|
702
|
+
this.setAttribute('controls', Boolean(value).toString());
|
|
434
703
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
return;
|
|
704
|
+
get controls() {
|
|
705
|
+
const val = this.getAttribute('controls');
|
|
706
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
438
707
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
708
|
+
/**
|
|
709
|
+
* Number of times to loop.
|
|
710
|
+
*/ set count(value) {
|
|
711
|
+
this.setAttribute('count', value.toString());
|
|
443
712
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
713
|
+
get count() {
|
|
714
|
+
const val = this.getAttribute('count');
|
|
715
|
+
if (val) {
|
|
716
|
+
return Number(val);
|
|
717
|
+
}
|
|
718
|
+
return 0;
|
|
447
719
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
720
|
+
/**
|
|
721
|
+
* Description for screen readers.
|
|
722
|
+
*/ set description(value) {
|
|
723
|
+
if (value) {
|
|
724
|
+
this.setAttribute('description', value);
|
|
725
|
+
}
|
|
451
726
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
next.onclick = this.next;
|
|
727
|
+
get description() {
|
|
728
|
+
return this.getAttribute('description');
|
|
455
729
|
}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
730
|
+
/**
|
|
731
|
+
* Direction of animation.
|
|
732
|
+
*/ set direction(value) {
|
|
733
|
+
this.setAttribute('direction', value.toString());
|
|
460
734
|
}
|
|
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;
|
|
735
|
+
get direction() {
|
|
736
|
+
const val = Number(this.getAttribute('direction'));
|
|
737
|
+
if (val === -1) {
|
|
738
|
+
return val;
|
|
473
739
|
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
740
|
+
return 1;
|
|
741
|
+
}
|
|
742
|
+
/**
|
|
743
|
+
* Whether to play on mouseover.
|
|
744
|
+
*/ set hover(value) {
|
|
745
|
+
this.setAttribute('hover', value.toString());
|
|
746
|
+
}
|
|
747
|
+
get hover() {
|
|
748
|
+
const val = this.getAttribute('hover');
|
|
749
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Pause between loop intrations, in miliseconds.
|
|
753
|
+
*/ set intermission(value) {
|
|
754
|
+
this.setAttribute('intermission', value.toString());
|
|
755
|
+
}
|
|
756
|
+
get intermission() {
|
|
757
|
+
const val = Number(this.getAttribute('intermission'));
|
|
758
|
+
if (!isNaN(val)) {
|
|
759
|
+
return val;
|
|
477
760
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
761
|
+
return 0;
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* Loop animation.
|
|
765
|
+
*/ set loop(value) {
|
|
766
|
+
this.setAttribute('loop', Boolean(value).toString());
|
|
767
|
+
}
|
|
768
|
+
get loop() {
|
|
769
|
+
const val = this.getAttribute('loop');
|
|
770
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
771
|
+
}
|
|
772
|
+
/**
|
|
773
|
+
* Play mode.
|
|
774
|
+
*/ set mode(value) {
|
|
775
|
+
this.setAttribute('mode', value.toString());
|
|
776
|
+
}
|
|
777
|
+
get mode() {
|
|
778
|
+
const val = this.getAttribute('mode');
|
|
779
|
+
if (val === PlayMode.Bounce) {
|
|
780
|
+
return val;
|
|
482
781
|
}
|
|
782
|
+
return PlayMode.Normal;
|
|
483
783
|
}
|
|
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] = [];
|
|
784
|
+
/**
|
|
785
|
+
* Resizing to container.
|
|
786
|
+
*/ set objectfit(value) {
|
|
787
|
+
this.setAttribute('objectfit', value);
|
|
788
|
+
}
|
|
789
|
+
get objectfit() {
|
|
790
|
+
const val = this.getAttribute('objectfit');
|
|
791
|
+
if (val && Object.values(ObjectFit).includes(val)) {
|
|
792
|
+
return val;
|
|
503
793
|
}
|
|
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
|
-
}
|
|
794
|
+
return ObjectFit.Contain;
|
|
795
|
+
}
|
|
796
|
+
/**
|
|
797
|
+
* Resizing to container (Deprecated).
|
|
798
|
+
*/ set preserveAspectRatio(value) {
|
|
799
|
+
this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
|
|
800
|
+
}
|
|
801
|
+
get preserveAspectRatio() {
|
|
802
|
+
const val = this.getAttribute('preserveAspectRatio');
|
|
803
|
+
if (val && Object.values(PreserveAspectRatio).includes(val)) {
|
|
804
|
+
return val;
|
|
526
805
|
}
|
|
806
|
+
return null;
|
|
527
807
|
}
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
808
|
+
/**
|
|
809
|
+
* Renderer to use: svg, canvas or html.
|
|
810
|
+
*/ set renderer(value) {
|
|
811
|
+
this.setAttribute('renderer', value);
|
|
812
|
+
}
|
|
813
|
+
get renderer() {
|
|
814
|
+
const val = this.getAttribute('renderer');
|
|
815
|
+
if (val === RendererType.Canvas || val === RendererType.HTML) {
|
|
816
|
+
return val;
|
|
532
817
|
}
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
818
|
+
return RendererType.SVG;
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Hide advanced controls.
|
|
822
|
+
*/ set simple(value) {
|
|
823
|
+
this.setAttribute('simple', value.toString());
|
|
824
|
+
}
|
|
825
|
+
get simple() {
|
|
826
|
+
const val = this.getAttribute('simple');
|
|
827
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Speed.
|
|
831
|
+
*/ set speed(value) {
|
|
832
|
+
this.setAttribute('speed', value.toString());
|
|
833
|
+
}
|
|
834
|
+
get speed() {
|
|
835
|
+
const val = this.getAttribute('speed');
|
|
836
|
+
if (val !== null && !isNaN(Number(val))) {
|
|
837
|
+
return Number(val);
|
|
541
838
|
}
|
|
839
|
+
return 1;
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Source, either path or JSON string.
|
|
843
|
+
*/ set src(value) {
|
|
844
|
+
this.setAttribute('src', value || '');
|
|
845
|
+
}
|
|
846
|
+
get src() {
|
|
847
|
+
return this.getAttribute('src');
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Subframe.
|
|
851
|
+
*/ set subframe(value) {
|
|
852
|
+
this.setAttribute('subframe', Boolean(value).toString());
|
|
853
|
+
}
|
|
854
|
+
get subframe() {
|
|
855
|
+
const val = this.getAttribute('subframe');
|
|
856
|
+
return Boolean(val === 'true' || val === '' || val === '1');
|
|
542
857
|
}
|
|
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
858
|
constructor(){
|
|
557
|
-
super(),
|
|
558
|
-
*
|
|
559
|
-
*/ this._multiAnimationSettings = [], /**
|
|
560
|
-
* Animation Container
|
|
561
|
-
*/ this._container = null, /**
|
|
562
|
-
* @state
|
|
563
|
-
* Player state
|
|
859
|
+
super(), /**
|
|
860
|
+
* Player state.
|
|
564
861
|
*/ 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 = {
|
|
862
|
+
* Animation Container.
|
|
863
|
+
*/ this._container = null, this._errorMessage = 'Something went wrong', this._identifier = this.id || createElementID(), /**
|
|
864
|
+
* Whether settings toolbar is open.
|
|
865
|
+
*/ this._isSettingsOpen = false, this._playerState = {
|
|
579
866
|
count: 0,
|
|
580
867
|
loaded: false,
|
|
581
868
|
prev: PlayerState.Loading,
|
|
582
869
|
scrollTimeout: null,
|
|
583
870
|
scrollY: 0,
|
|
584
871
|
visible: false
|
|
585
|
-
}, /**
|
|
586
|
-
*
|
|
872
|
+
}, this._render = renderPlayer, this._renderControls = renderControls, /**
|
|
873
|
+
* Seeker.
|
|
874
|
+
*/ this._seeker = 0, /**
|
|
875
|
+
* This is included in watched properties,
|
|
876
|
+
* so that next-button will show up
|
|
877
|
+
* on load, if controls are visible.
|
|
878
|
+
*/ this._animations = [], /**
|
|
879
|
+
* Which animation to show, if several.
|
|
880
|
+
*/ this._currentAnimation = 0, this._isBounce = false, this._isDotLottie = false, this._lottieInstance = null, /**
|
|
881
|
+
* Multi-animation settings.
|
|
882
|
+
*/ this._multiAnimationSettings = [], /**
|
|
883
|
+
* Handle settings click event.
|
|
587
884
|
*/ this._handleSettingsClick = ({ target })=>{
|
|
588
885
|
this._toggleSettings();
|
|
589
886
|
// Because Safari does not add focus on click, we need to add it manually, so the onblur event will fire
|
|
@@ -622,55 +919,58 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
622
919
|
});
|
|
623
920
|
}
|
|
624
921
|
/**
|
|
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
|
-
|
|
922
|
+
* Creates a new dotLottie file, by combinig several animations.
|
|
923
|
+
* If set to false the function returns an ArrayBuffer. Defaults to true.
|
|
924
|
+
*/ async addAnimation(configs, fileName, shouldDownload = true) {
|
|
925
|
+
// Initialize meta object for animation, with fallbacks for
|
|
926
|
+
// when the method is called indepenently
|
|
927
|
+
const { animations = [], manifest = {
|
|
928
|
+
animations: this.src ? [
|
|
929
|
+
{
|
|
930
|
+
id: this._identifier
|
|
931
|
+
}
|
|
932
|
+
] : []
|
|
933
|
+
} } = this.src ? await getAnimationData(this.src) : {};
|
|
934
|
+
try {
|
|
935
|
+
if (!manifest) {
|
|
936
|
+
throw new Error('Manifest is not set');
|
|
937
|
+
}
|
|
938
|
+
manifest.generator = generator;
|
|
939
|
+
const { length } = configs;
|
|
940
|
+
for(let i = 0; i < length; i++){
|
|
941
|
+
const { url } = configs[i], { animations: animationsToAdd } = await getAnimationData(url);
|
|
942
|
+
if (!animationsToAdd) {
|
|
943
|
+
throw new Error('No animation loaded');
|
|
944
|
+
}
|
|
945
|
+
if (manifest.animations.some(({ id })=>id === configs[i].id)) {
|
|
946
|
+
throw new Error('Duplicate id for animation');
|
|
947
|
+
}
|
|
948
|
+
manifest.animations = [
|
|
949
|
+
...manifest.animations,
|
|
950
|
+
{
|
|
951
|
+
id: configs[i].id
|
|
952
|
+
}
|
|
953
|
+
];
|
|
954
|
+
animations.push(...animationsToAdd);
|
|
955
|
+
}
|
|
956
|
+
return {
|
|
957
|
+
result: await createDotLottie({
|
|
958
|
+
animations,
|
|
959
|
+
fileName,
|
|
960
|
+
manifest,
|
|
961
|
+
shouldDownload
|
|
962
|
+
}),
|
|
963
|
+
success: true
|
|
964
|
+
};
|
|
965
|
+
} catch (error) {
|
|
966
|
+
return {
|
|
967
|
+
error: handleErrors(error).message,
|
|
968
|
+
success: false
|
|
969
|
+
};
|
|
652
970
|
}
|
|
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
971
|
}
|
|
672
972
|
/**
|
|
673
|
-
* Runs when the value of an attribute is changed on the component
|
|
973
|
+
* Runs when the value of an attribute is changed on the component.
|
|
674
974
|
*/ async attributeChangedCallback(name, _oldValue, value) {
|
|
675
975
|
if (!this._lottieInstance) {
|
|
676
976
|
return;
|
|
@@ -701,7 +1001,8 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
701
1001
|
}
|
|
702
1002
|
if (name === 'direction') {
|
|
703
1003
|
if (Number(value) === -1) {
|
|
704
|
-
|
|
1004
|
+
this.setDirection(-1);
|
|
1005
|
+
return;
|
|
705
1006
|
}
|
|
706
1007
|
this.setDirection(1);
|
|
707
1008
|
}
|
|
@@ -715,14 +1016,14 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
715
1016
|
this._container.removeEventListener('mouseleave', this._mouseLeave);
|
|
716
1017
|
}
|
|
717
1018
|
if (name === 'loop') {
|
|
718
|
-
const toggleLoop = this.shadow
|
|
1019
|
+
const toggleLoop = this.shadow?.querySelector('.toggleLoop');
|
|
719
1020
|
if (toggleLoop instanceof HTMLButtonElement) {
|
|
720
1021
|
toggleLoop.dataset.active = value;
|
|
721
1022
|
}
|
|
722
1023
|
this.setLoop(value === '' || Boolean(value));
|
|
723
1024
|
}
|
|
724
1025
|
if (name === 'mode') {
|
|
725
|
-
const toggleBoomerang = this.shadow
|
|
1026
|
+
const toggleBoomerang = this.shadow?.querySelector('.toggleBoomerang');
|
|
726
1027
|
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
727
1028
|
toggleBoomerang.dataset.active = (value === PlayMode.Bounce).toString();
|
|
728
1029
|
}
|
|
@@ -741,759 +1042,189 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
741
1042
|
this.setSubframe(value === '' || Boolean(value));
|
|
742
1043
|
}
|
|
743
1044
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
'_currentAnimation',
|
|
750
|
-
'_animations'
|
|
751
|
-
];
|
|
752
|
-
}
|
|
753
|
-
// name: string, oldValue: string, newValue: string
|
|
754
|
-
propertyChangedCallback(name, _oldValue, value) {
|
|
1045
|
+
/**
|
|
1046
|
+
* Initialize everything on component first render.
|
|
1047
|
+
*/ async connectedCallback() {
|
|
1048
|
+
await super.connectedCallback();
|
|
1049
|
+
await this._render();
|
|
755
1050
|
if (!this.shadow) {
|
|
756
|
-
|
|
1051
|
+
throw new Error('Missing Shadow element');
|
|
757
1052
|
}
|
|
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);
|
|
1053
|
+
this._container = this.shadow.querySelector('.animation');
|
|
1054
|
+
this._renderControls();
|
|
1055
|
+
// Add listener for Visibility API's change event.
|
|
1056
|
+
if (typeof document.hidden !== 'undefined') {
|
|
1057
|
+
document.addEventListener('visibilitychange', this._onVisibilityChange);
|
|
1275
1058
|
}
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
}, this.intermission);
|
|
1059
|
+
// Add intersection observer for detecting component being out-of-view.
|
|
1060
|
+
this._addIntersectionObserver();
|
|
1061
|
+
// Setup lottie player
|
|
1062
|
+
await this.load(this.src);
|
|
1063
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Rendered));
|
|
1282
1064
|
}
|
|
1283
|
-
|
|
1284
|
-
|
|
1065
|
+
async convert({ animations: animationsFromProps, fileName, manifest, shouldDownload = true, src: srcFromProps, typeCheck }) {
|
|
1066
|
+
const src = srcFromProps || this.src || this.source;
|
|
1067
|
+
if (!src) {
|
|
1068
|
+
throw new Error('No animation to convert');
|
|
1069
|
+
}
|
|
1070
|
+
if (typeCheck || this._isDotLottie) {
|
|
1071
|
+
const animationData = await getAnimationData(src);
|
|
1072
|
+
createJSON({
|
|
1073
|
+
animation: animationData.animations?.[0],
|
|
1074
|
+
fileName: `${getFilename(fileName || src || 'converted')}.json`,
|
|
1075
|
+
shouldDownload
|
|
1076
|
+
});
|
|
1285
1077
|
return;
|
|
1286
1078
|
}
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1079
|
+
let animations = animationsFromProps;
|
|
1080
|
+
if (!animations) {
|
|
1081
|
+
const animationData = await getAnimationData(src);
|
|
1082
|
+
animations = animationData.animations;
|
|
1083
|
+
}
|
|
1084
|
+
return createDotLottie({
|
|
1085
|
+
animations,
|
|
1086
|
+
fileName: `${getFilename(fileName || src || 'converted')}.lottie`,
|
|
1087
|
+
manifest: {
|
|
1088
|
+
...manifest ?? this._manifest,
|
|
1089
|
+
generator
|
|
1090
|
+
},
|
|
1091
|
+
shouldDownload
|
|
1092
|
+
});
|
|
1295
1093
|
}
|
|
1296
|
-
|
|
1094
|
+
/**
|
|
1095
|
+
* Destroy animation and element.
|
|
1096
|
+
*/ destroy() {
|
|
1297
1097
|
if (!this._lottieInstance) {
|
|
1298
1098
|
return;
|
|
1299
1099
|
}
|
|
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));
|
|
1100
|
+
this.playerState = PlayerState.Destroyed;
|
|
1101
|
+
this._lottieInstance.destroy();
|
|
1102
|
+
this._lottieInstance = null;
|
|
1103
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Destroyed));
|
|
1104
|
+
this.remove();
|
|
1105
|
+
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
1329
1106
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1107
|
+
/**
|
|
1108
|
+
* Cleanup on component destroy.
|
|
1109
|
+
*/ disconnectedCallback() {
|
|
1110
|
+
// Remove intersection observer for detecting component being out-of-view
|
|
1111
|
+
if (this._intersectionObserver) {
|
|
1112
|
+
this._intersectionObserver.disconnect();
|
|
1113
|
+
this._intersectionObserver = undefined;
|
|
1333
1114
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1115
|
+
// Destroy the animation instance
|
|
1116
|
+
if (this._lottieInstance) {
|
|
1117
|
+
this._lottieInstance.destroy();
|
|
1336
1118
|
}
|
|
1119
|
+
// Remove the attached Visibility API's change event listener
|
|
1120
|
+
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
1337
1121
|
}
|
|
1338
1122
|
/**
|
|
1339
|
-
*
|
|
1340
|
-
*/
|
|
1341
|
-
|
|
1342
|
-
this.play();
|
|
1343
|
-
}
|
|
1123
|
+
* Returns the lottie-web instance used in the component.
|
|
1124
|
+
*/ getLottie() {
|
|
1125
|
+
return this._lottieInstance;
|
|
1344
1126
|
}
|
|
1345
1127
|
/**
|
|
1346
|
-
*
|
|
1347
|
-
*/
|
|
1348
|
-
|
|
1349
|
-
this.stop();
|
|
1350
|
-
}
|
|
1128
|
+
* Get Lottie Manifest.
|
|
1129
|
+
*/ getManifest() {
|
|
1130
|
+
return this._manifest;
|
|
1351
1131
|
}
|
|
1352
1132
|
/**
|
|
1353
|
-
*
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
if (this.playerState === PlayerState.Frozen) {
|
|
1360
|
-
this.play();
|
|
1361
|
-
}
|
|
1133
|
+
* Get Multi-animation settings.
|
|
1134
|
+
*
|
|
1135
|
+
*/ getMultiAnimationSettings() {
|
|
1136
|
+
return this._multiAnimationSettings;
|
|
1362
1137
|
}
|
|
1363
1138
|
/**
|
|
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
|
-
}
|
|
1139
|
+
* Get playback segment.
|
|
1140
|
+
*
|
|
1141
|
+
*/ getSegment() {
|
|
1142
|
+
return this._segment;
|
|
1390
1143
|
}
|
|
1391
1144
|
/**
|
|
1392
|
-
*
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
|
|
1145
|
+
* Initialize Lottie Web player.
|
|
1146
|
+
*/ async load(src) {
|
|
1147
|
+
if (!this.shadowRoot || !src) {
|
|
1396
1148
|
return;
|
|
1397
1149
|
}
|
|
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) : {};
|
|
1150
|
+
this.source = src;
|
|
1151
|
+
// Load the resource
|
|
1429
1152
|
try {
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
manifest.animations = [
|
|
1443
|
-
...manifest.animations,
|
|
1153
|
+
const { animations, isDotLottie, manifest } = await getAnimationData(src);
|
|
1154
|
+
if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
|
|
1155
|
+
throw new Error('Broken or corrupted file');
|
|
1156
|
+
}
|
|
1157
|
+
this._isBounce = this.mode === PlayMode.Bounce;
|
|
1158
|
+
if (this._multiAnimationSettings.length > 0 && this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1159
|
+
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1160
|
+
}
|
|
1161
|
+
this._isDotLottie = Boolean(isDotLottie);
|
|
1162
|
+
this._animations = animations;
|
|
1163
|
+
this._manifest = manifest ?? {
|
|
1164
|
+
animations: [
|
|
1444
1165
|
{
|
|
1445
|
-
|
|
1166
|
+
autoplay: !this.animateOnScroll && this.autoplay,
|
|
1167
|
+
direction: this.direction,
|
|
1168
|
+
id: createElementID(),
|
|
1169
|
+
loop: this.loop,
|
|
1170
|
+
mode: this.mode,
|
|
1171
|
+
speed: this.speed
|
|
1446
1172
|
}
|
|
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
|
|
1173
|
+
]
|
|
1464
1174
|
};
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1175
|
+
// Clear previous animation, if any
|
|
1176
|
+
if (this._lottieInstance) {
|
|
1177
|
+
this._lottieInstance.destroy();
|
|
1178
|
+
}
|
|
1179
|
+
this.playerState = PlayerState.Stopped;
|
|
1180
|
+
if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings[this._currentAnimation]?.autoplay)) {
|
|
1181
|
+
this.playerState = PlayerState.Playing;
|
|
1182
|
+
}
|
|
1183
|
+
// Initialize lottie player and load animation
|
|
1184
|
+
// @ts-expect-error TODO:
|
|
1185
|
+
this._lottieInstance = Lottie.loadAnimation({
|
|
1186
|
+
...this._getOptions(),
|
|
1187
|
+
animationData: animations[this._currentAnimation]
|
|
1188
|
+
});
|
|
1189
|
+
} catch (error) {
|
|
1190
|
+
this._errorMessage = handleErrors(error).message;
|
|
1191
|
+
this.playerState = PlayerState.Error;
|
|
1192
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1476
1193
|
return;
|
|
1477
1194
|
}
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1195
|
+
this._addEventListeners();
|
|
1196
|
+
const speed = this._multiAnimationSettings[this._currentAnimation]?.speed ?? this.speed, direction = this._multiAnimationSettings[this._currentAnimation]?.direction ?? this.direction;
|
|
1197
|
+
// Set initial playback speed and direction
|
|
1198
|
+
this._lottieInstance.setSpeed(speed);
|
|
1199
|
+
this._lottieInstance.setDirection(direction);
|
|
1200
|
+
this._lottieInstance.setSubframe(Boolean(this.subframe));
|
|
1201
|
+
// Start playing if autoplay is enabled
|
|
1202
|
+
if (this.autoplay || this.animateOnScroll) {
|
|
1203
|
+
if (this.direction === -1) {
|
|
1204
|
+
this.seek('99%');
|
|
1205
|
+
}
|
|
1206
|
+
if (!('IntersectionObserver' in window)) {
|
|
1207
|
+
if (!this.animateOnScroll) {
|
|
1208
|
+
this.play();
|
|
1209
|
+
}
|
|
1210
|
+
this._playerState.visible = true;
|
|
1211
|
+
}
|
|
1212
|
+
this._addIntersectionObserver();
|
|
1486
1213
|
}
|
|
1487
1214
|
}
|
|
1488
1215
|
/**
|
|
1489
|
-
*
|
|
1216
|
+
* Skip to next animation.
|
|
1217
|
+
*/ next() {
|
|
1218
|
+
this._currentAnimation++;
|
|
1219
|
+
this._switchInstance();
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* Pause.
|
|
1490
1223
|
*/ pause() {
|
|
1491
1224
|
if (!this._lottieInstance) {
|
|
1492
1225
|
return;
|
|
1493
1226
|
}
|
|
1494
|
-
|
|
1495
|
-
this._playerState.prev = this.playerState;
|
|
1496
|
-
}
|
|
1227
|
+
this._playerState.prev = this.playerState;
|
|
1497
1228
|
try {
|
|
1498
1229
|
this._lottieInstance.pause();
|
|
1499
1230
|
this.dispatchEvent(new CustomEvent(PlayerEvents.Pause));
|
|
@@ -1502,44 +1233,88 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1502
1233
|
}
|
|
1503
1234
|
}
|
|
1504
1235
|
/**
|
|
1505
|
-
*
|
|
1506
|
-
*/
|
|
1236
|
+
* Play.
|
|
1237
|
+
*/ play() {
|
|
1507
1238
|
if (!this._lottieInstance) {
|
|
1508
1239
|
return;
|
|
1509
1240
|
}
|
|
1510
|
-
|
|
1511
|
-
this._playerState.prev = this.playerState;
|
|
1512
|
-
}
|
|
1513
|
-
this._playerState.count = 0;
|
|
1241
|
+
this._playerState.prev = this.playerState;
|
|
1514
1242
|
try {
|
|
1515
|
-
this._lottieInstance.
|
|
1516
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.
|
|
1243
|
+
this._lottieInstance.play();
|
|
1244
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Play));
|
|
1517
1245
|
} finally{
|
|
1518
|
-
this.playerState = PlayerState.
|
|
1246
|
+
this.playerState = PlayerState.Playing;
|
|
1519
1247
|
}
|
|
1520
1248
|
}
|
|
1521
1249
|
/**
|
|
1522
|
-
*
|
|
1523
|
-
*/
|
|
1524
|
-
|
|
1250
|
+
* Skip to previous animation.
|
|
1251
|
+
*/ prev() {
|
|
1252
|
+
this._currentAnimation--;
|
|
1253
|
+
this._switchInstance(true);
|
|
1254
|
+
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Name: string, oldValue: string, newValue: string.
|
|
1257
|
+
*/ propertyChangedCallback(name, _oldValue, value) {
|
|
1258
|
+
if (!this.shadow) {
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
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');
|
|
1262
|
+
if (!(togglePlay instanceof HTMLButtonElement) || !(stop instanceof HTMLButtonElement) || !(next instanceof HTMLButtonElement) || !(prev instanceof HTMLButtonElement) || !(seeker instanceof HTMLInputElement) || !(progress instanceof HTMLProgressElement)) {
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
if (name === 'playerState') {
|
|
1266
|
+
togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
|
|
1267
|
+
stop.dataset.active = (value === PlayerState.Stopped).toString();
|
|
1268
|
+
if (value === PlayerState.Playing) {
|
|
1269
|
+
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>`;
|
|
1270
|
+
} else {
|
|
1271
|
+
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>`;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
if (name === '_seeker' && typeof value === 'number') {
|
|
1275
|
+
seeker.value = value.toString();
|
|
1276
|
+
seeker.ariaValueNow = value.toString();
|
|
1277
|
+
progress.value = value;
|
|
1278
|
+
}
|
|
1279
|
+
if (name === '_animations' && Array.isArray(value) && this._currentAnimation + 1 < value.length) {
|
|
1280
|
+
next.hidden = false;
|
|
1281
|
+
}
|
|
1282
|
+
if (name === '_currentAnimation' && typeof value === 'number') {
|
|
1283
|
+
if (value + 1 >= this._animations.length) {
|
|
1284
|
+
next.hidden = true;
|
|
1285
|
+
} else {
|
|
1286
|
+
next.hidden = false;
|
|
1287
|
+
}
|
|
1288
|
+
if (value) {
|
|
1289
|
+
prev.hidden = false;
|
|
1290
|
+
} else {
|
|
1291
|
+
prev.hidden = true;
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
if (name === '_isSettingsOpen' && typeof value === 'boolean' && popover instanceof HTMLDivElement && convert instanceof HTMLButtonElement) {
|
|
1295
|
+
popover.hidden = !value;
|
|
1296
|
+
convert.hidden = this._isDotLottie;
|
|
1297
|
+
}
|
|
1298
|
+
}
|
|
1299
|
+
/**
|
|
1300
|
+
* Reload animation.
|
|
1301
|
+
*/ async reload() {
|
|
1302
|
+
if (!this._lottieInstance || !this.src) {
|
|
1525
1303
|
return;
|
|
1526
1304
|
}
|
|
1527
|
-
this.playerState = PlayerState.Destroyed;
|
|
1528
1305
|
this._lottieInstance.destroy();
|
|
1529
|
-
this.
|
|
1530
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Destroyed));
|
|
1531
|
-
this.remove();
|
|
1532
|
-
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
1306
|
+
await this.load(this.src);
|
|
1533
1307
|
}
|
|
1534
1308
|
/**
|
|
1535
|
-
* Seek to a given frame
|
|
1536
|
-
*
|
|
1309
|
+
* Seek to a given frame.
|
|
1310
|
+
*
|
|
1311
|
+
* @param value - Frame to seek to.
|
|
1537
1312
|
*/ seek(value) {
|
|
1538
1313
|
if (!this._lottieInstance) {
|
|
1539
1314
|
return;
|
|
1540
1315
|
}
|
|
1541
1316
|
// Extract frame number from either number or percentage value
|
|
1542
|
-
const matches = value.toString().match(/^(
|
|
1317
|
+
const matches = value.toString().match(/^(\d+)(%?)$/);
|
|
1543
1318
|
if (!matches) {
|
|
1544
1319
|
return;
|
|
1545
1320
|
}
|
|
@@ -1557,7 +1332,63 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1557
1332
|
this._lottieInstance.pause();
|
|
1558
1333
|
}
|
|
1559
1334
|
/**
|
|
1560
|
-
*
|
|
1335
|
+
* Dynamically set count for loops.
|
|
1336
|
+
*/ setCount(value) {
|
|
1337
|
+
this.count = value;
|
|
1338
|
+
}
|
|
1339
|
+
/**
|
|
1340
|
+
* Animation play direction.
|
|
1341
|
+
*
|
|
1342
|
+
* @param value - Animation direction.
|
|
1343
|
+
*/ setDirection(value) {
|
|
1344
|
+
if (!this._lottieInstance) {
|
|
1345
|
+
return;
|
|
1346
|
+
}
|
|
1347
|
+
this._lottieInstance.setDirection(value);
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Set loop.
|
|
1351
|
+
*
|
|
1352
|
+
*/ setLoop(value) {
|
|
1353
|
+
if (!this._lottieInstance) {
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
this._lottieInstance.setLoop(value);
|
|
1357
|
+
}
|
|
1358
|
+
/**
|
|
1359
|
+
* Set Multi-animation settings.
|
|
1360
|
+
*
|
|
1361
|
+
*/ setMultiAnimationSettings(settings) {
|
|
1362
|
+
this._multiAnimationSettings = settings;
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Set playback segment.
|
|
1366
|
+
*
|
|
1367
|
+
*/ setSegment(segment) {
|
|
1368
|
+
this._segment = segment;
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Set animation playback speed.
|
|
1372
|
+
*
|
|
1373
|
+
* @param value - Playback speed.
|
|
1374
|
+
*/ setSpeed(value = 1) {
|
|
1375
|
+
if (!this._lottieInstance) {
|
|
1376
|
+
return;
|
|
1377
|
+
}
|
|
1378
|
+
this._lottieInstance.setSpeed(value);
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Toggles subframe, for more smooth animations.
|
|
1382
|
+
*
|
|
1383
|
+
* @param value - Whether animation uses subframe.
|
|
1384
|
+
*/ setSubframe(value) {
|
|
1385
|
+
if (!this._lottieInstance) {
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
1388
|
+
this._lottieInstance.setSubframe(value);
|
|
1389
|
+
}
|
|
1390
|
+
/**
|
|
1391
|
+
* Snapshot and download the current frame as SVG.
|
|
1561
1392
|
*/ snapshot(shouldDownload = true, name = 'AM Lottie') {
|
|
1562
1393
|
try {
|
|
1563
1394
|
if (!this.shadowRoot) {
|
|
@@ -1579,144 +1410,388 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1579
1410
|
});
|
|
1580
1411
|
}
|
|
1581
1412
|
return data;
|
|
1582
|
-
} catch (
|
|
1583
|
-
console.error(
|
|
1413
|
+
} catch (error) {
|
|
1414
|
+
console.error(error);
|
|
1584
1415
|
return null;
|
|
1585
1416
|
}
|
|
1586
1417
|
}
|
|
1587
|
-
/**
|
|
1588
|
-
*
|
|
1589
|
-
|
|
1590
|
-
|
|
1418
|
+
/**
|
|
1419
|
+
* Stop.
|
|
1420
|
+
*/ stop() {
|
|
1421
|
+
if (!this._lottieInstance) {
|
|
1422
|
+
return;
|
|
1423
|
+
}
|
|
1424
|
+
this._playerState.prev = this.playerState;
|
|
1425
|
+
this._playerState.count = 0;
|
|
1426
|
+
try {
|
|
1427
|
+
this._lottieInstance.stop();
|
|
1428
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Stop));
|
|
1429
|
+
} finally{
|
|
1430
|
+
this.playerState = PlayerState.Stopped;
|
|
1431
|
+
}
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Toggle Boomerang.
|
|
1435
|
+
*/ toggleBoomerang() {
|
|
1436
|
+
const curr = this._multiAnimationSettings[this._currentAnimation];
|
|
1437
|
+
if (curr.mode !== undefined) {
|
|
1438
|
+
if (curr.mode === PlayMode.Normal) {
|
|
1439
|
+
curr.mode = PlayMode.Bounce;
|
|
1440
|
+
this._isBounce = true;
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
curr.mode = PlayMode.Normal;
|
|
1444
|
+
this._isBounce = false;
|
|
1445
|
+
return;
|
|
1446
|
+
}
|
|
1447
|
+
if (this.mode === PlayMode.Normal) {
|
|
1448
|
+
this.mode = PlayMode.Bounce;
|
|
1449
|
+
this._isBounce = true;
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
this.mode = PlayMode.Normal;
|
|
1453
|
+
this._isBounce = false;
|
|
1454
|
+
}
|
|
1455
|
+
/**
|
|
1456
|
+
* Toggle loop.
|
|
1457
|
+
*/ toggleLoop() {
|
|
1458
|
+
const hasLoop = !this.loop;
|
|
1459
|
+
this.loop = hasLoop;
|
|
1460
|
+
this.setLoop(hasLoop);
|
|
1461
|
+
}
|
|
1462
|
+
/**
|
|
1463
|
+
* Toggle playing state.
|
|
1464
|
+
*/ togglePlay() {
|
|
1465
|
+
if (!this._lottieInstance) {
|
|
1466
|
+
return;
|
|
1467
|
+
}
|
|
1468
|
+
const { currentFrame, playDirection, totalFrames } = this._lottieInstance;
|
|
1469
|
+
if (this.playerState === PlayerState.Playing) {
|
|
1470
|
+
this.pause();
|
|
1471
|
+
return;
|
|
1472
|
+
}
|
|
1473
|
+
if (this.playerState !== PlayerState.Completed) {
|
|
1474
|
+
this.play();
|
|
1475
|
+
return;
|
|
1476
|
+
}
|
|
1477
|
+
this.playerState = PlayerState.Playing;
|
|
1478
|
+
if (this._isBounce) {
|
|
1479
|
+
this.setDirection(playDirection * -1);
|
|
1480
|
+
this._lottieInstance.goToAndPlay(currentFrame, true);
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
if (playDirection === -1) {
|
|
1484
|
+
this._lottieInstance.goToAndPlay(totalFrames, true);
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
this._lottieInstance.goToAndPlay(0, true);
|
|
1488
|
+
}
|
|
1489
|
+
/**
|
|
1490
|
+
* Freeze animation.
|
|
1491
|
+
* This internal state pauses animation and is used to differentiate between
|
|
1492
|
+
* user requested pauses and component instigated pauses.
|
|
1493
|
+
*/ _freeze() {
|
|
1494
|
+
if (!this._lottieInstance) {
|
|
1495
|
+
return;
|
|
1496
|
+
}
|
|
1497
|
+
this._playerState.prev = this.playerState;
|
|
1498
|
+
try {
|
|
1499
|
+
this._lottieInstance.pause();
|
|
1500
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Freeze));
|
|
1501
|
+
} finally{
|
|
1502
|
+
this.playerState = PlayerState.Frozen;
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
/**
|
|
1506
|
+
* Handle blur.
|
|
1507
|
+
*/ _handleBlur() {
|
|
1508
|
+
setTimeout(()=>{
|
|
1509
|
+
this._toggleSettings(false);
|
|
1510
|
+
}, 200);
|
|
1511
|
+
}
|
|
1512
|
+
/**
|
|
1513
|
+
* Handles click and drag actions on the progress track.
|
|
1514
|
+
*
|
|
1515
|
+
*/ _handleSeekChange({ target }) {
|
|
1516
|
+
if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
|
|
1517
|
+
return;
|
|
1518
|
+
}
|
|
1519
|
+
this.seek(Math.round(Number(target.value) / 100 * this._lottieInstance.totalFrames));
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Add event listeners.
|
|
1523
|
+
*/ _addEventListeners() {
|
|
1524
|
+
this._toggleEventListeners('add');
|
|
1525
|
+
}
|
|
1526
|
+
/**
|
|
1527
|
+
* Add IntersectionObserver.
|
|
1528
|
+
*/ _addIntersectionObserver() {
|
|
1529
|
+
if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
|
|
1530
|
+
return;
|
|
1531
|
+
}
|
|
1532
|
+
this._intersectionObserver = new IntersectionObserver((entries)=>{
|
|
1533
|
+
const { length } = entries;
|
|
1534
|
+
for(let i = 0; i < length; i++){
|
|
1535
|
+
if (!entries[i].isIntersecting || document.hidden) {
|
|
1536
|
+
if (this.playerState === PlayerState.Playing) {
|
|
1537
|
+
this._freeze();
|
|
1538
|
+
}
|
|
1539
|
+
this._playerState.visible = false;
|
|
1540
|
+
continue;
|
|
1541
|
+
}
|
|
1542
|
+
if (!this.animateOnScroll && this.playerState === PlayerState.Frozen) {
|
|
1543
|
+
this.play();
|
|
1544
|
+
}
|
|
1545
|
+
if (!this._playerState.scrollY) {
|
|
1546
|
+
this._playerState.scrollY = scrollY;
|
|
1547
|
+
}
|
|
1548
|
+
this._playerState.visible = true;
|
|
1549
|
+
}
|
|
1550
|
+
});
|
|
1551
|
+
this._intersectionObserver.observe(this._container);
|
|
1552
|
+
}
|
|
1553
|
+
_complete() {
|
|
1554
|
+
if (!this._lottieInstance) {
|
|
1555
|
+
return;
|
|
1556
|
+
}
|
|
1557
|
+
if (this._animations.length > 1) {
|
|
1558
|
+
if (this._multiAnimationSettings[this._currentAnimation + 1]?.autoplay) {
|
|
1559
|
+
this.next();
|
|
1560
|
+
return;
|
|
1561
|
+
}
|
|
1562
|
+
if (this.loop && this._currentAnimation === this._animations.length - 1) {
|
|
1563
|
+
this._currentAnimation = 0;
|
|
1564
|
+
this._switchInstance();
|
|
1565
|
+
return;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
const { currentFrame, totalFrames } = this._lottieInstance;
|
|
1569
|
+
this._seeker = Math.round(currentFrame / totalFrames * 100);
|
|
1570
|
+
this.playerState = PlayerState.Completed;
|
|
1571
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete, {
|
|
1572
|
+
detail: {
|
|
1573
|
+
frame: currentFrame,
|
|
1574
|
+
seeker: this._seeker
|
|
1575
|
+
}
|
|
1576
|
+
}));
|
|
1577
|
+
}
|
|
1578
|
+
_dataFailed() {
|
|
1579
|
+
this.playerState = PlayerState.Error;
|
|
1580
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1581
|
+
}
|
|
1582
|
+
_dataReady() {
|
|
1583
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Load));
|
|
1584
|
+
}
|
|
1585
|
+
_DOMLoaded() {
|
|
1586
|
+
this._playerState.loaded = true;
|
|
1587
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Ready));
|
|
1588
|
+
}
|
|
1589
|
+
_enterFrame() {
|
|
1591
1590
|
if (!this._lottieInstance) {
|
|
1592
1591
|
return;
|
|
1593
1592
|
}
|
|
1594
|
-
this._lottieInstance
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1593
|
+
const { currentFrame, totalFrames } = this._lottieInstance;
|
|
1594
|
+
this._seeker = Math.round(currentFrame / totalFrames * 100);
|
|
1595
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Frame, {
|
|
1596
|
+
detail: {
|
|
1597
|
+
frame: currentFrame,
|
|
1598
|
+
seeker: this._seeker
|
|
1599
|
+
}
|
|
1600
|
+
}));
|
|
1600
1601
|
}
|
|
1601
1602
|
/**
|
|
1602
|
-
*
|
|
1603
|
-
*
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
return;
|
|
1603
|
+
* Get options from props.
|
|
1604
|
+
*
|
|
1605
|
+
*/ _getOptions() {
|
|
1606
|
+
if (!this._container) {
|
|
1607
|
+
throw new Error('Container not rendered');
|
|
1608
1608
|
}
|
|
1609
|
-
|
|
1610
|
-
|
|
1609
|
+
const preserveAspectRatio = this.preserveAspectRatio ?? aspectRatio(this.objectfit), currentAnimationSettings = this._multiAnimationSettings.length > 0 ? this._multiAnimationSettings[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest?.animations[this._currentAnimation];
|
|
1610
|
+
// Loop
|
|
1611
|
+
let hasLoop = Boolean(this.loop);
|
|
1612
|
+
if (currentAnimationManifest?.loop !== undefined) {
|
|
1613
|
+
hasLoop = Boolean(currentAnimationManifest.loop);
|
|
1611
1614
|
}
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
this.dispatchEvent(new CustomEvent(PlayerEvents.Freeze));
|
|
1615
|
-
} finally{
|
|
1616
|
-
this.playerState = PlayerState.Frozen;
|
|
1615
|
+
if (currentAnimationSettings?.loop !== undefined) {
|
|
1616
|
+
hasLoop = Boolean(currentAnimationSettings.loop);
|
|
1617
1617
|
}
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
if (!this._lottieInstance || !this.src) {
|
|
1623
|
-
return;
|
|
1618
|
+
// Autoplay
|
|
1619
|
+
let hasAutoplay = Boolean(this.autoplay);
|
|
1620
|
+
if (currentAnimationManifest?.autoplay !== undefined) {
|
|
1621
|
+
hasAutoplay = Boolean(currentAnimationManifest.autoplay);
|
|
1624
1622
|
}
|
|
1625
|
-
|
|
1626
|
-
|
|
1623
|
+
if (currentAnimationSettings?.autoplay !== undefined) {
|
|
1624
|
+
hasAutoplay = Boolean(currentAnimationSettings.autoplay);
|
|
1625
|
+
}
|
|
1626
|
+
if (this.animateOnScroll) {
|
|
1627
|
+
hasAutoplay = false;
|
|
1628
|
+
}
|
|
1629
|
+
// Segment
|
|
1630
|
+
let initialSegment = this._segment;
|
|
1631
|
+
if (this._segment?.every((val)=>val > 0)) {
|
|
1632
|
+
initialSegment = [
|
|
1633
|
+
this._segment[0] - 1,
|
|
1634
|
+
this._segment[1] - 1
|
|
1635
|
+
];
|
|
1636
|
+
}
|
|
1637
|
+
if (this._segment?.some((val)=>val < 0)) {
|
|
1638
|
+
initialSegment = undefined;
|
|
1639
|
+
}
|
|
1640
|
+
const options = {
|
|
1641
|
+
autoplay: hasAutoplay,
|
|
1642
|
+
container: this._container,
|
|
1643
|
+
initialSegment,
|
|
1644
|
+
loop: hasLoop,
|
|
1645
|
+
renderer: this.renderer,
|
|
1646
|
+
rendererSettings: {
|
|
1647
|
+
imagePreserveAspectRatio: preserveAspectRatio
|
|
1648
|
+
}
|
|
1649
|
+
};
|
|
1650
|
+
switch(this.renderer){
|
|
1651
|
+
case RendererType.SVG:
|
|
1652
|
+
{
|
|
1653
|
+
options.rendererSettings = {
|
|
1654
|
+
...options.rendererSettings,
|
|
1655
|
+
hideOnTransparent: true,
|
|
1656
|
+
preserveAspectRatio,
|
|
1657
|
+
progressiveLoad: true
|
|
1658
|
+
};
|
|
1659
|
+
break;
|
|
1660
|
+
}
|
|
1661
|
+
case RendererType.Canvas:
|
|
1662
|
+
{
|
|
1663
|
+
options.rendererSettings = {
|
|
1664
|
+
...options.rendererSettings,
|
|
1665
|
+
// @ts-expect-error TODO:
|
|
1666
|
+
clearCanvas: true,
|
|
1667
|
+
preserveAspectRatio,
|
|
1668
|
+
progressiveLoad: true
|
|
1669
|
+
};
|
|
1670
|
+
break;
|
|
1671
|
+
}
|
|
1672
|
+
case RendererType.HTML:
|
|
1673
|
+
{
|
|
1674
|
+
options.rendererSettings = {
|
|
1675
|
+
...options.rendererSettings,
|
|
1676
|
+
hideOnTransparent: true
|
|
1677
|
+
};
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
return options;
|
|
1627
1681
|
}
|
|
1628
1682
|
/**
|
|
1629
|
-
*
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
if (!this._lottieInstance) {
|
|
1683
|
+
* Handle scroll.
|
|
1684
|
+
*/ _handleScroll() {
|
|
1685
|
+
if (!this.animateOnScroll || !this._lottieInstance) {
|
|
1633
1686
|
return;
|
|
1634
1687
|
}
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
/**
|
|
1638
|
-
* Animation play direction
|
|
1639
|
-
* @param { AnimationDirection } value Animation direction
|
|
1640
|
-
*/ setDirection(value) {
|
|
1641
|
-
if (!this._lottieInstance) {
|
|
1688
|
+
if (isServer()) {
|
|
1689
|
+
console.warn('DotLottie: Scroll animations might not work properly in a Server Side Rendering context. Try to wrap this in a client component.');
|
|
1642
1690
|
return;
|
|
1643
1691
|
}
|
|
1644
|
-
this.
|
|
1692
|
+
if (this._playerState.visible) {
|
|
1693
|
+
if (this._playerState.scrollTimeout) {
|
|
1694
|
+
clearTimeout(this._playerState.scrollTimeout);
|
|
1695
|
+
}
|
|
1696
|
+
this._playerState.scrollTimeout = setTimeout(()=>{
|
|
1697
|
+
this.playerState = PlayerState.Paused;
|
|
1698
|
+
}, 400);
|
|
1699
|
+
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;
|
|
1700
|
+
requestAnimationFrame(()=>{
|
|
1701
|
+
if (roundedScroll < (this._lottieInstance?.totalFrames ?? 0)) {
|
|
1702
|
+
this.playerState = PlayerState.Playing;
|
|
1703
|
+
this._lottieInstance?.goToAndStop(roundedScroll, true);
|
|
1704
|
+
} else {
|
|
1705
|
+
this.playerState = PlayerState.Paused;
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1645
1709
|
}
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
if (
|
|
1651
|
-
|
|
1710
|
+
_handleWindowBlur({ type }) {
|
|
1711
|
+
if (this.playerState === PlayerState.Playing && type === 'blur') {
|
|
1712
|
+
this._freeze();
|
|
1713
|
+
}
|
|
1714
|
+
if (this.playerState === PlayerState.Frozen && type === 'focus') {
|
|
1715
|
+
this.play();
|
|
1652
1716
|
}
|
|
1653
|
-
this._lottieInstance.setLoop(value);
|
|
1654
1717
|
}
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1718
|
+
_isLottie(json) {
|
|
1719
|
+
const mandatory = [
|
|
1720
|
+
'v',
|
|
1721
|
+
'ip',
|
|
1722
|
+
'op',
|
|
1723
|
+
'layers',
|
|
1724
|
+
'fr',
|
|
1725
|
+
'w',
|
|
1726
|
+
'h'
|
|
1727
|
+
];
|
|
1728
|
+
return mandatory.every((field)=>Object.hasOwn(json, field));
|
|
1729
|
+
}
|
|
1730
|
+
_loopComplete() {
|
|
1658
1731
|
if (!this._lottieInstance) {
|
|
1659
1732
|
return;
|
|
1660
1733
|
}
|
|
1661
|
-
const {
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1734
|
+
const { playDirection, // firstFrame,
|
|
1735
|
+
totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
|
|
1736
|
+
if (this.count) {
|
|
1737
|
+
if (this._isBounce) {
|
|
1738
|
+
this._playerState.count += 0.5;
|
|
1739
|
+
} else {
|
|
1740
|
+
this._playerState.count += 1;
|
|
1741
|
+
}
|
|
1742
|
+
if (this._playerState.count >= this.count) {
|
|
1743
|
+
this.setLoop(false);
|
|
1744
|
+
this.playerState = PlayerState.Completed;
|
|
1745
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Complete));
|
|
1746
|
+
return;
|
|
1747
|
+
}
|
|
1667
1748
|
}
|
|
1668
|
-
this.
|
|
1749
|
+
this.dispatchEvent(new CustomEvent(PlayerEvents.Loop));
|
|
1669
1750
|
if (this._isBounce) {
|
|
1670
|
-
this.
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1751
|
+
this._lottieInstance.goToAndStop(playDirection === -1 ? inPoint : outPoint * 0.99, true);
|
|
1752
|
+
this._lottieInstance.setDirection(playDirection * -1);
|
|
1753
|
+
return setTimeout(()=>{
|
|
1754
|
+
if (!this.animateOnScroll) {
|
|
1755
|
+
this._lottieInstance?.play();
|
|
1756
|
+
}
|
|
1757
|
+
}, this.intermission);
|
|
1675
1758
|
}
|
|
1676
|
-
|
|
1759
|
+
this._lottieInstance.goToAndStop(playDirection === -1 ? outPoint * 0.99 : inPoint, true);
|
|
1760
|
+
return setTimeout(()=>{
|
|
1761
|
+
if (!this.animateOnScroll) {
|
|
1762
|
+
this._lottieInstance?.play();
|
|
1763
|
+
}
|
|
1764
|
+
}, this.intermission);
|
|
1677
1765
|
}
|
|
1678
1766
|
/**
|
|
1679
|
-
*
|
|
1680
|
-
*/
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1767
|
+
* Handle MouseEnter.
|
|
1768
|
+
*/ _mouseEnter() {
|
|
1769
|
+
if (this.hover && this.playerState !== PlayerState.Playing) {
|
|
1770
|
+
this.play();
|
|
1771
|
+
}
|
|
1684
1772
|
}
|
|
1685
1773
|
/**
|
|
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;
|
|
1774
|
+
* Handle MouseLeave.
|
|
1775
|
+
*/ _mouseLeave() {
|
|
1776
|
+
if (this.hover && this.playerState === PlayerState.Playing) {
|
|
1777
|
+
this.stop();
|
|
1703
1778
|
}
|
|
1704
|
-
this.mode = PlayMode.Normal;
|
|
1705
|
-
this._isBounce = false;
|
|
1706
1779
|
}
|
|
1707
1780
|
/**
|
|
1708
|
-
*
|
|
1709
|
-
*/
|
|
1710
|
-
if (
|
|
1711
|
-
this.
|
|
1781
|
+
* Handle visibility change events.
|
|
1782
|
+
*/ _onVisibilityChange() {
|
|
1783
|
+
if (document.hidden && this.playerState === PlayerState.Playing) {
|
|
1784
|
+
this._freeze();
|
|
1712
1785
|
return;
|
|
1713
1786
|
}
|
|
1714
|
-
this.
|
|
1787
|
+
if (this.playerState === PlayerState.Frozen) {
|
|
1788
|
+
this.play();
|
|
1789
|
+
}
|
|
1715
1790
|
}
|
|
1716
1791
|
/**
|
|
1717
|
-
*
|
|
1718
|
-
*/
|
|
1719
|
-
|
|
1792
|
+
* Remove event listeners.
|
|
1793
|
+
*/ _removeEventListeners() {
|
|
1794
|
+
this._toggleEventListeners('remove');
|
|
1720
1795
|
}
|
|
1721
1796
|
_switchInstance(isPrevious = false) {
|
|
1722
1797
|
// Bail early if there is not animation to play
|
|
@@ -1730,82 +1805,85 @@ var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-
|
|
|
1730
1805
|
}
|
|
1731
1806
|
// Re-initialize lottie player
|
|
1732
1807
|
// @ts-expect-error TODO:
|
|
1733
|
-
this._lottieInstance = Lottie.
|
|
1808
|
+
this._lottieInstance = Lottie.loadAnimation({
|
|
1734
1809
|
...this._getOptions(),
|
|
1735
1810
|
animationData: this._animations[this._currentAnimation]
|
|
1736
1811
|
});
|
|
1737
1812
|
// Check play mode for current animation
|
|
1738
|
-
if (this._multiAnimationSettings
|
|
1813
|
+
if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
|
|
1739
1814
|
this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
|
|
1740
1815
|
}
|
|
1741
1816
|
// Remove event listeners to new Lottie instance, and add new
|
|
1742
1817
|
this._removeEventListeners();
|
|
1743
1818
|
this._addEventListeners();
|
|
1744
1819
|
this.dispatchEvent(new CustomEvent(isPrevious ? PlayerEvents.Previous : PlayerEvents.Next));
|
|
1745
|
-
if (this._multiAnimationSettings
|
|
1820
|
+
if (this._multiAnimationSettings[this._currentAnimation]?.autoplay ?? this.autoplay) {
|
|
1746
1821
|
if (this.animateOnScroll) {
|
|
1747
|
-
this._lottieInstance
|
|
1822
|
+
this._lottieInstance.goToAndStop(0, true);
|
|
1748
1823
|
this.playerState = PlayerState.Paused;
|
|
1749
1824
|
return;
|
|
1750
1825
|
}
|
|
1751
|
-
this._lottieInstance
|
|
1826
|
+
this._lottieInstance.goToAndPlay(0, true);
|
|
1752
1827
|
this.playerState = PlayerState.Playing;
|
|
1753
1828
|
return;
|
|
1754
1829
|
}
|
|
1755
|
-
this._lottieInstance
|
|
1830
|
+
this._lottieInstance.goToAndStop(0, true);
|
|
1756
1831
|
this.playerState = PlayerState.Stopped;
|
|
1757
|
-
} catch (
|
|
1758
|
-
this._errorMessage = handleErrors(
|
|
1832
|
+
} catch (error) {
|
|
1833
|
+
this._errorMessage = handleErrors(error).message;
|
|
1759
1834
|
this.playerState = PlayerState.Error;
|
|
1760
1835
|
this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
|
|
1761
1836
|
}
|
|
1762
1837
|
}
|
|
1763
1838
|
/**
|
|
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
|
-
});
|
|
1839
|
+
* Toggle event listeners.
|
|
1840
|
+
*/ _toggleEventListeners(action) {
|
|
1841
|
+
const method = action === 'add' ? 'addEventListener' : 'removeEventListener';
|
|
1842
|
+
if (this._lottieInstance) {
|
|
1843
|
+
this._lottieInstance[method]('enterFrame', this._enterFrame);
|
|
1844
|
+
this._lottieInstance[method]('complete', this._complete);
|
|
1845
|
+
this._lottieInstance[method]('loopComplete', this._loopComplete);
|
|
1846
|
+
this._lottieInstance[method]('DOMLoaded', this._DOMLoaded);
|
|
1847
|
+
this._lottieInstance[method]('data_ready', this._dataReady);
|
|
1848
|
+
this._lottieInstance[method]('data_failed', this._dataFailed);
|
|
1782
1849
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1850
|
+
if (this._container && this.hover) {
|
|
1851
|
+
this._container[method]('mouseenter', this._mouseEnter);
|
|
1852
|
+
this._container[method]('mouseleave', this._mouseLeave);
|
|
1853
|
+
}
|
|
1854
|
+
window[method]('focus', this._handleWindowBlur, {
|
|
1855
|
+
capture: false,
|
|
1856
|
+
passive: true
|
|
1857
|
+
});
|
|
1858
|
+
window[method]('blur', this._handleWindowBlur, {
|
|
1859
|
+
capture: false,
|
|
1860
|
+
passive: true
|
|
1791
1861
|
});
|
|
1862
|
+
if (this.animateOnScroll) {
|
|
1863
|
+
window[method]('scroll', this._handleScroll, {
|
|
1864
|
+
capture: true,
|
|
1865
|
+
passive: true
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
1792
1868
|
}
|
|
1793
1869
|
/**
|
|
1794
|
-
*
|
|
1795
|
-
*/
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1870
|
+
* Toggle show Settings.
|
|
1871
|
+
*/ _toggleSettings(flag) {
|
|
1872
|
+
if (flag === undefined) {
|
|
1873
|
+
this._isSettingsOpen = !this._isSettingsOpen;
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
this._isSettingsOpen = flag;
|
|
1799
1877
|
}
|
|
1800
1878
|
}
|
|
1801
1879
|
|
|
1802
1880
|
/**
|
|
1803
|
-
* Expose DotLottiePlayer class as global variable
|
|
1804
|
-
*
|
|
1881
|
+
* Expose DotLottiePlayer class as global variable.
|
|
1882
|
+
*
|
|
1805
1883
|
*/ globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
|
|
1806
1884
|
const tagName = 'dotlottie-player';
|
|
1807
1885
|
if (!isServer()) {
|
|
1808
|
-
customElements.define(
|
|
1886
|
+
customElements.define(tagName, DotLottiePlayer);
|
|
1809
1887
|
}
|
|
1810
1888
|
|
|
1811
1889
|
export { PlayMode, PlayerEvents, PlayerState, DotLottiePlayer as default, tagName };
|