Skip to content

Commit

Permalink
Include edge gaps when containScroll is active
Browse files Browse the repository at this point in the history
  • Loading branch information
davidcetinkaya authored and davidjerleke committed May 7, 2022
1 parent 6489920 commit 4f16d0b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 23 deletions.
18 changes: 10 additions & 8 deletions packages/embla-carousel/src/components/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { ScrollContain } from './ScrollContain'
import { ScrollLimit } from './ScrollLimit'
import { ScrollLooper, ScrollLooperType } from './ScrollLooper'
import { ScrollProgress, ScrollProgressType } from './ScrollProgress'
import { ScrollSnap } from './ScrollSnap'
import { ScrollSnaps } from './ScrollSnaps'
import { ScrollTarget, ScrollTargetType } from './ScrollTarget'
import { ScrollTo, ScrollToType } from './ScrollTo'
import { SlideLooper, SlideLooperType } from './SlideLooper'
Expand Down Expand Up @@ -86,35 +86,37 @@ export function Engine(
const viewSize = axis.measureSize(containerRect)
const percentOfView = PercentOfView(viewSize)
const alignment = Alignment(align, viewSize)
const containSnaps = !loop && containScroll !== ''
const includeEdgeGap = loop || containScroll !== ''
const { slideSizes, slideSizesWithGaps } = SlideSizes(
axis,
slides,
containerRect,
slideRects,
loop,
slides,
includeEdgeGap,
)
const slidesToScroll = SlidesToScroll(
viewSize,
slideSizesWithGaps,
groupSlides,
)
const { snaps, snapsAligned } = ScrollSnap(
const { snaps, snapsAligned } = ScrollSnaps(
axis,
alignment,
containerRect,
slideRects,
slideSizesWithGaps,
slidesToScroll,
containSnaps,
)
const contentSize = -arrayLast(snaps) + arrayLast(slideSizesWithGaps)
const { snapsContained } = ScrollContain(
viewSize,
contentSize,
snaps,
snapsAligned,
containScroll,
)

const contain = !loop && containScroll !== ''
const scrollSnaps = contain ? snapsContained : snapsAligned
const scrollSnaps = containSnaps ? snapsContained : snapsAligned
const { limit } = ScrollLimit(contentSize, scrollSnaps, loop)

// Indexes
Expand Down
3 changes: 1 addition & 2 deletions packages/embla-carousel/src/components/ScrollContain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ export type ScrollContainType = {
export function ScrollContain(
viewSize: number,
contentSize: number,
snaps: number[],
snapsAligned: number[],
containScroll: ScrollContainOptionType,
): ScrollContainType {
const scrollBounds = Limit(-contentSize + viewSize, snaps[0])
const scrollBounds = Limit(-contentSize + viewSize, snapsAligned[0])
const snapsBounded = snapsAligned.map(scrollBounds.constrain)
const snapsContained = measureContained()

Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,36 @@
import { AlignmentType } from './Alignment'
import { AxisType } from './Axis'
import { SlidesToScrollType } from './SlidesToScroll'
import { arrayLast, mathAbs } from './utils'
import { arrayLast, arrayLastIndex, mathAbs } from './utils'

export type ScrollSnapType = {
export type ScrollSnapsType = {
snaps: number[]
snapsAligned: number[]
}

export function ScrollSnap(
export function ScrollSnaps(
axis: AxisType,
alignment: AlignmentType,
containerRect: DOMRect,
slideRects: DOMRect[],
slideSizesWithGaps: number[],
slidesToScroll: SlidesToScrollType,
): ScrollSnapType {
containScroll: boolean,
): ScrollSnapsType {
const { startEdge, endEdge } = axis
const { groupSlides } = slidesToScroll
const alignments = measureSizes().map(alignment.measure)
const snaps = measureUnaligned()
const snapsAligned = measureAligned()

function measureStart(): number {
return 0
}

function measureEnd(): number {
return arrayLast(snaps) - arrayLast(slideSizesWithGaps)
}

function measureSizes(): number[] {
return groupSlides(slideRects)
.map((rects) => arrayLast(rects)[endEdge] - rects[0][startEdge])
Expand All @@ -33,12 +44,18 @@ export function ScrollSnap(
}

function measureAligned(): number[] {
const groupedSnaps = groupSlides(snaps).map((g) => g[0])
const alignments = measureSizes().map(alignment.measure)
return groupedSnaps.map((snap, index) => snap + alignments[index])
return groupSlides(snaps)
.map((g) => g[0])
.map((snap, index, groupedSnaps) => {
const isFirst = !index
const isLast = index === arrayLastIndex(groupedSnaps)
if (containScroll && isFirst) return measureStart()
if (containScroll && isLast) return measureEnd()
return snap + alignments[index]
})
}

const self: ScrollSnapType = {
const self: ScrollSnapsType = {
snaps,
snapsAligned,
}
Expand Down
25 changes: 20 additions & 5 deletions packages/embla-carousel/src/components/SlideSizes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,36 @@ export type SlideSizesType = {

export function SlideSizes(
axis: AxisType,
slides: HTMLElement[],
containerRect: DOMRect,
slideRects: DOMRect[],
loop: boolean,
slides: HTMLElement[],
includeEdgeGap: boolean,
): SlideSizesType {
const { measureSize, startEdge, endEdge } = axis
const startGap = measureStartGap()
const endGap = measureEndGap()
const slideSizes = slideRects.map(measureSize)
const slideSizesWithGaps = measureWithGaps()

function measureStartGap(): number {
if (!includeEdgeGap) return 0
const slideRect = slideRects[0]
return Math.abs(containerRect[startEdge] - slideRect[startEdge])
}

function measureEndGap(): number {
if (!includeEdgeGap) return 0
const style = window.getComputedStyle(arrayLast(slides))
return parseFloat(style.getPropertyValue('margin-'.concat(endEdge)))
}

function measureWithGaps(): number[] {
return slideRects
.map((rect, index, rects) => {
const isFirst = !index
const isLast = index === arrayLastIndex(rects)
const style = window.getComputedStyle(arrayLast(slides))
const endGap = parseFloat(style.getPropertyValue(`margin-${endEdge}`))
if (isLast) return slideSizes[index] + (loop ? endGap : 0)
if (isFirst) return slideSizes[index] + startGap
if (isLast) return slideSizes[index] + endGap
return rects[index + 1][startEdge] - rect[startEdge]
})
.map(mathAbs)
Expand Down

0 comments on commit 4f16d0b

Please sign in to comment.