Skip to content

Commit

Permalink
Add NodeRect component.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjerleke committed Nov 25, 2023
1 parent 1a5c01c commit ab973c9
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -505,15 +505,16 @@ const IOS_PICKER_STYLES = css`
min-width: 100%;
height: 100%;
overflow: hidden;
display: flex;
align-items: center;
touch-action: pan-x;
}
.embla__ios-picker__viewport {
height: 100%;
height: 32px;
width: 100%;
position: relative;
display: flex;
perspective: 1000px;
align-items: center;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
Expand All @@ -534,7 +535,7 @@ const IOS_PICKER_STYLES = css`
}
.embla__ios-picker__container {
height: 32px;
height: 100%;
width: 100%;
position: absolute;
transform-style: preserve-3d;
Expand Down
22 changes: 10 additions & 12 deletions packages/embla-carousel/src/__tests__/mocks/testElements.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ export type TestElementDimensionsType = {
}
}

function mockNodeRects(node: HTMLElement, rect: DOMRect): void {
Object.defineProperty(node, 'offsetTop', { value: rect.top })
Object.defineProperty(node, 'offsetLeft', { value: rect.left })
Object.defineProperty(node, 'offsetWidth', { value: rect.width })
Object.defineProperty(node, 'offsetHeight', { value: rect.height })
}

