Skip to content

Commit

Permalink
Change name for drag components and ship Settle event
Browse files Browse the repository at this point in the history
  • Loading branch information
David Cetinkaya committed Feb 26, 2020
1 parent 88a70e0 commit 1d48512
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 63 deletions.
46 changes: 41 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1850,7 +1850,7 @@ embla.on('init', onInitCallback)
</a>
&nbsp;
<a href="#">
<code>CodeSandbox</code>
<code>CodeSandbox (upcoming)</code>
</a>
</div>
<br>
Expand Down Expand Up @@ -1882,7 +1882,7 @@ const embla = EmblaCarousel(emblaNode, options)
</a>
&nbsp;
<a href="#">
<code>CodeSandbox</code>
<code>CodeSandbox (upcoming)</code>
</a>
</div>
<br>
Expand Down Expand Up @@ -1934,6 +1934,42 @@ embla.on('scroll', () => {
<hr>
</details>

##### `settle`

<details>
<summary>
Fire a callback when the carousel has settled.
</summary>
<hr>
<div>
Under construction...
</div>
<br>
<div>
<a href="https://codesandbox.io/s/embla-carousel-scrollprogress-cghc5">
<img src="https://rawgit.com/davidcetinkaya/embla-carousel/master/docs/assets/codesandbox-logo.svg" height="23" align="top" />
</a>
&nbsp;
<a href="https://codesandbox.io/s/embla-carousel-scrollprogress-cghc5">
<code>CodeSandbox (upcoming)</code>
</a>
</div>
<br>
<p>
<strong>Usage</strong>
</p>

```javascript
const embla = EmblaCarousel(emblaNode, options)

embla.on('settle', () => {
console.log(`The carousel has stopped scrolling.`)
})
```

<hr>
</details>

##### `resize`

<details>
Expand All @@ -1951,7 +1987,7 @@ embla.on('scroll', () => {
</a>
&nbsp;
<a href="#">
<code>CodeSandbox</code>
<code>CodeSandbox (upcoming)</code>
</a>
</div>
<br>
Expand Down Expand Up @@ -1983,7 +2019,7 @@ const embla = EmblaCarousel(emblaNode, options)
</a>
&nbsp;
<a href="#">
<code>CodeSandbox</code>
<code>CodeSandbox (upcoming)</code>
</a>
</div>
<br>
Expand Down Expand Up @@ -2015,7 +2051,7 @@ const embla = EmblaCarousel(emblaNode, options)
</a>
&nbsp;
<a href="#">
<code>CodeSandbox</code>
<code>CodeSandbox (upcoming)</code>
</a>
</div>
<br>
Expand Down
2 changes: 1 addition & 1 deletion docs/index.js

Large diffs are not rendered by default.

36 changes: 18 additions & 18 deletions src/components/dragBehaviour.ts → src/components/dragHandler.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Animation } from './animation'
import { Counter } from './counter'
import { Direction } from './direction'
import { DragTracker } from './dragTracker'
import { EventDispatcher } from './eventDispatcher'
import { EventStore } from './eventStore'
import { Limit } from './limit'
import { Pointer } from './pointer'
import { ScrollBody } from './scrollBody'
import { ScrollTo } from './scrollTo'
import { Vector1D } from './vector1d'
Expand All @@ -14,7 +14,7 @@ type Params = {
target: Vector1D
dragFree: boolean
snapSizes: number[]
pointer: Pointer
dragTracker: DragTracker
location: Vector1D
animation: Animation
scrollTo: ScrollTo
Expand All @@ -25,18 +25,18 @@ type Params = {
events: EventDispatcher
}

export type DragBehaviour = {
export type DragHandler = {
addActivationEvents: () => void
clickAllowed: () => boolean
direction: Direction
isDown: () => boolean
pointerDown: () => boolean
removeAllEvents: () => void
}

export function DragBehaviour(params: Params): DragBehaviour {
export function DragHandler(params: Params): DragHandler {
const { target, scrollBody, dragFree, animation } = params
const { element, pointer, location, events, limit } = params
const { direction } = pointer
const { element, dragTracker, location, events, limit } = params
const { direction } = dragTracker
const focusNodes = ['INPUT', 'SELECT', 'TEXTAREA']
const startX = Vector1D(0)
const startY = Vector1D(0)
Expand Down Expand Up @@ -92,7 +92,7 @@ export function DragBehaviour(params: Params): DragBehaviour {
return speed[type]
}

function pointerForceBoost(): number {
function dragForceBoost(): number {
const boost = dragFree ? freeForceBoost : snapForceBoost
const type = state.isMouse ? 'mouse' : 'touch'
return boost[type]
Expand Down Expand Up @@ -126,14 +126,14 @@ export function DragBehaviour(params: Params): DragBehaviour {

state.isDown = true
state.isMouse = isMouse
pointer.down(evt)
dragTracker.pointerDown(evt)
dragStartLocation.set(target)
target.set(location)
scrollBody.useDefaultMass().useSpeed(80)
addInteractionEvents()
animation.start()
startX.set(pointer.read(evt, 'x'))
startY.set(pointer.read(evt, 'y'))
startX.set(dragTracker.readPoint(evt, 'x'))
startY.set(dragTracker.readPoint(evt, 'y'))
events.dispatch('dragStart')

if (clearPreventClick) state.preventClick = false
Expand All @@ -142,14 +142,14 @@ export function DragBehaviour(params: Params): DragBehaviour {

function move(evt: Event): void {
if (!state.preventScroll && !state.isMouse) {
const X = pointer.read(evt, 'x').get()
const Y = pointer.read(evt, 'y').get()
const X = dragTracker.readPoint(evt, 'x').get()
const Y = dragTracker.readPoint(evt, 'y').get()
const diffX = Math.abs(X - startX.get())
const diffY = Math.abs(Y - startY.get())
state.preventScroll = diffX > diffY
if (!state.preventScroll && !state.preventClick) return up()
}
const diff = pointer.move(evt)
const diff = dragTracker.pointerMove(evt)
const reachedLimit = limit.reachedAny(location.get())
const resist = !params.loop && reachedLimit ? 2 : 1
const preventClick = !state.preventClick && diff
Expand All @@ -160,7 +160,7 @@ export function DragBehaviour(params: Params): DragBehaviour {
}

function up(): void {
const force = pointer.up() * pointerForceBoost()
const force = dragTracker.pointerUp() * dragForceBoost()
const diffToTarget = target.get() - dragStartLocation.get()
const isMoving = Math.abs(diffToTarget) >= 0.5
const preventClick = isMoving && !state.isMouse
Expand All @@ -183,15 +183,15 @@ export function DragBehaviour(params: Params): DragBehaviour {
return !state.preventClick
}

function isDown(): boolean {
function pointerDown(): boolean {
return state.isDown
}

const self: DragBehaviour = {
const self: DragHandler = {
addActivationEvents,
clickAllowed,
direction,
isDown,
pointerDown,
removeAllEvents,
}
return Object.freeze(self)
Expand Down
38 changes: 20 additions & 18 deletions src/components/pointer.ts → src/components/dragTracker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ type State = {
trackTime: number
}

export type Pointer = {
export type DragTracker = {
direction: Direction
down: (evt: Event) => number
move: (evt: Event) => number
up: () => number
read: (evt: any, axis: Axis) => Vector1D
pointerDown: (evt: Event) => number
pointerMove: (evt: Event) => number
pointerUp: () => number
readPoint: (evt: any, axis: Axis) => Vector1D
}

export function Pointer(pxToPercent: PxToPercent): Pointer {
export function DragTracker(pxToPercent: PxToPercent): DragTracker {
const coords = { x: 'clientX', y: 'clientY' }
const startDrag = Vector1D(0)
const diffDrag = Vector1D(0)
Expand All @@ -32,22 +32,22 @@ export function Pointer(pxToPercent: PxToPercent): Pointer {
trackTime: new Date().getTime(),
}

function read(evt: any, axis: Axis): Vector1D {
function readPoint(evt: any, axis: Axis): Vector1D {
state.isMouse = !evt.touches
const c = coords[axis]
const value = state.isMouse ? evt[c] : evt.touches[0][c]
return pointValue.setNumber(value)
}

function down(evt: Event): number {
const point = read(evt, 'x')
function pointerDown(evt: Event): number {
const point = readPoint(evt, 'x')
startDrag.set(point)
lastDrag.set(point)
return pxToPercent.measure(startDrag.get())
}

function move(evt: Event): number {
const point = read(evt, 'x')
function pointerMove(evt: Event): number {
const point = readPoint(evt, 'x')
const time2 = new Date().getTime()
const time1 = state.trackTime

Expand All @@ -62,25 +62,27 @@ export function Pointer(pxToPercent: PxToPercent): Pointer {
return pxToPercent.measure(diffDrag.get())
}

function up(): number {
function pointerUp(): number {
const currentPoint = lastDrag.get()
const trackLength = state.isMouse ? 5 : 4
const point = state.trackPoints
.slice(-trackLength)
.map(trackPoint => currentPoint - trackPoint)
.sort((p1, p2) => (Math.abs(p1) < Math.abs(p2) ? 1 : -1))[0]
.sort((p1, p2) => {
return Math.abs(p1) < Math.abs(p2) ? 1 : -1
})[0]

lastDrag.setNumber(point || 0)
state.trackPoints = []
return pxToPercent.measure(lastDrag.get())
}

const self: Pointer = {
const self: DragTracker = {
direction,
down,
move,
read,
up,
pointerDown,
pointerMove,
pointerUp,
readPoint,
}
return Object.freeze(self)
}
27 changes: 14 additions & 13 deletions src/components/engine.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Alignment } from './alignment'
import { Animation } from './animation'
import { Counter } from './counter'
import { DragBehaviour } from './dragBehaviour'
import { DragHandler } from './dragHandler'
import { DragTracker } from './dragTracker'
import { EventDispatcher } from './eventDispatcher'
import { Limit } from './limit'
import { Options } from './options'
import { Pointer } from './pointer'
import { PxToPercent } from './pxToPercent'
import { ScrollBody } from './scrollBody'
import { ScrollBounds } from './scrollBounds'
Expand All @@ -31,7 +31,7 @@ export type Engine = {
indexPrevious: Counter
indexGroups: number[][]
scrollBody: ScrollBody
pointer: DragBehaviour
dragHandler: DragHandler
slideLooper: SlideLooper
target: Vector1D
translate: Translate
Expand Down Expand Up @@ -96,25 +96,26 @@ export function Engine(

// Direction
const direction = (): number => {
return pointer.isDown()
? pointer.direction.get()
return dragHandler.pointerDown()
? dragHandler.direction.get()
: engine.scrollBody.direction.get()
}

// Draw
const update = (): void => {
engine.scrollBody.seek(target).update()
if (!pointer.isDown()) {

if (!dragHandler.pointerDown()) {
if (!loop) engine.scrollBounds.constrain(target)
if (engine.scrollBody.settle(target)) engine.animation.stop()
}
if (loop) {
engine.scrollLooper.loop(direction())
engine.slideLooper.loop(slides)
}
if (engine.scrollBody.location.get() !== target.get()) {
events.dispatch('scroll')
}

const settled = engine.scrollBody.settle(target)
events.dispatch(settled ? 'settle' : 'scroll')
engine.translate.to(engine.scrollBody.location)
engine.animation.proceed()
}
Expand Down Expand Up @@ -143,17 +144,17 @@ export function Engine(
target,
})

// Pointer
const pointer = DragBehaviour({
// DragHandler
const dragHandler = DragHandler({
animation,
dragFree,
dragTracker: DragTracker(pxToPercent),
element: root,
events,
index,
limit,
location,
loop,
pointer: Pointer(pxToPercent),
scrollBody,
scrollTo,
snapSizes,
Expand All @@ -163,10 +164,10 @@ export function Engine(
// Slider
const engine: Engine = {
animation,
dragHandler,
index,
indexGroups,
indexPrevious,
pointer,
scrollBody,
scrollBounds: ScrollBounds({
animation,
Expand Down
2 changes: 2 additions & 0 deletions src/components/eventDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export type Event =
| 'init'
| 'scroll'
| 'select'
| 'settle'
| 'dragStart'
| 'dragEnd'
| 'destroy'
Expand All @@ -24,6 +25,7 @@ export function EventDispatcher(): EventDispatcher {
resize: [],
scroll: [],
select: [],
settle: [],
}

function dispatch(evt: Event): EventDispatcher {
Expand Down
Loading

0 comments on commit 1d48512

Please sign in to comment.