@aarsteinmedia/dotlottie-player 6.5.3 → 6.5.4
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/custom-elements.json +3 -3
- package/dist/canvas.d.ts +2 -2
- package/dist/canvas.js +2 -2
- package/dist/chunks/{DotLottiePlayerBase-B9TsipSe.js → DotLottiePlayerBase-D2f8vWzM.js} +458 -399
- package/dist/chunks/{constants.d-D4NjmiZl.d.ts → constants.d-D18TmCtN.d.ts} +40 -25
- package/dist/full.d.ts +2 -2
- package/dist/full.js +2 -2
- package/dist/light.d.ts +2 -2
- package/dist/light.js +2 -2
- package/dist/svg.d.ts +2 -2
- package/dist/svg.js +2 -2
- package/dist/unpkg-canvas.js +3 -3
- package/dist/unpkg-full.js +3 -3
- package/dist/unpkg-light.js +4 -2
- package/dist/unpkg-svg.js +3 -3
- package/package.json +11 -9
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getAnimationData } from '@aarsteinmedia/lottie-web/dotlottie';
|
|
2
|
-
import { isServer,
|
|
2
|
+
import { isServer, PreserveAspectRatio, PlayMode, RendererType, createElementID, clamp, PlayerEvent, download, getFilename } from '@aarsteinmedia/lottie-web/utils';
|
|
3
3
|
|
|
4
4
|
let modulePromise$1;
|
|
5
5
|
function loadControlsModule() {
|
|
@@ -73,45 +73,6 @@ if (isServer) {
|
|
|
73
73
|
|
|
74
74
|
var css_248z = "*{box-sizing:border-box}:host{--lottie-player-toolbar-height:35px;--lottie-player-toolbar-background-color:#fff;--lottie-player-toolbar-icon-color:#000;--lottie-player-toolbar-icon-hover-color:#000;--lottie-player-toolbar-icon-active-color:#4285f4;--lottie-player-seeker-track-color:#0003;--lottie-player-seeker-thumb-color:#4285f4;--lottie-player-seeker-display:block;height:100%;width:100%;&:not([hidden]){display:block}.main{display:flex;flex-direction:column;height:100%;margin:0;padding:0;width:100%}.animation{contain:content;display:flex;height:100%;margin:0;padding:0;width:100%;& svg g{will-change:transform}}[data-controls=true] .animation{height:calc(100% - 35px)}.animation-container{position:relative}.popover{animation:fade-in .2s ease-in-out;background-color:var(--lottie-player-toolbar-background-color);border:2px solid var(--lottie-player-toolbar-icon-color);border-radius:5px;bottom:40px;padding:10px 15px;position:absolute;right:5px;&:before{border:7px solid #0000;border-top:7px solid var(--lottie-player-toolbar-icon-color);content:\"\";height:0;margin-right:-7px;pointer-events:none;position:absolute;right:10px;top:100%;width:0}}.error{align-items:center;display:flex;height:100%;justify-content:center;margin:auto;& svg{height:auto;width:100%}}.toolbar{background:var(--lottie-player-toolbar-background-color);border-radius:5px;display:flex;gap:5px;height:35px;margin:0;padding:5px;place-items:center center;&.has-error{opacity:.5;pointer-events:none}& button{fill:var(--lottie-player-toolbar-icon-color);align-items:center;background:none;border:0;color:var(--lottie-player-toolbar-icon-color);cursor:pointer;gap:5px;height:100%;margin:0;opacity:.9;outline:0;padding:0;&:not([hidden]){display:flex}&:hover{opacity:1}&[data-active=true]{fill:var(--lottie-player-toolbar-icon-active-color);opacity:1}&:disabled{opacity:.5}&:focus{outline:0}& svg{pointer-events:none;&>*{fill:inherit}}&.disabled svg{display:none}}}.progress-container{position:relative;width:100%;&.simple{margin-right:12px}}& progress{appearance:none;background-color:var(--lottie-player-seeker-track-color);border:0;border-radius:3px;height:5px;left:0;margin:7.5px 0;outline:none;pointer-events:none;position:absolute;top:0;width:100%;&::-webkit-progress-inner-element{border-radius:3px;overflow:hidden}&::-webkit-slider-runnable-track{background-color:initial}&::-webkit-progress-value{background-color:var(--lottie-player-seeker-thumb-color)}}.seeker{appearance:none;background-color:initial;border:0;border-radius:3px;color:var(--lottie-player-seeker-thumb-color);cursor:pointer;display:var(--lottie-player-seeker-display);height:20px;margin:0;outline:none;padding:7.5px 0;position:relative;width:100%;z-index:1;&::-webkit-slider-runnable-track,&::-webkit-slider-thumb{appearance:none;outline:none}&::-webkit-slider-thumb{background-color:var(--lottie-player-seeker-thumb-color);border:0;border-radius:50%;cursor:pointer;height:15px;transform:scale(0);-webkit-transition:transform .2s ease-in-out;transition:transform .2s ease-in-out;width:15px}&:focus::-webkit-slider-thumb,&:hover::-webkit-slider-thumb{transform:scale(1)}&::-moz-range-progress{background-color:var(--lottie-player-seeker-thumb-color);border-radius:3px;height:5px}&::-moz-range-thumb{background-color:var(--lottie-player-seeker-thumb-color);border:0;border-radius:50%;cursor:pointer;height:15px;transform:scale(0);-moz-transition:transform .2s ease-in-out;transition:transform .2s ease-in-out;width:15px}&:focus::-moz-range-thumb,&:hover::-moz-range-thumb{transform:scale(1)}&::-ms-track{background:#0000;border-color:#0000;color:#0000;cursor:pointer;height:5px;width:100%}&::-ms-fill-upper{background:var(--lottie-player-seeker-track-color);border-radius:3px}&::-ms-fill-lower{background-color:var(--lottie-player-seeker-thumb-color);border-radius:3px}&::-ms-thumb{background:var(--lottie-player-seeker-thumb-color);border:0;border-radius:50%;cursor:pointer;height:15px;transform:scale(0);-ms-transition:transform .2s ease-in-out;transition:transform .2s ease-in-out;width:15px}&:hover::-ms-thumb{transform:scale(1)}&:focus{&::-ms-thumb{transform:scale(1)}&::-ms-fill-lower,&::-ms-fill-upper{background:var(--lottie-player-seeker-track-color)}}}& ::-moz-progress-bar{background-color:var(--lottie-player-seeker-thumb-color)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@media (prefers-color-scheme:dark){:host{--lottie-player-toolbar-background-color:#000;--lottie-player-toolbar-icon-color:#fff;--lottie-player-toolbar-icon-hover-color:#fff;--lottie-player-seeker-track-color:#fff9}}";
|
|
75
75
|
|
|
76
|
-
let dotlottieTools = null, loadPromise = null;
|
|
77
|
-
function loadDotLottieTools() {
|
|
78
|
-
if (dotlottieTools) {
|
|
79
|
-
return Promise.resolve(dotlottieTools);
|
|
80
|
-
}
|
|
81
|
-
loadPromise = loadPromise ?? (async ()=>{
|
|
82
|
-
const { addAnimation, convert } = await import('@aarsteinmedia/lottie-web/dotlottie');
|
|
83
|
-
dotlottieTools = {
|
|
84
|
-
addAnimation,
|
|
85
|
-
convert
|
|
86
|
-
};
|
|
87
|
-
return {
|
|
88
|
-
addAnimation,
|
|
89
|
-
convert
|
|
90
|
-
};
|
|
91
|
-
})();
|
|
92
|
-
return loadPromise;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const boomerangIcon = /* HTML */ `<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>`;
|
|
96
|
-
|
|
97
|
-
const convertIcon = /* HTML */ `<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>`;
|
|
98
|
-
|
|
99
|
-
const downloadIcon = /* HTML */ `<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>`;
|
|
100
|
-
|
|
101
|
-
const loopIcon = /* HTML */ `<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>`;
|
|
102
|
-
|
|
103
|
-
const nextIcon = /* HTML */ `<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>`;
|
|
104
|
-
|
|
105
|
-
const pauseIcon = /* 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>`;
|
|
106
|
-
|
|
107
|
-
const playIcon = /* 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>`;
|
|
108
|
-
|
|
109
|
-
const prevIcon = /* HTML */ `<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>`;
|
|
110
|
-
|
|
111
|
-
const settingsIcon = /* HTML */ `<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>`;
|
|
112
|
-
|
|
113
|
-
const stopIcon = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M6 6h12v12H6V6z"/></svg>`;
|
|
114
|
-
|
|
115
76
|
var ObjectFit = /*#__PURE__*/ function(ObjectFit) {
|
|
116
77
|
ObjectFit["Contain"] = "contain";
|
|
117
78
|
ObjectFit["Cover"] = "cover";
|
|
@@ -139,135 +100,6 @@ var PlayerState = /*#__PURE__*/ function(PlayerState) {
|
|
|
139
100
|
return PlayerState;
|
|
140
101
|
}({});
|
|
141
102
|
|
|
142
|
-
function advancedButtons() {
|
|
143
|
-
if (!this.shadow) {
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
const toggleLoop = this.shadow.querySelector('.toggleLoop');
|
|
147
|
-
if (toggleLoop instanceof HTMLButtonElement) {
|
|
148
|
-
toggleLoop.onclick = this.toggleLoop;
|
|
149
|
-
}
|
|
150
|
-
const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
|
|
151
|
-
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
152
|
-
toggleBoomerang.onclick = this.toggleBoomerang;
|
|
153
|
-
}
|
|
154
|
-
const convertButton = this.shadow.querySelector('.convert');
|
|
155
|
-
if (convertButton instanceof HTMLButtonElement) {
|
|
156
|
-
convertButton.onclick = async ()=>{
|
|
157
|
-
convertButton.disabled = true;
|
|
158
|
-
try {
|
|
159
|
-
const { convert } = await loadDotLottieTools();
|
|
160
|
-
await convert({
|
|
161
|
-
isDotLottie: this.isDotLottie,
|
|
162
|
-
manifest: this.getManifest(),
|
|
163
|
-
src: this.src || this.source
|
|
164
|
-
});
|
|
165
|
-
} finally{
|
|
166
|
-
convertButton.disabled = false;
|
|
167
|
-
}
|
|
168
|
-
};
|
|
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
|
-
function handleButtons() {
|
|
181
|
-
if (!this.shadow) {
|
|
182
|
-
return;
|
|
183
|
-
}
|
|
184
|
-
const togglePlay = this.shadow.querySelector('.togglePlay');
|
|
185
|
-
if (togglePlay instanceof HTMLButtonElement) {
|
|
186
|
-
togglePlay.onclick = this.togglePlay;
|
|
187
|
-
}
|
|
188
|
-
const stopButton = this.shadow.querySelector('.stop');
|
|
189
|
-
if (stopButton instanceof HTMLButtonElement) {
|
|
190
|
-
stopButton.onclick = this.stop;
|
|
191
|
-
}
|
|
192
|
-
const prevButton = this.shadow.querySelector('.prev');
|
|
193
|
-
if (prevButton instanceof HTMLButtonElement) {
|
|
194
|
-
if (this.animations.length > 0 && this.currentAnimation) {
|
|
195
|
-
prevButton.hidden = false;
|
|
196
|
-
}
|
|
197
|
-
prevButton.onclick = this.prev;
|
|
198
|
-
}
|
|
199
|
-
const nextButton = this.shadow.querySelector('.next');
|
|
200
|
-
if (nextButton instanceof HTMLButtonElement) {
|
|
201
|
-
if (this.animations.length > 0 && this.currentAnimation < this.animations.length - 1) {
|
|
202
|
-
nextButton.hidden = false;
|
|
203
|
-
}
|
|
204
|
-
nextButton.onclick = this.next;
|
|
205
|
-
}
|
|
206
|
-
const seeker = this.shadow.querySelector('.seeker');
|
|
207
|
-
if (seeker instanceof HTMLInputElement) {
|
|
208
|
-
seeker.onchange = this._handleSeekChange;
|
|
209
|
-
seeker.onmousedown = this._freeze;
|
|
210
|
-
}
|
|
211
|
-
if (this.simple) {
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
advancedButtons.call(this);
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Render Controls.
|
|
218
|
-
*/ function renderControls() {
|
|
219
|
-
if (!this.shadow) {
|
|
220
|
-
throw new Error('No Shadow Element');
|
|
221
|
-
}
|
|
222
|
-
const slot = this.shadow.querySelector('slot[name=controls]');
|
|
223
|
-
if (!slot) {
|
|
224
|
-
return;
|
|
225
|
-
}
|
|
226
|
-
if (!this.controls) {
|
|
227
|
-
slot.innerHTML = '';
|
|
228
|
-
return;
|
|
229
|
-
}
|
|
230
|
-
const convertLabel = this.isDotLottie ? 'dotLottie animation to JSON format' : 'JSON animation to dotLottie format', convertButtonText = this.isDotLottie ? 'Convert to JSON' : 'Convert to dotLottie';
|
|
231
|
-
slot.innerHTML = /* HTML */ `<div class="lottie-controls toolbar ${this.playerState === PlayerState.Error ? 'has-error' : ''}" aria-label="Lottie Animation controls"><button class="togglePlay" data-active="${this.autoplay}" aria-label="Toggle Play/Pause">${playIcon}</button> <button class="stop" data-active="${!this.autoplay}" aria-label="Stop">${stopIcon}</button> <button class="prev" aria-label="Previous animation" hidden="false">${prevIcon}</button> <button class="next" aria-label="Next animation" hidden>${nextIcon}</button><form class="progress-container${this.simple ? ' simple' : ''}"><input type="range" class="seeker" min="0" max="100" step="1" value="${this._seeker.toString()}" aria-valuemin="0" aria-valuemax="100" 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">${loopIcon}</button> <button class="toggleBoomerang" data-active="${this.mode === PlayMode.Bounce}" aria-label="Toggle boomerang" tabindex="0">${boomerangIcon}</button> <button class="toggleSettings" aria-label="Settings" aria-haspopup="true" aria-expanded="${this._isSettingsOpen}" aria-controls="${this._identifier}-settings">${settingsIcon}</button><div id="${this._identifier}-settings" class="popover" hidden><button class="convert" aria-label="Convert ${convertLabel}" hidden>${convertIcon} ${convertButtonText}</button> <button class="snapshot" aria-label="Download still image">${downloadIcon} Download still image</button></div>`}</div>`;
|
|
232
|
-
handleButtons.call(this);
|
|
233
|
-
}
|
|
234
|
-
function updatePlayPauseButton(togglePlay, state) {
|
|
235
|
-
const isActive = state === PlayerState.Playing || state === PlayerState.Paused;
|
|
236
|
-
togglePlay.dataset.active = isActive.toString();
|
|
237
|
-
togglePlay.innerHTML = state === PlayerState.Playing ? pauseIcon : playIcon;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
var controls = /*#__PURE__*/Object.freeze({
|
|
241
|
-
__proto__: null,
|
|
242
|
-
renderControls: renderControls,
|
|
243
|
-
updatePlayPauseButton: updatePlayPauseButton
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Render Player.
|
|
248
|
-
*/ async function renderPlayer() {
|
|
249
|
-
if (!this.shadow || !this.template) {
|
|
250
|
-
throw new Error('No Shadow Element or Template');
|
|
251
|
-
}
|
|
252
|
-
let langAttribute = '';
|
|
253
|
-
/**
|
|
254
|
-
* If player has aria-description, it's safe to assume
|
|
255
|
-
* language should be the same as `document.documentElement.lang`.
|
|
256
|
-
* Accessible labels on controls are only in English, so with no
|
|
257
|
-
* aria tag, and controls enabled, lang should reflect this.
|
|
258
|
-
* With neither controls or description, the lang attribute is
|
|
259
|
-
* not needed.
|
|
260
|
-
*/ if (this.description || this.controls) {
|
|
261
|
-
const lang = this.description ? document.documentElement.lang : 'en';
|
|
262
|
-
langAttribute = `lang="${lang}"`;
|
|
263
|
-
}
|
|
264
|
-
this.template.innerHTML = /* HTML */ `<div class="animation-container main" data-controls="${this.controls ?? false}" ${langAttribute}><figure class="animation" style="background:${this.background}" ${this.description ? `aria-label="${this.description}"` : ''}></figure><slot name="controls"></slot></div>`;
|
|
265
|
-
this.shadow.adoptedStyleSheets = [
|
|
266
|
-
await DotLottiePlayerBase.styles()
|
|
267
|
-
];
|
|
268
|
-
this.shadow.appendChild(this.template.content.cloneNode(true));
|
|
269
|
-
}
|
|
270
|
-
|
|
271
103
|
/**
|
|
272
104
|
* Get extension from filename, URL or path.
|
|
273
105
|
*/ const aspectRatio = (objectFit)=>{
|
|
@@ -334,42 +166,12 @@ var controls = /*#__PURE__*/Object.freeze({
|
|
|
334
166
|
|
|
335
167
|
const tagName = 'dotlottie-player', hasReducedMotion = !isServer && matchMedia('(prefers-reduced-motion: reduce)').matches, hasIOSupport = !isServer && 'IntersectionObserver' in window, hasVTSupport = !isServer && 'ViewTimeline' in window;
|
|
336
168
|
|
|
337
|
-
const
|
|
169
|
+
const getStyles = async ()=>{
|
|
338
170
|
const styleSheet = new CSSStyleSheet();
|
|
339
171
|
await styleSheet.replace(css_248z);
|
|
340
172
|
return styleSheet;
|
|
341
|
-
};
|
|
342
|
-
|
|
343
|
-
* DotLottie Player Web Component.
|
|
344
|
-
*/ class DotLottiePlayerBase extends PropertyCallbackElement {
|
|
345
|
-
/**
|
|
346
|
-
* Attributes to observe.
|
|
347
|
-
*/ static get observedAttributes() {
|
|
348
|
-
return [
|
|
349
|
-
'animateOnScroll',
|
|
350
|
-
'autoplay',
|
|
351
|
-
'controls',
|
|
352
|
-
'direction',
|
|
353
|
-
'hover',
|
|
354
|
-
'loop',
|
|
355
|
-
'mode',
|
|
356
|
-
'playOnClick',
|
|
357
|
-
'playOnVisible',
|
|
358
|
-
'selector',
|
|
359
|
-
'speed',
|
|
360
|
-
'src',
|
|
361
|
-
'subframe'
|
|
362
|
-
];
|
|
363
|
-
}
|
|
364
|
-
static get observedProperties() {
|
|
365
|
-
return [
|
|
366
|
-
'playerState',
|
|
367
|
-
'_isSettingsOpen',
|
|
368
|
-
'_seeker',
|
|
369
|
-
'_currentAnimation',
|
|
370
|
-
'_animations'
|
|
371
|
-
];
|
|
372
|
-
}
|
|
173
|
+
}, notImplemented$1 = 'Method is not implemented';
|
|
174
|
+
class BaseElement extends PropertyCallbackElement {
|
|
373
175
|
/**
|
|
374
176
|
* Return the styles for the component.
|
|
375
177
|
*/ static get styles() {
|
|
@@ -492,9 +294,6 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
492
294
|
}
|
|
493
295
|
return 0;
|
|
494
296
|
}
|
|
495
|
-
get isDotLottie() {
|
|
496
|
-
return this._isDotLottie;
|
|
497
|
-
}
|
|
498
297
|
/**
|
|
499
298
|
* Loop animation.
|
|
500
299
|
*/ set loop(value) {
|
|
@@ -588,99 +387,463 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
588
387
|
}
|
|
589
388
|
return null;
|
|
590
389
|
}
|
|
591
|
-
/**
|
|
592
|
-
* Whether to display error screen on load error.
|
|
593
|
-
*/ set quiet(value) {
|
|
594
|
-
this.setAttribute('quiet', Boolean(value).toString());
|
|
390
|
+
/**
|
|
391
|
+
* Whether to display error screen on load error.
|
|
392
|
+
*/ set quiet(value) {
|
|
393
|
+
this.setAttribute('quiet', Boolean(value).toString());
|
|
394
|
+
}
|
|
395
|
+
get quiet() {
|
|
396
|
+
const val = this.getAttribute('quiet');
|
|
397
|
+
return parseHTMLBooleans(val);
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Renderer to use: svg, canvas or html.
|
|
401
|
+
*/ set renderer(value) {
|
|
402
|
+
this.setAttribute('renderer', value);
|
|
403
|
+
}
|
|
404
|
+
get renderer() {
|
|
405
|
+
const val = this.getAttribute('renderer');
|
|
406
|
+
if (val === RendererType.Canvas || val === RendererType.HTML) {
|
|
407
|
+
return val;
|
|
408
|
+
}
|
|
409
|
+
return RendererType.SVG;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Play on clicked element by id attribute, other than animation.
|
|
413
|
+
*/ set selector(value) {
|
|
414
|
+
if (value) {
|
|
415
|
+
this.setAttribute('selector', value);
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
this.removeAttribute('selector');
|
|
419
|
+
}
|
|
420
|
+
get selector() {
|
|
421
|
+
return this.getAttribute('selector');
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Hide advanced controls.
|
|
425
|
+
*/ set simple(value) {
|
|
426
|
+
this.setAttribute('simple', Boolean(value).toString());
|
|
427
|
+
}
|
|
428
|
+
get simple() {
|
|
429
|
+
const val = this.getAttribute('simple');
|
|
430
|
+
return parseHTMLBooleans(val);
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* Speed.
|
|
434
|
+
*/ set speed(value) {
|
|
435
|
+
this.setAttribute('speed', value.toString());
|
|
436
|
+
}
|
|
437
|
+
get speed() {
|
|
438
|
+
const val = this.getAttribute('speed');
|
|
439
|
+
if (val !== null && !isNaN(Number(val))) {
|
|
440
|
+
return Number(val);
|
|
441
|
+
}
|
|
442
|
+
return 1;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Source, either path or JSON string.
|
|
446
|
+
*/ set src(value) {
|
|
447
|
+
this.setAttribute('src', value || '');
|
|
448
|
+
}
|
|
449
|
+
get src() {
|
|
450
|
+
return this.getAttribute('src');
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Subframe.
|
|
454
|
+
*/ set subframe(value) {
|
|
455
|
+
this.setAttribute('subframe', Boolean(value).toString());
|
|
456
|
+
}
|
|
457
|
+
get subframe() {
|
|
458
|
+
const val = this.getAttribute('subframe');
|
|
459
|
+
return parseHTMLBooleans(val);
|
|
460
|
+
}
|
|
461
|
+
clearDevLog() {
|
|
462
|
+
this._toLog = null;
|
|
463
|
+
}
|
|
464
|
+
devLog(toLog, type = 'error') {
|
|
465
|
+
{
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
play() {
|
|
470
|
+
throw new Error(notImplemented$1);
|
|
471
|
+
}
|
|
472
|
+
_freeze() {
|
|
473
|
+
throw new Error(notImplemented$1);
|
|
474
|
+
}
|
|
475
|
+
constructor(...args){
|
|
476
|
+
super(...args), /**
|
|
477
|
+
* Player state.
|
|
478
|
+
*/ this.playerState = PlayerState.Loading, /**
|
|
479
|
+
* This is included in watched properties,
|
|
480
|
+
* so that next-button will show up
|
|
481
|
+
* on load, if controls are visible.
|
|
482
|
+
*/ this._animations = [], /**
|
|
483
|
+
* Animation Container.
|
|
484
|
+
*/ this._container = null, /**
|
|
485
|
+
* Which animation to show, if several.
|
|
486
|
+
*/ this._currentAnimation = 0, this._errorMessage = 'Something went wrong', this._identifier = this.id || createElementID(), this._lottieInstance = null, this._playerState = {
|
|
487
|
+
count: 0,
|
|
488
|
+
frame: 0,
|
|
489
|
+
loaded: false,
|
|
490
|
+
playTimeout: null,
|
|
491
|
+
prev: PlayerState.Loading
|
|
492
|
+
}, this._toLog = null;
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
class ScrollElement extends BaseElement {
|
|
497
|
+
applyScrollProgress() {
|
|
498
|
+
if (!this.animateOnScroll || !this._lottieInstance) {
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
const progress = this._getScrollProgress();
|
|
502
|
+
if (progress === null) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
const { totalFrames } = this._lottieInstance, frame = progress * (totalFrames - 1), epsilon = this.subframe ? 0.1 : 0.5;
|
|
506
|
+
if (Math.abs(frame - this._playerState.frame) < epsilon) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
this._playerState.frame = frame;
|
|
510
|
+
this._lottieInstance.goToAndStop(frame, true);
|
|
511
|
+
}
|
|
512
|
+
cancelIntersectionObserver() {
|
|
513
|
+
// Remove intersection observer for detecting component being out-of-view
|
|
514
|
+
this._intersectionObserver?.disconnect();
|
|
515
|
+
this._intersectionObserver = undefined;
|
|
516
|
+
}
|
|
517
|
+
cancelScrollProbe() {
|
|
518
|
+
this._scrollProbe?.cancel();
|
|
519
|
+
this._scrollProbe = undefined;
|
|
520
|
+
}
|
|
521
|
+
scrollLoop() {
|
|
522
|
+
this._playerState.scrollLoopId = requestAnimationFrame(this.scrollLoop);
|
|
523
|
+
this.applyScrollProgress();
|
|
524
|
+
}
|
|
525
|
+
startScrollLoop() {
|
|
526
|
+
if (isServer) {
|
|
527
|
+
this.devLog('DotLottie: Scroll animations will not work in a Server Side Rendering context. Try to wrap this in a client component.');
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
this._playerState.scrollLoopId ??= requestAnimationFrame(this.scrollLoop);
|
|
531
|
+
}
|
|
532
|
+
stopScrollLoop() {
|
|
533
|
+
if (this._playerState.scrollLoopId === undefined) {
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
cancelAnimationFrame(this._playerState.scrollLoopId);
|
|
537
|
+
this._playerState.scrollLoopId = undefined;
|
|
538
|
+
this.applyScrollProgress();
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Add IntersectionObserver.
|
|
542
|
+
*/ _addIntersectionObserver() {
|
|
543
|
+
if (!this._container || this._intersectionObserver || !hasIOSupport) {
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
this._intersectionObserver = new IntersectionObserver(([{ isIntersecting }])=>{
|
|
547
|
+
this.isIntersecting = isIntersecting;
|
|
548
|
+
// Prevent animate on scroll for users with who prefers reduces motion.
|
|
549
|
+
if (this.animateOnScroll && !hasReducedMotion) {
|
|
550
|
+
if (isIntersecting) {
|
|
551
|
+
this.startScrollLoop();
|
|
552
|
+
} else {
|
|
553
|
+
this.stopScrollLoop();
|
|
554
|
+
}
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
if (!isIntersecting || document.hidden) {
|
|
558
|
+
if (this.playerState === PlayerState.Playing) {
|
|
559
|
+
this._freeze();
|
|
560
|
+
}
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
if (!this.playOnVisible && this.playerState === PlayerState.Frozen && !(this.autoplay && hasReducedMotion)) {
|
|
564
|
+
this.play();
|
|
565
|
+
}
|
|
566
|
+
if (!this.playOnVisible || hasReducedMotion) {
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
if (this.playerState === PlayerState.Completed && !this.once) {
|
|
570
|
+
this.playerState = PlayerState.Playing;
|
|
571
|
+
this._lottieInstance?.goToAndPlay(this.direction === 1 ? 0 : this._lottieInstance.totalFrames);
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
this._playerState.playTimeout = setTimeout(()=>{
|
|
575
|
+
this.play();
|
|
576
|
+
}, this.delay);
|
|
577
|
+
if (this.playerState === PlayerState.Playing) {
|
|
578
|
+
clearTimeout(this._playerState.playTimeout);
|
|
579
|
+
}
|
|
580
|
+
});
|
|
581
|
+
this._observeIntersectionTarget();
|
|
582
|
+
}
|
|
583
|
+
_canDriveTimeline({ source }) {
|
|
584
|
+
if (!source || source === document.scrollingElement) {
|
|
585
|
+
return true;
|
|
586
|
+
}
|
|
587
|
+
return getComputedStyle(source).overflowY !== 'hidden' && source.scrollHeight > source.clientHeight;
|
|
588
|
+
}
|
|
589
|
+
_getGeometricScrollProgress() {
|
|
590
|
+
if (!this._container) {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
const { height, top } = this._container.getBoundingClientRect(), viewport = visualViewport?.height ?? innerHeight;
|
|
594
|
+
return clamp((viewport - top) / (viewport + height), 0, 1);
|
|
595
|
+
}
|
|
596
|
+
_getScrollProgress() {
|
|
597
|
+
if (!this._container) {
|
|
598
|
+
return null;
|
|
599
|
+
}
|
|
600
|
+
if (!hasVTSupport) {
|
|
601
|
+
return this._getGeometricScrollProgress();
|
|
602
|
+
}
|
|
603
|
+
const timeline = new ViewTimeline({
|
|
604
|
+
axis: 'block',
|
|
605
|
+
subject: this._container
|
|
606
|
+
}), canDriveTimeline = this._canDriveTimeline(timeline);
|
|
607
|
+
if (!canDriveTimeline) {
|
|
608
|
+
this.devLog('[dotlottie-player] animateOnScroll: the player\'s nearest scrolling ancestor cannot ' + 'scroll, so its ViewTimeline would never advance. This is almost always an ancestor ' + 'with `overflow: hidden` — use `overflow: clip` instead. Falling back to viewport ' + 'measurement.');
|
|
609
|
+
return this._getGeometricScrollProgress();
|
|
610
|
+
}
|
|
611
|
+
this._scrollProbe ??= this._container.animate({
|
|
612
|
+
'--dotlottie-scroll': [
|
|
613
|
+
0,
|
|
614
|
+
1
|
|
615
|
+
]
|
|
616
|
+
}, {
|
|
617
|
+
fill: 'both',
|
|
618
|
+
rangeEnd: 'cover 100%',
|
|
619
|
+
rangeStart: 'cover 0%',
|
|
620
|
+
timeline
|
|
621
|
+
});
|
|
622
|
+
return this._scrollProbe.effect?.getComputedTiming().progress ?? null;
|
|
623
|
+
}
|
|
624
|
+
_observeIntersectionTarget() {
|
|
625
|
+
if (!this._intersectionObserver || !this._container) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
this._intersectionObserver.disconnect();
|
|
629
|
+
// Observing the host is more reliable than inner shadow nodes when ancestors
|
|
630
|
+
// use overflow-* (IO / layout interaction quirks).
|
|
631
|
+
this._intersectionObserver.observe(this._container);
|
|
632
|
+
}
|
|
633
|
+
constructor(...args){
|
|
634
|
+
super(...args), this.isIntersecting = false;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
let dotlottieTools = null, loadPromise = null;
|
|
639
|
+
function loadDotLottieTools() {
|
|
640
|
+
if (dotlottieTools) {
|
|
641
|
+
return Promise.resolve(dotlottieTools);
|
|
642
|
+
}
|
|
643
|
+
loadPromise = loadPromise ?? (async ()=>{
|
|
644
|
+
const { addAnimation, convert } = await import('@aarsteinmedia/lottie-web/dotlottie');
|
|
645
|
+
dotlottieTools = {
|
|
646
|
+
addAnimation,
|
|
647
|
+
convert
|
|
648
|
+
};
|
|
649
|
+
return {
|
|
650
|
+
addAnimation,
|
|
651
|
+
convert
|
|
652
|
+
};
|
|
653
|
+
})();
|
|
654
|
+
return loadPromise;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
const boomerangIcon = /* HTML */ `<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>`;
|
|
658
|
+
|
|
659
|
+
const convertIcon = /* HTML */ `<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>`;
|
|
660
|
+
|
|
661
|
+
const downloadIcon = /* HTML */ `<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>`;
|
|
662
|
+
|
|
663
|
+
const loopIcon = /* HTML */ `<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>`;
|
|
664
|
+
|
|
665
|
+
const nextIcon = /* HTML */ `<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>`;
|
|
666
|
+
|
|
667
|
+
const pauseIcon = /* 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>`;
|
|
668
|
+
|
|
669
|
+
const playIcon = /* 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>`;
|
|
670
|
+
|
|
671
|
+
const prevIcon = /* HTML */ `<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>`;
|
|
672
|
+
|
|
673
|
+
const settingsIcon = /* HTML */ `<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>`;
|
|
674
|
+
|
|
675
|
+
const stopIcon = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M6 6h12v12H6V6z"/></svg>`;
|
|
676
|
+
|
|
677
|
+
function advancedButtons() {
|
|
678
|
+
if (!this.shadow) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const toggleLoop = this.shadow.querySelector('.toggleLoop');
|
|
682
|
+
if (toggleLoop instanceof HTMLButtonElement) {
|
|
683
|
+
toggleLoop.onclick = this.toggleLoop;
|
|
684
|
+
}
|
|
685
|
+
const toggleBoomerang = this.shadow.querySelector('.toggleBoomerang');
|
|
686
|
+
if (toggleBoomerang instanceof HTMLButtonElement) {
|
|
687
|
+
toggleBoomerang.onclick = this.toggleBoomerang;
|
|
688
|
+
}
|
|
689
|
+
const convertButton = this.shadow.querySelector('.convert');
|
|
690
|
+
if (convertButton instanceof HTMLButtonElement) {
|
|
691
|
+
convertButton.onclick = async ()=>{
|
|
692
|
+
convertButton.disabled = true;
|
|
693
|
+
try {
|
|
694
|
+
const { convert } = await loadDotLottieTools();
|
|
695
|
+
await convert({
|
|
696
|
+
isDotLottie: this.isDotLottie,
|
|
697
|
+
manifest: this.getManifest(),
|
|
698
|
+
src: this.src || this.source
|
|
699
|
+
});
|
|
700
|
+
} finally{
|
|
701
|
+
convertButton.disabled = false;
|
|
702
|
+
}
|
|
703
|
+
};
|
|
704
|
+
}
|
|
705
|
+
const snapshot = this.shadow.querySelector('.snapshot');
|
|
706
|
+
if (snapshot instanceof HTMLButtonElement) {
|
|
707
|
+
snapshot.onclick = ()=>this.snapshot(true);
|
|
708
|
+
}
|
|
709
|
+
const toggleSettings = this.shadow.querySelector('.toggleSettings');
|
|
710
|
+
if (toggleSettings instanceof HTMLButtonElement) {
|
|
711
|
+
toggleSettings.onclick = this._handleSettingsClick;
|
|
712
|
+
toggleSettings.onblur = this._handleBlur;
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
function handleButtons() {
|
|
716
|
+
if (!this.shadow) {
|
|
717
|
+
return;
|
|
595
718
|
}
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
719
|
+
const togglePlay = this.shadow.querySelector('.togglePlay');
|
|
720
|
+
if (togglePlay instanceof HTMLButtonElement) {
|
|
721
|
+
togglePlay.onclick = this.togglePlay;
|
|
599
722
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
this.setAttribute('renderer', value);
|
|
723
|
+
const stopButton = this.shadow.querySelector('.stop');
|
|
724
|
+
if (stopButton instanceof HTMLButtonElement) {
|
|
725
|
+
stopButton.onclick = this.stop;
|
|
604
726
|
}
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
if (
|
|
608
|
-
|
|
727
|
+
const prevButton = this.shadow.querySelector('.prev');
|
|
728
|
+
if (prevButton instanceof HTMLButtonElement) {
|
|
729
|
+
if (this.animations.length > 0 && this.currentAnimation) {
|
|
730
|
+
prevButton.hidden = false;
|
|
609
731
|
}
|
|
610
|
-
|
|
732
|
+
prevButton.onclick = this.prev;
|
|
611
733
|
}
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
this.setAttribute('selector', value);
|
|
617
|
-
return;
|
|
734
|
+
const nextButton = this.shadow.querySelector('.next');
|
|
735
|
+
if (nextButton instanceof HTMLButtonElement) {
|
|
736
|
+
if (this.animations.length > 0 && this.currentAnimation < this.animations.length - 1) {
|
|
737
|
+
nextButton.hidden = false;
|
|
618
738
|
}
|
|
619
|
-
this.
|
|
739
|
+
nextButton.onclick = this.next;
|
|
620
740
|
}
|
|
621
|
-
|
|
622
|
-
|
|
741
|
+
const seeker = this.shadow.querySelector('.seeker');
|
|
742
|
+
if (seeker instanceof HTMLInputElement) {
|
|
743
|
+
seeker.onchange = this._handleSeekChange;
|
|
744
|
+
seeker.onmousedown = this._freeze;
|
|
623
745
|
}
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
*/ set simple(value) {
|
|
627
|
-
this.setAttribute('simple', Boolean(value).toString());
|
|
746
|
+
if (this.simple) {
|
|
747
|
+
return;
|
|
628
748
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
749
|
+
advancedButtons.call(this);
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Render Controls.
|
|
753
|
+
*/ function renderControls() {
|
|
754
|
+
if (!this.shadow) {
|
|
755
|
+
throw new Error('No Shadow Element');
|
|
632
756
|
}
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
this.setAttribute('speed', value.toString());
|
|
757
|
+
const slot = this.shadow.querySelector('slot[name=controls]');
|
|
758
|
+
if (!slot) {
|
|
759
|
+
return;
|
|
637
760
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
return Number(val);
|
|
642
|
-
}
|
|
643
|
-
return 1;
|
|
761
|
+
if (!this.controls) {
|
|
762
|
+
slot.innerHTML = '';
|
|
763
|
+
return;
|
|
644
764
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
765
|
+
const convertLabel = this.isDotLottie ? 'dotLottie animation to JSON format' : 'JSON animation to dotLottie format', convertButtonText = this.isDotLottie ? 'Convert to JSON' : 'Convert to dotLottie';
|
|
766
|
+
slot.innerHTML = /* HTML */ `<div class="lottie-controls toolbar ${this.playerState === PlayerState.Error ? 'has-error' : ''}" aria-label="Lottie Animation controls"><button class="togglePlay" data-active="${this.autoplay}" aria-label="Toggle Play/Pause">${playIcon}</button> <button class="stop" data-active="${!this.autoplay}" aria-label="Stop">${stopIcon}</button> <button class="prev" aria-label="Previous animation" hidden="false">${prevIcon}</button> <button class="next" aria-label="Next animation" hidden>${nextIcon}</button><form class="progress-container${this.simple ? ' simple' : ''}"><input type="range" class="seeker" min="0" max="100" step="1" value="${this._seeker.toString()}" aria-valuemin="0" aria-valuemax="100" 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">${loopIcon}</button> <button class="toggleBoomerang" data-active="${this.mode === PlayMode.Bounce}" aria-label="Toggle boomerang" tabindex="0">${boomerangIcon}</button> <button class="toggleSettings" aria-label="Settings" aria-haspopup="true" aria-expanded="${this._isSettingsOpen}" aria-controls="${this._identifier}-settings">${settingsIcon}</button><div id="${this._identifier}-settings" class="popover" hidden><button class="convert" aria-label="Convert ${convertLabel}" hidden>${convertIcon} ${convertButtonText}</button> <button class="snapshot" aria-label="Download still image">${downloadIcon} Download still image</button></div>`}</div>`;
|
|
767
|
+
handleButtons.call(this);
|
|
768
|
+
}
|
|
769
|
+
function updatePlayPauseButton(togglePlay, state) {
|
|
770
|
+
const isActive = state === PlayerState.Playing || state === PlayerState.Paused;
|
|
771
|
+
togglePlay.dataset.active = isActive.toString();
|
|
772
|
+
togglePlay.innerHTML = state === PlayerState.Playing ? pauseIcon : playIcon;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
var controls = /*#__PURE__*/Object.freeze({
|
|
776
|
+
__proto__: null,
|
|
777
|
+
renderControls: renderControls,
|
|
778
|
+
updatePlayPauseButton: updatePlayPauseButton
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* Render Player.
|
|
783
|
+
*/ async function renderPlayer() {
|
|
784
|
+
if (!this.shadow || !this.template) {
|
|
785
|
+
throw new Error('No Shadow Element or Template');
|
|
649
786
|
}
|
|
650
|
-
|
|
651
|
-
|
|
787
|
+
let langAttribute = '';
|
|
788
|
+
/**
|
|
789
|
+
* If player has aria-description, it's safe to assume
|
|
790
|
+
* language should be the same as `document.documentElement.lang`.
|
|
791
|
+
* Accessible labels on controls are only in English, so with no
|
|
792
|
+
* aria tag, and controls enabled, lang should reflect this.
|
|
793
|
+
* With neither controls or description, the lang attribute is
|
|
794
|
+
* not needed.
|
|
795
|
+
*/ if (this.description || this.controls) {
|
|
796
|
+
const lang = this.description ? document.documentElement.lang : 'en';
|
|
797
|
+
langAttribute = `lang="${lang}"`;
|
|
652
798
|
}
|
|
799
|
+
this.template.innerHTML = /* HTML */ `<div class="animation-container main" data-controls="${this.controls ?? false}" ${langAttribute}><figure class="animation" style="background:${this.background}" ${this.description ? `aria-label="${this.description}"` : ''}></figure><slot name="controls"></slot></div>`;
|
|
800
|
+
this.shadow.adoptedStyleSheets = [
|
|
801
|
+
await DotLottiePlayerBase.styles()
|
|
802
|
+
];
|
|
803
|
+
this.shadow.appendChild(this.template.content.cloneNode(true));
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
const notImplemented = 'Method is not implemented';
|
|
807
|
+
/**
|
|
808
|
+
* DotLottie Player Web Component.
|
|
809
|
+
*/ class DotLottiePlayerBase extends ScrollElement {
|
|
653
810
|
/**
|
|
654
|
-
*
|
|
655
|
-
*/
|
|
656
|
-
|
|
811
|
+
* Attributes to observe.
|
|
812
|
+
*/ static get observedAttributes() {
|
|
813
|
+
return [
|
|
814
|
+
'animateOnScroll',
|
|
815
|
+
'autoplay',
|
|
816
|
+
'controls',
|
|
817
|
+
'direction',
|
|
818
|
+
'hover',
|
|
819
|
+
'loop',
|
|
820
|
+
'mode',
|
|
821
|
+
'playOnClick',
|
|
822
|
+
'playOnVisible',
|
|
823
|
+
'selector',
|
|
824
|
+
'speed',
|
|
825
|
+
'src',
|
|
826
|
+
'subframe'
|
|
827
|
+
];
|
|
657
828
|
}
|
|
658
|
-
get
|
|
659
|
-
|
|
660
|
-
|
|
829
|
+
static get observedProperties() {
|
|
830
|
+
return [
|
|
831
|
+
'playerState',
|
|
832
|
+
'_isSettingsOpen',
|
|
833
|
+
'_seeker',
|
|
834
|
+
'_currentAnimation',
|
|
835
|
+
'_animations'
|
|
836
|
+
];
|
|
837
|
+
}
|
|
838
|
+
get isDotLottie() {
|
|
839
|
+
return this._isDotLottie;
|
|
661
840
|
}
|
|
662
841
|
constructor(){
|
|
663
842
|
super(), this.isLight = false, /**
|
|
664
|
-
* Player state.
|
|
665
|
-
*/ this.playerState = PlayerState.Loading, /**
|
|
666
|
-
* Animation Container.
|
|
667
|
-
*/ this._container = null, this._errorMessage = 'Something went wrong', this._identifier = this.id || createElementID(), /**
|
|
668
843
|
* Whether settings toolbar is open.
|
|
669
|
-
*/ this._isSettingsOpen = false, this.
|
|
670
|
-
count: 0,
|
|
671
|
-
frame: 0,
|
|
672
|
-
loaded: false,
|
|
673
|
-
playTimeout: null,
|
|
674
|
-
prev: PlayerState.Loading
|
|
675
|
-
}, this._render = renderPlayer, /**
|
|
844
|
+
*/ this._isSettingsOpen = false, this._render = renderPlayer, /**
|
|
676
845
|
* Seeker.
|
|
677
|
-
*/ this._seeker = 0, /**
|
|
678
|
-
* This is included in watched properties,
|
|
679
|
-
* so that next-button will show up
|
|
680
|
-
* on load, if controls are visible.
|
|
681
|
-
*/ this._animations = [], this._controlsLoadId = 0, /**
|
|
682
|
-
* Which animation to show, if several.
|
|
683
|
-
*/ this._currentAnimation = 0, this._errorLoadId = 0, this._isBounce = false, this._isDotLottie = false, this._isIntersecting = false, this._lottieInstance = null, /**
|
|
846
|
+
*/ this._seeker = 0, this._controlsLoadId = 0, this._errorLoadId = 0, this._isBounce = false, this._isDotLottie = false, /**
|
|
684
847
|
* Multi-animation settings.
|
|
685
848
|
*/ this._multiAnimationSettings = [], this._renderControls = async ()=>{
|
|
686
849
|
const slot = this.shadow?.querySelector('slot[name=controls]');
|
|
@@ -711,7 +874,8 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
711
874
|
this._mouseEnter = this._mouseEnter.bind(this);
|
|
712
875
|
this._mouseLeave = this._mouseLeave.bind(this);
|
|
713
876
|
this._onVisibilityChange = this._onVisibilityChange.bind(this);
|
|
714
|
-
this.
|
|
877
|
+
this.scrollLoop = this.scrollLoop.bind(this);
|
|
878
|
+
// this.startScrollLoop = this.startScrollLoop.bind(this)
|
|
715
879
|
this._switchInstance = this._switchInstance.bind(this);
|
|
716
880
|
this._handleSettingsClick = this._handleSettingsClick.bind(this);
|
|
717
881
|
this.togglePlay = this.togglePlay.bind(this);
|
|
@@ -737,17 +901,18 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
737
901
|
if (!this._lottieInstance || !this.shadow || !this._container) {
|
|
738
902
|
return;
|
|
739
903
|
}
|
|
904
|
+
this.clearDevLog();
|
|
740
905
|
switch(name){
|
|
741
906
|
case 'animateOnScroll':
|
|
742
907
|
{
|
|
743
908
|
if (value === '' || Boolean(value)) {
|
|
744
909
|
this._lottieInstance.autoplay = false;
|
|
745
|
-
if (this.
|
|
746
|
-
this.
|
|
910
|
+
if (this.isIntersecting) {
|
|
911
|
+
this.startScrollLoop();
|
|
747
912
|
}
|
|
748
913
|
return;
|
|
749
914
|
}
|
|
750
|
-
this.
|
|
915
|
+
this.stopScrollLoop();
|
|
751
916
|
break;
|
|
752
917
|
}
|
|
753
918
|
case 'autoplay':
|
|
@@ -885,11 +1050,11 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
885
1050
|
if (!this._lottieInstance?.destroy) {
|
|
886
1051
|
return;
|
|
887
1052
|
}
|
|
888
|
-
this.
|
|
1053
|
+
this.cancelScrollProbe();
|
|
889
1054
|
this.playerState = PlayerState.Destroyed;
|
|
890
1055
|
this._lottieInstance.destroy();
|
|
891
1056
|
this._lottieInstance = null;
|
|
892
|
-
this.
|
|
1057
|
+
this.stopScrollLoop();
|
|
893
1058
|
this.dispatchEvent(new CustomEvent(PlayerEvent.Destroyed));
|
|
894
1059
|
this.remove();
|
|
895
1060
|
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
@@ -897,10 +1062,8 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
897
1062
|
/**
|
|
898
1063
|
* Cleanup on component destroy.
|
|
899
1064
|
*/ disconnectedCallback() {
|
|
900
|
-
|
|
901
|
-
this.
|
|
902
|
-
this._intersectionObserver = undefined;
|
|
903
|
-
this._cancelScrollProbe();
|
|
1065
|
+
this.cancelIntersectionObserver();
|
|
1066
|
+
this.cancelScrollProbe();
|
|
904
1067
|
if (this._playerState.scrollLoopId) {
|
|
905
1068
|
cancelAnimationFrame(this._playerState.scrollLoopId);
|
|
906
1069
|
}
|
|
@@ -911,6 +1074,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
911
1074
|
document.removeEventListener('visibilitychange', this._onVisibilityChange);
|
|
912
1075
|
// Destroy the animation instance
|
|
913
1076
|
this.destroy();
|
|
1077
|
+
this.clearDevLog();
|
|
914
1078
|
}
|
|
915
1079
|
/**
|
|
916
1080
|
* Returns the lottie-web instance used in the component.
|
|
@@ -990,7 +1154,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
990
1154
|
this._lottieInstance.setSubframe(Boolean(this.subframe));
|
|
991
1155
|
// Set progress on load if AnimateOnScroll
|
|
992
1156
|
if (this.animateOnScroll) {
|
|
993
|
-
this.
|
|
1157
|
+
this.applyScrollProgress();
|
|
994
1158
|
}
|
|
995
1159
|
// Start playing if autoplay is enabled
|
|
996
1160
|
if ((this.autoplay || this.animateOnScroll || this.playOnVisible) && this.direction === -1) {
|
|
@@ -1023,7 +1187,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1023
1187
|
this.dispatchEvent(new CustomEvent(PlayerEvent.Pause));
|
|
1024
1188
|
} catch (error) {
|
|
1025
1189
|
hasError = true;
|
|
1026
|
-
|
|
1190
|
+
this.devLog(error);
|
|
1027
1191
|
} finally{
|
|
1028
1192
|
this.playerState = hasError ? PlayerState.Error : PlayerState.Paused;
|
|
1029
1193
|
}
|
|
@@ -1041,7 +1205,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1041
1205
|
this.dispatchEvent(new CustomEvent(PlayerEvent.Play));
|
|
1042
1206
|
} catch (error) {
|
|
1043
1207
|
hasError = true;
|
|
1044
|
-
|
|
1208
|
+
this.devLog(error);
|
|
1045
1209
|
} finally{
|
|
1046
1210
|
this.playerState = hasError ? PlayerState.Error : PlayerState.Playing;
|
|
1047
1211
|
}
|
|
@@ -1197,7 +1361,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1197
1361
|
}
|
|
1198
1362
|
return data;
|
|
1199
1363
|
} catch (error) {
|
|
1200
|
-
|
|
1364
|
+
this.devLog(error);
|
|
1201
1365
|
return null;
|
|
1202
1366
|
}
|
|
1203
1367
|
}
|
|
@@ -1350,68 +1514,6 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1350
1514
|
*/ _addEventListeners() {
|
|
1351
1515
|
this._toggleEventListeners('add');
|
|
1352
1516
|
}
|
|
1353
|
-
/**
|
|
1354
|
-
* Add IntersectionObserver.
|
|
1355
|
-
*/ _addIntersectionObserver() {
|
|
1356
|
-
if (!this._container || this._intersectionObserver || !hasIOSupport) {
|
|
1357
|
-
return;
|
|
1358
|
-
}
|
|
1359
|
-
this._intersectionObserver = new IntersectionObserver(([{ isIntersecting }])=>{
|
|
1360
|
-
this._isIntersecting = isIntersecting;
|
|
1361
|
-
// Prevent animate on scroll for users with who prefers reduces motion.
|
|
1362
|
-
if (this.animateOnScroll && !hasReducedMotion) {
|
|
1363
|
-
if (isIntersecting) {
|
|
1364
|
-
this._startScrollLoop();
|
|
1365
|
-
} else {
|
|
1366
|
-
this._stopScrollLoop();
|
|
1367
|
-
}
|
|
1368
|
-
return;
|
|
1369
|
-
}
|
|
1370
|
-
if (!isIntersecting || document.hidden) {
|
|
1371
|
-
if (this.playerState === PlayerState.Playing) {
|
|
1372
|
-
this._freeze();
|
|
1373
|
-
}
|
|
1374
|
-
return;
|
|
1375
|
-
}
|
|
1376
|
-
if (!this.playOnVisible && this.playerState === PlayerState.Frozen && !(this.autoplay && hasReducedMotion)) {
|
|
1377
|
-
this.play();
|
|
1378
|
-
}
|
|
1379
|
-
if (!this.playOnVisible || hasReducedMotion) {
|
|
1380
|
-
return;
|
|
1381
|
-
}
|
|
1382
|
-
if (this.playerState === PlayerState.Completed && !this.once) {
|
|
1383
|
-
this.playerState = PlayerState.Playing;
|
|
1384
|
-
this._lottieInstance?.goToAndPlay(this.direction === 1 ? 0 : this._lottieInstance.totalFrames);
|
|
1385
|
-
return;
|
|
1386
|
-
}
|
|
1387
|
-
this._playerState.playTimeout = setTimeout(()=>{
|
|
1388
|
-
this.play();
|
|
1389
|
-
}, this.delay);
|
|
1390
|
-
if (this.playerState === PlayerState.Playing) {
|
|
1391
|
-
clearTimeout(this._playerState.playTimeout);
|
|
1392
|
-
}
|
|
1393
|
-
});
|
|
1394
|
-
this._intersectionObserver.observe(this._container);
|
|
1395
|
-
}
|
|
1396
|
-
_applyScrollProgress() {
|
|
1397
|
-
if (!this.animateOnScroll || !this._lottieInstance) {
|
|
1398
|
-
return;
|
|
1399
|
-
}
|
|
1400
|
-
const progress = this._getScrollProgress();
|
|
1401
|
-
if (progress === null) {
|
|
1402
|
-
return;
|
|
1403
|
-
}
|
|
1404
|
-
const { totalFrames } = this._lottieInstance, frame = progress * (totalFrames - 1), epsilon = this.subframe ? 0.1 : 0.5;
|
|
1405
|
-
if (Math.abs(frame - this._playerState.frame) < epsilon) {
|
|
1406
|
-
return;
|
|
1407
|
-
}
|
|
1408
|
-
this._playerState.frame = frame;
|
|
1409
|
-
this._lottieInstance.goToAndStop(frame, true);
|
|
1410
|
-
}
|
|
1411
|
-
_cancelScrollProbe() {
|
|
1412
|
-
this._scrollProbe?.cancel();
|
|
1413
|
-
this._scrollProbe = undefined;
|
|
1414
|
-
}
|
|
1415
1517
|
_clearPrevious() {
|
|
1416
1518
|
this._lottieInstance?.destroy();
|
|
1417
1519
|
const figure = this.shadow?.querySelector('.animation');
|
|
@@ -1514,30 +1616,6 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1514
1616
|
rendererType: this.renderer
|
|
1515
1617
|
});
|
|
1516
1618
|
}
|
|
1517
|
-
_getScrollProgress() {
|
|
1518
|
-
if (!this._container) {
|
|
1519
|
-
return null;
|
|
1520
|
-
}
|
|
1521
|
-
if (hasVTSupport) {
|
|
1522
|
-
this._scrollProbe ??= this._container.animate({
|
|
1523
|
-
'--dotlottie-scroll': [
|
|
1524
|
-
0,
|
|
1525
|
-
1
|
|
1526
|
-
]
|
|
1527
|
-
}, {
|
|
1528
|
-
fill: 'both',
|
|
1529
|
-
rangeEnd: 'cover 100%',
|
|
1530
|
-
rangeStart: 'cover 0%',
|
|
1531
|
-
timeline: new ViewTimeline({
|
|
1532
|
-
axis: 'block',
|
|
1533
|
-
subject: this._container
|
|
1534
|
-
})
|
|
1535
|
-
});
|
|
1536
|
-
return this._scrollProbe.effect?.getComputedTiming().progress ?? null;
|
|
1537
|
-
}
|
|
1538
|
-
const { height, top } = this._container.getBoundingClientRect(), viewport = visualViewport?.height ?? innerHeight;
|
|
1539
|
-
return clamp((viewport - top) / (viewport + height), 0, 1);
|
|
1540
|
-
}
|
|
1541
1619
|
async _handleError(error) {
|
|
1542
1620
|
this.playerState = PlayerState.Error;
|
|
1543
1621
|
if (!this.quiet) {
|
|
@@ -1545,7 +1623,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1545
1623
|
await this._showError();
|
|
1546
1624
|
}
|
|
1547
1625
|
this.dispatchEvent(new CustomEvent(PlayerEvent.Error));
|
|
1548
|
-
|
|
1626
|
+
this.devLog(error);
|
|
1549
1627
|
}
|
|
1550
1628
|
_handleLdScript() {
|
|
1551
1629
|
const ldScript = this.parentElement?.querySelector('script[type="application/ld+json"]');
|
|
@@ -1691,25 +1769,6 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1691
1769
|
*/ _removeEventListeners() {
|
|
1692
1770
|
this._toggleEventListeners('remove');
|
|
1693
1771
|
}
|
|
1694
|
-
_scrollLoop() {
|
|
1695
|
-
this._playerState.scrollLoopId = requestAnimationFrame(this._scrollLoop);
|
|
1696
|
-
this._applyScrollProgress();
|
|
1697
|
-
}
|
|
1698
|
-
_startScrollLoop() {
|
|
1699
|
-
if (isServer) {
|
|
1700
|
-
console.warn('DotLottie: Scroll animations will not work in a Server Side Rendering context. Try to wrap this in a client component.');
|
|
1701
|
-
return;
|
|
1702
|
-
}
|
|
1703
|
-
this._playerState.scrollLoopId ??= requestAnimationFrame(this._scrollLoop);
|
|
1704
|
-
}
|
|
1705
|
-
_stopScrollLoop() {
|
|
1706
|
-
if (this._playerState.scrollLoopId === undefined) {
|
|
1707
|
-
return;
|
|
1708
|
-
}
|
|
1709
|
-
cancelAnimationFrame(this._playerState.scrollLoopId);
|
|
1710
|
-
this._playerState.scrollLoopId = undefined;
|
|
1711
|
-
this._applyScrollProgress();
|
|
1712
|
-
}
|
|
1713
1772
|
_switchInstance(isPrevious = false) {
|
|
1714
1773
|
// Bail early if there is not animation to play
|
|
1715
1774
|
if (!this._animations[this._currentAnimation]) {
|
|
@@ -1718,7 +1777,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1718
1777
|
try {
|
|
1719
1778
|
// Clear previous animation
|
|
1720
1779
|
this._lottieInstance?.destroy();
|
|
1721
|
-
this.
|
|
1780
|
+
this.cancelScrollProbe();
|
|
1722
1781
|
// Re-initialize lottie player
|
|
1723
1782
|
this._lottieInstance = this.loadAnimation({
|
|
1724
1783
|
...this._getOptions(),
|
|
@@ -1735,7 +1794,7 @@ const notImplemented = 'Method is not implemented', getStyles = async ()=>{
|
|
|
1735
1794
|
if (this._multiAnimationSettings[this._currentAnimation]?.autoplay ?? this.autoplay) {
|
|
1736
1795
|
if (this.animateOnScroll) {
|
|
1737
1796
|
// Get instant scroll position
|
|
1738
|
-
this.
|
|
1797
|
+
this.applyScrollProgress();
|
|
1739
1798
|
this.playerState = PlayerState.Paused;
|
|
1740
1799
|
return;
|
|
1741
1800
|
}
|