wheel-gestures
Advanced tools
Comparing version 2.1.0 to 2.1.1
export { WheelGestures as default } from './wheel-gestures/wheel-gestures'; | ||
export * from './wheel-gestures/wheel-gestures'; | ||
export * from './wheel-gestures/options'; | ||
export * from './wheel-gestures/wheel-gestures-types'; | ||
export * from './wheel-normalizer/wheel-normalizer'; | ||
export * from './events/EventBus'; | ||
export * from './types'; | ||
export * from './utils'; |
@@ -1,2 +0,2 @@ | ||
import { WheelEventData } from '../../wheel-gestures/wheel-gestures-types'; | ||
import { WheelEventData } from '../../types'; | ||
interface GenerateEventsProps { | ||
@@ -3,0 +3,0 @@ deltaTotal: number[]; |
@@ -1,2 +0,2 @@ | ||
import { WheelEventData, WheelEventState } from '../..'; | ||
import { WheelEventData, WheelEventState } from '../../types'; | ||
interface SubAndFeedProps { | ||
@@ -9,9 +9,9 @@ beforeFeed?: (e: WheelEventData, i: number) => void; | ||
wheelGestures: Readonly<{ | ||
on: <EK extends "wheel">(type: EK, listener: import("../..").EventListener<import("../..").WheelGesturesEventMap[EK]>) => import("../..").Off; | ||
off: <EK_1 extends "wheel">(type: EK_1, listener: import("../..").EventListener<import("../..").WheelGesturesEventMap[EK_1]>) => void; | ||
observe: (target: EventTarget) => import("../..").Unobserve; | ||
on: <EK extends "wheel">(type: EK, listener: import("../../events/EventBus").EventListener<import("../../types").WheelGesturesEventMap[EK]>) => import("../../events/EventBus").Off; | ||
off: <EK_1 extends "wheel">(type: EK_1, listener: import("../../events/EventBus").EventListener<import("../../types").WheelGesturesEventMap[EK_1]>) => void; | ||
observe: (target: EventTarget) => () => void; | ||
unobserve: (target: EventTarget) => void; | ||
disconnect: () => void; | ||
feedWheel: (wheelEvents: WheelEventData | WheelEventData[]) => void; | ||
updateOptions: (newOptions?: Partial<import("../..").WheelGesturesConfig>) => import("../..").WheelGesturesConfig; | ||
updateOptions: (newOptions?: Partial<import("../../types").WheelGesturesConfig>) => import("../../types").WheelGesturesConfig; | ||
}>; | ||
@@ -23,3 +23,3 @@ allPhaseData: WheelEventState[]; | ||
export declare type RangeWheelType = 'user' | 'momentum'; | ||
export interface PhaseRange extends Omit<WheelEventState, 'previous'> { | ||
export interface PhaseRange extends Omit<WheelEventState, 'previous' | 'axisMovementProjection'> { | ||
wheelType: RangeWheelType; | ||
@@ -26,0 +26,0 @@ range: Range; |
@@ -0,5 +1,7 @@ | ||
export * from './projection'; | ||
export declare function lastOf<T>(array: T[]): T; | ||
export declare function average(numbers: number[]): number; | ||
export declare const clamp: (value: number, min: number, max: number) => number; | ||
export declare function addVectors<T extends number[]>(v1: T, v2: T): T; | ||
export declare function absMax(numbers: number[]): number; | ||
export declare function deepFreeze<T extends object>(o: T): Readonly<T>; |
@@ -53,2 +53,17 @@ 'use strict'; | ||
var DECAY = 0.996; | ||
/** | ||
* movement projection based on velocity | ||
* @param velocityPxMs | ||
* @param decay | ||
*/ | ||
var projection = function projection(velocityPxMs, decay) { | ||
if (decay === void 0) { | ||
decay = DECAY; | ||
} | ||
return velocityPxMs * decay / (1 - decay); | ||
}; | ||
function lastOf(array) { | ||
@@ -62,2 +77,5 @@ return array[array.length - 1]; | ||
} | ||
var clamp = function clamp(value, min, max) { | ||
return Math.min(Math.max(min, value), max); | ||
}; | ||
function addVectors(v1, v2) { | ||
@@ -85,2 +103,35 @@ if (v1.length !== v2.length) { | ||
function WheelTargetObserver(eventListener) { | ||
var targets = []; // add event listener to target element | ||
var observe = function observe(target) { | ||
target.addEventListener('wheel', eventListener, { | ||
passive: false | ||
}); | ||
targets.push(target); | ||
return function () { | ||
return unobserve(target); | ||
}; | ||
}; /// remove event listener from target element | ||
var unobserve = function unobserve(target) { | ||
target.removeEventListener('wheel', eventListener); | ||
targets = targets.filter(function (t) { | ||
return t !== target; | ||
}); | ||
}; // stops watching all of its target elements for visibility changes. | ||
var disconnect = function disconnect() { | ||
targets.forEach(unobserve); | ||
}; | ||
return deepFreeze({ | ||
observe: observe, | ||
unobserve: unobserve, | ||
disconnect: disconnect | ||
}); | ||
} | ||
var LINE_HEIGHT = 16 * 1.125; | ||
@@ -113,5 +164,2 @@ var PAGE_HEIGHT = typeof window !== 'undefined' && window.innerHeight || 800; | ||
} | ||
var clamp = function clamp(value, min, max) { | ||
return Math.min(Math.max(min, value), max); | ||
}; | ||
var DELTA_MAX_ABS = 700; | ||
@@ -126,2 +174,7 @@ var clampAxisDelta = function clampAxisDelta(wheel) { | ||
var ACC_FACTOR_MIN = 0.6; | ||
var ACC_FACTOR_MAX = 0.96; | ||
var WHEELEVENTS_TO_MERGE = 2; | ||
var WHEELEVENTS_TO_ANALAZE = 5; | ||
var configDefaults = /*#__PURE__*/deepFreeze({ | ||
@@ -132,6 +185,2 @@ preventWheelAction: true, | ||
/** | ||
* the timeout is automatically adjusted during a gesture | ||
* the initial timeout period is pretty long, so even old mouses, which emit wheel events less often, can produce a continuous gesture | ||
*/ | ||
var WILL_END_TIMEOUT_DEFAULT = 400; | ||
@@ -154,6 +203,2 @@ function createWheelGesturesState() { | ||
var ACC_FACTOR_MIN = 0.6; | ||
var ACC_FACTOR_MAX = 0.96; | ||
var WHEELEVENTS_TO_MERGE = 2; | ||
var WHEELEVENTS_TO_ANALAZE = 5; | ||
function WheelGestures(optionsParam) { | ||
@@ -171,48 +216,6 @@ if (optionsParam === void 0) { | ||
var state = createWheelGesturesState(); | ||
var targets = []; | ||
var currentEvent; | ||
var negativeZeroFingerUpSpecialEvent = false; | ||
var prevWheelEventState; // TODO: extract observe | ||
var prevWheelEventState; | ||
var observe = function observe(target) { | ||
target.addEventListener('wheel', feedWheel, { | ||
passive: false | ||
}); | ||
targets.push(target); | ||
return function () { | ||
return unobserve(target); | ||
}; | ||
}; | ||
var unobserve = function unobserve(target) { | ||
target.removeEventListener('wheel', feedWheel); | ||
targets = targets.filter(function (t) { | ||
return t !== target; | ||
}); | ||
}; // stops watching all of its target elements for visibility changes. | ||
var disconnect = function disconnect() { | ||
targets.forEach(unobserve); | ||
}; | ||
var publishWheel = function publishWheel(additionalData) { | ||
var wheelEventState = _extends({ | ||
isStart: false, | ||
isEnding: false, | ||
isMomentumCancel: false, | ||
isMomentum: state.isMomentum, | ||
axisMovement: state.axisMovement, | ||
axisVelocity: state.axisVelocity, | ||
axisDelta: [0, 0, 0], | ||
event: currentEvent | ||
}, additionalData); | ||
dispatch('wheel', _extends({}, wheelEventState, { | ||
previous: prevWheelEventState | ||
})); // keep reference without previous, otherwise we would create a long chain | ||
prevWheelEventState = wheelEventState; | ||
}; | ||
var feedWheel = function feedWheel(wheelEvents) { | ||
@@ -241,2 +244,28 @@ if (Array.isArray(wheelEvents)) { | ||
return config = deepFreeze(_extends({}, configDefaults, {}, config, {}, newOptions)); | ||
}; | ||
var publishWheel = function publishWheel(additionalData) { | ||
var wheelEventState = _extends({ | ||
event: currentEvent, | ||
isStart: false, | ||
isEnding: false, | ||
isMomentumCancel: false, | ||
isMomentum: state.isMomentum, | ||
axisDelta: [0, 0, 0], | ||
axisVelocity: state.axisVelocity, | ||
axisMovement: state.axisMovement, | ||
get axisMovementProjection() { | ||
return addVectors(wheelEventState.axisMovement, wheelEventState.axisVelocity.map(function (velocity) { | ||
return projection(velocity); | ||
})); | ||
} | ||
}, additionalData); | ||
dispatch('wheel', _extends({}, wheelEventState, { | ||
previous: prevWheelEventState | ||
})); // keep reference without previous, otherwise we would create a long chain | ||
prevWheelEventState = wheelEventState; | ||
}; // should prevent when there is mainly movement on the desired axis | ||
@@ -299,27 +328,34 @@ | ||
state.scrollPointsToMerge.push({ | ||
deltaMaxAbs: deltaMaxAbs, | ||
axisDelta: axisDelta, | ||
timeStamp: timeStamp | ||
}); | ||
mergeScrollPointsCalcVelocity(); // only wheel event (move) and not start/end get the delta values | ||
publishWheel({ | ||
axisDelta: axisDelta, | ||
isStart: !state.isStartPublished | ||
}); // state.isMomentum ? MOMENTUM_WHEEL : WHEEL, { axisDelta }) | ||
// publish start after velocity etc. have been updated | ||
state.isStartPublished = true; // calc debounced end function, to recognize end of wheel event stream | ||
willEnd(); | ||
}; | ||
var mergeScrollPointsCalcVelocity = function mergeScrollPointsCalcVelocity() { | ||
if (state.scrollPointsToMerge.length === WHEELEVENTS_TO_MERGE) { | ||
var _state = state, | ||
scrollPointsToMerge = _state.scrollPointsToMerge; | ||
var mergedScrollPoint = { | ||
deltaMaxAbsAverage: average(scrollPointsToMerge.map(function (b) { | ||
return b.deltaMaxAbs; | ||
})), | ||
axisDeltaSum: scrollPointsToMerge.map(function (b) { | ||
state.scrollPoints.unshift({ | ||
axisDeltaSum: state.scrollPointsToMerge.map(function (b) { | ||
return b.axisDelta; | ||
}).reduce(addVectors), | ||
timeStamp: average(scrollPointsToMerge.map(function (b) { | ||
timeStamp: average(state.scrollPointsToMerge.map(function (b) { | ||
return b.timeStamp; | ||
})) | ||
}; // TODO: remove scroll points | ||
}); // only update velocity after a merged scrollpoint was generated | ||
state.scrollPoints.push(mergedScrollPoint); // only update velocity after a merged scrollpoint was generated | ||
updateVelocity(); // reset toMerge array | ||
updateVelocity(); // reset merge array | ||
state.scrollPointsToMerge.length = 0; // after calculation of velocity only keep the most recent merged scrollPoint | ||
state.scrollPointsToMerge = []; | ||
state.scrollPoints.length = 1; | ||
@@ -329,18 +365,5 @@ if (!state.isMomentum) { | ||
} | ||
} else if (!state.isStartPublished) { | ||
updateStartVelocity(); | ||
} | ||
if (!state.scrollPoints.length) { | ||
updateStartVelocity(); | ||
} // only wheel event (move) and not start/end get the delta values | ||
publishWheel({ | ||
axisDelta: axisDelta, | ||
isStart: !state.isStartPublished | ||
}); // state.isMomentum ? MOMENTUM_WHEEL : WHEEL, { axisDelta }) | ||
// publish start after velocity etc. have been updated | ||
state.isStartPublished = true; // calc debounced end function, to recognize end of wheel event stream | ||
willEnd(); | ||
}; | ||
@@ -356,7 +379,7 @@ | ||
// need to have two recent points to calc velocity | ||
var _state$scrollPoints$s = state.scrollPoints.slice(-2), | ||
pA = _state$scrollPoints$s[0], | ||
pB = _state$scrollPoints$s[1]; | ||
var _state$scrollPoints = state.scrollPoints, | ||
latestScrollPoint = _state$scrollPoints[0], | ||
prevScrollPoint = _state$scrollPoints[1]; | ||
if (!pA || !pB) { | ||
if (!prevScrollPoint || !latestScrollPoint) { | ||
return; | ||
@@ -366,3 +389,3 @@ } // time delta | ||
var deltaTime = pB.timeStamp - pA.timeStamp; | ||
var deltaTime = latestScrollPoint.timeStamp - prevScrollPoint.timeStamp; | ||
@@ -375,3 +398,3 @@ if (deltaTime <= 0) { | ||
var velocity = pB.axisDeltaSum.map(function (d) { | ||
var velocity = latestScrollPoint.axisDeltaSum.map(function (d) { | ||
return d / deltaTime; | ||
@@ -417,7 +440,6 @@ }); // calc the acceleration factor per axis | ||
var recentAccelerationFactors = state.accelerationFactors.slice(WHEELEVENTS_TO_ANALAZE * -1); // check recent acceleration / deceleration factors | ||
// all recent need to match, if any did not match | ||
var detectedMomentum = recentAccelerationFactors.reduce(function (mightBeMomentum, accFac) { | ||
// all recent need to match, if any did not match -> short circuit | ||
if (!mightBeMomentum) return false; // when both axis decelerate exactly in the same rate it is very likely caused by momentum | ||
var detectedMomentum = recentAccelerationFactors.every(function (accFac) { | ||
// when both axis decelerate exactly in the same rate it is very likely caused by momentum | ||
var sameAccFac = !!accFac.reduce(function (f1, f2) { | ||
@@ -430,3 +452,3 @@ return f1 && f1 < 1 && f1 === f2 ? 1 : 0; | ||
return sameAccFac || bothAreInRangeOrZero; | ||
}, true); | ||
}); | ||
@@ -484,4 +506,9 @@ if (detectedMomentum) { | ||
var _WheelTargetObserver = WheelTargetObserver(feedWheel), | ||
observe = _WheelTargetObserver.observe, | ||
unobserve = _WheelTargetObserver.unobserve, | ||
disconnect = _WheelTargetObserver.disconnect; | ||
updateOptions(optionsParam); | ||
return Object.freeze({ | ||
return deepFreeze({ | ||
on: on, | ||
@@ -502,9 +529,6 @@ off: off, | ||
exports.clamp = clamp; | ||
exports.clampAxisDelta = clampAxisDelta; | ||
exports.configDefaults = configDefaults; | ||
exports.deepFreeze = deepFreeze; | ||
exports.default = WheelGestures; | ||
exports.lastOf = lastOf; | ||
exports.normalizeWheel = normalizeWheel; | ||
exports.reverseAxisDeltaSign = reverseAxisDeltaSign; | ||
exports.projection = projection; | ||
//# sourceMappingURL=wheel-gestures.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";function t(){return(t=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}function e(t){return t[t.length-1]}function n(t){return t.reduce((function(t,e){return t+e}))/t.length}function i(t,e){if(t.length!==e.length)throw new Error("vectors must be same length");return t.map((function(t,n){return t+e[n]}))}function r(t){return Math.max.apply(Math,t.map(Math.abs))}function a(t){return Object.freeze(t),Object.values(t).forEach((function(t){null===t||"object"!=typeof t&&"function"!=typeof t||Object.isFrozen(t)||a(t)})),t}Object.defineProperty(exports,"__esModule",{value:!0});var o=[1,18,"undefined"!=typeof window&&window.innerHeight||800];function s(t){return{timeStamp:t.timeStamp,axisDelta:[t.deltaX*o[t.deltaMode],t.deltaY*o[t.deltaMode],(t.deltaZ||0)*o[t.deltaMode]]}}var u=[-1,-1,-1];function c(e,n){if(!n)return e;var i=!0===n?u:n.map((function(t){return t?-1:1}));return t({},e,{axisDelta:e.axisDelta.map((function(t,e){return t*i[e]}))})}var l=function(t,e,n){return Math.min(Math.max(e,t),n)},f=function(e){return t({},e,{axisDelta:e.axisDelta.map((function(t){return l(t,-700,700)}))})},m=a({preventWheelAction:!0,reverseSign:[!0,!0,!1]});function p(o){void 0===o&&(o={});var u,l,p,d=function(){var t={};function e(e,n){t[e]=(t[e]||[]).filter((function(t){return t!==n}))}return Object.freeze({on:function(n,i){return t[n]=(t[n]||[]).concat(i),function(){return e(n,i)}},off:e,dispatch:function(e,n){e in t&&t[e].forEach((function(t){return t(n)}))}})}(),h=d.on,v=d.off,x=d.dispatch,M=m,b={isStarted:!1,isStartPublished:!1,isMomentum:!1,startTime:0,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400},g=[],S=!1,D=function(t){t.removeEventListener("wheel",P),g=g.filter((function(e){return e!==t}))},y=function(e){var n=t({isStart:!1,isEnding:!1,isMomentumCancel:!1,isMomentum:b.isMomentum,axisMovement:b.axisMovement,axisVelocity:b.axisVelocity,axisDelta:[0,0,0],event:u},e);x("wheel",t({},n,{previous:l})),l=n},P=function(t){Array.isArray(t)?t.forEach((function(t){return T(t)})):T(t)},w=function(e){return void 0===e&&(e={}),Object.values(e).some((function(t){return null==t}))?M:M=a(t({},m,{},M,{},e))},T=function(t){var e=f(c(s(t),M.reverseSign)),a=e.axisDelta,o=e.timeStamp,l=r(a);if(t.preventDefault&&function(t,e){var n=M.preventWheelAction,i=e[0],r=e[1],a=e[2];if("boolean"==typeof n)return n;switch(n){case"x":return Math.abs(i)>=t;case"y":return Math.abs(r)>=t;case"z":return Math.abs(a)>=t;default:return!1}}(l,a)&&t.preventDefault(),b.isStarted?b.isMomentum&&l>Math.max(2,2*b.lastAbsDelta)&&(C(!0),z()):z(),0===l&&Object.is&&Object.is(t.deltaX,-0))S=!0;else{if(u=t,b.axisMovement=i(b.axisMovement,a),b.lastAbsDelta=l,b.scrollPointsToMerge.push({deltaMaxAbs:l,axisDelta:a,timeStamp:o}),2===b.scrollPointsToMerge.length){var m=b.scrollPointsToMerge,p={deltaMaxAbsAverage:n(m.map((function(t){return t.deltaMaxAbs}))),axisDeltaSum:m.map((function(t){return t.axisDelta})).reduce(i),timeStamp:n(m.map((function(t){return t.timeStamp})))};b.scrollPoints.push(p),A(),b.scrollPointsToMerge=[],b.isMomentum||V()}b.scrollPoints.length||E(),y({axisDelta:a,isStart:!b.isStartPublished}),b.isStartPublished=!0,W()}},E=function(){b.axisVelocity=e(b.scrollPointsToMerge).axisDelta.map((function(t){return t/b.willEndTimeout}))},A=function(){var t=b.scrollPoints.slice(-2),e=t[0],n=t[1];if(e&&n){var i=n.timeStamp-e.timeStamp;if(!(i<=0)){var r=n.axisDeltaSum.map((function(t){return t/i})),a=r.map((function(t,e){return t/(b.axisVelocity[e]||1)}));b.axisVelocity=r,b.accelerationFactors.push(a),O(i)}}},O=function(t){var e=10*Math.ceil(t/10)*1.2;b.isMomentum||(e=Math.max(100,2*e)),b.willEndTimeout=Math.min(1e3,Math.round(e))},j=function(t){return 0===t||t<=.96&&t>=.6},V=function(){if(b.accelerationFactors.length>=5){if(S&&(S=!1,r(b.axisVelocity)>=.2))return void F();var t=b.accelerationFactors.slice(-5);t.reduce((function(t,e){if(!t)return!1;var n=!!e.reduce((function(t,e){return t&&t<1&&t===e?1:0})),i=e.filter(j).length===e.length;return n||i}),!0)&&F(),b.accelerationFactors=t}},F=function(){b.isMomentum=!0},z=function(){(b={isStarted:!1,isStartPublished:!1,isMomentum:!1,startTime:0,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400}).isStarted=!0,b.startTime=Date.now(),l=void 0,S=!1},W=function(){clearTimeout(p),p=setTimeout(C,b.willEndTimeout)},C=function(t){void 0===t&&(t=!1),b.isStarted&&(y(b.isMomentum&&t?{isEnding:!0,isMomentumCancel:!0}:{isEnding:!0}),b.isMomentum=!1,b.isStarted=!1)};return w(o),Object.freeze({on:h,off:v,observe:function(t){return t.addEventListener("wheel",P,{passive:!1}),g.push(t),function(){return D(t)}},unobserve:D,disconnect:function(){g.forEach(D)},feedWheel:P,updateOptions:w})}exports.WheelGestures=p,exports.absMax=r,exports.addVectors=i,exports.average=n,exports.clamp=l,exports.clampAxisDelta=f,exports.configDefaults=m,exports.deepFreeze=a,exports.default=p,exports.lastOf=e,exports.normalizeWheel=s,exports.reverseAxisDeltaSign=c; | ||
"use strict";function t(){return(t=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}Object.defineProperty(exports,"__esModule",{value:!0});var e=function(t,e){return void 0===e&&(e=.996),t*e/(1-e)};function n(t){return t[t.length-1]}function i(t){return t.reduce((function(t,e){return t+e}))/t.length}var r=function(t,e,n){return Math.min(Math.max(e,t),n)};function o(t,e){if(t.length!==e.length)throw new Error("vectors must be same length");return t.map((function(t,n){return t+e[n]}))}function a(t){return Math.max.apply(Math,t.map(Math.abs))}function s(t){return Object.freeze(t),Object.values(t).forEach((function(t){null===t||"object"!=typeof t&&"function"!=typeof t||Object.isFrozen(t)||s(t)})),t}var u=[1,18,"undefined"!=typeof window&&window.innerHeight||800],c=[-1,-1,-1],l=s({preventWheelAction:!0,reverseSign:[!0,!0,!1]});function f(f){void 0===f&&(f={});var m,d,p,v=function(){var t={};function e(e,n){t[e]=(t[e]||[]).filter((function(t){return t!==n}))}return Object.freeze({on:function(n,i){return t[n]=(t[n]||[]).concat(i),function(){return e(n,i)}},off:e,dispatch:function(e,n){e in t&&t[e].forEach((function(t){return t(n)}))}})}(),h=v.on,x=v.off,M=v.dispatch,b=l,g={isStarted:!1,isStartPublished:!1,isMomentum:!1,startTime:0,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400},S=!1,y=function(t){Array.isArray(t)?t.forEach((function(t){return T(t)})):T(t)},P=function(e){return void 0===e&&(e={}),Object.values(e).some((function(t){return null==t}))?b:b=s(t({},l,{},b,{},e))},D=function(n){var i=t({event:m,isStart:!1,isEnding:!1,isMomentumCancel:!1,isMomentum:g.isMomentum,axisDelta:[0,0,0],axisVelocity:g.axisVelocity,axisMovement:g.axisMovement,get axisMovementProjection(){return o(i.axisMovement,i.axisVelocity.map((function(t){return e(t)})))}},n);M("wheel",t({},i,{previous:d})),d=i},T=function(e){var n,i=function(e){return t({},e,{axisDelta:e.axisDelta.map((function(t){return r(t,-700,700)}))})}(function(e,n){if(!n)return e;var i=!0===n?c:n.map((function(t){return t?-1:1}));return t({},e,{axisDelta:e.axisDelta.map((function(t,e){return t*i[e]}))})}({timeStamp:(n=e).timeStamp,axisDelta:[n.deltaX*u[n.deltaMode],n.deltaY*u[n.deltaMode],(n.deltaZ||0)*u[n.deltaMode]]},b.reverseSign)),s=i.axisDelta,l=i.timeStamp,f=a(s);e.preventDefault&&function(t,e){var n=b.preventWheelAction,i=e[0],r=e[1],o=e[2];if("boolean"==typeof n)return n;switch(n){case"x":return Math.abs(i)>=t;case"y":return Math.abs(r)>=t;case"z":return Math.abs(o)>=t;default:return!1}}(f,s)&&e.preventDefault(),g.isStarted?g.isMomentum&&f>Math.max(2,2*g.lastAbsDelta)&&(C(!0),z()):z(),0===f&&Object.is&&Object.is(e.deltaX,-0)?S=!0:(m=e,g.axisMovement=o(g.axisMovement,s),g.lastAbsDelta=f,g.scrollPointsToMerge.push({axisDelta:s,timeStamp:l}),w(),D({axisDelta:s,isStart:!g.isStartPublished}),g.isStartPublished=!0,W())},w=function(){2===g.scrollPointsToMerge.length?(g.scrollPoints.unshift({axisDeltaSum:g.scrollPointsToMerge.map((function(t){return t.axisDelta})).reduce(o),timeStamp:i(g.scrollPointsToMerge.map((function(t){return t.timeStamp})))}),j(),g.scrollPointsToMerge.length=0,g.scrollPoints.length=1,g.isMomentum||A()):g.isStartPublished||E()},E=function(){g.axisVelocity=n(g.scrollPointsToMerge).axisDelta.map((function(t){return t/g.willEndTimeout}))},j=function(){var t=g.scrollPoints,e=t[0],n=t[1];if(n&&e){var i=e.timeStamp-n.timeStamp;if(!(i<=0)){var r=e.axisDeltaSum.map((function(t){return t/i})),o=r.map((function(t,e){return t/(g.axisVelocity[e]||1)}));g.axisVelocity=r,g.accelerationFactors.push(o),O(i)}}},O=function(t){var e=10*Math.ceil(t/10)*1.2;g.isMomentum||(e=Math.max(100,2*e)),g.willEndTimeout=Math.min(1e3,Math.round(e))},V=function(t){return 0===t||t<=.96&&t>=.6},A=function(){if(g.accelerationFactors.length>=5){if(S&&(S=!1,a(g.axisVelocity)>=.2))return void F();var t=g.accelerationFactors.slice(-5);t.every((function(t){var e=!!t.reduce((function(t,e){return t&&t<1&&t===e?1:0})),n=t.filter(V).length===t.length;return e||n}))&&F(),g.accelerationFactors=t}},F=function(){g.isMomentum=!0},z=function(){(g={isStarted:!1,isStartPublished:!1,isMomentum:!1,startTime:0,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400}).isStarted=!0,g.startTime=Date.now(),d=void 0,S=!1},W=function(){clearTimeout(p),p=setTimeout(C,g.willEndTimeout)},C=function(t){void 0===t&&(t=!1),g.isStarted&&(D(g.isMomentum&&t?{isEnding:!0,isMomentumCancel:!0}:{isEnding:!0}),g.isMomentum=!1,g.isStarted=!1)},I=function(t){var e=[],n=function(n){n.removeEventListener("wheel",t),e=e.filter((function(t){return t!==n}))};return s({observe:function(i){return i.addEventListener("wheel",t,{passive:!1}),e.push(i),function(){return n(i)}},unobserve:n,disconnect:function(){e.forEach(n)}})}(y),L=I.observe,X=I.unobserve,_=I.disconnect;return P(f),s({on:h,off:x,observe:L,unobserve:X,disconnect:_,feedWheel:y,updateOptions:P})}exports.WheelGestures=f,exports.absMax=a,exports.addVectors=o,exports.average=i,exports.clamp=r,exports.deepFreeze=s,exports.default=f,exports.lastOf=n,exports.projection=e; | ||
//# sourceMappingURL=wheel-gestures.cjs.production.min.js.map |
@@ -49,2 +49,17 @@ function _extends() { | ||
var DECAY = 0.996; | ||
/** | ||
* movement projection based on velocity | ||
* @param velocityPxMs | ||
* @param decay | ||
*/ | ||
var projection = function projection(velocityPxMs, decay) { | ||
if (decay === void 0) { | ||
decay = DECAY; | ||
} | ||
return velocityPxMs * decay / (1 - decay); | ||
}; | ||
function lastOf(array) { | ||
@@ -58,2 +73,5 @@ return array[array.length - 1]; | ||
} | ||
var clamp = function clamp(value, min, max) { | ||
return Math.min(Math.max(min, value), max); | ||
}; | ||
function addVectors(v1, v2) { | ||
@@ -81,2 +99,35 @@ if (v1.length !== v2.length) { | ||
function WheelTargetObserver(eventListener) { | ||
var targets = []; // add event listener to target element | ||
var observe = function observe(target) { | ||
target.addEventListener('wheel', eventListener, { | ||
passive: false | ||
}); | ||
targets.push(target); | ||
return function () { | ||
return unobserve(target); | ||
}; | ||
}; /// remove event listener from target element | ||
var unobserve = function unobserve(target) { | ||
target.removeEventListener('wheel', eventListener); | ||
targets = targets.filter(function (t) { | ||
return t !== target; | ||
}); | ||
}; // stops watching all of its target elements for visibility changes. | ||
var disconnect = function disconnect() { | ||
targets.forEach(unobserve); | ||
}; | ||
return deepFreeze({ | ||
observe: observe, | ||
unobserve: unobserve, | ||
disconnect: disconnect | ||
}); | ||
} | ||
var LINE_HEIGHT = 16 * 1.125; | ||
@@ -109,5 +160,2 @@ var PAGE_HEIGHT = typeof window !== 'undefined' && window.innerHeight || 800; | ||
} | ||
var clamp = function clamp(value, min, max) { | ||
return Math.min(Math.max(min, value), max); | ||
}; | ||
var DELTA_MAX_ABS = 700; | ||
@@ -122,2 +170,8 @@ var clampAxisDelta = function clampAxisDelta(wheel) { | ||
var __DEV__ = process.env.NODE_ENV !== 'production'; | ||
var ACC_FACTOR_MIN = 0.6; | ||
var ACC_FACTOR_MAX = 0.96; | ||
var WHEELEVENTS_TO_MERGE = 2; | ||
var WHEELEVENTS_TO_ANALAZE = 5; | ||
var configDefaults = /*#__PURE__*/deepFreeze({ | ||
@@ -128,6 +182,2 @@ preventWheelAction: true, | ||
/** | ||
* the timeout is automatically adjusted during a gesture | ||
* the initial timeout period is pretty long, so even old mouses, which emit wheel events less often, can produce a continuous gesture | ||
*/ | ||
var WILL_END_TIMEOUT_DEFAULT = 400; | ||
@@ -150,7 +200,2 @@ function createWheelGesturesState() { | ||
var isDev = process.env.NODE_ENV !== 'production'; | ||
var ACC_FACTOR_MIN = 0.6; | ||
var ACC_FACTOR_MAX = 0.96; | ||
var WHEELEVENTS_TO_MERGE = 2; | ||
var WHEELEVENTS_TO_ANALAZE = 5; | ||
function WheelGestures(optionsParam) { | ||
@@ -168,48 +213,6 @@ if (optionsParam === void 0) { | ||
var state = createWheelGesturesState(); | ||
var targets = []; | ||
var currentEvent; | ||
var negativeZeroFingerUpSpecialEvent = false; | ||
var prevWheelEventState; // TODO: extract observe | ||
var prevWheelEventState; | ||
var observe = function observe(target) { | ||
target.addEventListener('wheel', feedWheel, { | ||
passive: false | ||
}); | ||
targets.push(target); | ||
return function () { | ||
return unobserve(target); | ||
}; | ||
}; | ||
var unobserve = function unobserve(target) { | ||
target.removeEventListener('wheel', feedWheel); | ||
targets = targets.filter(function (t) { | ||
return t !== target; | ||
}); | ||
}; // stops watching all of its target elements for visibility changes. | ||
var disconnect = function disconnect() { | ||
targets.forEach(unobserve); | ||
}; | ||
var publishWheel = function publishWheel(additionalData) { | ||
var wheelEventState = _extends({ | ||
isStart: false, | ||
isEnding: false, | ||
isMomentumCancel: false, | ||
isMomentum: state.isMomentum, | ||
axisMovement: state.axisMovement, | ||
axisVelocity: state.axisVelocity, | ||
axisDelta: [0, 0, 0], | ||
event: currentEvent | ||
}, additionalData); | ||
dispatch('wheel', _extends({}, wheelEventState, { | ||
previous: prevWheelEventState | ||
})); // keep reference without previous, otherwise we would create a long chain | ||
prevWheelEventState = wheelEventState; | ||
}; | ||
var feedWheel = function feedWheel(wheelEvents) { | ||
@@ -233,3 +236,3 @@ if (Array.isArray(wheelEvents)) { | ||
})) { | ||
isDev && console.error('updateOptions ignored! undefined & null options not allowed'); | ||
__DEV__ && console.error('updateOptions ignored! undefined & null options not allowed'); | ||
return config; | ||
@@ -239,2 +242,28 @@ } | ||
return config = deepFreeze(_extends({}, configDefaults, {}, config, {}, newOptions)); | ||
}; | ||
var publishWheel = function publishWheel(additionalData) { | ||
var wheelEventState = _extends({ | ||
event: currentEvent, | ||
isStart: false, | ||
isEnding: false, | ||
isMomentumCancel: false, | ||
isMomentum: state.isMomentum, | ||
axisDelta: [0, 0, 0], | ||
axisVelocity: state.axisVelocity, | ||
axisMovement: state.axisMovement, | ||
get axisMovementProjection() { | ||
return addVectors(wheelEventState.axisMovement, wheelEventState.axisVelocity.map(function (velocity) { | ||
return projection(velocity); | ||
})); | ||
} | ||
}, additionalData); | ||
dispatch('wheel', _extends({}, wheelEventState, { | ||
previous: prevWheelEventState | ||
})); // keep reference without previous, otherwise we would create a long chain | ||
prevWheelEventState = wheelEventState; | ||
}; // should prevent when there is mainly movement on the desired axis | ||
@@ -262,3 +291,3 @@ | ||
default: | ||
isDev && console.warn('unsupported preventWheelAction value: ' + preventWheelAction, 'warn'); | ||
__DEV__ && console.warn('unsupported preventWheelAction value: ' + preventWheelAction, 'warn'); | ||
return false; | ||
@@ -298,27 +327,34 @@ } | ||
state.scrollPointsToMerge.push({ | ||
deltaMaxAbs: deltaMaxAbs, | ||
axisDelta: axisDelta, | ||
timeStamp: timeStamp | ||
}); | ||
mergeScrollPointsCalcVelocity(); // only wheel event (move) and not start/end get the delta values | ||
publishWheel({ | ||
axisDelta: axisDelta, | ||
isStart: !state.isStartPublished | ||
}); // state.isMomentum ? MOMENTUM_WHEEL : WHEEL, { axisDelta }) | ||
// publish start after velocity etc. have been updated | ||
state.isStartPublished = true; // calc debounced end function, to recognize end of wheel event stream | ||
willEnd(); | ||
}; | ||
var mergeScrollPointsCalcVelocity = function mergeScrollPointsCalcVelocity() { | ||
if (state.scrollPointsToMerge.length === WHEELEVENTS_TO_MERGE) { | ||
var _state = state, | ||
scrollPointsToMerge = _state.scrollPointsToMerge; | ||
var mergedScrollPoint = { | ||
deltaMaxAbsAverage: average(scrollPointsToMerge.map(function (b) { | ||
return b.deltaMaxAbs; | ||
})), | ||
axisDeltaSum: scrollPointsToMerge.map(function (b) { | ||
state.scrollPoints.unshift({ | ||
axisDeltaSum: state.scrollPointsToMerge.map(function (b) { | ||
return b.axisDelta; | ||
}).reduce(addVectors), | ||
timeStamp: average(scrollPointsToMerge.map(function (b) { | ||
timeStamp: average(state.scrollPointsToMerge.map(function (b) { | ||
return b.timeStamp; | ||
})) | ||
}; // TODO: remove scroll points | ||
}); // only update velocity after a merged scrollpoint was generated | ||
state.scrollPoints.push(mergedScrollPoint); // only update velocity after a merged scrollpoint was generated | ||
updateVelocity(); // reset toMerge array | ||
updateVelocity(); // reset merge array | ||
state.scrollPointsToMerge.length = 0; // after calculation of velocity only keep the most recent merged scrollPoint | ||
state.scrollPointsToMerge = []; | ||
state.scrollPoints.length = 1; | ||
@@ -328,18 +364,5 @@ if (!state.isMomentum) { | ||
} | ||
} else if (!state.isStartPublished) { | ||
updateStartVelocity(); | ||
} | ||
if (!state.scrollPoints.length) { | ||
updateStartVelocity(); | ||
} // only wheel event (move) and not start/end get the delta values | ||
publishWheel({ | ||
axisDelta: axisDelta, | ||
isStart: !state.isStartPublished | ||
}); // state.isMomentum ? MOMENTUM_WHEEL : WHEEL, { axisDelta }) | ||
// publish start after velocity etc. have been updated | ||
state.isStartPublished = true; // calc debounced end function, to recognize end of wheel event stream | ||
willEnd(); | ||
}; | ||
@@ -355,7 +378,7 @@ | ||
// need to have two recent points to calc velocity | ||
var _state$scrollPoints$s = state.scrollPoints.slice(-2), | ||
pA = _state$scrollPoints$s[0], | ||
pB = _state$scrollPoints$s[1]; | ||
var _state$scrollPoints = state.scrollPoints, | ||
latestScrollPoint = _state$scrollPoints[0], | ||
prevScrollPoint = _state$scrollPoints[1]; | ||
if (!pA || !pB) { | ||
if (!prevScrollPoint || !latestScrollPoint) { | ||
return; | ||
@@ -365,6 +388,6 @@ } // time delta | ||
var deltaTime = pB.timeStamp - pA.timeStamp; | ||
var deltaTime = latestScrollPoint.timeStamp - prevScrollPoint.timeStamp; | ||
if (deltaTime <= 0) { | ||
isDev && console.warn('invalid deltaTime'); | ||
__DEV__ && console.warn('invalid deltaTime'); | ||
return; | ||
@@ -374,3 +397,3 @@ } // calc the velocity per axes | ||
var velocity = pB.axisDeltaSum.map(function (d) { | ||
var velocity = latestScrollPoint.axisDeltaSum.map(function (d) { | ||
return d / deltaTime; | ||
@@ -416,7 +439,6 @@ }); // calc the acceleration factor per axis | ||
var recentAccelerationFactors = state.accelerationFactors.slice(WHEELEVENTS_TO_ANALAZE * -1); // check recent acceleration / deceleration factors | ||
// all recent need to match, if any did not match | ||
var detectedMomentum = recentAccelerationFactors.reduce(function (mightBeMomentum, accFac) { | ||
// all recent need to match, if any did not match -> short circuit | ||
if (!mightBeMomentum) return false; // when both axis decelerate exactly in the same rate it is very likely caused by momentum | ||
var detectedMomentum = recentAccelerationFactors.every(function (accFac) { | ||
// when both axis decelerate exactly in the same rate it is very likely caused by momentum | ||
var sameAccFac = !!accFac.reduce(function (f1, f2) { | ||
@@ -429,3 +451,3 @@ return f1 && f1 < 1 && f1 === f2 ? 1 : 0; | ||
return sameAccFac || bothAreInRangeOrZero; | ||
}, true); | ||
}); | ||
@@ -483,4 +505,9 @@ if (detectedMomentum) { | ||
var _WheelTargetObserver = WheelTargetObserver(feedWheel), | ||
observe = _WheelTargetObserver.observe, | ||
unobserve = _WheelTargetObserver.unobserve, | ||
disconnect = _WheelTargetObserver.disconnect; | ||
updateOptions(optionsParam); | ||
return Object.freeze({ | ||
return deepFreeze({ | ||
on: on, | ||
@@ -497,3 +524,3 @@ off: off, | ||
export default WheelGestures; | ||
export { WheelGestures, absMax, addVectors, average, clamp, clampAxisDelta, configDefaults, deepFreeze, lastOf, normalizeWheel, reverseAxisDeltaSign }; | ||
export { WheelGestures, absMax, addVectors, average, clamp, deepFreeze, lastOf, projection }; | ||
//# sourceMappingURL=wheel-gestures.esm.js.map |
@@ -1,9 +0,2 @@ | ||
import { BooleanXYZ } from './wheel-gestures-types'; | ||
export declare type PreventWheelActionType = true | 'x' | 'y' | 'z' | false; | ||
export declare type ReverseSign = BooleanXYZ | boolean; | ||
export interface WheelGesturesConfig { | ||
preventWheelAction: PreventWheelActionType; | ||
reverseSign: ReverseSign; | ||
} | ||
export declare type WheelGesturesOptions = Partial<WheelGesturesConfig>; | ||
import { WheelGesturesConfig } from '../types'; | ||
export declare const configDefaults: WheelGesturesConfig; |
@@ -1,2 +0,6 @@ | ||
import { WheelGesturesInternalState } from './wheel-gestures-types'; | ||
/** | ||
* the timeout is automatically adjusted during a gesture | ||
* the initial timeout period is pretty long, so even old mouses, which emit wheel events less often, can produce a continuous gesture | ||
*/ | ||
import { WheelGesturesInternalState } from './internal-types'; | ||
export declare function createWheelGesturesState(): WheelGesturesInternalState; |
@@ -1,7 +0,6 @@ | ||
import { WheelGesturesConfig, WheelGesturesOptions } from './options'; | ||
import { Unobserve, WheelEventData, WheelGesturesEventMap } from './wheel-gestures-types'; | ||
import { WheelEventData, WheelGesturesConfig, WheelGesturesEventMap, WheelGesturesOptions } from '../types'; | ||
export declare function WheelGestures(optionsParam?: WheelGesturesOptions): Readonly<{ | ||
on: <EK extends "wheel">(type: EK, listener: import("../events/EventBus").EventListener<WheelGesturesEventMap[EK]>) => import("../events/EventBus").Off; | ||
off: <EK_1 extends "wheel">(type: EK_1, listener: import("../events/EventBus").EventListener<WheelGesturesEventMap[EK_1]>) => void; | ||
observe: (target: EventTarget) => Unobserve; | ||
observe: (target: EventTarget) => () => void; | ||
unobserve: (target: EventTarget) => void; | ||
@@ -8,0 +7,0 @@ disconnect: () => void; |
@@ -1,3 +0,2 @@ | ||
import { ReverseSign } from '../wheel-gestures/options'; | ||
import { VectorXYZ, WheelEventData } from '../wheel-gestures/wheel-gestures-types'; | ||
import { ReverseSign, VectorXYZ, WheelEventData } from '../types'; | ||
export interface NormalizedWheel { | ||
@@ -9,5 +8,4 @@ axisDelta: VectorXYZ; | ||
export declare function reverseAxisDeltaSign<T extends Pick<NormalizedWheel, 'axisDelta'>>(wheel: T, reverseSign: ReverseSign): T; | ||
export declare const clamp: (value: number, min: number, max: number) => number; | ||
export declare const clampAxisDelta: <T extends Pick<NormalizedWheel, "axisDelta">>(wheel: T) => T & { | ||
axisDelta: number[]; | ||
}; |
{ | ||
"name": "wheel-gestures", | ||
"version": "2.1.0", | ||
"version": "2.1.1", | ||
"description": "wheel gestures and momentum detection", | ||
@@ -9,3 +9,4 @@ "main": "dist/index.js", | ||
"files": [ | ||
"dist" | ||
"dist", | ||
"src" | ||
], | ||
@@ -12,0 +13,0 @@ "engines": { |
@@ -25,1 +25,3 @@ # ![wheel gestures](./WheelGestures.svg) | ||
- https://github.com/d4nyll/lethargy | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
354542
76
11450
27
1