embla-carousel-vue
Advanced tools
Comparing version 8.0.0-rc02 to 8.0.0-rc03
@@ -74,6 +74,2 @@ (function (global, factory) { | ||
} | ||
function roundToDecimals(decimalPoints) { | ||
const pow = Math.pow(10, decimalPoints); | ||
return n => Math.round(n * pow) / pow; | ||
} | ||
function arrayKeys(array) { | ||
@@ -129,72 +125,2 @@ return objectKeys(array).map(Number); | ||
} | ||
function EventStore() { | ||
let listeners = []; | ||
function add(node, type, handler, options = { | ||
passive: true | ||
}) { | ||
node.addEventListener(type, handler, options); | ||
listeners.push(() => node.removeEventListener(type, handler, options)); | ||
return self; | ||
} | ||
function clear() { | ||
listeners = listeners.filter(remove => remove()); | ||
} | ||
const self = { | ||
add, | ||
clear | ||
}; | ||
return self; | ||
} | ||
function Animation(update, draw) { | ||
const documentVisibleHandler = EventStore(); | ||
const timeStep = 1000 / 60; | ||
let lastTimeStamp = null; | ||
let delta = 0; | ||
let animationFrame = 0; | ||
let engine; | ||
function init(engineInstance) { | ||
engine = engineInstance; | ||
documentVisibleHandler.add(document, 'visibilitychange', () => { | ||
if (document.hidden) lastTimeStamp = null; | ||
}); | ||
} | ||
function destroy() { | ||
stop(); | ||
documentVisibleHandler.clear(); | ||
} | ||
function ifAnimating(active, cb) { | ||
return () => { | ||
if (active === !!animationFrame) cb(); | ||
}; | ||
} | ||
function animate(timeStamp) { | ||
if (!lastTimeStamp) { | ||
lastTimeStamp = timeStamp; | ||
return start(); | ||
} | ||
delta += timeStamp - lastTimeStamp; | ||
lastTimeStamp = timeStamp; | ||
while (delta >= timeStep) { | ||
update(engine); | ||
delta -= timeStep; | ||
} | ||
draw(engine); | ||
if (animationFrame) start(); | ||
} | ||
function start() { | ||
animationFrame = window.requestAnimationFrame(animate); | ||
} | ||
function stop() { | ||
window.cancelAnimationFrame(animationFrame); | ||
lastTimeStamp = null; | ||
animationFrame = 0; | ||
} | ||
const self = { | ||
init, | ||
destroy, | ||
start: ifAnimating(false, start), | ||
stop: ifAnimating(true, stop) | ||
}; | ||
return self; | ||
} | ||
function Axis(axis, direction) { | ||
@@ -303,46 +229,21 @@ const scroll = axis === 'y' ? 'y' : 'x'; | ||
} | ||
function Vector1D(value) { | ||
let vector = value; | ||
function get() { | ||
return vector; | ||
} | ||
function set(n) { | ||
vector = readNumber(n); | ||
function EventStore() { | ||
let listeners = []; | ||
function add(node, type, handler, options = { | ||
passive: true | ||
}) { | ||
node.addEventListener(type, handler, options); | ||
listeners.push(() => node.removeEventListener(type, handler, options)); | ||
return self; | ||
} | ||
function add(n) { | ||
vector += readNumber(n); | ||
return self; | ||
function clear() { | ||
listeners = listeners.filter(remove => remove()); | ||
} | ||
function subtract(n) { | ||
vector -= readNumber(n); | ||
return self; | ||
} | ||
function multiply(n) { | ||
vector *= n; | ||
return self; | ||
} | ||
function divide(n) { | ||
vector /= n; | ||
return self; | ||
} | ||
function normalize() { | ||
if (vector !== 0) divide(vector); | ||
return self; | ||
} | ||
function readNumber(n) { | ||
return isNumber(n) ? n : n.get(); | ||
} | ||
const self = { | ||
add, | ||
divide, | ||
get, | ||
multiply, | ||
normalize, | ||
set, | ||
subtract | ||
clear | ||
}; | ||
return self; | ||
} | ||
function DragHandler(axis, direction, rootNode, target, dragTracker, location, animation, scrollTo, scrollBody, scrollTarget, index, eventHandler, percentOfView, dragFree, skipSnaps, baseFriction) { | ||
function DragHandler(axis, direction, rootNode, target, dragTracker, location, animation, scrollTo, scrollBody, scrollTarget, index, eventHandler, percentOfView, dragFree, dragThreshold, skipSnaps, baseFriction) { | ||
const { | ||
@@ -355,3 +256,2 @@ cross: crossAxis | ||
}; | ||
const dragStartPoint = Vector1D(0); | ||
const initEvents = EventStore(); | ||
@@ -417,3 +317,2 @@ const dragEvents = EventStore(); | ||
dragTracker.pointerDown(evt); | ||
dragStartPoint.set(target); | ||
scrollBody.useFriction(0).useDuration(0); | ||
@@ -427,8 +326,8 @@ target.set(location); | ||
function move(evt) { | ||
const lastScroll = dragTracker.readPoint(evt); | ||
const lastCross = dragTracker.readPoint(evt, crossAxis); | ||
const diffScroll = deltaAbs(lastScroll, startScroll); | ||
const diffCross = deltaAbs(lastCross, startCross); | ||
if (!preventScroll && !isMouse) { | ||
if (!evt.cancelable) return up(evt); | ||
const lastScroll = dragTracker.readPoint(evt); | ||
const lastCross = dragTracker.readPoint(evt, crossAxis); | ||
const diffScroll = deltaAbs(lastScroll, startScroll); | ||
const diffCross = deltaAbs(lastCross, startCross); | ||
preventScroll = diffScroll > diffCross; | ||
@@ -438,3 +337,3 @@ if (!preventScroll) return up(evt); | ||
const diff = dragTracker.pointerMove(evt); | ||
if (diff) preventClick = true; | ||
if (diffScroll > dragThreshold) preventClick = true; | ||
scrollBody.useFriction(0.3).useDuration(1); | ||
@@ -571,30 +470,32 @@ animation.start(); | ||
} | ||
function ScrollBody(location, baseDuration, baseFriction) { | ||
const roundToTwoDecimals = roundToDecimals(2); | ||
const attraction = Vector1D(0); | ||
let attractionDirection = 0; | ||
function ScrollBody(location, target, baseDuration, baseFriction) { | ||
let hasSettled = true; | ||
let bodyVelocity = 0; | ||
let scrollDirection = 0; | ||
let duration = baseDuration; | ||
let friction = baseFriction; | ||
function seek(target) { | ||
function seek() { | ||
const diff = target.get() - location.get(); | ||
const isInstant = !friction || !duration; | ||
if (isInstant) { | ||
attraction.set(0); | ||
bodyVelocity = 0; | ||
location.set(target); | ||
} else { | ||
attraction.add(diff / duration); | ||
attraction.multiply(friction); | ||
location.add(attraction); | ||
bodyVelocity += diff / duration; | ||
bodyVelocity *= friction; | ||
location.add(bodyVelocity); | ||
} | ||
attractionDirection = mathSign(attraction.get() || diff); | ||
scrollDirection = mathSign(bodyVelocity || diff); | ||
hasSettled = mathAbs(diff) < 0.001; | ||
return self; | ||
} | ||
function settle(target) { | ||
const diff = target.get() - location.get(); | ||
const hasSettled = !roundToTwoDecimals(diff); | ||
function settled() { | ||
if (hasSettled) location.set(target); | ||
return hasSettled; | ||
} | ||
function velocity() { | ||
return bodyVelocity; | ||
} | ||
function direction() { | ||
return attractionDirection; | ||
return scrollDirection; | ||
} | ||
@@ -618,7 +519,8 @@ function useBaseDuration() { | ||
seek, | ||
settle, | ||
settled, | ||
useBaseFriction, | ||
useBaseDuration, | ||
useFriction, | ||
useDuration | ||
useDuration, | ||
velocity | ||
}; | ||
@@ -861,2 +763,27 @@ return self; | ||
} | ||
function Vector1D(initialValue) { | ||
let value = initialValue; | ||
function get() { | ||
return value; | ||
} | ||
function set(n) { | ||
value = normalizeInput(n); | ||
} | ||
function add(n) { | ||
value += normalizeInput(n); | ||
} | ||
function subtract(n) { | ||
value -= normalizeInput(n); | ||
} | ||
function normalizeInput(n) { | ||
return isNumber(n) ? n : n.get(); | ||
} | ||
const self = { | ||
get, | ||
set, | ||
add, | ||
subtract | ||
}; | ||
return self; | ||
} | ||
function Translate(axis, direction, container) { | ||
@@ -874,3 +801,3 @@ const translate = axis.scroll === 'x' ? x : y; | ||
if (disabled) return; | ||
containerStyle.transform = translate(direction.apply(target.get())); | ||
containerStyle.transform = translate(direction.apply(target)); | ||
} | ||
@@ -916,6 +843,5 @@ function toggleActive(active) { | ||
const point = bounds[isStartEdge ? 'end' : 'start']; | ||
const shift = Vector1D(-1); | ||
const location = Vector1D(-1); | ||
const translate = Translate(axis, direction, slides[index]); | ||
const target = () => shift.set(scroll.get() > point ? initial : altered); | ||
const target = () => scroll.get() > point ? initial : altered; | ||
return { | ||
@@ -955,4 +881,4 @@ index, | ||
const shift = target(); | ||
if (shift.get() === location.get()) return; | ||
if (shift.get() === 0) translate.clear();else translate.to(shift); | ||
if (shift === location.get()) return; | ||
translate.to(shift); | ||
location.set(shift); | ||
@@ -1109,2 +1035,59 @@ }); | ||
} | ||
function Animation(update, render) { | ||
const documentVisibleHandler = EventStore(); | ||
const timeStep = 1000 / 60; | ||
let lastTimeStamp = null; | ||
let lag = 0; | ||
let animationFrame = 0; | ||
let engine; | ||
function init(engineInstance) { | ||
engine = engineInstance; | ||
documentVisibleHandler.add(document, 'visibilitychange', () => { | ||
if (document.hidden) { | ||
lastTimeStamp = null; | ||
lag = 0; | ||
} | ||
}); | ||
} | ||
function destroy() { | ||
stop(); | ||
documentVisibleHandler.clear(); | ||
} | ||
function ifAnimating(active, cb) { | ||
return () => { | ||
if (active === !!animationFrame) cb(); | ||
}; | ||
} | ||
function animate(timeStamp) { | ||
if (!lastTimeStamp) { | ||
lastTimeStamp = timeStamp; | ||
return start(); | ||
} | ||
const elapsed = timeStamp - lastTimeStamp; | ||
lastTimeStamp = timeStamp; | ||
lag += elapsed; | ||
while (lag >= timeStep) { | ||
update(engine); | ||
lag -= timeStep; | ||
} | ||
render(engine, mathAbs(lag / timeStep)); | ||
if (animationFrame) start(); | ||
} | ||
function start() { | ||
animationFrame = window.requestAnimationFrame(animate); | ||
} | ||
function stop() { | ||
window.cancelAnimationFrame(animationFrame); | ||
lastTimeStamp = null; | ||
lag = 0; | ||
animationFrame = 0; | ||
} | ||
const self = { | ||
init, | ||
destroy, | ||
start: ifAnimating(false, start), | ||
stop: ifAnimating(true, stop) | ||
}; | ||
return self; | ||
} | ||
function Engine(root, container, slides, options, eventHandler) { | ||
@@ -1121,2 +1104,3 @@ // Options | ||
dragFree, | ||
dragThreshold, | ||
slidesToScroll: groupSlides, | ||
@@ -1158,4 +1142,3 @@ skipSnaps, | ||
// Animation | ||
function update({ | ||
target, | ||
const update = ({ | ||
dragHandler, | ||
@@ -1168,11 +1151,11 @@ scrollBody, | ||
animation | ||
}) { | ||
}) => { | ||
const pointerDown = dragHandler.pointerDown(); | ||
if (!loop) scrollBounds.constrain(pointerDown); | ||
const settled = scrollBody.seek(target).settle(target); | ||
if (settled && !pointerDown) { | ||
const hasSettled = scrollBody.seek().settled(); | ||
if (hasSettled && !pointerDown) { | ||
animation.stop(); | ||
eventHandler.emit('settle'); | ||
} | ||
if (!settled) { | ||
if (!hasSettled) { | ||
eventHandler.emit('scroll'); | ||
@@ -1184,16 +1167,19 @@ } | ||
} | ||
} | ||
function draw({ | ||
}; | ||
const render = ({ | ||
scrollBody, | ||
translate, | ||
location | ||
}) { | ||
translate.to(location); | ||
} | ||
}, lagFactor) => { | ||
const velocity = scrollBody.velocity(); | ||
const lagLocation = location.get() - velocity + velocity * lagFactor; | ||
translate.to(lagLocation); | ||
}; | ||
// Shared | ||
const friction = 0.68; | ||
const animation = Animation(update, draw); | ||
const animation = Animation(update, render); | ||
const startLocation = scrollSnaps[index.get()]; | ||
const location = Vector1D(startLocation); | ||
const target = Vector1D(startLocation); | ||
const scrollBody = ScrollBody(location, duration, friction); | ||
const scrollBody = ScrollBody(location, target, duration, friction); | ||
const scrollTarget = ScrollTarget(loop, scrollSnaps, contentSize, limit, target); | ||
@@ -1210,3 +1196,3 @@ const scrollTo = ScrollTo(animation, index, indexPrevious, scrollTarget, target, eventHandler); | ||
direction, | ||
dragHandler: DragHandler(axis, direction, root, target, DragTracker(axis), location, animation, scrollTo, scrollBody, scrollTarget, index, eventHandler, percentOfView, dragFree, skipSnaps, friction), | ||
dragHandler: DragHandler(axis, direction, root, target, DragTracker(axis), location, animation, scrollTo, scrollBody, scrollTarget, index, eventHandler, percentOfView, dragFree, dragThreshold, skipSnaps, friction), | ||
eventStore: EventStore(), | ||
@@ -1276,2 +1262,3 @@ percentOfView, | ||
dragFree: false, | ||
dragThreshold: 10, | ||
inViewThreshold: 0, | ||
@@ -1367,3 +1354,3 @@ loop: false, | ||
if (!options.active) return deActivate(); | ||
engine.translate.to(engine.location); | ||
engine.translate.to(engine.location.get()); | ||
pluginList = withPlugins || pluginList; | ||
@@ -1370,0 +1357,0 @@ pluginApis = pluginsHandler.init(pluginList, self); |
{ | ||
"name": "embla-carousel-vue", | ||
"version": "8.0.0-rc02", | ||
"version": "8.0.0-rc03", | ||
"author": "David Jerleke", | ||
@@ -59,4 +59,4 @@ "description": "A lightweight carousel library with fluid motion and great swipe precision", | ||
"dependencies": { | ||
"embla-carousel": "8.0.0-rc02", | ||
"embla-carousel-reactive-utils": "8.0.0-rc02" | ||
"embla-carousel": "8.0.0-rc03", | ||
"embla-carousel-reactive-utils": "8.0.0-rc03" | ||
}, | ||
@@ -63,0 +63,0 @@ "peerDependencies": { |
55785
1604
+ Added@babel/parser@7.26.8(transitive)
+ Added@babel/types@7.26.8(transitive)
+ Addedembla-carousel@8.0.0-rc03(transitive)
+ Addedembla-carousel-reactive-utils@8.0.0-rc03(transitive)
+ Addedpostcss@8.5.1(transitive)
- Removed@babel/parser@7.26.9(transitive)
- Removed@babel/types@7.26.9(transitive)
- Removedembla-carousel@8.0.0-rc02(transitive)
- Removedembla-carousel-reactive-utils@8.0.0-rc02(transitive)
- Removedpostcss@8.5.2(transitive)
Updatedembla-carousel@8.0.0-rc03