angular-gallery
Version:
Responsive gallery for Angular with touch screen support.
1,262 lines (1,256 loc) • 56.9 kB
JavaScript
import { __decorate } from 'tslib';
import { Injectable, EventEmitter, ElementRef, ChangeDetectorRef, Input, Output, HostBinding, HostListener, Component, ViewContainerRef, Directive, ComponentFactoryResolver, ViewChild, ApplicationRef, Injector, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReplaySubject } from 'rxjs';
class Touches {
constructor(properties) {
this.eventType = undefined;
this.handlers = {};
this.startX = 0;
this.startY = 0;
this.lastTap = 0;
this.doubleTapMinTimeout = 300;
this.tapMinTimeout = 200;
this.touchstartTime = 0;
this.i = 0;
this.isMousedown = false;
this.touchListeners = {
"touchstart": "handleTouchstart",
"touchmove": "handleTouchmove",
"touchend": "handleTouchend"
};
this.mouseListeners = {
"mousedown": "handleMousedown",
"mousemove": "handleMousemove",
"mouseup": "handleMouseup",
"wheel": "handleWheel"
};
this.otherListeners = {
"resize": "handleResize"
};
/*
* Listeners
*/
/* Touchstart */
this.handleTouchstart = (event) => {
this.elementPosition = this.getElementPosition();
this.touchstartTime = new Date().getTime();
if (this.eventType === undefined) {
this.getTouchstartPosition(event);
}
this.runHandler("touchstart", event);
};
/* Touchmove */
this.handleTouchmove = (event) => {
const touches = event.touches;
// Pan
if (this.detectPan(touches)) {
this.runHandler("pan", event);
}
// Pinch
if (this.detectPinch(event)) {
this.runHandler("pinch", event);
}
// Linear swipe
switch (this.detectLinearSwipe(event)) {
case "horizontal-swipe":
event.swipeType = "horizontal-swipe";
this.runHandler("horizontal-swipe", event);
break;
case "vertical-swipe":
event.swipeType = "vertical-swipe";
this.runHandler("vertical-swipe", event);
break;
}
// Linear swipe
if (this.detectLinearSwipe(event) ||
this.eventType === 'horizontal-swipe' ||
this.eventType === 'vertical-swipe') {
this.handleLinearSwipe(event);
}
};
/* Touchend */
this.handleTouchend = (event) => {
const touches = event.touches;
// Double Tap
if (this.detectDoubleTap()) {
this.runHandler("double-tap", event);
}
// Tap
this.detectTap();
this.runHandler("touchend", event);
this.eventType = 'touchend';
if (touches && touches.length === 0) {
this.eventType = undefined;
this.i = 0;
}
};
/* Mousedown */
this.handleMousedown = (event) => {
this.isMousedown = true;
this.elementPosition = this.getElementPosition();
this.touchstartTime = new Date().getTime();
if (this.eventType === undefined) {
this.getMousedownPosition(event);
}
this.runHandler("mousedown", event);
};
/* Mousemove */
this.handleMousemove = (event) => {
//event.preventDefault();
if (!this.isMousedown) {
return;
}
// Pan
this.runHandler("pan", event);
// Linear swipe
switch (this.detectLinearSwipe(event)) {
case "horizontal-swipe":
event.swipeType = "horizontal-swipe";
this.runHandler("horizontal-swipe", event);
break;
case "vertical-swipe":
event.swipeType = "vertical-swipe";
this.runHandler("vertical-swipe", event);
break;
}
// Linear swipe
if (this.detectLinearSwipe(event) ||
this.eventType === 'horizontal-swipe' ||
this.eventType === 'vertical-swipe') {
this.handleLinearSwipe(event);
}
};
/* Mouseup */
this.handleMouseup = (event) => {
// Tap
this.detectTap();
this.isMousedown = false;
this.runHandler("mouseup", event);
this.eventType = undefined;
this.i = 0;
};
/* Wheel */
this.handleWheel = (event) => {
this.runHandler("wheel", event);
};
/* Resize */
this.handleResize = (event) => {
this.runHandler("resize", event);
};
this.properties = properties;
this.element = this.properties.element;
this.elementPosition = this.getElementPosition();
this.toggleEventListeners('addEventListener');
}
destroy() {
this.toggleEventListeners('removeEventListener');
}
toggleEventListeners(action) {
let listeners;
if (this.properties.listeners === 'mouse and touch') {
listeners = Object.assign(this.touchListeners, this.mouseListeners);
}
else {
listeners = this.detectTouchScreen() ? this.touchListeners : this.mouseListeners;
}
if (this.properties.resize) {
listeners = Object.assign(listeners, this.otherListeners);
}
for (var listener in listeners) {
const handler = listeners[listener];
// Window
if (listener === "resize") {
if (action === 'addEventListener') {
window.addEventListener(listener, this[handler], false);
}
if (action === 'removeEventListener') {
window.removeEventListener(listener, this[handler], false);
}
// Document
}
else if (listener === 'mouseup' || listener === "mousemove") {
if (action === 'addEventListener') {
document.addEventListener(listener, this[handler], false);
}
if (action === 'removeEventListener') {
document.removeEventListener(listener, this[handler], false);
}
// Element
}
else {
if (action === 'addEventListener') {
this.element.addEventListener(listener, this[handler], false);
}
if (action === 'removeEventListener') {
this.element.removeEventListener(listener, this[handler], false);
}
}
}
}
handleLinearSwipe(event) {
//event.preventDefault();
this.i++;
if (this.i > 3) {
this.eventType = this.getLinearSwipeType(event);
}
if (this.eventType === 'horizontal-swipe') {
this.runHandler('horizontal-swipe', event);
}
if (this.eventType === 'vertical-swipe') {
this.runHandler('vertical-swipe', event);
}
}
runHandler(eventName, response) {
if (this.handlers[eventName]) {
this.handlers[eventName](response);
}
}
/*
* Detection
*/
detectPan(touches) {
return touches.length === 1 && !this.eventType || this.eventType === 'pan';
}
detectDoubleTap() {
if (this.eventType != undefined) {
return;
}
const currentTime = new Date().getTime();
const tapLength = currentTime - this.lastTap;
clearTimeout(this.doubleTapTimeout);
if (tapLength < this.doubleTapMinTimeout && tapLength > 0) {
return true;
}
else {
this.doubleTapTimeout = setTimeout(() => {
clearTimeout(this.doubleTapTimeout);
}, this.doubleTapMinTimeout);
}
this.lastTap = currentTime;
}
detectTap() {
if (this.eventType != undefined) {
return;
}
const currentTime = new Date().getTime();
const tapLength = currentTime - this.touchstartTime;
if (tapLength > 0) {
if (tapLength < this.tapMinTimeout) {
this.runHandler("tap", event);
}
else {
this.runHandler("longtap", event);
}
}
}
detectPinch(event) {
const touches = event.touches;
return (touches.length === 2 && this.eventType === undefined) || this.eventType === 'pinch';
}
detectLinearSwipe(event) {
const touches = event.touches;
if (touches) {
if (touches.length === 1 && !this.eventType || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') {
return this.getLinearSwipeType(event);
}
}
else {
if (!this.eventType || this.eventType === 'horizontal-swipe' || this.eventType === 'vertical-swipe') {
return this.getLinearSwipeType(event);
}
}
}
getLinearSwipeType(event) {
if (this.eventType !== 'horizontal-swipe' && this.eventType !== 'vertical-swipe') {
const movementX = Math.abs(this.moveLeft(0, event) - this.startX);
const movementY = Math.abs(this.moveTop(0, event) - this.startY);
if ((movementY * 3) > movementX) {
return 'vertical-swipe';
}
else {
return 'horizontal-swipe';
}
}
else {
return this.eventType;
}
}
getElementPosition() {
return this.element.getBoundingClientRect();
}
getTouchstartPosition(event) {
this.startX = event.touches[0].clientX - this.elementPosition.left;
this.startY = event.touches[0].clientY - this.elementPosition.top;
}
getMousedownPosition(event) {
this.startX = event.clientX - this.elementPosition.left;
this.startY = event.clientY - this.elementPosition.top;
}
moveLeft(index, event) {
const touches = event.touches;
if (touches) {
return touches[index].clientX - this.elementPosition.left;
}
else {
return event.clientX - this.elementPosition.left;
}
}
moveTop(index, event) {
const touches = event.touches;
if (touches) {
return touches[index].clientY - this.elementPosition.top;
}
else {
return event.clientY - this.elementPosition.top;
}
}
detectTouchScreen() {
var prefixes = ' -webkit- -moz- -o- -ms- '.split(' ');
var mq = function (query) {
return window.matchMedia(query).matches;
};
if (('ontouchstart' in window)) {
return true;
}
// include the 'heartz' as a way to have a non matching MQ to help terminate the join
// https://git.io/vznFH
var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join('');
return mq(query);
}
/* Public properties and methods */
on(event, handler) {
if (event) {
this.handlers[event] = handler;
}
}
}
class Carousel {
constructor(properties) {
this.initialPositionX = 0;
this.newContainerPositionIndex = 0; // The index of the new position relative to the active index, for example -1 or +1
this.preliminarySlideCounter = 0;
this.slideCounter = 0; // Scrolling Index (counter)
this.previousSlideCounter = 0;
this.isContentImages = true;
this.isLazyLoad = true;
this.isContainerLocked = false;
this.alignCells = "left";
this.initialContainerPosition = 0;
this.handleTouchstart = (event) => {
this.isTouchstart = true;
if (this.isSlideInProgress) {
return;
}
const touches = event.touches;
if (touches) {
this.startX = touches[0].clientX - this.getCarouselElementPosition()['left'];
}
else {
this.startX = event.clientX - this.getCarouselElementPosition()['left'];
}
this.containerInitialPositionX = this.getElementPosition()['left'] - this.getCarouselElementPosition()['left'];
this.isMoveInProgress = true;
};
this.handleHorizontalSwipe = (event) => {
if (this.isSlideInProgress) {
return;
}
const touches = event.touches;
if (touches) {
this.moveX = touches[0].clientX - this.getCarouselElementPosition()['left'];
}
else {
this.moveX = event.clientX - this.getCarouselElementPosition()['left'];
}
this.distanceAbs = this.getDistanceAbs();
this.direction = this.getDirection();
this.moveContainer();
};
this.handleTouchend = (event) => {
if (this.isSlideInProgress || !this.isTouchstart) {
this.isTouchstart = false;
return;
}
this.isMoveInProgress = false;
if (this.detectSlide()) {
this.handleSlide();
}
else {
this.newContainerPositionIndex = 0;
this.alignContainer();
}
this.startX = this.moveX = this.distanceAbs = undefined;
this.isTouchstart = false;
};
this.element = properties.element;
this.properties = properties;
this.cells = this.element.children;
this.visibleWidth = this.properties.visibleWidth || this.element.parentElement.clientWidth;
this.setContainerWidth();
this.alignContainer(0);
}
get isFirstCell() {
return this.slideCounter === 0;
}
get lastCellIndex() {
return this.images.length ? (this.images.length - 1) : (this.cells.length - 1);
}
get overflowCellsLimit() {
return this.properties.overflowCellsLimit;
}
get cellLimit() {
return this.visibleCellsCount + this.overflowCellsLimit * 2;
}
get images() {
return this.properties.images;
}
get margin() {
return this.properties.margin;
}
get minSwipeDistance() {
return this.properties.minSwipeDistance;
}
get transitionDuration() {
return this.properties.transitionDuration;
}
get transitionTimingFunction() {
return this.properties.transitionTimingFunction;
}
get fullCellWidth() {
return this.properties.cellWidth + this.margin;
}
get visibleCellsCount() {
return Math.ceil(this.visibleWidth / this.fullCellWidth);
}
get lapCounter() {
return Math.floor(this.slideCounter / this.totalContainerCellsCount);
}
get visibleCellsOverflowContainer() {
return (this.visibleCellsCount * this.fullCellWidth - this.margin) > this.visibleWidth;
}
/* Move */
moveContainer() {
let positionX = this.getMovePositionX();
this.transformPositionX(positionX, 0);
}
getMovePositionX() {
const distance = this.getDistance();
return this.containerInitialPositionX - distance;
}
/* Align */
alignContainer(duration = this.transitionDuration) {
let positionX = this.getContainerPosition();
this.transformPositionX(positionX, duration);
this.setInitialContainerPosition(positionX);
}
getContainerPosition() {
let correction = this.getContainerPositionCorrection();
this.isContainerPositionCorrection = correction != 0;
return (this.initialContainerPosition + this.newContainerPositionIndex * this.fullCellWidth) + correction;
}
setInitialContainerPosition(position) {
let correction = this.getContainerPositionCorrection();
this.initialContainerPosition = position - correction;
}
getContainerPositionCorrection() {
let correction = 0;
if ((this.images.length - this.preliminarySlideCounter) < this.visibleCellsCount || this.isSlideLengthLimited) {
if (this.visibleWidth < this.totalContainerCellsCount * this.fullCellWidth) {
correction = -(this.visibleCellsCount * this.fullCellWidth - this.visibleWidth - this.margin);
}
if (correction >= -this.margin) {
correction = 0;
}
}
return correction;
}
/* Quickly center */
quicklyPositionContainer() {
let correction = this.getContainerPositionCorrection();
const initialPosition = this.getNewContainerPosition() + correction;
this.transformPositionX(initialPosition, 0);
this.setInitialContainerPosition(initialPosition);
}
getNewContainerPosition() {
if (this.slideCounter > this.overflowCellsLimit) {
if (this.alignCells === "left") {
this.lineUpCells();
return -(this.overflowCellsLimit * this.fullCellWidth);
}
}
if (this.slideCounter <= this.overflowCellsLimit) {
if (this.previousSlideCounter > this.overflowCellsLimit) {
this.lineUpCells();
}
return -(this.slideCounter * this.fullCellWidth);
}
}
setContainerWidth() {
const containerWidth = this.getContainerWidth();
this.element.style.width = containerWidth + "px";
}
getContainerWidth() {
this.totalContainerCellsCount = this.visibleCellsCount + this.overflowCellsLimit * 2;
let containerWidth = this.totalContainerCellsCount * this.fullCellWidth;
let totalImageWidth = this.images.length * this.fullCellWidth;
if (totalImageWidth < containerWidth) {
containerWidth = totalImageWidth;
}
return containerWidth;
}
getFile(cellIndex) {
let imageIndex = this.getFileIndex(cellIndex);
let file = this.images[imageIndex];
if (file && !file.type) {
file.type = 'image';
}
return {
image: this.images[imageIndex],
imageIndex
};
}
getFileIndex(cellIndex) {
const positionIndex = this.getPositionIndex(cellIndex);
const numberLeftCells = (this.totalContainerCellsCount - 1) / 2;
let imageIndex;
if (!this.isContainerLocked) {
if (this.slideCounter <= this.overflowCellsLimit) {
return cellIndex;
}
else {
let cellLimitOverflow = this.slideCounter - this.overflowCellsLimit;
imageIndex = positionIndex + cellLimitOverflow;
return imageIndex;
}
}
if (this.alignCells === "left") {
if (this.slideCounter > this.overflowCellsLimit) {
let cellLimitOverflow = this.slideCounter - this.overflowCellsLimit;
imageIndex = positionIndex + cellLimitOverflow;
}
else {
imageIndex = cellIndex;
}
}
if (imageIndex > this.lastCellIndex) {
return false;
}
return imageIndex;
}
transformPositionX(value, duration = this.transitionDuration) {
this.element.style.transition = 'transform ' + duration + 'ms ' + this.transitionTimingFunction;
this.element.style.transform = 'translateX(' + value + 'px)';
}
detectSlide() {
return this.distanceAbs >= this.minSwipeDistance;
}
next() {
if (this.isSlideInProgress) {
return;
}
this.direction = 'left';
this.handleSlide(1);
}
prev() {
if (this.isSlideInProgress) {
return;
}
this.direction = 'right';
this.handleSlide(1);
}
select(index) {
this.slideCounter = index;
this.quicklyPositionContainer();
}
handleSlide(slideLength = undefined) {
this.slideLength = this.getSlideLength();
this.slideLength = slideLength ? slideLength : this.limitSlideLength(this.slideLength);
if (this.direction === 'left' && !this.isSlideInProgress) {
this.preliminarySlideCounter = this.slideCounter + this.slideLength;
if (!this.detectLastSlide(this.slideCounter + this.slideLength)) {
this.newContainerPositionIndex = this.newContainerPositionIndex - this.slideLength;
this.isSlideInProgress = true;
if (this.isLazyLoad) {
this.isContainerLocked = this.preliminarySlideCounter > this.overflowCellsLimit;
if (this.detectContainerUnlock()) {
this.isContainerLocked = false;
}
}
}
}
if (this.direction === 'right' && !this.isSlideInProgress) {
if (this.slideCounter - this.slideLength < 0) {
this.slideLength = this.slideCounter;
}
this.preliminarySlideCounter = this.slideCounter - this.slideLength;
if (!this.isFirstCell) {
this.newContainerPositionIndex = this.newContainerPositionIndex + this.slideLength;
this.isSlideInProgress = true;
if (this.isLazyLoad) {
if (this.preliminarySlideCounter > this.overflowCellsLimit) {
this.isContainerLocked = true;
}
else {
this.isContainerLocked = false;
}
if (this.detectContainerUnlock()) {
this.isContainerLocked = false;
}
}
}
}
this.alignContainer();
}
getSlideLength() {
let correction = this.getContainerPositionCorrection();
let length = Math.floor((this.distanceAbs + correction) / this.fullCellWidth);
if (this.distanceAbs % this.fullCellWidth >= this.minSwipeDistance) {
length++;
}
return length;
}
limitSlideLength(slideLength) {
if (slideLength > 1) {
for (var i = 0; i < slideLength; i++) {
let newSlideCounter = this.slideCounter + (slideLength - i);
if (!this.detectLastSlide(newSlideCounter)) {
slideLength = slideLength - i;
this.isSlideLengthLimited = i > 0;
break;
}
}
}
return slideLength;
}
detectLastSlide(slideCounter) {
return (this.images.length - slideCounter) < this.visibleCellsCount;
}
isNextArrowDisabled() {
if (this.visibleCellsOverflowContainer) {
return this.detectLastSlide(this.slideCounter + 1) && this.isContainerPositionCorrection;
}
else {
return this.detectLastSlide(this.slideCounter + 1);
}
}
isPrevArrowDisabled() {
return this.slideCounter === 0;
}
detectContainerUnlock() {
return (this.images.length - this.preliminarySlideCounter) < (this.visibleCellsCount + this.overflowCellsLimit);
}
handleSlideEnd() {
if (this.isSlideInProgress) {
this.transformSlideEnd();
this.isSlideInProgress = false;
this.newContainerPositionIndex = 0;
this.isSlideLengthLimited = undefined;
}
}
transformSlideEnd() {
if (this.isLazyLoad) {
this.setSlideCounter();
this.quicklyPositionContainer();
}
this.previousSlideCounter = this.slideCounter;
}
setSlideCounter() {
if (this.direction === 'left') {
this.slideCounter = this.slideCounter + this.slideLength;
}
if (this.direction === 'right') {
this.slideCounter = this.slideCounter - this.slideLength;
}
this.direction = undefined;
this.slideLength = 0;
}
resetTransition() {
this.element.style.transition = '';
}
getElementPosition() {
return this.element.getBoundingClientRect();
}
getCarouselElementPosition() {
return this.properties.container.getBoundingClientRect();
}
getDistance() {
return this.startX - this.moveX;
}
getDistanceAbs() {
return Math.abs(this.startX - this.moveX);
}
getDirection() {
const direction = Math.sign(this.startX - this.moveX);
if (direction === -1) {
return 'right';
}
if (direction === 1) {
return 'left';
}
}
lineUpCells() {
const cells = this.element.children;
for (var i = 0; i < cells.length; i++) {
let cell = cells[i];
let positionX = this.getCellPositionX(i);
cell.style.transform = 'translateX(' + positionX + 'px)';
}
;
}
getCellPositionX(index) {
let positionIndex = this.getPositionIndex(index);
return positionIndex * this.fullCellWidth;
}
getPositionIndex(cellIndex) {
let slideCounter = this.slideCounter - this.overflowCellsLimit;
let positionIndex;
if (slideCounter > this.totalContainerCellsCount) {
slideCounter = slideCounter % this.totalContainerCellsCount;
}
if (slideCounter < 0) {
return cellIndex;
}
else {
positionIndex = cellIndex - slideCounter;
if (positionIndex < 0) {
positionIndex = this.totalContainerCellsCount + positionIndex;
}
}
return positionIndex;
}
get containerOverflowRightCount() {
let totalOverflowCellsCount = this.images.length - this.totalContainerCellsCount;
let overflowRight = 0;
if (totalOverflowCellsCount > 0) {
overflowRight = totalOverflowCellsCount - (this.previousSlideCounter - this.overflowCellsLimit);
if (overflowRight > 0) {
return overflowRight;
}
}
return overflowRight;
}
getCenterPositionIndex() {
return (this.totalContainerCellsCount - 1) / 2;
}
}
let EventService = class EventService {
constructor() {
this.emitter = new ReplaySubject(1);
}
emitChangeEvent(data) {
this.emitter.next(data);
}
};
EventService = __decorate([
Injectable()
], EventService);
let CarouselComponent = class CarouselComponent {
constructor(elementRef, ref, overlayEventService) {
this.elementRef = elementRef;
this.ref = ref;
this.overlayEventService = overlayEventService;
this.minTimeout = 30;
this._cellWidth = 200;
this._transitionDuration = 200;
this.events = new EventEmitter();
this.height = 200;
this.margin = 10;
this.objectFit = 'cover';
this.minSwipeDistance = 50;
this.transitionTimingFunction = 'ease';
this.counterSeparator = " / ";
this.overflowCellsLimit = 3;
this.listeners = 'mouse and touch';
this.arrows = true;
this.arrowsTheme = 'light';
this.hostClassCarousel = true;
/* Touchstart */
this.handleTouchstart = (event) => {
event.preventDefault();
this.carousel.handleTouchstart(event);
this.isMoving = true;
this.events.emit({
type: 'touchstart',
event
});
};
/* Touchmove */
this.handleHorizontalSwipe = (event) => {
event.preventDefault();
this.carousel.handleHorizontalSwipe(event);
this.events.emit({
type: 'swipe',
event
});
};
/* Touchend */
this.handleTouchend = (event) => {
const touches = event.touches;
this.carousel.handleTouchend(event);
this.isMoving = false;
this.events.emit({
type: 'touchend',
event
});
};
/* Tap */
this.handleTap = (event) => {
const i = this.carousel.slideCounter;
const cellIndex = this.carousel.currentCellIndex;
const fileIndex = this.carousel.getFileIndex(i);
const file = this.carousel.getFile(cellIndex);
this.events.emit({
type: 'click',
file: file,
index: fileIndex
});
};
}
get isLandscape() {
return window.innerWidth > window.innerHeight;
}
get isSafari() {
const ua = navigator.userAgent.toLowerCase();
if (ua.indexOf('safari') !== -1) {
return !(ua.indexOf('chrome') > -1);
}
}
get counter() {
return this.carousel.slideCounter + 1 + this.counterSeparator + this.images.length;
}
set images(images) {
this._images = images;
}
get images() {
return this._images;
}
get isNgContent() {
return this.elementRef.nativeElement.querySelector('.carousel-content-wrapper').children.length > 0;
}
set transitionDuration(value) {
this._transitionDuration = value;
}
get transitionDuration() {
if (this._transitionDuration === 0) {
return 1;
}
else {
return this._transitionDuration;
}
}
set cellWidth(value) {
if (value) {
this._cellWidth = value;
}
}
set isCounter(value) {
if (value) {
this._isCounter = value;
}
}
get isCounter() {
return this._isCounter && this.images.length > 1;
}
set overlayProperties(properties) {
this._properties = properties;
this._images = this._properties.metadata.images;
this._cellWidth = this._properties.metadata.width;
this.height = this._properties.metadata.height;
this.objectFit = this._properties.metadata.objectFit;
this.margin = this._properties.metadata.margin;
this.transitionDuration = this._properties.metadata.transitionDuration;
this.overflowCellsLimit = this._properties.metadata.overflowCellsLimit;
this.minSwipeDistance = this._properties.metadata.minSwipeDistance;
this.transitionTimingFunction = this._properties.metadata.transitionTimingFunction;
this._isCounter = this._properties.metadata.counter;
this.counterSeparator = this._properties.metadata.counterSeparator;
this.arrows = this._properties.metadata.arrows;
}
get properties() {
return this._properties;
}
get cellLimit() {
if (this.carousel) {
return this.carousel.cellLimit;
}
}
onWindowResize(event) {
this.landscapeMode = this.isLandscape;
this.ref.detectChanges();
this.initCarousel();
this.carousel.lineUpCells();
}
ngOnInit() {
this.touches = new Touches({
element: this.elementRef.nativeElement.querySelector('.carousel-cells'),
listeners: this.listeners
});
this.touches.on('touchstart', this.handleTouchstart);
this.touches.on('horizontal-swipe', this.handleHorizontalSwipe);
this.touches.on('touchend', this.handleTouchend);
this.touches.on('mousedown', this.handleTouchstart);
this.touches.on('mouseup', this.handleTouchend);
this.touches.on('tap', this.handleTap);
this.initCarousel();
this.setDimensions();
this.setInitialIndex();
}
ngAfterViewInit() {
this.carousel.lineUpCells();
}
ngOnChanges(changes) {
if (changes.width || changes.height) {
this.setDimensions();
this.initCarousel();
this.carousel.lineUpCells();
}
}
ngOnDestroy() {
this.touches.destroy();
}
initCarousel() {
this.carousel = new Carousel({
element: this.elementRef.nativeElement.querySelector('.carousel-cells'),
container: this.elementRef.nativeElement,
images: this.images,
cellWidth: this.getCellWidth(),
overflowCellsLimit: this.overflowCellsLimit,
visibleWidth: this.width,
margin: this.margin,
minSwipeDistance: this.minSwipeDistance,
transitionDuration: this.transitionDuration,
transitionTimingFunction: this.transitionTimingFunction,
videoProperties: this.videoProperties
});
}
setDimensions() {
this.hostStyleHeight = this.height + 'px';
this.hostStyleWidth = this.width + 'px';
}
getFile(index) {
return this.carousel.getFile(index);
}
handleTransitionendCellContainer(event) {
this.carousel.handleSlideEnd();
}
toggleVideo(video) {
event.preventDefault();
if (this.videoProperties.noPlay) {
return;
}
if (video.paused) {
video.play();
this.isVideoPlaying = true;
}
else {
video.pause();
this.isVideoPlaying = false;
}
this.ref.detectChanges();
}
getCurrentIndex() {
return this.carousel.slideCounter;
}
getCellWidth() {
if (this._cellWidth === '100%') {
return this.elementRef.nativeElement.clientWidth;
}
else {
return this._cellWidth;
}
}
next() {
this.carousel.next(1);
}
prev() {
this.carousel.prev(1);
}
select(index) {
this.carousel.select(index);
}
isNextArrowDisabled() {
return this.carousel.isNextArrowDisabled();
}
isPrevArrowDisabled() {
return this.carousel.isPrevArrowDisabled();
}
close() {
this.overlayEventService.emitChangeEvent({
type: 'Hide'
});
}
setInitialIndex() {
if (this._properties.metadata.index != undefined) {
this.select(this._properties.metadata.index);
}
}
};
CarouselComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: EventService }
];
__decorate([
Input()
], CarouselComponent.prototype, "images", null);
__decorate([
Output()
], CarouselComponent.prototype, "events", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "height", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "width", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "borderRadius", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "margin", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "objectFit", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "minSwipeDistance", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "transitionDuration", null);
__decorate([
Input()
], CarouselComponent.prototype, "transitionTimingFunction", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "videoProperties", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "counterSeparator", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "overflowCellsLimit", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "listeners", void 0);
__decorate([
Input('cellWidth')
], CarouselComponent.prototype, "cellWidth", null);
__decorate([
Input('counter')
], CarouselComponent.prototype, "isCounter", null);
__decorate([
Input()
], CarouselComponent.prototype, "arrows", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "arrowsOutside", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "arrowsTheme", void 0);
__decorate([
Input()
], CarouselComponent.prototype, "overlayProperties", null);
__decorate([
HostBinding('class.carousel')
], CarouselComponent.prototype, "hostClassCarousel", void 0);
__decorate([
HostBinding('style.height')
], CarouselComponent.prototype, "hostStyleHeight", void 0);
__decorate([
HostBinding('style.width')
], CarouselComponent.prototype, "hostStyleWidth", void 0);
__decorate([
HostListener('window:resize', ['$event'])
], CarouselComponent.prototype, "onWindowResize", null);
CarouselComponent = __decorate([
Component({
selector: 'carousel, [carousel]',
exportAs: 'carousel',
template: "<div class=\"carousel-backdrop\"></div>\n\n<div class=\"carousel-close\" (click)=\"close()\"></div>\n\n<div class=\"carousel-counter\" *ngIf=\"isCounter\">{{counter}}</div>\n\n<div class=\"carousel-container\" [class.carousel-moving]=\"isMoving\">\n\t<div class=\"carousel-cells\" (transitionend)=\"handleTransitionendCellContainer($event)\">\n\t\t<ng-template ngFor let-image [ngForOf]=\"images\" let-i=\"index\">\n\t\t\t<div class=\"carousel-cell\" \n\t\t\t\t*ngIf=\"i < cellLimit\" \n\t\t\t\t[style.width]=\"getCellWidth()+'px'\"\n\t\t\t\t[style.border-radius]=\"borderRadius+'px'\">\n\t\t\t\t<!-- Image -->\n\t\t\t\t<img \n\t\t\t\t\t*ngIf=\"getFile(i) && getFile(i)['image']\" \n\t\t\t\t\t[src]=\"getFile(i)['image']['path']\"\n\t\t\t\t\t[style.object-fit]=\"objectFit\"\n\t\t\t\t\tdraggable=\"false\" />\n\n\t\t\t\t<!-- Video -->\n\t\t\t\t<ng-template [ngIf]=\"getFile(i) && getFile(i)['type'] === 'video'\">\n\t\t\t\t\t<div class=\"carousel-play\" (click)=\"toggleVideo(video)\"></div>\n\n\t\t\t\t\t<video #video\n\t\t\t\t\t\t[loop]=\"videoProperties.loop\"\n\t\t\t\t\t\t[muted]=\"videoProperties.muted\"\n\t\t\t\t\t\t[controls]=\"isSafari\"\n\t\t\t\t\t\t[style.object-fit]=\"objectFit\"\n\t\t\t\t\t\t[style.border-radius]=\"borderRadius+'px'\">\n\t\t\t\t\t\t\n\t\t\t\t\t\t<source [src]=\"getFile(i)['path']\" type=\"video/mp4\">\n\t\t\t\t\t</video>\n\t\t\t\t</ng-template>\n\t\t\t</div>\n\t\t</ng-template>\n\t</div>\n</div>\n\n<div class=\"carousel-arrows\" \n\t[class.carousel-arrows-outside]=\"arrowsOutside\" \n\t[class.carousel-dark-arrows]=\"arrowsTheme === 'dark'\"\n\t*ngIf=\"arrows\">\n\t\n\t<div class=\"carousel-arrow carousel-arrow-prev\" [class.carousel-arrow-disabled]=\"isPrevArrowDisabled()\" (click)=\"prev()\"></div>\n\t<div class=\"carousel-arrow carousel-arrow-next\" [class.carousel-arrow-disabled]=\"isNextArrowDisabled()\" (click)=\"next()\"></div>\n</div>",
styles: [":host{position:relative;display:block;top:0;left:0;width:100%;height:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10000;transform-origin:top left;box-sizing:border-box}:host .carousel-container{overflow:hidden;width:100%;height:100%;cursor:-webkit-grab;cursor:grab}:host .carousel-container.carousel-moving{cursor:-webkit-grabbing;cursor:grabbing}:host .carousel-counter{text-align:right;position:absolute;z-index:30;transition:opacity .2s;top:15px;left:10px;border-radius:13px;background-color:rgba(23,37,68,.3);font-size:13px;color:#fff;padding:5px 7px;line-height:initial}:host .carousel-cells{transition:transform .2s;width:100%;height:100%;display:block}:host .carousel-cells ::ng-deep .carousel-cell.swiper-prev-image{transform:translate3d(-100%,0,0)}:host .carousel-cells ::ng-deep .carousel-cell.swiper-next-image{transform:translate3d(100%,0,0)}:host .carousel-cells ::ng-deep .carousel-cell{width:100%;height:100%;text-align:center;position:absolute;display:flex;align-items:center;justify-content:center;overflow:hidden}:host .carousel-cells ::ng-deep .carousel-cell img,:host .carousel-cells ::ng-deep .carousel-cell video{width:100%;height:100%;position:relative;-o-object-fit:contain;object-fit:contain}:host .carousel-cells ::ng-deep .carousel-cell img.swiper-hide{display:none}:host .carousel-cells ::ng-deep .carousel-cell .carousel-play{position:absolute;top:0;left:0;bottom:0;right:0;z-index:1}:host .carousel-arrow{width:40px;height:40px;background-color:#fff;background-repeat:no-repeat;background-size:31px;background-position:center;border-radius:100px;position:absolute;top:50%;margin-top:-20px;z-index:10;cursor:pointer;box-shadow:0 0 5px rgba(0,0,0,.15)}:host .carousel-arrow-prev{left:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMTUuNDEgMTYuNTlMMTAuODMgMTJsNC41OC00LjU5TDE0IDZsLTYgNiA2IDYgMS40MS0xLjQxeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMFYweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==)}:host .carousel-arrow-next{right:10px;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNOC41OSAxNi41OUwxMy4xNyAxMiA4LjU5IDcuNDEgMTAgNmw2IDYtNiA2LTEuNDEtMS40MXoiLz48cGF0aCBkPSJNMCAwaDI0djI0SDBWMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=)}:host .carousel-arrows-outside .carousel-arrow-prev{left:-60px}:host .carousel-arrows-outside .carousel-arrow-next{right:-60px}:host .carousel-dark-arrows .carousel-arrow{-webkit-filter:invert(1);filter:invert(1)}:host .carousel-arrow-disabled{cursor:default;opacity:.5}:host .carousel-close{position:fixed;top:10px;right:10px;width:40px;height:40px;z-index:100;cursor:pointer;background-repeat:no-repeat;background-size:31px;background-position:center;background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgd2lkdGg9IjI0Ij48cGF0aCBkPSJNMTkgNi40MUwxNy41OSA1IDEyIDEwLjU5IDYuNDEgNSA1IDYuNDEgMTAuNTkgMTIgNSAxNy41OSA2LjQxIDE5IDEyIDEzLjQxIDE3LjU5IDE5IDE5IDE3LjU5IDEzLjQxIDEyeiIvPjxwYXRoIGQ9Ik0wIDBoMjR2MjRIMHoiIGZpbGw9Im5vbmUiLz48L3N2Zz4=);-webkit-filter:invert(1);filter:invert(1)}:host .carousel-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;background-color:#000;opacity:.5}"]
})
], CarouselComponent);
let AdDirective = class AdDirective {
constructor(viewContainerRef) {
this.viewContainerRef = viewContainerRef;
}
};
AdDirective.ctorParameters = () => [
{ type: ViewContainerRef }
];
AdDirective = __decorate([
Directive({
selector: '[ad-host]',
})
], AdDirective);
let OverlayContainerComponent = class OverlayContainerComponent {
constructor(componentFactoryResolver, elementRef, eventService) {
this.componentFactoryResolver = componentFactoryResolver;
this.elementRef = elementRef;
this.eventService = eventService;
this.overlayBackdrop = true;
this.minTimeout = 30;
this._hostOpacity = 0;
this.globalEventsSubscription = this.eventService.emitter.subscribe((event) => {
this.handleGlobalEvents(event);
});
}
get hostOpacity() {
return this.properties.fadeIn ? this._hostOpacity : 1;
}
set hostOpacity(value) {
this._hostOpacity = value;
}
get hostTransition() {
const duration = this.properties.animationDuration + 'ms ';
const esing = this.properties.animationTimingFunction;
return 'opacity ' + duration + esing + ', transform ' + duration + esing;
}
get hostZIndex() {
return this.properties.zIndex;
}
get hostWidth() {
return this.properties.wrapperWidth;
}
get hostHeight() {
return this.properties.wrapperHeight;
}
get hostPosition() {
return this.properties.position;
}
onClick(event) {
if (!this.elementRef.nativeElement.contains(event.target)) {
if (this.hostShown) {
this.closeOverlay();
}
}
}
transitionEnd(event) {
if (event.target.tagName.toLowerCase() != "overlay") {
return;
}
if (event.propertyName != "opacity") {
return;
}
if (this.hostShown) {
this.closeOverlayEnd();
//this.stateEvents.emit("shown");
}
else {
this.hostShown = true;
//this.stateEvents.emit("hidden");
}
}
get popoverClass() {
if (this.properties.metadata) {
return this.properties.metadata.popoverClass;
}
}
ngOnInit() {
this.loadComponent();
this.initialOverlay();
setTimeout(() => {
this.isInitial = true;
}, this.minTimeout); // Note: not good
}
ngAfterViewInit() {
setTimeout(() => {
this.showOverlayAnimation();
}, this.minTimeout);
}
ngOnDestroy() {
if (this.globalEventsSubscription) {
this.globalEventsSubscription.unsubscribe();
}
}
initialOverlay() {
this.hostTransform = 'translateY(' + this.properties.animationTranslateY + ')';
}
showOverlayAnimation() {
this.hostOpacity = 1;
this.hostTransform = 'translateY(0px)';
}
loadComponent() {
let adItem = this.properties;
let componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.mainComponent);
let viewContainerRef = this.adHost.viewContainerRef;
viewContainerRef.clear();
let componentRef = viewContainerRef.createComponent(componentFactory);
let componentRefElement = componentRef.location.nativeElement;
// Set styles
componentRefElement.style.width = this.properties.width;
componentRefElement.style.height = this.properties.height;
// Set classes
if (typeof this.popoverClass === 'string') {
componentRefElement.classList.add(this.popoverClass);
}
if (typeof this.popoverClass === 'object') {
this.popoverClass.forEach(function (className) {
componentRefElement.classList.add(className);
});
}
// Pass properties
componentRef.instance.overlayProperties = this.properties;
}
closeOverlay() {
this.hostOpacity = 0;
this.hostTransform = 'translateY(' + this.properties.animationTranslateY + ')';
}
closeOverlayEnd() {
this.hostShown = false;
this.eventService.emitChangeEvent({
type: '[Overlay] Hide'
});
}
handleGlobalEvents(event) {
if (event.type === 'Hide') {
this.closeOverlay();
}
}
};
OverlayContainerComponent.ctorParameters = () => [
{ type: ComponentFactoryResolver },
{ type: ElementRef },
{ type: EventService }
];
__decorate([
ViewChild(AdDirective, { static: true })
], OverlayContainerComponent.prototype, "adHost", void 0);
__decorate([
Input()
], OverlayContainerComponent.prototype, "properties", void 0);
__decorate([
HostBinding('style.opacity')
], OverlayContainerComponent.prototype, "hostOpacity", null);
__decorate([
HostBinding('style.transition')
], OverlayContainerComponent.prototype, "hostTransition", null);
__decorate([
HostBinding('style.transform')
], OverlayContainerComponent.prototype, "hostTransform", void 0);
__decorate([
HostBinding('style.z-index')
], OverlayContainerComponent.prototype, "hostZIndex", null);
__decorate([
HostBinding('style.width')
], OverlayContainerComponent.prototype, "hostWidth", null);
__decorate([
HostBinding('style.height')
], OverlayContainerComponent.prototype, "hostHeight", null);
__decorate([
HostBinding('style.position')
], OverlayContainerComponent.prototype, "hostPosition", null);
__decorate([
HostBinding('class.overlay-shown')
], OverlayContainerComponent.prototype, "hostShown", void 0);
__decorate([
HostListener('document:click', ['$event'])
], OverlayContainerComponent.prototype, "onClick", null);
__decorate([
HostListener('transitionend', ['$event'])
], OverlayContainerComponent.prototype, "transitionEnd", null);
OverlayContainerComponent = __decorate([
Component({
selector: 'overlay',
template: "<!--\n<div class=\"overlay-backdrop\" \n\t*ngIf=\"properties.overlayBackdrop\" \n\t(click)=\"onBackdropClick()\" \n\t[ngClass]=\"properties.backdropClass\"></div>\n-->\n<!--\n<div class=\"overlay-container\"\n\t[ngStyle]=\"containerStyles\" \n\t[ngClass]=\"properties.overlayClass\">\n\n\t<ng-template ad-host></ng-template>\n</div>\n-->\n