Skip to content

Commit 083a8e2

Browse files
authored
Merge pull request #146 from BKWLD/slide-width-based-on-client
Add Pagination for Variable Width Slides
2 parents 472768c + 7cc0ed2 commit 083a8e2

File tree

6 files changed

+83
-7
lines changed

6 files changed

+83
-7
lines changed
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<template>
2+
<ssr-carousel :slides-per-page="null" show-arrows show-dots>
3+
<slide :index="1" :style="{ width: '65%', height: '30vw' }"></slide>
4+
<slide :index="2" :style="{ width: '50%', height: '30vw' }"></slide>
5+
<slide :index="3" :style="{ width: '30%', height: '30vw' }"></slide>
6+
<slide :index="4" :style="{ width: '65%', height: '30vw' }"></slide>
7+
<slide :index="5" :style="{ width: '30%', height: '30vw' }"></slide>
8+
<slide :index="6" :style="{ width: '50%', height: '30vw' }"></slide>
9+
<slide :index="7" :style="{ width: '50%', height: '30vw' }"></slide>
10+
<slide :index="8" :style="{ width: '65%', height: '30vw' }"></slide>
11+
<slide :index="9" :style="{ width: '30%', height: '30vw' }"></slide>
12+
</ssr-carousel>
13+
</template>

demo/content/responsive.md

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,10 @@ While it's not the primary use case of this package, you if you set `slidesPerPa
7070

7171
- If there are not enough slides to fill the viewport, slides will be left aligned rather than center aligned.
7272
- This hasn't been tested with responsive props or looping. Peeking doesn't make sense for this use case but care hasn't been taken to disabling it.
73-
- Pagination controls aren't supported yet, this is purely drag only.
73+
- Pagination controls are in beta
74+
- Pagination is done on a per slide basis
75+
- Looping still has not been implemented
76+
- Slides are left aligned
7477

7578
<demos-responsive-variable-width></demos-responsive-variable-width>
7679

