@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
60 lines (59 loc) • 3.81 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { boolAttr } from '../../../esl-utils/decorators';
import { afterNextRender } from '../../../esl-utils/async/raf';
import { ESLCarouselAutoplayStateMixin } from './esl-carousel.autoplay.state.mixin';
/**
* A mixin (custom attribute) element that manages the progress animation for the autoplay functionality
* of an ESL Carousel. It extends the autoplay state mixin and adds progress/animation markers.
* Uses an exclusive autoplay state marker to represent autoplay progress:
* - `animate` attribute - appears on each cycle of active autoplay;
* drops one frame before the next cycle to activate CSS animation
* - `autoplay-state` attribute - indicates the current autoplay runtime state
* - `--esl-autoplay-timeout` CSS variable - indicates the remaining autoplay cycle duration
* - `--esl-autoplay-duration` CSS variable - indicates the full autoplay cycle duration
* - `--esl-autoplay-progress` CSS variable - indicates completed progress ratio (0..1)
*/
export class ESLCarouselAutoplayProgressMixin extends ESLCarouselAutoplayStateMixin {
disconnectedCallback() {
super.disconnectedCallback();
this.animate = false;
this.$host.style.removeProperty('--esl-autoplay-timeout');
this.$host.style.removeProperty('--esl-autoplay-duration');
this.$host.style.removeProperty('--esl-autoplay-progress');
}
isBlockedProgress(baseRemaining) {
var _a;
return !!((_a = this.autoplay) === null || _a === void 0 ? void 0 : _a.blocked) && baseRemaining > 0;
}
getProgressSnapshot() {
var _a, _b, _c;
const autoplay = this.autoplay;
const duration = Math.max((autoplay === null || autoplay === void 0 ? void 0 : autoplay.effectiveDuration) || 0, 0);
const active = (_a = autoplay === null || autoplay === void 0 ? void 0 : autoplay.active) !== null && _a !== void 0 ? _a : false;
const paused = (_b = autoplay === null || autoplay === void 0 ? void 0 : autoplay.paused) !== null && _b !== void 0 ? _b : false;
const baseRemaining = Math.max((_c = autoplay === null || autoplay === void 0 ? void 0 : autoplay.remaining) !== null && _c !== void 0 ? _c : 0, 0);
const isProgressState = active || paused || this.isBlockedProgress(baseRemaining);
const remaining = isProgressState ? baseRemaining : duration;
const elapsed = isProgressState ? Math.max(duration - remaining, 0) : 0;
const progress = duration > 0 ? Math.min(elapsed / duration, 1) : 0;
return { active, duration, remaining, progress };
}
syncState() {
super.syncState();
const { active, duration, remaining, progress } = this.getProgressSnapshot();
this.$host.style.setProperty('--esl-autoplay-timeout', `${remaining}ms`);
this.$host.style.setProperty('--esl-autoplay-duration', `${duration}ms`);
this.$host.style.setProperty('--esl-autoplay-progress', `${progress}`);
requestAnimationFrame(() => this.animate = false);
active && afterNextRender(() => this.animate = true);
}
}
ESLCarouselAutoplayProgressMixin.is = 'esl-carousel-autoplay-progress';
__decorate([
boolAttr()
], ESLCarouselAutoplayProgressMixin.prototype, "animate", void 0);