wheel-gestures
Advanced tools
Comparing version 1.4.0 to 1.5.0
@@ -5,2 +5,3 @@ export * from './wheel-gestures/wheel-gestures'; | ||
export * from './wheel-analyzer/wheel-analyzer-types'; | ||
export * from './wheel-normalizer/wheel-normalizer'; | ||
export * from './utils'; |
export declare function lastOf<T>(array: T[]): T; | ||
export declare function average(numbers: number[]): number; | ||
export declare function addVectors<T extends number[]>(v1: T, v2: T): T; | ||
export declare function absMax(numbers: number[]): number; |
@@ -7,2 +7,3 @@ export declare type VectorXYZ = [number, number, number]; | ||
isMomentum: boolean; | ||
startTime: number; | ||
lastAbsDelta: number; | ||
@@ -12,3 +13,3 @@ axisMovement: VectorXYZ; | ||
accelerationFactors: number[][]; | ||
scrollPoints: ScrollPoint[]; | ||
scrollPoints: MergedScrollPoint[]; | ||
scrollPointsToMerge: ScrollPoint[]; | ||
@@ -20,3 +21,2 @@ willEndTimeout: number; | ||
isMomentum: boolean; | ||
isEndingSoon: boolean; | ||
axisMovement: VectorXYZ; | ||
@@ -28,6 +28,11 @@ axisVelocity: VectorXYZ; | ||
export interface ScrollPoint { | ||
currentAbsDelta: number; | ||
axisDeltaUnclampt: VectorXYZ; | ||
timestamp: number; | ||
deltaMaxAbs: number; | ||
axisDelta: VectorXYZ; | ||
timeStamp: number; | ||
} | ||
export interface MergedScrollPoint { | ||
deltaMaxAbsAverage: number; | ||
axisDeltaSum: VectorXYZ; | ||
timeStamp: number; | ||
} | ||
export declare type WheelEventDataRequiredFields = 'deltaMode' | 'deltaX' | 'deltaY' | 'timeStamp'; | ||
@@ -34,0 +39,0 @@ export interface WheelEventData extends Pick<WheelEvent, WheelEventDataRequiredFields>, Partial<Omit<WheelEvent, WheelEventDataRequiredFields>> { |
@@ -85,2 +85,5 @@ 'use strict'; | ||
} | ||
function absMax(numbers) { | ||
return Math.max.apply(Math, numbers.map(Math.abs)); | ||
} | ||
@@ -95,4 +98,4 @@ var LINE_HEIGHT = 16 * 1.125; | ||
return { | ||
axisDelta: [deltaX, deltaY, deltaZ], | ||
timeStamp: e.timeStamp | ||
timeStamp: e.timeStamp, | ||
axisDelta: [deltaX, deltaY, deltaZ] | ||
}; | ||
@@ -115,2 +118,13 @@ } | ||
} | ||
var clamp = function clamp(value, min, max) { | ||
return Math.min(Math.max(min, value), max); | ||
}; | ||
var DELTA_MAX_ABS = 700; | ||
var clampDelta = function clampDelta(wheel) { | ||
return _extends({}, wheel, { | ||
axisDelta: wheel.axisDelta.map(function (delta) { | ||
return clamp(delta, -DELTA_MAX_ABS, DELTA_MAX_ABS); | ||
}) | ||
}); | ||
}; | ||
@@ -127,2 +141,3 @@ /** | ||
isMomentum: false, | ||
startTime: 0, | ||
lastAbsDelta: Infinity, | ||
@@ -151,9 +166,6 @@ axisMovement: [0, 0, 0], | ||
var SOON_ENDING_THRESHOLD = 1.4; | ||
var ACC_FACTOR_MIN = 0.6; | ||
var ACC_FACTOR_MAX = 0.96; | ||
var DELTA_MAX_ABS = 150; | ||
var WHEELEVENTS_TO_MERGE = 2; | ||
var WHEELEVENTS_TO_ANALAZE = 5; | ||
var SOON_ENDING_WHEEL_COUNT = 3; | ||
var reverseSignDefault = [true, true, false]; | ||
@@ -170,2 +182,3 @@ function WheelAnalyzer(optionsParam) { | ||
var currentEvent; | ||
var negativeZeroFingerUpSpecialEvent = false; | ||
@@ -215,3 +228,2 @@ var observe = function observe(target) { | ||
type: type, | ||
isEndingSoon: willEndSoon(), | ||
isMomentum: state.isMomentum, | ||
@@ -278,12 +290,8 @@ axisMovement: state.axisMovement, | ||
var clampDelta = function clampDelta(delta) { | ||
return Math.min(DELTA_MAX_ABS, Math.max(-DELTA_MAX_ABS, delta)); | ||
}; | ||
var processWheelEventData = function processWheelEventData(wheelEvent) { | ||
var _reverseSign = reverseSign(normalizeWheel(wheelEvent), options.reverseSign), | ||
axisDelta = _reverseSign.axisDelta; | ||
var _clampDelta = clampDelta(reverseSign(normalizeWheel(wheelEvent), options.reverseSign)), | ||
axisDelta = _clampDelta.axisDelta, | ||
timeStamp = _clampDelta.timeStamp; | ||
var deltaX = axisDelta[0], | ||
deltaY = axisDelta[1]; // TODO: deltaZ | ||
var deltaMaxAbs = absMax(axisDelta); | ||
@@ -296,23 +304,22 @@ if (wheelEvent.preventDefault && shouldPreventDefault(wheelEvent)) { | ||
start(); | ||
} // TODO: deltaZ | ||
} // check if user started scrolling again -> cancel | ||
else if (state.isMomentum && deltaMaxAbs > Math.max(2, state.lastAbsDelta * 2)) { | ||
end(true); | ||
start(); | ||
} // special finger up event on windows + blink | ||
var currentDelta = clampDelta(Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX); | ||
var currentAbsDelta = Math.abs(currentDelta); | ||
if (deltaMaxAbs === 0 && Object.is && Object.is(wheelEvent.deltaX, -0)) { | ||
negativeZeroFingerUpSpecialEvent = true; // return -> zero delta event should not influence velocity | ||
if (state.isMomentum && currentAbsDelta > state.lastAbsDelta) { | ||
end(); | ||
start(); | ||
return; | ||
} | ||
currentEvent = wheelEvent; // TODO: clampDelta like reverseSign | ||
state.axisMovement = state.axisMovement.map(function (prevDelta, i) { | ||
return prevDelta + clampDelta(axisDelta[i]); | ||
}); | ||
state.lastAbsDelta = currentAbsDelta; | ||
currentEvent = wheelEvent; | ||
state.axisMovement = addVectors(state.axisMovement, axisDelta); | ||
state.lastAbsDelta = deltaMaxAbs; | ||
state.scrollPointsToMerge.push({ | ||
currentAbsDelta: currentAbsDelta, | ||
axisDeltaUnclampt: axisDelta, | ||
timestamp: wheelEvent.timeStamp | ||
deltaMaxAbs: deltaMaxAbs, | ||
axisDelta: axisDelta, | ||
timeStamp: timeStamp | ||
}); | ||
@@ -324,10 +331,10 @@ | ||
var mergedScrollPoint = { | ||
currentAbsDelta: average(scrollPointsToMerge.map(function (b) { | ||
return b.currentAbsDelta; | ||
deltaMaxAbsAverage: average(scrollPointsToMerge.map(function (b) { | ||
return b.deltaMaxAbs; | ||
})), | ||
axisDeltaUnclampt: scrollPointsToMerge.map(function (b) { | ||
return b.axisDeltaUnclampt; | ||
axisDeltaSum: scrollPointsToMerge.map(function (b) { | ||
return b.axisDelta; | ||
}).reduce(addVectors), | ||
timestamp: average(scrollPointsToMerge.map(function (b) { | ||
return b.timestamp; | ||
timeStamp: average(scrollPointsToMerge.map(function (b) { | ||
return b.timeStamp; | ||
})) | ||
@@ -337,10 +344,9 @@ }; | ||
updateVelocity(); | ||
updateVelocity(); // reset merge array | ||
state.scrollPointsToMerge = []; | ||
if (!state.isMomentum) { | ||
detectMomentum(); | ||
} // reset merge array | ||
state.scrollPointsToMerge = []; | ||
} | ||
} | ||
@@ -371,4 +377,3 @@ | ||
var updateStartVelocity = function updateStartVelocity() { | ||
var latestScrollPoint = state.scrollPointsToMerge[state.scrollPointsToMerge.length - 1]; | ||
state.axisVelocity = latestScrollPoint.axisDeltaUnclampt.map(function (d) { | ||
state.axisVelocity = lastOf(state.scrollPointsToMerge).axisDelta.map(function (d) { | ||
return d / state.willEndTimeout; | ||
@@ -389,3 +394,3 @@ }); | ||
var deltaTime = pB.timestamp - pA.timestamp; | ||
var deltaTime = pB.timeStamp - pA.timeStamp; | ||
@@ -398,3 +403,3 @@ if (deltaTime <= 0) { | ||
var velocity = pB.axisDeltaUnclampt.map(function (d) { | ||
var velocity = pB.axisDeltaSum.map(function (d) { | ||
return d / deltaTime; | ||
@@ -429,24 +434,38 @@ }); // calc the acceleration factor per axis | ||
var detectMomentum = function detectMomentum() { | ||
if (state.accelerationFactors.length < WHEELEVENTS_TO_ANALAZE) { | ||
return state.isMomentum; | ||
} | ||
if (state.accelerationFactors.length >= WHEELEVENTS_TO_ANALAZE) { | ||
if (negativeZeroFingerUpSpecialEvent) { | ||
negativeZeroFingerUpSpecialEvent = false; | ||
var recentAccelerationFactors = state.accelerationFactors.slice(WHEELEVENTS_TO_ANALAZE * -1); // check recent acceleration / deceleration factors | ||
if (absMax(state.axisVelocity) >= 0.2) { | ||
recognizedMomentum(); | ||
return; | ||
} | ||
} | ||
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 recentAccelerationFactors = state.accelerationFactors.slice(WHEELEVENTS_TO_ANALAZE * -1); // check recent acceleration / deceleration factors | ||
var sameAccFac = !!accFac.reduce(function (f1, f2) { | ||
return f1 && f1 < 1 && f1 === f2 ? 1 : 0; | ||
}); // check if acceleration factor is within momentum range | ||
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 bothAreInRangeOrZero = accFac.filter(accelerationFactorInMomentumRange).length === accFac.length; // one the requirements must be fulfilled | ||
var sameAccFac = !!accFac.reduce(function (f1, f2) { | ||
return f1 && f1 < 1 && f1 === f2 ? 1 : 0; | ||
}); // check if acceleration factor is within momentum range | ||
return sameAccFac || bothAreInRangeOrZero; | ||
}, true); // only keep the most recent events | ||
var bothAreInRangeOrZero = accFac.filter(accelerationFactorInMomentumRange).length === accFac.length; // one the requirements must be fulfilled | ||
state.accelerationFactors = recentAccelerationFactors; | ||
return sameAccFac || bothAreInRangeOrZero; | ||
}, true); | ||
if (detectedMomentum && !state.isMomentum) { | ||
if (detectedMomentum) { | ||
recognizedMomentum(); | ||
} // only keep the most recent events | ||
state.accelerationFactors = recentAccelerationFactors; | ||
} | ||
}; | ||
var recognizedMomentum = function recognizedMomentum() { | ||
if (!state.isMomentum) { | ||
publish(exports.WheelPhase.WHEEL_END); | ||
@@ -456,4 +475,2 @@ state.isMomentum = true; | ||
} | ||
return state.isMomentum; | ||
}; | ||
@@ -464,2 +481,4 @@ | ||
state.isStarted = true; | ||
state.startTime = Date.now(); | ||
negativeZeroFingerUpSpecialEvent = false; | ||
}; | ||
@@ -475,7 +494,11 @@ | ||
var end = function end() { | ||
var end = function end(isMomentumCancel) { | ||
if (isMomentumCancel === void 0) { | ||
isMomentumCancel = false; | ||
} | ||
if (!state.isStarted) return; | ||
if (state.isMomentum) { | ||
if (!willEndSoon()) { | ||
if (isMomentumCancel) { | ||
publish(exports.WheelPhase.MOMENTUM_WHEEL_CANCEL); | ||
@@ -495,13 +518,2 @@ } else { | ||
var willEndSoon = function willEndSoon() { | ||
var absDeltas = state.scrollPoints.slice(SOON_ENDING_WHEEL_COUNT * -1).map(function (_ref) { | ||
var currentAbsDelta = _ref.currentAbsDelta; | ||
return currentAbsDelta; | ||
}); | ||
var absDeltaAverage = absDeltas.reduce(function (a, b) { | ||
return a + b; | ||
}, 0) / absDeltas.length; | ||
return absDeltaAverage <= SOON_ENDING_THRESHOLD; | ||
}; | ||
updateOptions(optionsParam); | ||
@@ -598,5 +610,10 @@ return Object.freeze({ | ||
exports.WheelGestures = WheelGestures; | ||
exports.absMax = absMax; | ||
exports.addVectors = addVectors; | ||
exports.average = average; | ||
exports.clamp = clamp; | ||
exports.clampDelta = clampDelta; | ||
exports.lastOf = lastOf; | ||
exports.normalizeWheel = normalizeWheel; | ||
exports.reverseSign = reverseSign; | ||
//# sourceMappingURL=wheel-gestures.cjs.development.js.map |
@@ -1,2 +0,2 @@ | ||
"use strict";function e(){return(e=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function t(e){return e.reduce((function(e,t){return e+t}))/e.length}function n(e,t){if(e.length!==t.length)throw new Error("vectors must be same length");return e.map((function(e,n){return e+t[n]}))}Object.defineProperty(exports,"__esModule",{value:!0});var r,o=[1,18,"undefined"!=typeof window&&window.innerHeight||800],s=[-1,-1,-1];(r=exports.WheelPhase||(exports.WheelPhase={})).ANY_WHEEL_START="ANY_WHEEL_START",r.ANY_WHEEL="ANY_WHEEL",r.ANY_WHEEL_END="ANY_WHEEL_END",r.WHEEL_START="WHEEL_START",r.WHEEL="WHEEL",r.WHEEL_END="WHEEL_END",r.MOMENTUM_WHEEL_START="MOMENTUM_WHEEL_START",r.MOMENTUM_WHEEL="MOMENTUM_WHEEL",r.MOMENTUM_WHEEL_CANCEL="MOMENTUM_WHEEL_CANCEL",r.MOMENTUM_WHEEL_END="MOMENTUM_WHEEL_END";var a,i,l=[!0,!0,!1];function u(r){var a;void 0===r&&(r={});var i,u,c={isStarted:!1,isStartPublished:!1,isMomentum:!1,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400},E=[],h=[],f=function(e){e.removeEventListener("wheel",p),h=h.filter((function(t){return t!==e}))},m=function(e){e&&(E=E.filter((function(t){return t!==e})))},M=function(t,n){var r=e({type:t,isEndingSoon:H(),isMomentum:c.isMomentum,axisMovement:c.axisMovement,axisVelocity:c.axisVelocity,axisDelta:[0,0,0],event:i},n);E.forEach((function(e){return e(t,r)}))},p=function(e){Array.isArray(e)?e.forEach((function(e){return v(e)})):v(e)},W=function(t){void 0===t&&(t={});var n=t.preventWheelAction,r=void 0===n?"all":n,o=t.reverseSign,s=void 0===o?l:o,i=function(e,t){if(null==e)return{};var n,r,o={},s=Object.keys(e);for(r=0;r<s.length;r++)t.indexOf(n=s[r])>=0||(o[n]=e[n]);return o}(t,["preventWheelAction","reverseSign"]);return a=e({preventWheelAction:r,reverseSign:s},i)},d=function(e){return Math.min(150,Math.max(-150,e))},v=function(r){var l,u=function(t,n){if(!n)return t;var r=!0===n?s:n.map((function(e){return e?-1:1}));return e({},t,{axisDelta:t.axisDelta.map((function(e,t){return e*r[t]}))})}({axisDelta:[(l=r).deltaX*o[l.deltaMode],l.deltaY*o[l.deltaMode],(l.deltaZ||0)*o[l.deltaMode]],timeStamp:l.timeStamp},a.reverseSign).axisDelta,E=u[0],h=u[1];r.preventDefault&&function(e){var t=e.deltaX,n=e.deltaY;switch(a.preventWheelAction){case"all":return!0;case"x":return Math.abs(t)>=Math.abs(n);case"y":return Math.abs(n)>=Math.abs(t)}}(r)&&r.preventDefault(),c.isStarted||L();var f=d(Math.abs(h)>Math.abs(E)?h:E),m=Math.abs(f);if(c.isMomentum&&m>c.lastAbsDelta&&(P(),L()),i=r,c.axisMovement=c.axisMovement.map((function(e,t){return e+d(u[t])})),c.lastAbsDelta=m,c.scrollPointsToMerge.push({currentAbsDelta:m,axisDeltaUnclampt:u,timestamp:r.timeStamp}),2===c.scrollPointsToMerge.length){var p=c.scrollPointsToMerge,W={currentAbsDelta:t(p.map((function(e){return e.currentAbsDelta}))),axisDeltaUnclampt:p.map((function(e){return e.axisDeltaUnclampt})).reduce(n),timestamp:t(p.map((function(e){return e.timestamp})))};c.scrollPoints.push(W),_(),c.isMomentum||b(),c.scrollPointsToMerge=[]}c.scrollPoints.length||x(),c.isStartPublished||(M(exports.WheelPhase.ANY_WHEEL_START),M(exports.WheelPhase.WHEEL_START),c.isStartPublished=!0),M(exports.WheelPhase.ANY_WHEEL,{axisDelta:u}),M(c.isMomentum?exports.WheelPhase.MOMENTUM_WHEEL:exports.WheelPhase.WHEEL,{axisDelta:u}),N()},x=function(){c.axisVelocity=c.scrollPointsToMerge[c.scrollPointsToMerge.length-1].axisDeltaUnclampt.map((function(e){return e/c.willEndTimeout}))},_=function(){var e=c.scrollPoints.slice(-2),t=e[0],n=e[1];if(t&&n){var r=n.timestamp-t.timestamp;if(!(r<=0)){var o=n.axisDeltaUnclampt.map((function(e){return e/r})),s=o.map((function(e,t){return e/(c.axisVelocity[t]||1)}));c.axisVelocity=o,c.accelerationFactors.push(s),T(r)}}},T=function(e){var t=10*Math.ceil(e/10)*1.2;c.isMomentum||(t=Math.max(100,2*t)),c.willEndTimeout=Math.min(1e3,Math.round(t))},A=function(e){return 0===e||e<=.96&&e>=.6},b=function(){if(c.accelerationFactors.length<5)return c.isMomentum;var e=c.accelerationFactors.slice(-5),t=e.reduce((function(e,t){if(!e)return!1;var n=!!t.reduce((function(e,t){return e&&e<1&&e===t?1:0})),r=t.filter(A).length===t.length;return n||r}),!0);return c.accelerationFactors=e,t&&!c.isMomentum&&(M(exports.WheelPhase.WHEEL_END),c.isMomentum=!0,M(exports.WheelPhase.MOMENTUM_WHEEL_START)),c.isMomentum},L=function(){(c={isStarted:!1,isStartPublished:!1,isMomentum:!1,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400}).isStarted=!0},N=function(){clearTimeout(u),u=setTimeout(P,c.willEndTimeout)},P=function(){c.isStarted&&(c.isMomentum?H()?M(exports.WheelPhase.MOMENTUM_WHEEL_END):M(exports.WheelPhase.MOMENTUM_WHEEL_CANCEL):M(exports.WheelPhase.WHEEL_END),M(exports.WheelPhase.ANY_WHEEL_END),c.isMomentum=!1,c.isStarted=!1)},H=function(){var e=c.scrollPoints.slice(-3).map((function(e){return e.currentAbsDelta}));return e.reduce((function(e,t){return e+t}),0)/e.length<=1.4};return W(r),Object.freeze({observe:function(e){return e.addEventListener("wheel",p,{passive:!1}),h.push(e),function(){return f(e)}},unobserve:f,disconnect:function(){h.forEach(f)},subscribe:function(e){return E.push(e),function(){return m(e)}},unsubscribe:m,feedWheel:p,updateOptions:W})}(a=exports.WheelReason||(exports.WheelReason={})).USER="USER",a.ANY="ANY";var c=((i={})[exports.WheelReason.USER]={start:exports.WheelPhase.WHEEL_START,wheel:exports.WheelPhase.WHEEL,end:exports.WheelPhase.WHEEL_END},i[exports.WheelReason.ANY]={start:exports.WheelPhase.ANY_WHEEL_START,wheel:exports.WheelPhase.ANY_WHEEL,end:exports.WheelPhase.ANY_WHEEL_END},i);exports.WheelAnalyzer=u,exports.WheelGestures=function(t){var n=void 0===t?{}:t,r=n.axis,o=n.wheelReason,s=void 0===o?exports.WheelReason.USER:o,a=u({preventWheelAction:void 0===r?"all":r}),i=a.observe,l=a.unobserve,E=a.disconnect,h=function(){var e={};function t(t,n){e[t]=(e[t]||[]).filter((function(e){return e!==n}))}return Object.freeze({on:function(n,r){return e[n]=(e[n]||[]).concat(r),function(){return t(n,r)}},off:t,dispatch:function(t,n){t in e&&e[t].forEach((function(e){return e(n)}))}})}(),f=h.on,m=h.off,M=h.dispatch;return a.subscribe((function(t,n){var r=e({},n,{down:!0,start:!1});switch(t){case c[s].start:r=e({},r,{down:!0,start:!0}),M("wheelstart",r);break;case c[s].wheel:r=e({},r,{down:!0}),M("wheelmove",r);break;case c[s].end:r=e({},r,{down:!1}),M("wheelend",r);break;default:return}})),Object.freeze({observe:i,unobserve:l,disconnect:E,on:f,off:m})},exports.addVectors=n,exports.average=t,exports.lastOf=function(e){return e[e.length-1]}; | ||
"use strict";function e(){return(e=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var n=arguments[t];for(var r in n)Object.prototype.hasOwnProperty.call(n,r)&&(e[r]=n[r])}return e}).apply(this,arguments)}function t(e){return e[e.length-1]}function n(e){return e.reduce((function(e,t){return e+t}))/e.length}function r(e,t){if(e.length!==t.length)throw new Error("vectors must be same length");return e.map((function(e,n){return e+t[n]}))}function a(e){return Math.max.apply(Math,e.map(Math.abs))}Object.defineProperty(exports,"__esModule",{value:!0});var o=[1,18,"undefined"!=typeof window&&window.innerHeight||800];function i(e){return{timeStamp:e.timeStamp,axisDelta:[e.deltaX*o[e.deltaMode],e.deltaY*o[e.deltaMode],(e.deltaZ||0)*o[e.deltaMode]]}}var s=[-1,-1,-1];function l(t,n){if(!n)return t;var r=!0===n?s:n.map((function(e){return e?-1:1}));return e({},t,{axisDelta:t.axisDelta.map((function(e,t){return e*r[t]}))})}var u,c=function(e,t,n){return Math.min(Math.max(t,e),n)},E=function(t){return e({},t,{axisDelta:t.axisDelta.map((function(e){return c(e,-700,700)}))})};(u=exports.WheelPhase||(exports.WheelPhase={})).ANY_WHEEL_START="ANY_WHEEL_START",u.ANY_WHEEL="ANY_WHEEL",u.ANY_WHEEL_END="ANY_WHEEL_END",u.WHEEL_START="WHEEL_START",u.WHEEL="WHEEL",u.WHEEL_END="WHEEL_END",u.MOMENTUM_WHEEL_START="MOMENTUM_WHEEL_START",u.MOMENTUM_WHEEL="MOMENTUM_WHEEL",u.MOMENTUM_WHEEL_CANCEL="MOMENTUM_WHEEL_CANCEL",u.MOMENTUM_WHEEL_END="MOMENTUM_WHEEL_END";var h,f,p=[!0,!0,!1];function M(o){var s;void 0===o&&(o={});var u,c,h={isStarted:!1,isStartPublished:!1,isMomentum:!1,startTime:0,lastAbsDelta:Infinity,axisMovement:[0,0,0],axisVelocity:[0,0,0],accelerationFactors:[],scrollPoints:[],scrollPointsToMerge:[],willEndTimeout:400},f=[],M=[],m=!1,x=function(e){e.removeEventListener("wheel",v),M=M.filter((function(t){return t!==e}))},d=function(e){e&&(f=f.filter((function(t){return t!==e})))},W=function(t,n){var r=e({type:t,isMomentum:h.isMomentum,axisMovement:h.axisMovement,axisVelocity:h.axisVelocity,axisDelta:[0,0,0],event:u},n);f.forEach((function(e){return e(t,r)}))},v=function(e){Array.isArray(e)?e.forEach((function(e){return T(e)})):T(e)},_=function(t){void 0===t&&(t={});var n=t.preventWheelAction,r=void 0===n?"all":n,a=t.reverseSign,o=void 0===a?p:a,i=function(e,t){if(null==e)return{};var n,r,a={},o=Object.keys(e);for(r=0;r<o.length;r++)t.indexOf(n=o[r])>=0||(a[n]=e[n]);return a}(t,["preventWheelAction","reverseSign"]);return s=e({preventWheelAction:r,reverseSign:o},i)},T=function(e){var t=E(l(i(e),s.reverseSign)),o=t.axisDelta,c=t.timeStamp,f=a(o);if(e.preventDefault&&function(e){var t=e.deltaX,n=e.deltaY;switch(s.preventWheelAction){case"all":return!0;case"x":return Math.abs(t)>=Math.abs(n);case"y":return Math.abs(n)>=Math.abs(t)}}(e)&&e.preventDefault(),h.isStarted?h.isMomentum&&f>Math.max(2,2*h.lastAbsDelta)&&(g(!0),P()):P(),0===f&&Object.is&&Object.is(e.deltaX,-0))m=!0;else{if(u=e,h.axisMovement=r(h.axisMovement,o),h.lastAbsDelta=f,h.scrollPointsToMerge.push({deltaMaxAbs:f,axisDelta:o,timeStamp:c}),2===h.scrollPointsToMerge.length){var p=h.scrollPointsToMerge,M={deltaMaxAbsAverage:n(p.map((function(e){return e.deltaMaxAbs}))),axisDeltaSum:p.map((function(e){return e.axisDelta})).reduce(r),timeStamp:n(p.map((function(e){return e.timeStamp})))};h.scrollPoints.push(M),b(),h.scrollPointsToMerge=[],h.isMomentum||S()}h.scrollPoints.length||A(),h.isStartPublished||(W(exports.WheelPhase.ANY_WHEEL_START),W(exports.WheelPhase.WHEEL_START),h.isStartPublished=!0),W(exports.WheelPhase.ANY_WHEEL,{axisDelta:o}),W(h.isMomentum?exports.WheelPhase.MOMENTUM_WHEEL:exports.WheelPhase.WHEEL,{axisDelta:o}),D()}},A=function(){h.axisVelocity=t(h.scrollPointsToMerge).axisDelta.map((function(e){return e/h.willEndTimeout}))},b=function(){var e=h.scrollPoints.slice(-2),t=e[0],n=e[1];if(t&&n){var r=n.timeStamp-t.timeStamp;if(!(r<=0)){var a=n.axisDeltaSum.map((function(e){return e/r})),o=a.map((function(e,t){return e/(h.axisVelocity[t]||1)}));h.axisVelocity=a,h.accelerationFactors.push(o),L(r)}}},L=function(e){var t=10*Math.ceil(e/10)*1.2;h.isMomentum||(t=Math.max(100,2*t)),h.willEndTimeout=Math.min(1e3,Math.round(t))},N=function(e){return 0===e||e<=.96&&e>=.6},S=function(){if(h.accelerationFactors.length>=5){if(m&&(m=!1,a(h.axisVelocity)>=.2))return void H();var e=h.accelerationFactors.slice(-5);e.reduce((function(e,t){if(!e)return!1;var n=!!t.reduce((function(e,t){return e&&e<1&&e===t?1:0})),r=t.filter(N).length===t.length;return n||r}),!0)&&H(),h.accelerationFactors=e}},H=function(){h.isMomentum||(W(exports.WheelPhase.WHEEL_END),h.isMomentum=!0,W(exports.WheelPhase.MOMENTUM_WHEEL_START))},P=function(){(h={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,h.startTime=Date.now(),m=!1},D=function(){clearTimeout(c),c=setTimeout(g,h.willEndTimeout)},g=function(e){void 0===e&&(e=!1),h.isStarted&&(W(h.isMomentum?e?exports.WheelPhase.MOMENTUM_WHEEL_CANCEL:exports.WheelPhase.MOMENTUM_WHEEL_END:exports.WheelPhase.WHEEL_END),W(exports.WheelPhase.ANY_WHEEL_END),h.isMomentum=!1,h.isStarted=!1)};return _(o),Object.freeze({observe:function(e){return e.addEventListener("wheel",v,{passive:!1}),M.push(e),function(){return x(e)}},unobserve:x,disconnect:function(){M.forEach(x)},subscribe:function(e){return f.push(e),function(){return d(e)}},unsubscribe:d,feedWheel:v,updateOptions:_})}(h=exports.WheelReason||(exports.WheelReason={})).USER="USER",h.ANY="ANY";var m=((f={})[exports.WheelReason.USER]={start:exports.WheelPhase.WHEEL_START,wheel:exports.WheelPhase.WHEEL,end:exports.WheelPhase.WHEEL_END},f[exports.WheelReason.ANY]={start:exports.WheelPhase.ANY_WHEEL_START,wheel:exports.WheelPhase.ANY_WHEEL,end:exports.WheelPhase.ANY_WHEEL_END},f);exports.WheelAnalyzer=M,exports.WheelGestures=function(t){var n=void 0===t?{}:t,r=n.axis,a=n.wheelReason,o=void 0===a?exports.WheelReason.USER:a,i=M({preventWheelAction:void 0===r?"all":r}),s=i.observe,l=i.unobserve,u=i.disconnect,c=function(){var e={};function t(t,n){e[t]=(e[t]||[]).filter((function(e){return e!==n}))}return Object.freeze({on:function(n,r){return e[n]=(e[n]||[]).concat(r),function(){return t(n,r)}},off:t,dispatch:function(t,n){t in e&&e[t].forEach((function(e){return e(n)}))}})}(),E=c.on,h=c.off,f=c.dispatch;return i.subscribe((function(t,n){var r=e({},n,{down:!0,start:!1});switch(t){case m[o].start:r=e({},r,{down:!0,start:!0}),f("wheelstart",r);break;case m[o].wheel:r=e({},r,{down:!0}),f("wheelmove",r);break;case m[o].end:r=e({},r,{down:!1}),f("wheelend",r);break;default:return}})),Object.freeze({observe:s,unobserve:l,disconnect:u,on:E,off:h})},exports.absMax=a,exports.addVectors=r,exports.average=n,exports.clamp=c,exports.clampDelta=E,exports.lastOf=t,exports.normalizeWheel=i,exports.reverseSign=l; | ||
//# sourceMappingURL=wheel-gestures.cjs.production.min.js.map |
@@ -81,2 +81,5 @@ function _extends() { | ||
} | ||
function absMax(numbers) { | ||
return Math.max.apply(Math, numbers.map(Math.abs)); | ||
} | ||
@@ -91,4 +94,4 @@ var LINE_HEIGHT = 16 * 1.125; | ||
return { | ||
axisDelta: [deltaX, deltaY, deltaZ], | ||
timeStamp: e.timeStamp | ||
timeStamp: e.timeStamp, | ||
axisDelta: [deltaX, deltaY, deltaZ] | ||
}; | ||
@@ -111,2 +114,13 @@ } | ||
} | ||
var clamp = function clamp(value, min, max) { | ||
return Math.min(Math.max(min, value), max); | ||
}; | ||
var DELTA_MAX_ABS = 700; | ||
var clampDelta = function clampDelta(wheel) { | ||
return _extends({}, wheel, { | ||
axisDelta: wheel.axisDelta.map(function (delta) { | ||
return clamp(delta, -DELTA_MAX_ABS, DELTA_MAX_ABS); | ||
}) | ||
}); | ||
}; | ||
@@ -123,2 +137,3 @@ /** | ||
isMomentum: false, | ||
startTime: 0, | ||
lastAbsDelta: Infinity, | ||
@@ -150,9 +165,6 @@ axisMovement: [0, 0, 0], | ||
var isDev = process.env.NODE_ENV !== 'production'; | ||
var SOON_ENDING_THRESHOLD = 1.4; | ||
var ACC_FACTOR_MIN = 0.6; | ||
var ACC_FACTOR_MAX = 0.96; | ||
var DELTA_MAX_ABS = 150; | ||
var WHEELEVENTS_TO_MERGE = 2; | ||
var WHEELEVENTS_TO_ANALAZE = 5; | ||
var SOON_ENDING_WHEEL_COUNT = 3; | ||
var reverseSignDefault = [true, true, false]; | ||
@@ -169,2 +181,3 @@ function WheelAnalyzer(optionsParam) { | ||
var currentEvent; | ||
var negativeZeroFingerUpSpecialEvent = false; | ||
@@ -215,3 +228,2 @@ var observe = function observe(target) { | ||
type: type, | ||
isEndingSoon: willEndSoon(), | ||
isMomentum: state.isMomentum, | ||
@@ -278,12 +290,8 @@ axisMovement: state.axisMovement, | ||
var clampDelta = function clampDelta(delta) { | ||
return Math.min(DELTA_MAX_ABS, Math.max(-DELTA_MAX_ABS, delta)); | ||
}; | ||
var processWheelEventData = function processWheelEventData(wheelEvent) { | ||
var _reverseSign = reverseSign(normalizeWheel(wheelEvent), options.reverseSign), | ||
axisDelta = _reverseSign.axisDelta; | ||
var _clampDelta = clampDelta(reverseSign(normalizeWheel(wheelEvent), options.reverseSign)), | ||
axisDelta = _clampDelta.axisDelta, | ||
timeStamp = _clampDelta.timeStamp; | ||
var deltaX = axisDelta[0], | ||
deltaY = axisDelta[1]; // TODO: deltaZ | ||
var deltaMaxAbs = absMax(axisDelta); | ||
@@ -296,23 +304,22 @@ if (wheelEvent.preventDefault && shouldPreventDefault(wheelEvent)) { | ||
start(); | ||
} // TODO: deltaZ | ||
} // check if user started scrolling again -> cancel | ||
else if (state.isMomentum && deltaMaxAbs > Math.max(2, state.lastAbsDelta * 2)) { | ||
end(true); | ||
start(); | ||
} // special finger up event on windows + blink | ||
var currentDelta = clampDelta(Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX); | ||
var currentAbsDelta = Math.abs(currentDelta); | ||
if (deltaMaxAbs === 0 && Object.is && Object.is(wheelEvent.deltaX, -0)) { | ||
negativeZeroFingerUpSpecialEvent = true; // return -> zero delta event should not influence velocity | ||
if (state.isMomentum && currentAbsDelta > state.lastAbsDelta) { | ||
end(); | ||
start(); | ||
return; | ||
} | ||
currentEvent = wheelEvent; // TODO: clampDelta like reverseSign | ||
state.axisMovement = state.axisMovement.map(function (prevDelta, i) { | ||
return prevDelta + clampDelta(axisDelta[i]); | ||
}); | ||
state.lastAbsDelta = currentAbsDelta; | ||
currentEvent = wheelEvent; | ||
state.axisMovement = addVectors(state.axisMovement, axisDelta); | ||
state.lastAbsDelta = deltaMaxAbs; | ||
state.scrollPointsToMerge.push({ | ||
currentAbsDelta: currentAbsDelta, | ||
axisDeltaUnclampt: axisDelta, | ||
timestamp: wheelEvent.timeStamp | ||
deltaMaxAbs: deltaMaxAbs, | ||
axisDelta: axisDelta, | ||
timeStamp: timeStamp | ||
}); | ||
@@ -324,10 +331,10 @@ | ||
var mergedScrollPoint = { | ||
currentAbsDelta: average(scrollPointsToMerge.map(function (b) { | ||
return b.currentAbsDelta; | ||
deltaMaxAbsAverage: average(scrollPointsToMerge.map(function (b) { | ||
return b.deltaMaxAbs; | ||
})), | ||
axisDeltaUnclampt: scrollPointsToMerge.map(function (b) { | ||
return b.axisDeltaUnclampt; | ||
axisDeltaSum: scrollPointsToMerge.map(function (b) { | ||
return b.axisDelta; | ||
}).reduce(addVectors), | ||
timestamp: average(scrollPointsToMerge.map(function (b) { | ||
return b.timestamp; | ||
timeStamp: average(scrollPointsToMerge.map(function (b) { | ||
return b.timeStamp; | ||
})) | ||
@@ -337,10 +344,9 @@ }; | ||
updateVelocity(); | ||
updateVelocity(); // reset merge array | ||
state.scrollPointsToMerge = []; | ||
if (!state.isMomentum) { | ||
detectMomentum(); | ||
} // reset merge array | ||
state.scrollPointsToMerge = []; | ||
} | ||
} | ||
@@ -371,4 +377,3 @@ | ||
var updateStartVelocity = function updateStartVelocity() { | ||
var latestScrollPoint = state.scrollPointsToMerge[state.scrollPointsToMerge.length - 1]; | ||
state.axisVelocity = latestScrollPoint.axisDeltaUnclampt.map(function (d) { | ||
state.axisVelocity = lastOf(state.scrollPointsToMerge).axisDelta.map(function (d) { | ||
return d / state.willEndTimeout; | ||
@@ -389,3 +394,3 @@ }); | ||
var deltaTime = pB.timestamp - pA.timestamp; | ||
var deltaTime = pB.timeStamp - pA.timeStamp; | ||
@@ -398,3 +403,3 @@ if (deltaTime <= 0) { | ||
var velocity = pB.axisDeltaUnclampt.map(function (d) { | ||
var velocity = pB.axisDeltaSum.map(function (d) { | ||
return d / deltaTime; | ||
@@ -429,24 +434,38 @@ }); // calc the acceleration factor per axis | ||
var detectMomentum = function detectMomentum() { | ||
if (state.accelerationFactors.length < WHEELEVENTS_TO_ANALAZE) { | ||
return state.isMomentum; | ||
} | ||
if (state.accelerationFactors.length >= WHEELEVENTS_TO_ANALAZE) { | ||
if (negativeZeroFingerUpSpecialEvent) { | ||
negativeZeroFingerUpSpecialEvent = false; | ||
var recentAccelerationFactors = state.accelerationFactors.slice(WHEELEVENTS_TO_ANALAZE * -1); // check recent acceleration / deceleration factors | ||
if (absMax(state.axisVelocity) >= 0.2) { | ||
recognizedMomentum(); | ||
return; | ||
} | ||
} | ||
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 recentAccelerationFactors = state.accelerationFactors.slice(WHEELEVENTS_TO_ANALAZE * -1); // check recent acceleration / deceleration factors | ||
var sameAccFac = !!accFac.reduce(function (f1, f2) { | ||
return f1 && f1 < 1 && f1 === f2 ? 1 : 0; | ||
}); // check if acceleration factor is within momentum range | ||
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 bothAreInRangeOrZero = accFac.filter(accelerationFactorInMomentumRange).length === accFac.length; // one the requirements must be fulfilled | ||
var sameAccFac = !!accFac.reduce(function (f1, f2) { | ||
return f1 && f1 < 1 && f1 === f2 ? 1 : 0; | ||
}); // check if acceleration factor is within momentum range | ||
return sameAccFac || bothAreInRangeOrZero; | ||
}, true); // only keep the most recent events | ||
var bothAreInRangeOrZero = accFac.filter(accelerationFactorInMomentumRange).length === accFac.length; // one the requirements must be fulfilled | ||
state.accelerationFactors = recentAccelerationFactors; | ||
return sameAccFac || bothAreInRangeOrZero; | ||
}, true); | ||
if (detectedMomentum && !state.isMomentum) { | ||
if (detectedMomentum) { | ||
recognizedMomentum(); | ||
} // only keep the most recent events | ||
state.accelerationFactors = recentAccelerationFactors; | ||
} | ||
}; | ||
var recognizedMomentum = function recognizedMomentum() { | ||
if (!state.isMomentum) { | ||
publish(WheelPhase.WHEEL_END); | ||
@@ -456,4 +475,2 @@ state.isMomentum = true; | ||
} | ||
return state.isMomentum; | ||
}; | ||
@@ -464,2 +481,4 @@ | ||
state.isStarted = true; | ||
state.startTime = Date.now(); | ||
negativeZeroFingerUpSpecialEvent = false; | ||
}; | ||
@@ -475,7 +494,11 @@ | ||
var end = function end() { | ||
var end = function end(isMomentumCancel) { | ||
if (isMomentumCancel === void 0) { | ||
isMomentumCancel = false; | ||
} | ||
if (!state.isStarted) return; | ||
if (state.isMomentum) { | ||
if (!willEndSoon()) { | ||
if (isMomentumCancel) { | ||
publish(WheelPhase.MOMENTUM_WHEEL_CANCEL); | ||
@@ -495,13 +518,2 @@ } else { | ||
var willEndSoon = function willEndSoon() { | ||
var absDeltas = state.scrollPoints.slice(SOON_ENDING_WHEEL_COUNT * -1).map(function (_ref) { | ||
var currentAbsDelta = _ref.currentAbsDelta; | ||
return currentAbsDelta; | ||
}); | ||
var absDeltaAverage = absDeltas.reduce(function (a, b) { | ||
return a + b; | ||
}, 0) / absDeltas.length; | ||
return absDeltaAverage <= SOON_ENDING_THRESHOLD; | ||
}; | ||
updateOptions(optionsParam); | ||
@@ -598,3 +610,3 @@ return Object.freeze({ | ||
export { WheelAnalyzer, WheelGestures, WheelPhase, WheelReason, addVectors, average, lastOf }; | ||
export { WheelAnalyzer, WheelGestures, WheelPhase, WheelReason, absMax, addVectors, average, clamp, clampDelta, lastOf, normalizeWheel, reverseSign }; | ||
//# sourceMappingURL=wheel-gestures.esm.js.map |
@@ -8,1 +8,5 @@ import { ReverseSign, VectorXYZ, WheelEventData } from '../wheel-analyzer/wheel-analyzer-types'; | ||
export declare function reverseSign<T extends Pick<NormalizedWheel, 'axisDelta'>>(wheel: T, reverseSign: ReverseSign): T; | ||
export declare const clamp: (value: number, min: number, max: number) => number; | ||
export declare const clampDelta: <T extends Pick<NormalizedWheel, "axisDelta">>(wheel: T) => T & { | ||
axisDelta: number[]; | ||
}; |
{ | ||
"name": "wheel-gestures", | ||
"version": "1.4.0", | ||
"version": "1.5.0", | ||
"description": "wheel gestures and momentum detection", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
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
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
147447
1196