UNPKG

@exadel/esl

Version:

Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components

143 lines (142 loc) 6.79 kB
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; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var ESLCSSCarouselRenderer_1; import { promisifyNextRender } from '../../esl-utils/async/promise'; import { CSSClassUtils } from '../../esl-utils/dom/class'; import { ESLCarouselRenderer } from '../core/esl-carousel.renderer'; import { sign, bounds } from '../core/esl-carousel.utils'; import { ESLCarouselDirection } from '../core/esl-carousel.types'; let ESLCSSCarouselRenderer = ESLCSSCarouselRenderer_1 = class ESLCSSCarouselRenderer extends ESLCarouselRenderer { constructor() { super(...arguments); /** Active index */ this.currentIndex = 0; } get tolerance() { return this.$carousel.clientWidth * ESLCSSCarouselRenderer_1.NEXT_SLIDE_TOLERANCE; } get offset() { const offset = this.$area.style.getPropertyValue(ESLCSSCarouselRenderer_1.OFFSET_PROP); return parseFloat(offset) || 0; } set offset(offset) { if (offset) { const abs = Math.min(1, Math.abs(offset) / this.tolerance); this.$area.style.setProperty(ESLCSSCarouselRenderer_1.OFFSET_PROP, `${offset.toFixed(1)}px`); this.$area.style.setProperty(ESLCSSCarouselRenderer_1.OFFSET_PROP_REL, abs.toFixed(4)); } else { this.$area.style.removeProperty(ESLCSSCarouselRenderer_1.OFFSET_PROP); this.$area.style.removeProperty(ESLCSSCarouselRenderer_1.OFFSET_PROP_REL); } } /** * Processes binding of defined renderer to the carousel {@link ESLCarousel}. * Prepare to renderer animation. */ onBind() { this.currentIndex = bounds(this.$carousel.activeIndex, 0, this.size - this.count); this.setActive(this.currentIndex); } /** * Processes unbinding of defined view from the carousel {@link ESLCarousel}. * Clear animation. */ onUnbind() { this.animating = false; CSSClassUtils.remove(this.$area, 'forward backward'); } /** Processes animation. */ onAnimate(index, direction) { return __awaiter(this, void 0, void 0, function* () { const { $activeSlide } = this.$carousel; if (!$activeSlide) throw new Error('[ESL] Carousel: no active slide'); yield promisifyNextRender(); this.animating = true; this.$area.classList.add(direction === ESLCarouselDirection.NEXT ? 'forward' : 'backward'); yield promisifyNextRender(); yield this.transitionDuration$$; }); } /** Post-processing animation action. */ onAfterAnimate(index, direction, params) { const _super = Object.create(null, { onAfterAnimate: { get: () => super.onAfterAnimate } }); return __awaiter(this, void 0, void 0, function* () { this.currentIndex = index; this.animating = false; this.offset = 0; CSSClassUtils.remove(this.$area, 'forward backward'); return _super.onAfterAnimate.call(this, index, direction, params); }); } move(offset, from, params) { if (this.animating) return; const { $activeSlide } = this.$carousel; if (!$activeSlide) throw new Error('[ESL] Carousel: no active slide'); if (Math.abs(offset) > $activeSlide.offsetWidth) return; const direction = sign(-offset); const nextIndex = this.normalizeIndex(this.currentIndex + direction); const $nextSlide = this.$carousel.$slides[nextIndex]; if (!$nextSlide || $nextSlide === $activeSlide) return; const offsetBefore = this.offset; this.offset = offset; this.$carousel.$$attr('shifted', !!offset); this.setPreActive(nextIndex, Object.assign(Object.assign({}, params), { direction })); this.dispatchMoveEvent(offsetBefore, params); } commit(params) { return __awaiter(this, void 0, void 0, function* () { const { offset } = this; const $activeSlide = this.$carousel.$activeSlide; if (!$activeSlide) throw new Error('[ESL] Carousel: no active slide'); const dir = sign(-offset); const nextIndex = this.currentIndex + sign(-offset); const slideWidth = this.$carousel.clientWidth; const isBorderSlide = !this.loop && (nextIndex < 0 || nextIndex + this.count > this.size); const shouldChangeSlide = Math.abs(offset) >= slideWidth * ESLCSSCarouselRenderer_1.NEXT_SLIDE_TOLERANCE; this.animating = true; let direction = dir; if (!isBorderSlide && shouldChangeSlide) { this.offset = -1 * dir * slideWidth; this.currentIndex = this.normalizeIndex(nextIndex); } else { this.offset = 0; direction = -direction; } yield this.transitionDuration$$; this.$carousel.$$attr('shifted', false); yield this.onAfterAnimate(this.currentIndex, direction, params); }); } }; ESLCSSCarouselRenderer.is = 'css'; ESLCSSCarouselRenderer.classes = ['esl-carousel-css-renderer']; ESLCSSCarouselRenderer.NEXT_SLIDE_TOLERANCE = 0.25; ESLCSSCarouselRenderer.OFFSET_PROP = '--esl-carousel-offset'; ESLCSSCarouselRenderer.OFFSET_PROP_REL = '--esl-carousel-offset-ratio'; ESLCSSCarouselRenderer = ESLCSSCarouselRenderer_1 = __decorate([ ESLCarouselRenderer.register ], ESLCSSCarouselRenderer); export { ESLCSSCarouselRenderer };