enso-carousel
Advanced tools
Comparing version 1.0.0 to 2.0.0
@@ -19,6 +19,12 @@ export default { | ||
computed: { | ||
totalSlideWidth() { | ||
return (this.slides.length + 2) * 100 + 'vw'; | ||
}, | ||
}, | ||
mounted() { | ||
this.slides_container_el = this.$el.querySelector('.enso-carousel__slides'); | ||
this.slides_els = this.$el.querySelectorAll('.enso-carousel__slide'); | ||
this.containerEl = this.$el.querySelector('.enso-carousel__slides'); | ||
this.slidesEls = this.$el.querySelectorAll('.enso-carousel__slide'); | ||
this.linkDragging = false; | ||
this.allowShift = true; | ||
@@ -29,16 +35,29 @@ this.posX1 = 0; | ||
this.posFinal = null; | ||
this.slideWidth = this.slides_els[0].offsetWidth; | ||
this.firstSlide = this.slides_els[0]; | ||
this.lastSlide = this.slides_els[this.slides.length - 1]; | ||
this.firstSlide = this.slidesEls[0]; | ||
this.lastSlide = this.slidesEls[this.slides.length - 1]; | ||
this.cloneFirst = this.firstSlide.cloneNode(true); | ||
this.cloneLast = this.lastSlide.cloneNode(true); | ||
this.slides_container_el.appendChild(this.cloneFirst); | ||
this.slides_container_el.insertBefore(this.cloneLast, this.firstSlide); | ||
this.slides_container_el.onmousedown = this.dragStart; | ||
this.slides_container_el.addEventListener('touchstart', this.dragStart); | ||
this.slides_container_el.addEventListener('touchend', this.dragEnd); | ||
this.slides_container_el.addEventListener('touchmove', this.dragMove); | ||
this.slides_container_el.addEventListener('transitionend', this.onTransitionEnd); | ||
this.slides_container_el.addEventListener('webkitTransitionEnd', this.onTransitionEnd); | ||
this.containerEl.appendChild(this.cloneFirst); | ||
this.containerEl.insertBefore(this.cloneLast, this.firstSlide); | ||
this.containerEl.onmousedown = this.dragStart; | ||
this.containerEl.addEventListener('touchstart', this.dragStart); | ||
this.containerEl.addEventListener('touchend', this.dragEnd); | ||
this.containerEl.addEventListener('touchmove', this.dragMove); | ||
this.containerEl.addEventListener('transitionend', this.onTransitionEnd); | ||
this.containerEl.addEventListener('webkitTransitionEnd', this.onTransitionEnd); | ||
this.containerEl.addEventListener('click', this.onClick); | ||
this.containerEl.style.width = this.totalSlideWidth; | ||
this.slideWidth = this.slidesEls[0].offsetWidth; | ||
this.links = this.containerEl.getElementsByTagName('a'); | ||
// Add a click handler to all links. Instead we will handle click events | ||
// that bubble up to the container and inspect their originalTarget. | ||
// This way we can have slides with links be draggable. | ||
Array.from(this.links).forEach((link) => { | ||
link.addEventListener('click', (e) => { | ||
e.preventDefault(); | ||
}); | ||
}); | ||
window.addEventListener('resize', this.onResize); | ||
@@ -50,5 +69,12 @@ | ||
methods: { | ||
onClick(e) { | ||
// If a link was clicked and not dragged, navigate to the link's href | ||
if (e.originalTarget.tagName === 'A' && !this.linkDragging) { | ||
window.location = e.originalTarget.href; | ||
} | ||
}, | ||
onResize() { | ||
this.slideWidth = this.slides_els[0].offsetWidth; | ||
this.posInitial = this.slides_container_el.offsetLeft; | ||
this.slideWidth = this.slidesEls[0].offsetWidth; | ||
this.posInitial = this.containerEl.offsetLeft; | ||
}, | ||
@@ -65,5 +91,19 @@ | ||
dragStart(e) { | ||
// By deafult links and images can be dragged around into a | ||
// file browser or into the address bar. Instead of this we | ||
// want to use our own drag logic so we'll disable this. | ||
e.preventDefault(); | ||
// If we're dragging a link element then make a note of that so that we | ||
// can handle click events. We need this value to persist after the | ||
// dragend event has fired as the mouseup event that causes the click | ||
// fires after the dragend. We'll only reset this to false if the | ||
// drag didn't pass the threshold. | ||
if (e.originalTarget.tagName === 'A') { | ||
this.linkDragging = true; | ||
} | ||
e = e || window.event; | ||
e.preventDefault; | ||
this.posInitial = this.slides_container_el.offsetLeft; | ||
this.posInitial = this.containerEl.offsetLeft; | ||
@@ -92,3 +132,3 @@ if (e.type === 'touchstart') { | ||
this.slides_container_el.style.left = `${this.slides_container_el.offsetLeft - this.posX2}px`; | ||
this.containerEl.style.left = `${this.containerEl.offsetLeft - this.posX2}px`; | ||
@@ -99,10 +139,16 @@ this.$emit('drag-move'); | ||
dragEnd(e) { | ||
this.posFinal = this.slides_container_el.offsetLeft; | ||
this.posFinal = this.containerEl.offsetLeft; | ||
if (this.posFinal - this.posInitial < -this.threshold) { | ||
// We dragged to the left | ||
this.slideTo(1, 'drag'); | ||
} else if (this.posFinal - this.posInitial > this.threshold) { | ||
// We dragged to the right | ||
this.slideTo(-1, 'drag'); | ||
} else { | ||
this.slides_container_el.style.left = `${this.posInitial}px`; | ||
// We didn't actually drag. Treat this as a click | ||
this.linkDragging = false; | ||
// Reset the left value to move the carousel back to initial position | ||
this.containerEl.style.left = `${this.posInitial}px`; | ||
} | ||
@@ -117,21 +163,19 @@ | ||
slideTo(direction, action) { | ||
this.slides_container_el.classList.add('enso-carousel__slides--sliding'); | ||
this.containerEl.classList.add('enso-carousel__slides--sliding'); | ||
if (this.allowShift) { | ||
this.allowShift = false; | ||
if (!action) { | ||
this.posInitial = this.slides_container_el.offsetLeft; | ||
this.posInitial = this.containerEl.offsetLeft; | ||
} | ||
if (direction > 0) { | ||
this.slides_container_el.style.left = | ||
this.posInitial - this.slideWidth * direction + 'px'; | ||
this.containerEl.style.left = this.posInitial - this.slideWidth * direction + 'px'; | ||
this.currentIndex = this.currentIndex + direction; | ||
} else if (direction < 0) { | ||
this.slides_container_el.style.left = | ||
this.posInitial - this.slideWidth * direction + 'px'; | ||
this.containerEl.style.left = this.posInitial - this.slideWidth * direction + 'px'; | ||
this.currentIndex = this.currentIndex + direction; | ||
} | ||
} | ||
this.allowShift = false; | ||
}, | ||
@@ -145,6 +189,6 @@ | ||
onTransitionEnd() { | ||
this.slides_container_el.classList.remove('enso-carousel__slides--sliding'); | ||
this.containerEl.classList.remove('enso-carousel__slides--sliding'); | ||
if (this.currentIndex === -1) { | ||
this.slides_container_el.style.left = `${-(this.slides.length * this.slideWidth)}px`; | ||
this.containerEl.style.left = `${-(this.slides.length * this.slideWidth)}px`; | ||
this.currentIndex = this.slides.length - 1; | ||
@@ -154,3 +198,3 @@ } | ||
if (this.currentIndex === this.slides.length) { | ||
this.slides_container_el.style.left = `${-(1 * this.slideWidth)}px`; | ||
this.containerEl.style.left = `${-(1 * this.slideWidth)}px`; | ||
this.currentIndex = 0; | ||
@@ -157,0 +201,0 @@ } |
{ | ||
"name": "enso-carousel", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"description": "A renderless Vue component carousel.", | ||
@@ -5,0 +5,0 @@ "main": "js/EnsoCarousel.js", |
@@ -5,2 +5,6 @@ # Enso Carousel | ||
## Limitations | ||
The carousel and its slides must be 100vw wide. | ||
## Installation | ||
@@ -41,9 +45,11 @@ | ||
> | ||
<div class="enso-carousel" slot-scope="{ prev, next, goto, isCurrentIndex, slides }"> | ||
<slide | ||
class="enso-carousel__slide" | ||
v-for="(slide, index) in slides" | ||
:key="'slide' + index" | ||
v-bind="slide" | ||
></slide> | ||
<div slot-scope="{ prev, next, goto, isCurrentIndex, slides }"> | ||
<div class="enso-carousel__slides"> | ||
<slide | ||
class="enso-carousel__slide" | ||
v-for="(slide, index) in slides" | ||
:key="'slide' + index" | ||
v-bind="slide" | ||
></slide> | ||
</div> | ||
@@ -100,2 +106,39 @@ <button @click="prev"> | ||
## Usage with links | ||
```vue | ||
<template> | ||
<enso-carousel | ||
:slides="[ | ||
{ | ||
content: 'This is my carousel. Here is the first slide.', | ||
url: 'https://example.com', | ||
}, | ||
{ | ||
content: 'This is the second slide.', | ||
url: 'https://example.com', | ||
}, | ||
{ | ||
content: 'And here is the third slide.', | ||
url: 'https://example.com', | ||
}, | ||
]" | ||
> | ||
<div slot-scope="{ prev, next, goto, isCurrentIndex, slides }"> | ||
<div class="enso-carousel__slides"> | ||
<a | ||
:href="slide.url" | ||
class="enso-carousel__slide" | ||
v-for="(slide, index) in slides" | ||
:key="index" | ||
v-bind="slide" | ||
> | ||
{{ slide.content }} | ||
</a> | ||
</div> | ||
</div> | ||
</enso-carousel> | ||
</template> | ||
``` | ||
## Props | ||
@@ -120,5 +163,1 @@ | ||
- isCurrentIndex(index) | ||
## Limitations | ||
CSS limits the slides to being 100vw. |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
10454
5
184
160