Skip to content

Commit f529b0b

Browse files
authored
Merge pull request #2 from ErikPham/feat/support-adjust-slide
feat: support adjust slide
2 parents 8bd3ea7 + 2f7f5f1 commit f529b0b

File tree

5 files changed

+140
-4
lines changed

5 files changed

+140
-4
lines changed

demo/App.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@
8585
<example-basic />
8686
<example-responsive />
8787
<example-scroll-per-page />
88+
<example-adjust />
8889
</div>
8990
<div id="license" class="container">
9091
<h2 style="border-bottom: 1px solid #eaecef; padding-bottom: 0.3em">
@@ -106,9 +107,15 @@
106107
import ExampleBasic from './ExampleBasic.vue';
107108
import ExampleResponsive from './ExampleResponsive.vue';
108109
import ExampleScrollPerPage from './ExampleScrollPerPage.vue';
110+
import ExampleAdjust from './ExampleAdjust.vue';
109111
export default {
110112
name: 'App',
111-
components: { ExampleBasic, ExampleResponsive, ExampleScrollPerPage },
113+
components: {
114+
ExampleBasic,
115+
ExampleResponsive,
116+
ExampleScrollPerPage,
117+
ExampleAdjust,
118+
},
112119
setup() {
113120
return { slideCount: 6 };
114121
},

demo/ExampleAdjust.vue

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<template>
2+
<div class="content">
3+
<h3 style="border-bottom: 1px solid #eaecef; padding-bottom: 0.3em">
4+
4. Adjust
5+
</h3>
6+
<p>
7+
Sometimes we need to show not the first slide. And do not want to reduce
8+
the score of page speed.
9+
</p>
10+
<div class="example-basic" style="margin-bottom: 50px">
11+
<div class="preview">
12+
<carousel :per-page="1" :navigate-to="1" :navigationEnabled="true">
13+
<slide :adjust="true">
14+
<img src="https://via.placeholder.com/1211x300.png/09f/fff" />
15+
</slide>
16+
<slide>
17+
<img src="https://via.placeholder.com/1210x300.png/09f/fff" />
18+
</slide>
19+
<slide>
20+
<img src="https://via.placeholder.com/1211x300.png/09f/fff" />
21+
</slide>
22+
<slide>
23+
<img src="https://via.placeholder.com/1212x300.png/09f/fff" />
24+
</slide>
25+
</carousel>
26+
</div>
27+
<div class="template">
28+
<pre
29+
class="language-html"
30+
><code class="language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
31+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
32+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>carousel</span><span class="token punctuation">&gt;</span></span>
33+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>slide <span class="token attr-name">:adjust</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>true</span></span><span class="token punctuation">&gt;</span></span>1<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>slide</span><span class="token punctuation">&gt;</span></span>
34+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>slide</span><span class="token punctuation">&gt;</span></span>2<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>slide</span><span class="token punctuation">&gt;</span></span>
35+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>slide</span><span class="token punctuation">&gt;</span></span>3<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>slide</span><span class="token punctuation">&gt;</span></span>
36+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>slide</span><span class="token punctuation">&gt;</span></span>4<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>slide</span><span class="token punctuation">&gt;</span></span>
37+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>carousel</span><span class="token punctuation">&gt;</span></span>
38+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
39+
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>
40+
</code></pre>
41+
</div>
42+
</div>
43+
</div>
44+
</template>
45+
46+
<script>
47+
export default {
48+
name: 'ExampleBasic',
49+
};
50+
</script>

src/Carousel.vue

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ import {
7272
watch,
7373
} from 'vue';
7474
import debounce from './utils/debounce';
75+
import delay from './utils/delay';
7576
import Navigation from './Navigation.vue';
7677
import Pagination from './Pagination.vue';
7778
@@ -403,6 +404,7 @@ export default {
403404
const startTime = ref(null);
404405
const autoplayInterval = ref(null);
405406
const slotSlides = ref([]);
407+
const isFinishSlideAdjust = ref(false);
406408
407409
// Ref template
408410
const vueConciseCarousel = ref(null);
@@ -694,8 +696,8 @@ export default {
694696
*/
695697
const getSlideCount = () => {
696698
if (vueConciseCarousel.value) {
697-
const carouselInnerElements = vueConciseCarousel.value.getElementsByClassName(
698-
'VueCarousel-slide'
699+
const carouselInnerElements = vueConciseCarousel.value.querySelectorAll(
700+
'.VueCarousel-slide:not(.VueCarousel-slide-adjust)'
699701
);
700702
slotSlides.value = carouselInnerElements;
701703
slideCount.value = carouselInnerElements.length;
@@ -715,8 +717,20 @@ export default {
715717
* @param {Number} page The value of the new page number
716718
* @param {string|undefined} advanceType An optional value describing the type of page advance
717719
*/
718-
const goToPage = (page, advanceType) => {
720+
const goToPage = async (page, advanceType) => {
719721
if (page >= 0 && page <= pageCount.value) {
722+
if (hasVueCarouselSlideAdjust.value && !isFinishSlideAdjust.value) {
723+
if (page === navigateTo.value) {
724+
currentPage.value = navigateTo.value;
725+
return;
726+
}
727+
728+
dragging.value = true;
729+
handleVueCarouselSlideAdjust();
730+
await delay(refreshRate.value);
731+
dragging.value = false;
732+
}
733+
720734
offset.value = props.scrollPerPage
721735
? Math.min(
722736
slideWidth.value * currentPerPage.value * page,
@@ -810,6 +824,15 @@ export default {
810824
* @param {Object} e The event object
811825
*/
812826
const onDrag = (e) => {
827+
if (
828+
hasVueCarouselSlideAdjust.value &&
829+
!isFinishSlideAdjust.value &&
830+
currentPage.value > 0
831+
) {
832+
handleVueCarouselSlideAdjust();
833+
return;
834+
}
835+
813836
const eventPosX = isTouch ? e.touches[0].clientX : e.clientX;
814837
const eventPosY = isTouch ? e.touches[0].clientY : e.clientY;
815838
const newOffsetX = dragStartX.value - eventPosX;
@@ -934,6 +957,39 @@ export default {
934957
}
935958
};
936959
960+
const hasVueCarouselSlideAdjust = computed(() => {
961+
if (vueConciseCarousel.value) {
962+
return (
963+
vueConciseCarousel.value.querySelector(
964+
'.VueCarousel-slide-adjust'
965+
) !== null
966+
);
967+
}
968+
969+
return false;
970+
});
971+
972+
const handleVueCarouselSlideAdjust = () => {
973+
if (hasVueCarouselSlideAdjust.value && !isFinishSlideAdjust.value) {
974+
if (currentPage.value > 0) {
975+
offset.value = props.scrollPerPage
976+
? Math.min(
977+
slideWidth.value * currentPerPage.value * currentPage.value,
978+
maxOffset.value
979+
)
980+
: slideWidth.value * currentPage.value;
981+
}
982+
983+
const element = vueConciseCarousel.value.querySelector(
984+
'.VueCarousel-slide-adjust'
985+
);
986+
if (element) {
987+
element.parentElement.removeChild(element);
988+
}
989+
isFinishSlideAdjust.value = true;
990+
}
991+
};
992+
937993
provide('carousel', {
938994
isTouch,
939995
dragStartX,
@@ -947,6 +1003,7 @@ export default {
9471003
render();
9481004
}
9491005
});
1006+
9501007
watch(
9511008
navigateTo,
9521009
(val) => {
@@ -981,6 +1038,9 @@ export default {
9811038
watch(currentPage, (val) => {
9821039
ctx.emit('page-change', val);
9831040
ctx.emit('input', val);
1041+
if (currentPage.value !== navigateTo.value) {
1042+
handleVueCarouselSlideAdjust();
1043+
}
9841044
});
9851045
onMounted(() => {
9861046
startAutoplay();

src/Slide.vue

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
'VueCarousel-slide',
88
{
99
'VueCarousel-slide-adjustableHeight': isAdjustableHeight,
10+
'VueCarousel-slide-adjust': adjust,
1011
},
1112
]"
1213
>
@@ -27,6 +28,12 @@ import {
2728
export default {
2829
name: 'Slide',
2930
emits: ['slide-click'],
31+
props: {
32+
adjust: {
33+
type: Boolean,
34+
default: false,
35+
},
36+
},
3037
setup(props, ctx) {
3138
const carousel = inject('carousel');
3239

src/utils/delay.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* Delay time
3+
* @param ms
4+
* @returns {Promise<unknown>}
5+
*/
6+
const delay = (ms) => {
7+
return new Promise((resolve) => {
8+
setTimeout(() => resolve(), ms);
9+
});
10+
};
11+
12+
export default delay;

0 commit comments

Comments
 (0)