export function mockTestElementDimensions(
dimensions: TestElementDimensionsType,
rootNode: HTMLElement
Expand All @@ -20,18 +27,9 @@ export function mockTestElementDimensions(
containerNode.innerHTML = ''
slideNodes.forEach((slideNode) => containerNode.appendChild(slideNode))

const mockNodeOffset = (node: any, rect: DOMRect) => {
Object.defineProperty(node, 'offsetTop', { value: rect.top })
Object.defineProperty(node, 'offsetLeft', { value: rect.left })
Object.defineProperty(node, 'offsetWidth', { value: rect.width })
Object.defineProperty(node, 'offsetHeight', { value: rect.height })
}

mockNodeOffset(rootNode, containerRect)
mockNodeOffset(containerNode, containerRect)
slideNodes.forEach((s, i) => {
mockNodeOffset(s, slideRects[i])
})
mockNodeRects(rootNode, containerRect)
mockNodeRects(containerNode, containerRect)
slideNodes.forEach((s, i) => mockNodeRects(s, slideRects[i]))

if (!slideNodes.length) return

Expand Down
7 changes: 4 additions & 3 deletions packages/embla-carousel/src/components/Axis.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DirectionOptionType } from './Direction'
import { NodeRectType } from './NodeRects'

export type AxisOptionType = 'x' | 'y'
type AxisEdgeType = 'top' | 'right' | 'bottom' | 'left'
Expand All @@ -8,7 +9,7 @@ export type AxisType = {
cross: AxisOptionType
startEdge: AxisEdgeType
endEdge: AxisEdgeType
measureSize: (rect: DOMRect) => number
measureSize: (nodeRect: NodeRectType) => number
}

export function Axis(
Expand All @@ -20,8 +21,8 @@ export function Axis(
const startEdge = getStartEdge()
const endEdge = getEndEdge()

function measureSize(rect: DOMRect): number {
const { width, height } = rect
function measureSize(nodeRect: NodeRectType): number {
const { width, height } = nodeRect
return scroll === 'x' ? width : height
}

Expand Down
21 changes: 9 additions & 12 deletions packages/embla-carousel/src/components/Engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { DragTracker } from './DragTracker'
import { EventHandlerType } from './EventHandler'
import { EventStore, EventStoreType } from './EventStore'
import { LimitType } from './Limit'
import { NodeRectType, NodeRects } from './NodeRects'
import { OptionsType } from './Options'
import { PercentOfView, PercentOfViewType } from './PercentOfView'
import { ResizeHandler, ResizeHandlerType } from './ResizeHandler'
Expand All @@ -27,13 +28,7 @@ import { SlidesInView, SlidesInViewType } from './SlidesInView'
import { SlideSizes } from './SlideSizes'
import { SlidesToScroll, SlidesToScrollType } from './SlidesToScroll'
import { Translate, TranslateType } from './Translate'
import {
arrayKeys,
arrayLast,
arrayLastIndex,
getNodeRect,
WindowType
} from './utils'
import { arrayKeys, arrayLast, arrayLastIndex, WindowType } from './utils'
import { Vector1D, Vector1DType } from './Vector1d'
import {
AnimationType,
Expand Down Expand Up @@ -76,8 +71,8 @@ export type EngineType = {
slideIndexes: number[]
slideFocus: SlideFocusType
slideRegistry: SlideRegistryType['slideRegistry']
containerRect: DOMRect
slideRects: DOMRect[]
containerRect: NodeRectType
slideRects: NodeRectType[]
}

export function Engine(
Expand Down Expand Up @@ -110,8 +105,9 @@ export function Engine(
} = options

// Measurements
const containerRect = getNodeRect(container)
const slideRects = slides.map((slide) => getNodeRect(slide))
const nodeRects = NodeRects()
const containerRect = nodeRects.measure(container)
const slideRects = slides.map(nodeRects.measure)
const direction = Direction(contentDirection)
const axis = Axis(scrollAxis, contentDirection)
const viewSize = axis.measureSize(containerRect)
Expand Down Expand Up @@ -312,7 +308,8 @@ export function Engine(
ownerWindow,
slides,
axis,
watchResize
watchResize,
nodeRects
),
scrollBody,
scrollBounds: ScrollBounds(
Expand Down
33 changes: 33 additions & 0 deletions packages/embla-carousel/src/components/NodeRects.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
export type NodeRectType = {
top: number
right: number
bottom: number
left: number
width: number
height: number
}

export type NodeRectsType = {
measure: (node: HTMLElement) => NodeRectType
}

export function NodeRects(): NodeRectsType {
function measure(node: HTMLElement): NodeRectType {
const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = node
const offset: NodeRectType = {
top: offsetTop,
right: offsetLeft + offsetWidth,
bottom: offsetTop + offsetHeight,
left: offsetLeft,
width: offsetWidth,
height: offsetHeight
}

return offset
}

const self: NodeRectsType = {
measure
}
return self
}
10 changes: 6 additions & 4 deletions packages/embla-carousel/src/components/ResizeHandler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { AxisType } from './Axis'
import { EmblaCarouselType } from './EmblaCarousel'
import { EventHandlerType } from './EventHandler'
import { getNodeRect, isBoolean, mathAbs, WindowType } from './utils'
import { NodeRectsType } from './NodeRects'
import { isBoolean, mathAbs, WindowType } from './utils'

type ResizeHandlerCallbackType = (
emblaApi: EmblaCarouselType,
Expand All @@ -21,15 +22,16 @@ export function ResizeHandler(
ownerWindow: WindowType,
slides: HTMLElement[],
axis: AxisType,
watchResize: ResizeHandlerOptionType
watchResize: ResizeHandlerOptionType,
nodeRects: NodeRectsType
): ResizeHandlerType {
let resizeObserver: ResizeObserver
let containerSize: number
let slideSizes: number[] = []
let destroyed = false

function readSize(node: HTMLElement): number {
return axis.measureSize(getNodeRect(node))
return axis.measureSize(nodeRects.measure(node))
}

function init(emblaApi: EmblaCarouselType): void {
Expand All @@ -46,7 +48,7 @@ export function ResizeHandler(
const newSize = readSize(isContainer ? container : slides[slideIndex])
const diffSize = mathAbs(newSize - lastSize)

if (diffSize >= 0.2) {
if (diffSize >= 0.5) {
ownerWindow.requestAnimationFrame(() => {
emblaApi.reInit()
eventHandler.emit('resize')
Expand Down
5 changes: 3 additions & 2 deletions packages/embla-carousel/src/components/ScrollSnaps.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AlignmentType } from './Alignment'
import { AxisType } from './Axis'
import { NodeRectType } from './NodeRects'
import { SlidesToScrollType } from './SlidesToScroll'
import { arrayLast, mathAbs } from './utils'

Expand All @@ -11,8 +12,8 @@ export type ScrollSnapsType = {
export function ScrollSnaps(
axis: AxisType,
alignment: AlignmentType,
containerRect: DOMRect,
slideRects: DOMRect[],
containerRect: NodeRectType,
slideRects: NodeRectType[],
slidesToScroll: SlidesToScrollType
): ScrollSnapsType {
const { startEdge, endEdge } = axis
Expand Down
5 changes: 3 additions & 2 deletions packages/embla-carousel/src/components/SlideSizes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { AxisType } from './Axis'
import { NodeRectType } from './NodeRects'
import { arrayIsLastIndex, arrayLast, mathAbs, WindowType } from './utils'

export type SlideSizesType = {
Expand All @@ -10,8 +11,8 @@ export type SlideSizesType = {

export function SlideSizes(
axis: AxisType,
containerRect: DOMRect,
slideRects: DOMRect[],
containerRect: NodeRectType,
slideRects: NodeRectType[],
slides: HTMLElement[],
readEdgeGap: boolean,
ownerWindow: WindowType
Expand Down
5 changes: 3 additions & 2 deletions packages/embla-carousel/src/components/SlidesToScroll.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { AxisType } from './Axis'
import { DirectionType } from './Direction'
import { NodeRectType } from './NodeRects'
import {
arrayKeys,
arrayLast,
Expand All @@ -20,8 +21,8 @@ export function SlidesToScroll(
viewSize: number,
slidesToScroll: SlidesToScrollOptionType,
loop: boolean,
containerRect: DOMRect,
slideRects: DOMRect[],
containerRect: NodeRectType,
slideRects: NodeRectType[],
startGap: number,
endGap: number
): SlidesToScrollType {
Expand Down
20 changes: 0 additions & 20 deletions packages/embla-carousel/src/components/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,3 @@ export function isMouseEvent(
evt instanceof ownerWindow.MouseEvent
)
}

export function getNodeRect(node: HTMLElement): DOMRect {
const { offsetTop, offsetLeft, offsetWidth, offsetHeight } = node

const rect = {
top: offsetTop,
left: offsetLeft,
x: offsetLeft,
y: offsetTop,
width: offsetWidth,
height: offsetHeight,
bottom: offsetTop + offsetHeight,
right: offsetLeft + offsetWidth
}

return {
...rect,
toJSON: () => rect
}
}

0 comments on commit ab973c9

Please sign in to comment.