@@ -82,6 +85,24 @@ While it's not the primary use case of this package, you if you set `slidesPerPa
8285
</ssr-carousel>
8386
```
8487

88+
Carousel with variable width and arrows:
89+
90+
<demos-responsive-variable-width-with-arrows></demos-responsive-variable-width-with-arrows>
91+
92+
```vue
93+
<ssr-carousel data-cy="variable-width" :slides-per-page="null">
94+
<slide :index="1" :style="{ width: '65%', height: '30vw' }"></slide>
95+
<slide :index="2" :style="{ width: '50%', height: '30vw' }"></slide>
96+
<slide :index="3" :style="{ width: '30%', height: '30vw' }"></slide>
97+
<slide :index="4" :style="{ width: '65%', height: '30vw' }"></slide>
98+
<slide :index="5" :style="{ width: '30%', height: '30vw' }"></slide>
99+
<slide :index="6" :style="{ width: '50%', height: '30vw' }"></slide>
100+
<slide :index="7" :style="{ width: '50%', height: '30vw' }"></slide>
101+
<slide :index="8" :style="{ width: '65%', height: '30vw' }"></slide>
102+
<slide :index="9" :style="{ width: '30%', height: '30vw' }"></slide>
103+
</ssr-carousel>
104+
```
105+
85106
Here's an example where there aren't enough slides to exceed the carouel width:
86107

87108
<demos-responsive-variable-width-disabled></demos-responsive-variable-width-disabled>

src/concerns/dimensions.coffee

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export default
8080
@carouselWidth = @$el.getBoundingClientRect().width + @gutterWidth
8181
@viewportWidth = window.innerWidth
8282
@capturePeekingMeasurements()
83-
@captureTrackWidth() if @isVariableWidth
83+
@captureCarouselDims() if @isVariableWidth
8484

8585
# Make the width style that gives a slide it's width given
8686
# slidesPerPage. Reduce this width by the gutter if present
@@ -114,3 +114,10 @@ export default
114114
(#{@autoUnit(peekLeft)} + #{@autoUnit(peekRight)}) / #{slidesPerPage} -
115115
(#{@autoUnit(gutter)} * #{slidesPerPage - 1}) / #{slidesPerPage}
116116
)"
117+
118+
119+
# Get the target X scroll position of a given slide
120+
targetXOfIdx: (idx) ->
121+
if @isVariableWidth
122+
then @measuredSlidesWidths[idx].targetXScroll
123+
else @pageWidth / @currentSlidesPerPage

src/concerns/dragging.coffee

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ export default
7373
fractionalIndex: ->
7474
return 0 unless @trackWidth
7575

76+
if @isVariableWidth then return @fractionalIndexFromMeasurements
77+
7678
# Work in positive numbers
7779
x = @currentX * -1
7880

@@ -104,6 +106,16 @@ export default
104106
# Return the final value by adding all the passed index values
105107
return pageProgressPercent + setIndex * @pages + pageIndex
106108

109+
fractionalIndexFromMeasurements: ->
110+
# Work in positive numbers
111+
x = @currentX * -1
112+
113+
slideIdx = @measuredSlidesWidths.findIndex((measuredSlide) => measuredSlide.targetXScroll > x) - 1
114+
115+
percentage = (x - @measuredSlidesWidths[slideIdx].targetXScroll) / @measuredSlidesWidths[slideIdx].width
116+
117+
return slideIdx + percentage
118+
107119
# Determine if the user is dragging vertically
108120
isVerticalDrag: ->
109121
return unless @dragDirectionRatio
@@ -141,7 +153,7 @@ export default
141153
else @gotoEnd()
142154

143155
# If rendering variable width slides, don't come to a rest at an index
144-
else if @isVariableWidth then @tweenToStop()
156+
else if @isVariableWidth then @goto @dragIndex
145157

146158
# If user was vertically dragging, reset the index
147159
else if @isVerticalDrag then @goto @index

src/concerns/pagination.coffee

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ export default
2222

2323
# The current number of pages
2424
pages: -> switch
25+
# When variable width, pages is slide count
26+
when @isVariableWidth then @slidesCount
2527

2628
# When looping and paginating per slide, make a dot per slide
2729
when @paginateBySlide and @shouldLoop then @slidesCount
@@ -146,9 +148,10 @@ export default
146148
getXForIndex: (index) ->
147149

148150
# Figure out the new x position
149-
x = if @paginateBySlide
150-
then index * @slideWidth * -1
151-
else index * @pageWidth * -1
151+
x = switch
152+
when @isVariableWidth then @targetXOfIdx(@applyIndexBoundaries(index)) * -1
153+
when @paginateBySlide then index * @slideWidth * -1
154+
else index * @pageWidth * -1
152155

153156
# Apply adjustments to x value and persist
154157
x += @makeIncompletePageOffset index

src/concerns/variable-width.coffee

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,36 @@ Functionality related to supporting variable width slides
33
###
44
export default
55

6-
data: -> measuredTrackWidth: 0
6+
data: ->
7+
measuredTrackWidth: 0
8+
measuredSlidesWidths: []
79

810
computed:
911

1012
# Is the carousel in variable width mode
1113
isVariableWidth: -> @slidesPerPage == null
1214

1315
methods:
16+
# Capture all dimensions of carousel
17+
captureCarouselDims: ->
18+
@captureTrackWidth()
19+
@captureSlideWidths()
1420

1521
# Measure the width of the track
1622
captureTrackWidth: ->
1723
return unless @$refs.track
1824
@measuredTrackWidth = @$refs.track.$el.scrollWidth
25+
26+
# Capture slide dims and place them into an array of data
27+
captureSlideWidths: ->
28+
return unless @$refs.track
29+
@measuredSlidesWidths = @$refs?.track?.$children.reduce((acc, child, idx, arr) =>
30+
return [
31+
...acc
32+
{
33+
width: child.$el.clientWidth
34+
targetXScroll: (acc[idx - 1]?.targetXScroll || 0) + (acc[idx - 1]?.width || 0) + @gutter * (idx > 0)
35+
}
36+
]
37+
, [] )
38+

0 commit comments

Comments
 (0)