-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathcarousel.js
136 lines (135 loc) · 5.09 KB
/
carousel.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
Vue.component('carousel', {
template: `
<div class="card-carousel" @mouseover="stopTimer" @mouseleave="restartTimer">
<div class="progressbar" v-if="autoSlideInterval && showProgressBar">
<div :style="{width: progressBar + '%' }"></div>
</div>
<div class="card-img">
<img :src="currentImage" alt="">
<div class="actions">
<span @click="prevImage" class="prev">
<i class="fas fa-chevron-left"></i>
</span>
<span @click="nextImage" class="next">
<i class="fas fa-chevron-right"></i>
</span>
</div>
</div>
<div class="thumbnails">
<div
v-for="(image, index) in images"
:key="image.id"
:class="['thumbnail-image', (activeImage == index) ? 'active' : '']"
@click="activateImage(index)"
>
<img :src="image.thumb">
</div>
</div>
</div>
`,
computed: {
// currentImage gets called whenever activeImage changes
// and is the reason why we don't have to worry about the
// big image getting updated
currentImage() {
this.timeLeft = this.autoSlideInterval;
return this.images[this.activeImage].big;
},
progressBar() {
//Calculate the width of the progressbar
return 100 - (this.timeLeft/this.autoSlideInterval) * 100;
}
},
data() {
return {
//Index of the active image
activeImage: 0,
//Hold the timeout, so we can clear it when it is needed
autoSlideTimeout: null,
//If the timer is stopped e.g. when hovering over the carousel
stopSlider: false,
//Hold the time left until changing to the next image
timeLeft: 0,
//Hold the interval so we can clear it when needed
timerInterval: null,
//Every 10ms decrease the timeLeft
countdownInterval: 10
}
},
methods: {
// Go forward on the images array
// or go at the first image if you can't go forward
nextImage() {
var active = this.activeImage + 1;
if(active >= this.images.length) {
active = 0;
}
this.activateImage(active);
},
// Go backwards on the images array
// or go at the last image
prevImage() {
var active = this.activeImage - 1;
if(active < 0) {
active = this.images.length - 1;
}
this.activateImage(active);
},
activateImage(imageIndex) {
this.activeImage = imageIndex;
},
//Wait until 'interval' and go to the next image;
startTimer(interval) {
if(interval && interval > 0 && !this.stopSlider) {
var self = this;
clearTimeout(this.autoSlideTimeout);
this.autoSlideTimeout = setTimeout(function() {
self.nextImage();
self.startTimer(self.autoSlideInterval);
}, interval);
}
},
//Stop the timer when hovering over the carousel
stopTimer() {
clearTimeout(this.autoSlideTimeout);
this.stopSlider = true;
clearInterval(this.timerInterval);
},
//Restart the timer(with 'timeLeft') when leaving from the carousel
restartTimer() {
this.stopSlider = false;
clearInterval(this.timerInterval);
this.startCountdown();
this.startTimer(this.timeLeft);
},
//Start countdown from 'autoSlideInterval' to 0
startCountdown() {
if(!this.showProgressBar) return;
var self = this;
this.timerInterval = setInterval(function() {
self.timeLeft -= self.countdownInterval;
if(self.timeLeft <= 0) {
self.timeLeft = self.autoSlideInterval;
}
}, this.countdownInterval);
}
},
created() {
//Check if startingImage prop was given and if the index is inside the images array bounds
if(this.startingImage
&& this.startingImage >= 0
&& this.startingImage < this.images.length) {
this.activeImage = this.startingImage;
}
//Check if autoSlideInterval prop was given and if it is a positive number
if(this.autoSlideInterval
&& this.autoSlideInterval > this.countdownInterval) {
//Start the timer to go to the next image
this.startTimer(this.autoSlideInterval);
this.timeLeft = this.autoSlideInterval;
//Start countdown to show the progressbar
this.startCountdown();
}
},
props: ['startingImage', 'images', 'autoSlideInterval', 'showProgressBar']
})