| Server IP : 185.11.201.71 / Your IP : 192.168.7.18 Web Server : Apache/2.4.29 (Ubuntu) System : Linux tech-virtual-machine 4.15.0-213-generic #224-Ubuntu SMP Mon Jun 19 13:30:12 UTC 2023 x86_64 User : tech ( 1000) PHP Version : 7.4.28 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /comunica/app_ojos_/frontend/node_modules/vue-carousel/src/ |
Upload File : |
<template>
<div
class="VueCarousel"
v-bind:class="{ 'VueCarousel--reverse': paginationPosition === 'top' }"
>
<div
class="VueCarousel-wrapper"
ref="VueCarousel-wrapper"
>
<div
ref="VueCarousel-inner"
:class="[
'VueCarousel-inner',
{ 'VueCarousel-inner--center': isCenterModeEnabled }
]"
:style="{
'transform': `translate(${currentOffset}px, 0)`,
'transition': dragging ? 'none' : transitionStyle,
'ms-flex-preferred-size': `${slideWidth}px`,
'webkit-flex-basis': `${slideWidth}px`,
'flex-basis': `${slideWidth}px`,
'visibility': slideWidth ? 'visible' : 'hidden',
'height': `${currentHeight}`,
'padding-left': `${padding}px`,
'padding-right': `${padding}px`
}"
>
<slot></slot>
</div>
</div>
<slot name="navigation" v-if="navigationEnabled">
<navigation
v-if="isNavigationRequired"
:clickTargetSize="navigationClickTargetSize"
:nextLabel="navigationNextLabel"
:prevLabel="navigationPrevLabel"
@navigationclick="handleNavigation"
/>
</slot>
<slot name="pagination" v-if="paginationEnabled">
<pagination @paginationclick="goToPage($event, 'pagination')"/>
</slot>
</div>
</template>
<script>
import autoplay from "./mixins/autoplay";
import debounce from "./utils/debounce";
import Navigation from "./Navigation.vue";
import Pagination from "./Pagination.vue";
import Slide from "./Slide.vue";
const transitionStartNames = {
onwebkittransitionstart: "webkitTransitionStart",
onmoztransitionstart: "transitionstart",
onotransitionstart: "oTransitionStart otransitionstart",
ontransitionstart: "transitionstart"
};
const transitionEndNames = {
onwebkittransitionend: "webkitTransitionEnd",
onmoztransitionend: "transitionend",
onotransitionend: "oTransitionEnd otransitionend",
ontransitionend: "transitionend"
};
const getTransitionStart = () => {
for (let name in transitionStartNames) {
if (name in window) {
return transitionStartNames[name];
}
}
};
const getTransitionEnd = () => {
for (let name in transitionEndNames) {
if (name in window) {
return transitionEndNames[name];
}
}
};
export default {
name: "carousel",
beforeUpdate() {
this.computeCarouselWidth();
},
components: {
Navigation,
Pagination,
Slide
},
data() {
return {
browserWidth: null,
carouselWidth: 0,
currentPage: 0,
dragging: false,
dragMomentum: 0,
dragOffset: 0,
dragStartY: 0,
dragStartX: 0,
isTouch: typeof window !== "undefined" && "ontouchstart" in window,
offset: 0,
refreshRate: 16,
slideCount: 0,
transitionstart: "transitionstart",
transitionend: "transitionend",
currentHeight: "auto"
};
},
mixins: [autoplay],
// use `provide` to avoid `Slide` being nested with other components
provide() {
return {
carousel: this
};
},
props: {
/**
* Adjust the height of the carousel for the current slide
*/
adjustableHeight: {
type: Boolean,
default: false
},
/**
* Slide transition easing for adjustableHeight
* Any valid CSS transition easing accepted
*/
adjustableHeightEasing: {
type: String
},
/**
* Center images when the size is less than the container width
*/
centerMode: {
type: Boolean,
default: false
},
/**
* Slide transition easing
* Any valid CSS transition easing accepted
*/
easing: {
type: String,
validator: function(value) {
return (
["ease", "linear", "ease-in", "ease-out", "ease-in-out"].indexOf(
value
) !== -1 || value.includes("cubic-bezier")
);
},
default: "ease"
},
/**
* Flag to make the carousel loop around when it reaches the end
*/
loop: {
type: Boolean,
default: false
},
/**
* Minimum distance for the swipe to trigger
* a slide advance
*/
minSwipeDistance: {
type: Number,
default: 8
},
/**
* Flag to toggle mouse dragging
*/
mouseDrag: {
type: Boolean,
default: true
},
/**
* Flag to toggle touch dragging
*/
touchDrag: {
type: Boolean,
default: true
},
/**
* Listen for an external navigation request using this prop.
*/
navigateTo: {
type: [Number, Array],
default: 0
},
/**
* Amount of padding to apply around the label in pixels
*/
navigationClickTargetSize: {
type: Number,
default: 8
},
/**
* Flag to render the navigation component
* (next/prev buttons)
*/
navigationEnabled: {
type: Boolean,
default: false
},
/**
* Text content of the navigation next button
*/
navigationNextLabel: {
type: String,
default: "▶"
},
/**
* Text content of the navigation prev button
*/
navigationPrevLabel: {
type: String,
default: "◀"
},
/**
* The fill color of the active pagination dot
* Any valid CSS color is accepted
*/
paginationActiveColor: {
type: String,
default: "#000000"
},
/**
* The fill color of pagination dots
* Any valid CSS color is accepted
*/
paginationColor: {
type: String,
default: "#efefef"
},
/**
* Flag to render pagination component
*/
paginationEnabled: {
type: Boolean,
default: true
},
/**
* The padding inside each pagination dot
* Pixel values are accepted
*/
paginationPadding: {
type: Number,
default: 10
},
/**
* Configure the position for the pagination component.
* The possible values are: 'bottom', 'top', 'bottom-overlay' and 'top-overlay'
*/
paginationPosition: {
type: String,
default: "bottom"
},
/**
* The size of each pagination dot
* Pixel values are accepted
*/
paginationSize: {
type: Number,
default: 10
},
/**
* Maximum number of slides displayed on each page
*/
perPage: {
type: Number,
default: 2
},
/**
* Configure the number of visible slides with a particular browser width.
* This will be an array of arrays, ex. [[320, 2], [1199, 4]]
* Formatted as [x, y] where x=browser width, and y=number of slides displayed.
* ex. [1199, 4] means if (window <= 1199) then show 4 slides per page
*/
perPageCustom: {
type: Array
},
/**
* Resistance coefficient to dragging on the edge of the carousel
* This dictates the effect of the pull as you move towards the boundaries
*/
resistanceCoef: {
type: Number,
default: 20
},
/**
* Scroll per page, not per item
*/
scrollPerPage: {
type: Boolean,
default: true
},
/**
* Space padding option adds left and right padding style (in pixels) onto VueCarousel-inner.
*/
spacePadding: {
type: Number,
default: 0
},
/**
* Specify by how much should the space padding value be multiplied of, to re-arange the final slide padding.
*/
spacePaddingMaxOffsetFactor: {
type: Number,
default: 0
},
/**
* Slide transition speed
* Number of milliseconds accepted
*/
speed: {
type: Number,
default: 500
},
/**
* Name (tag) of slide component
* Overwrite when extending slide component
*/
tagName: {
type: String,
default: "slide"
},
/**
* Support for v-model functionality
*/
value: {
type: Number
},
/**
* Support Max pagination dot amount
*/
maxPaginationDotCount: {
type: Number,
default: -1
},
/**
* Support right to left
*/
rtl: {
type: Boolean,
default: false
}
},
watch: {
value(val) {
if (val !== this.currentPage) {
this.goToPage(val);
this.render();
}
},
navigateTo: {
immediate: true,
handler(val) {
// checking if val is an array, for arrays typeof returns object
if (typeof val === "object") {
if (val[1] == false) {
// following code is to disable animation
this.dragging = true;
// clear dragging after refresh rate
setTimeout(() => {
this.dragging = false;
}, this.refreshRate);
}
this.$nextTick(() => {
this.goToPage(val[0]);
});
} else {
this.$nextTick(() => {
this.goToPage(val);
});
}
}
},
currentPage(val) {
this.$emit("pageChange", val);
this.$emit("page-change", val);
this.$emit("input", val);
},
autoplay(val) {
if (val === false) {
this.pauseAutoplay();
} else {
this.restartAutoplay();
}
}
},
computed: {
/**
* Given a viewport width, find the number of slides to display
* @param {Number} width Current viewport width in pixels
* @return {Number} Number of slides to display
*/
breakpointSlidesPerPage() {
if (!this.perPageCustom) {
return this.perPage;
}
const breakpointArray = this.perPageCustom;
const width = this.browserWidth;
const breakpoints = breakpointArray.sort(
(a, b) => (a[0] > b[0] ? -1 : 1)
);
// Reduce the breakpoints to entries where the width is in range
// The breakpoint arrays are formatted as [widthToMatch, numberOfSlides]
const matches = breakpoints.filter(breakpoint => width >= breakpoint[0]);
// If there is a match, the result should return only
// the slide count from the first matching breakpoint
const match = matches[0] && matches[0][1];
return match || this.perPage;
},
/**
* @return {Boolean} Can the slider move forward?
*/
canAdvanceForward() {
return this.loop || this.offset < this.maxOffset;
},
/**
* @return {Boolean} Can the slider move backward?
*/
canAdvanceBackward() {
return this.loop || this.currentPage > 0;
},
/**
* Number of slides to display per page in the current context.
* This is constant unless responsive perPage option is set.
* @return {Number} The number of slides per page to display
*/
currentPerPage() {
return !this.perPageCustom || this.$isServer
? this.perPage
: this.breakpointSlidesPerPage;
},
/**
* The horizontal distance the inner wrapper is offset while navigating.
* @return {Number} Pixel value of offset to apply
*/
currentOffset() {
if (this.isCenterModeEnabled) {
return 0;
} else if (this.rtl) {
return (this.offset - this.dragOffset) * 1;
} else {
return (this.offset + this.dragOffset) * -1;
}
},
isHidden() {
return this.carouselWidth <= 0;
},
/**
* Maximum offset the carousel can slide
* Considering the spacePadding
* @return {Number}
*/
maxOffset() {
return Math.max(
this.slideWidth * (this.slideCount - this.currentPerPage) -
this.spacePadding * this.spacePaddingMaxOffsetFactor,
0
);
},
/**
* Calculate the number of pages of slides
* @return {Number} Number of pages
*/
pageCount() {
return this.scrollPerPage
? Math.ceil(this.slideCount / this.currentPerPage)
: this.slideCount - this.currentPerPage + 1;
},
/**
* Calculate the width of each slide
* @return {Number} Slide width
*/
slideWidth() {
const width = this.carouselWidth - this.spacePadding * 2;
const perPage = this.currentPerPage;
return width / perPage;
},
/**
* @return {Boolean} Is navigation required?
*/
isNavigationRequired() {
return this.slideCount > this.currentPerPage;
},
/**
* @return {Boolean} Center images when have less than min currentPerPage value
*/
isCenterModeEnabled() {
return this.centerMode && !this.isNavigationRequired;
},
transitionStyle() {
const speed = `${this.speed / 1000}s`;
const transtion = `${speed} ${this.easing} transform`;
if (this.adjustableHeight) {
return `${transtion}, height ${speed} ${this.adjustableHeightEasing ||
this.easing}`;
}
return transtion;
},
padding() {
const padding = this.spacePadding;
return padding > 0 ? padding : false;
}
},
methods: {
/**
* @return {Number} The index of the next page
* */
getNextPage() {
if (this.currentPage < this.pageCount - 1) {
return this.currentPage + 1;
}
return this.loop ? 0 : this.currentPage;
},
/**
* @return {Number} The index of the previous page
* */
getPreviousPage() {
if (this.currentPage > 0) {
return this.currentPage - 1;
}
return this.loop ? this.pageCount - 1 : this.currentPage;
},
/**
* Increase/decrease the current page value
* @param {String} direction (Optional) The direction to advance
*/
advancePage(direction) {
if (direction && direction === "backward" && this.canAdvanceBackward) {
this.goToPage(this.getPreviousPage(), "navigation");
} else if (
(!direction || (direction && direction !== "backward")) &&
this.canAdvanceForward
) {
this.goToPage(this.getNextPage(), "navigation");
}
},
goToLastSlide() {
// following code is to disable animation
this.dragging = true;
// clear dragging after refresh rate
setTimeout(() => {
this.dragging = false;
}, this.refreshRate);
this.$nextTick(() => {
this.goToPage(this.pageCount);
});
},
/**
* A mutation observer is used to detect changes to the containing node
* in order to keep the magnet container in sync with the height its reference node.
*/
attachMutationObserver() {
const MutationObserver =
window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver;
if (MutationObserver) {
let config = {
attributes: true,
data: true
};
if (this.adjustableHeight) {
config = {
...config,
childList: true,
subtree: true,
characterData: true
};
}
this.mutationObserver = new MutationObserver(() => {
this.$nextTick(() => {
this.computeCarouselWidth();
this.computeCarouselHeight();
});
});
if (this.$parent.$el) {
let carouselInnerElements = this.$el.getElementsByClassName(
"VueCarousel-inner"
);
for (let i = 0; i < carouselInnerElements.length; i++) {
this.mutationObserver.observe(carouselInnerElements[i], config);
}
}
}
},
handleNavigation(direction) {
this.advancePage(direction);
this.pauseAutoplay();
this.$emit("navigation-click", direction);
},
/**
* Stop listening to mutation changes
*/
detachMutationObserver() {
if (this.mutationObserver) {
this.mutationObserver.disconnect();
}
},
/**
* Get the current browser viewport width
* @return {Number} Browser"s width in pixels
*/
getBrowserWidth() {
this.browserWidth = window.innerWidth;
return this.browserWidth;
},
/**
* Get the width of the carousel DOM element
* @return {Number} Width of the carousel in pixels
*/
getCarouselWidth() {
let carouselInnerElements = this.$el.getElementsByClassName(
"VueCarousel-inner"
);
for (let i = 0; i < carouselInnerElements.length; i++) {
if (carouselInnerElements[i].clientWidth > 0) {
this.carouselWidth = carouselInnerElements[i].clientWidth || 0;
}
}
return this.carouselWidth;
},
/**
* Get the maximum height of the carousel active slides
* @return {String} The carousel height
*/
getCarouselHeight() {
if (!this.adjustableHeight) {
return "auto";
}
const slideOffset = this.currentPerPage * (this.currentPage + 1) - 1;
const maxSlideHeight = [...Array(this.currentPerPage)]
.map((_, idx) => this.getSlide(slideOffset + idx))
.reduce(
(clientHeight, slide) =>
Math.max(clientHeight, (slide && slide.$el.clientHeight) || 0),
0
);
this.currentHeight =
maxSlideHeight === 0 ? "auto" : `${maxSlideHeight}px`;
return this.currentHeight;
},
/**
* Filter slot contents to slide instances and return length
* @return {Number} The number of slides
*/
getSlideCount() {
this.slideCount =
(this.$slots &&
this.$slots.default &&
this.$slots.default.filter(
slot =>
slot.tag &&
slot.tag.match(`^vue-component-\\d+-${this.tagName}$`) !== null
).length) ||
0;
},
/**
* Gets the slide at the specified index
* @return {Object} The slide at the specified index
*/
getSlide(index) {
const slides = this.$children.filter(
child =>
child.$vnode.tag.match(`^vue-component-\\d+-${this.tagName}$`) !==
null
);
return slides[index];
},
/**
* Set the current page to a specific value
* This function will only apply the change if the value is within the carousel bounds
* for carousel scrolling per page.
* @param {Number} page The value of the new page number
* @param {string|undefined} advanceType An optional value describing the type of page advance
*/
goToPage(page, advanceType) {
if (page >= 0 && page <= this.pageCount) {
this.offset = this.scrollPerPage
? Math.min(
this.slideWidth * this.currentPerPage * page,
this.maxOffset
)
: this.slideWidth * page;
// restart autoplay if specified
if (this.autoplay && !this.autoplayHoverPause) {
this.restartAutoplay();
}
// update the current page
this.currentPage = page;
if (advanceType === "pagination") {
this.pauseAutoplay();
this.$emit("pagination-click", page);
}
}
},
/**
* Trigger actions when mouse is pressed
* @param {Object} e The event object
*/
/* istanbul ignore next */
onStart(e) {
// alert("start");
// detect right click
if (e.button == 2) {
return;
}
document.addEventListener(
this.isTouch ? "touchend" : "mouseup",
this.onEnd,
true
);
document.addEventListener(
this.isTouch ? "touchmove" : "mousemove",
this.onDrag,
true
);
this.startTime = e.timeStamp;
this.dragging = true;
this.dragStartX = this.isTouch ? e.touches[0].clientX : e.clientX;
this.dragStartY = this.isTouch ? e.touches[0].clientY : e.clientY;
},
/**
* Trigger actions when mouse is released
* @param {Object} e The event object
*/
onEnd(e) {
// restart autoplay if specified
if (this.autoplay && !this.autoplayHoverPause) {
this.restartAutoplay();
}
this.pauseAutoplay();
// compute the momemtum speed
const eventPosX = this.isTouch ? e.changedTouches[0].clientX : e.clientX;
const deltaX = this.dragStartX - eventPosX;
this.dragMomentum = deltaX / (e.timeStamp - this.startTime);
// take care of the minSwipteDistance prop, if not 0 and delta is bigger than delta
if (
this.minSwipeDistance !== 0 &&
Math.abs(deltaX) >= this.minSwipeDistance
) {
const width = this.scrollPerPage
? this.slideWidth * this.currentPerPage
: this.slideWidth;
this.dragOffset = this.dragOffset + Math.sign(deltaX) * (width / 2);
}
if (this.rtl) {
this.offset -= this.dragOffset;
} else {
this.offset += this.dragOffset;
}
this.dragOffset = 0;
this.dragging = false;
this.render();
// clear events listeners
document.removeEventListener(
this.isTouch ? "touchend" : "mouseup",
this.onEnd,
true
);
document.removeEventListener(
this.isTouch ? "touchmove" : "mousemove",
this.onDrag,
true
);
},
/**
* Trigger actions when mouse is pressed and then moved (mouse drag)
* @param {Object} e The event object
*/
onDrag(e) {
const eventPosX = this.isTouch ? e.touches[0].clientX : e.clientX;
const eventPosY = this.isTouch ? e.touches[0].clientY : e.clientY;
const newOffsetX = this.dragStartX - eventPosX;
const newOffsetY = this.dragStartY - eventPosY;
// if it is a touch device, check if we are below the min swipe threshold
// (if user scroll the page on the component)
if (this.isTouch && Math.abs(newOffsetX) < Math.abs(newOffsetY)) {
return;
}
e.stopImmediatePropagation();
this.dragOffset = newOffsetX;
const nextOffset = this.offset + this.dragOffset;
if (this.rtl) {
if (this.offset == 0 && this.dragOffset > 0) {
this.dragOffset = Math.sqrt(this.resistanceCoef * this.dragOffset);
} else if (this.offset == this.maxOffset && this.dragOffset < 0) {
this.dragOffset = -Math.sqrt(-this.resistanceCoef * this.dragOffset);
}
} else {
if (nextOffset < 0) {
this.dragOffset = -Math.sqrt(-this.resistanceCoef * this.dragOffset);
} else if (nextOffset > this.maxOffset) {
this.dragOffset = Math.sqrt(this.resistanceCoef * this.dragOffset);
}
}
},
onResize() {
this.computeCarouselWidth();
this.computeCarouselHeight();
this.dragging = true; // force a dragging to disable animation
this.render();
// clear dragging after refresh rate
setTimeout(() => {
this.dragging = false;
}, this.refreshRate);
},
render() {
// add extra slides depending on the momemtum speed
if (this.rtl) {
this.offset -=
Math.max(
-this.currentPerPage + 1,
Math.min(Math.round(this.dragMomentum), this.currentPerPage - 1)
) * this.slideWidth;
} else {
this.offset +=
Math.max(
-this.currentPerPage + 1,
Math.min(Math.round(this.dragMomentum), this.currentPerPage - 1)
) * this.slideWidth;
}
// & snap the new offset on a slide or page if scrollPerPage
const width = this.scrollPerPage
? this.slideWidth * this.currentPerPage
: this.slideWidth;
// lock offset to either the nearest page, or to the last slide
const lastFullPageOffset =
width * Math.floor(this.slideCount / (this.currentPerPage - 1));
const remainderOffset =
lastFullPageOffset +
this.slideWidth * (this.slideCount % this.currentPerPage);
if (this.offset > (lastFullPageOffset + remainderOffset) / 2) {
this.offset = remainderOffset;
} else {
this.offset = width * Math.round(this.offset / width);
}
// clamp the offset between 0 -> maxOffset
this.offset = Math.max(0, Math.min(this.offset, this.maxOffset));
// update the current page
this.currentPage = this.scrollPerPage
? Math.round(this.offset / this.slideWidth / this.currentPerPage)
: Math.round(this.offset / this.slideWidth);
},
/**
* Re-compute the width of the carousel and its slides
*/
computeCarouselWidth() {
this.getSlideCount();
this.getBrowserWidth();
this.getCarouselWidth();
this.setCurrentPageInBounds();
},
/**
* Re-compute the height of the carousel and its slides
*/
computeCarouselHeight() {
this.getCarouselHeight();
},
/**
* When the current page exceeds the carousel bounds, reset it to the maximum allowed
*/
setCurrentPageInBounds() {
if (!this.canAdvanceForward && this.scrollPerPage) {
const setPage = this.pageCount - 1;
this.currentPage = setPage >= 0 ? setPage : 0;
this.offset = Math.max(0, Math.min(this.offset, this.maxOffset));
}
},
handleTransitionStart() {
this.$emit("transitionStart");
this.$emit("transition-start");
},
handleTransitionEnd() {
this.$emit("transitionEnd");
this.$emit("transition-end");
}
},
mounted() {
window.addEventListener(
"resize",
debounce(this.onResize, this.refreshRate)
);
// setup the start event only if touch device or mousedrag activated
if ((this.isTouch && this.touchDrag) || this.mouseDrag) {
this.$refs["VueCarousel-wrapper"].addEventListener(
this.isTouch ? "touchstart" : "mousedown",
this.onStart
);
}
this.attachMutationObserver();
this.computeCarouselWidth();
this.computeCarouselHeight();
this.transitionstart = getTransitionEnd();
this.$refs["VueCarousel-inner"].addEventListener(
this.transitionstart,
this.handleTransitionStart
);
this.transitionend = getTransitionEnd();
this.$refs["VueCarousel-inner"].addEventListener(
this.transitionend,
this.handleTransitionEnd
);
this.$emit("mounted");
// when autoplay direction is backward start from the last slide
if (this.autoplayDirection === "backward") {
this.goToLastSlide();
}
},
beforeDestroy() {
this.detachMutationObserver();
window.removeEventListener("resize", this.getBrowserWidth);
this.$refs["VueCarousel-inner"].removeEventListener(
this.transitionstart,
this.handleTransitionStart
);
this.$refs["VueCarousel-inner"].removeEventListener(
this.transitionend,
this.handleTransitionEnd
);
this.$refs["VueCarousel-wrapper"].removeEventListener(
this.isTouch ? "touchstart" : "mousedown",
this.onStart
);
}
};
</script>
<style>
.VueCarousel {
display: flex;
flex-direction: column;
position: relative;
}
.VueCarousel--reverse {
flex-direction: column-reverse;
}
.VueCarousel-wrapper {
width: 100%;
position: relative;
overflow: hidden;
}
.VueCarousel-inner {
display: flex;
flex-direction: row;
backface-visibility: hidden;
}
.VueCarousel-inner--center {
justify-content: center;
}
</style>