lethargy-ts
Advanced tools
Comparing version 0.0.6-beta.0 to 0.0.6-beta.1
@@ -6,7 +6,5 @@ export declare enum CHECK_RESULT_CODES { | ||
ENOUGH_TIME_PASSED = "ENOUGH_TIME_PASSED", | ||
DELTA_MODULE_IS_BIGGER = "DELTA_MODULE_IS_BIGGER", | ||
VECTORS_DONT_MATCH = "VECTORS_DONT_MATCH", | ||
NON_DECREASING_DELTAS_OF_KNOWN_HUMAN = "NON_DECREASING_DELTAS_OF_KNOWN_HUMAN", | ||
HIGH_VELOCITY_NON_DECREASING_DELTAS = "HIGH_VELOCITY_NON_DECREASING_DELTAS", | ||
NON_DECREASING_DELTAS_OF_KNOWN_HUMAN = "NON_DECREASING_DELTAS_OF_KNOWN_HUMAN", | ||
ANOMALY_INERTIA_JUMP = "ANOMALY_INERTIA_JUMP" | ||
DELTA_MODULE_HAS_BEEN_INCREASING = "DELTA_MODULE_HAS_BEEN_INCREASING" | ||
} |
123
lib/index.js
@@ -25,25 +25,2 @@ /** Converts default WheelEvent to our custom IWheelEvent */ | ||
}; | ||
/** Returns true if two vectors are equal */ | ||
const compareVectors = (e1, e2, treshhold = 20) => { | ||
const v1 = getDeltas(e1); | ||
const v2 = getDeltas(e2); | ||
return v1.every((vector1, index) => { | ||
const vector = v2[index]; | ||
if (vector1 < treshhold && vector < treshhold) | ||
return true; | ||
const sign1 = getSign(vector1); | ||
const sign2 = getSign(vector); | ||
return sign1 === sign2; | ||
}); | ||
}; | ||
/** If e2 event is inertia, it's delta will be no more than threshold slower */ | ||
const isAnomalyInertia = (e1, e2, threshold = 10) => { | ||
const v1 = getDeltas(e1).map(Math.abs); | ||
const v2 = getDeltas(e2).map(Math.abs); | ||
return v2.some((delta, i) => { | ||
const actualDiff = v1[i] - delta; | ||
const believableDiff = Math.max(10, v1[i] * (threshold / 100)); | ||
return actualDiff > believableDiff; | ||
}); | ||
}; | ||
@@ -56,25 +33,23 @@ var CHECK_RESULT_CODES; | ||
CHECK_RESULT_CODES["ENOUGH_TIME_PASSED"] = "ENOUGH_TIME_PASSED"; | ||
CHECK_RESULT_CODES["DELTA_MODULE_IS_BIGGER"] = "DELTA_MODULE_IS_BIGGER"; | ||
CHECK_RESULT_CODES["VECTORS_DONT_MATCH"] = "VECTORS_DONT_MATCH"; | ||
CHECK_RESULT_CODES["NON_DECREASING_DELTAS_OF_KNOWN_HUMAN"] = "NON_DECREASING_DELTAS_OF_KNOWN_HUMAN"; | ||
CHECK_RESULT_CODES["HIGH_VELOCITY_NON_DECREASING_DELTAS"] = "HIGH_VELOCITY_NON_DECREASING_DELTAS"; | ||
CHECK_RESULT_CODES["NON_DECREASING_DELTAS_OF_KNOWN_HUMAN"] = "NON_DECREASING_DELTAS_OF_KNOWN_HUMAN"; | ||
CHECK_RESULT_CODES["ANOMALY_INERTIA_JUMP"] = "ANOMALY_INERTIA_JUMP"; | ||
CHECK_RESULT_CODES["DELTA_MODULE_HAS_BEEN_INCREASING"] = "DELTA_MODULE_HAS_BEEN_INCREASING"; | ||
})(CHECK_RESULT_CODES || (CHECK_RESULT_CODES = {})); | ||
class Lethargy { | ||
/** The wheelDelta threshold. If an event has a wheelDelta below this value, it will not register */ | ||
/** The minimum `wheelDelta` value for an event to be registered. Events with a `wheelDelta` below this value are ignored. */ | ||
sensitivity; | ||
/** Threshold for the amount of time between wheel events for them to be deemed separate */ | ||
/** If this time in milliseconds has passed since the last event, the current event is assumed to be user-triggered. */ | ||
delay; | ||
/** Max percentage decay speed of an Inertia event */ | ||
inertiaDecay; | ||
/** Events with high `wheelDelta` usually decay quickly. If `wheelDelta` is above this threshold and doesn't decrease, it's assumed to be user-triggered. */ | ||
highVelocity; | ||
/** If delta has been increasing for this amount of consecutive events, the event is considered to be user-triggered. */ | ||
increasingDeltasThreshold; | ||
/** `[lastKnownHumanEvent, ...inertiaEvents]` */ | ||
previousEvents; | ||
/** Deltas above this are considered high velocity */ | ||
highVelocity; | ||
constructor({ sensitivity = 2, inertiaDecay = 20, delay = 100, highVelocity = 100, } = {}) { | ||
constructor({ sensitivity = 2, delay = 100, highVelocity = 100, increasingDeltasThreshold = 3, } = {}) { | ||
this.sensitivity = Math.max(1, sensitivity); | ||
this.inertiaDecay = Math.max(1, inertiaDecay); | ||
this.delay = Math.max(1, delay); | ||
this.highVelocity = Math.max(1, highVelocity); | ||
this.increasingDeltasThreshold = Math.max(2, increasingDeltasThreshold); | ||
// Reset inner state | ||
@@ -118,3 +93,4 @@ this.previousEvents = []; | ||
// Skip all checks | ||
if (event.timeStamp < previousEvent.timeStamp) { | ||
const isEventFromThePast = event.timeStamp < previousEvent.timeStamp; | ||
if (isEventFromThePast) { | ||
return { | ||
@@ -125,4 +101,5 @@ isHuman: true, | ||
} | ||
// Enough of time passed from the last event | ||
if (event.timeStamp > previousEvent.timeStamp + this.delay) { | ||
// Enough time has passed since the last event | ||
const isEnoughTimePassed = event.timeStamp > previousEvent.timeStamp + this.delay; | ||
if (isEnoughTimePassed) { | ||
return { | ||
@@ -135,40 +112,34 @@ isHuman: true, | ||
const previousBiggestDeltaModule = getBiggestDeltaModule(previousEvent); | ||
// Biggest delta module is bigger than previous delta module | ||
if (biggestDeltaModule > previousBiggestDeltaModule) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.DELTA_MODULE_IS_BIGGER, | ||
}; | ||
const isDeltaModuleNonDecreasing = biggestDeltaModule >= previousBiggestDeltaModule; | ||
if (isDeltaModuleNonDecreasing) { | ||
const isPreviousEventHuman = this.previousEvents.length === 1; | ||
// Previous event is human and the delta is non-decreasing | ||
if (isPreviousEventHuman) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.NON_DECREASING_DELTAS_OF_KNOWN_HUMAN, | ||
}; | ||
} | ||
// High velocity non-decreasing deltas are likely human | ||
const isHighVelocity = biggestDeltaModule >= this.highVelocity; | ||
if (isHighVelocity) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.HIGH_VELOCITY_NON_DECREASING_DELTAS, | ||
}; | ||
} | ||
// Delta has been increasing for the last `increasingDeltasThreshold` consecutive events | ||
const deltaHasBeenIncreasing = this.increasingDeltasThreshold <= 2 || | ||
(this.previousEvents.length >= this.increasingDeltasThreshold && | ||
this.previousEvents | ||
.slice(-this.increasingDeltasThreshold) | ||
.map(getBiggestDeltaModule) | ||
.every((delta, i, arr) => i === 0 || delta > arr[i - 1])); | ||
if (deltaHasBeenIncreasing) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.DELTA_MODULE_HAS_BEEN_INCREASING, | ||
}; | ||
} | ||
} | ||
// Vectors don't match | ||
if (!compareVectors(event, previousEvent)) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.VECTORS_DONT_MATCH, | ||
}; | ||
} | ||
// High velocity non-decreasing deltas are likely human | ||
if (biggestDeltaModule >= this.highVelocity && | ||
biggestDeltaModule === previousBiggestDeltaModule) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.HIGH_VELOCITY_NON_DECREASING_DELTAS, | ||
}; | ||
} | ||
const lastKnownHumanEvent = this.previousEvents[0]; | ||
// Non-decreasing deltas of known human event are likely human | ||
if (this.previousEvents.length === 1 && | ||
biggestDeltaModule === getBiggestDeltaModule(lastKnownHumanEvent)) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.NON_DECREASING_DELTAS_OF_KNOWN_HUMAN, | ||
}; | ||
} | ||
// If speed of delta's change suddenly jumped, it's likely human | ||
if (isAnomalyInertia(previousEvent, event, this.inertiaDecay)) { | ||
return { | ||
isHuman: true, | ||
reason: CHECK_RESULT_CODES.ANOMALY_INERTIA_JUMP, | ||
}; | ||
} | ||
// No human checks passed. It's probably inertia | ||
@@ -182,3 +153,3 @@ return { | ||
export { CHECK_RESULT_CODES, Lethargy, compareVectors, getBiggestDeltaModule, getDeltas, getSign, getWheelEvent, isAnomalyInertia }; | ||
export { CHECK_RESULT_CODES, Lethargy, getBiggestDeltaModule, getDeltas, getSign, getWheelEvent }; | ||
//# sourceMappingURL=index.js.map |
import type { LethargyConfig, WheelEventLike } from "./types.js"; | ||
export declare class Lethargy { | ||
/** The wheelDelta threshold. If an event has a wheelDelta below this value, it will not register */ | ||
/** The minimum `wheelDelta` value for an event to be registered. Events with a `wheelDelta` below this value are ignored. */ | ||
sensitivity: number; | ||
/** Threshold for the amount of time between wheel events for them to be deemed separate */ | ||
/** If this time in milliseconds has passed since the last event, the current event is assumed to be user-triggered. */ | ||
delay: number; | ||
/** Max percentage decay speed of an Inertia event */ | ||
inertiaDecay: number; | ||
/** Events with high `wheelDelta` usually decay quickly. If `wheelDelta` is above this threshold and doesn't decrease, it's assumed to be user-triggered. */ | ||
highVelocity: number; | ||
/** If delta has been increasing for this amount of consecutive events, the event is considered to be user-triggered. */ | ||
increasingDeltasThreshold: number; | ||
/** `[lastKnownHumanEvent, ...inertiaEvents]` */ | ||
private previousEvents; | ||
/** Deltas above this are considered high velocity */ | ||
private highVelocity; | ||
constructor({ sensitivity, inertiaDecay, delay, highVelocity, }?: LethargyConfig); | ||
constructor({ sensitivity, delay, highVelocity, increasingDeltasThreshold, }?: LethargyConfig); | ||
/** Checks whether the wheel event is an intent. | ||
@@ -15,0 +15,0 @@ * Remembers a passed event to compare future events with it */ |
@@ -9,6 +9,10 @@ /** [deltaX, deltaY, deltaZ] */ | ||
export interface LethargyConfig { | ||
/** The minimum `wheelDelta` value for an event to be registered. Events with a `wheelDelta` below this value are ignored. */ | ||
sensitivity?: number; | ||
inertiaDecay?: number; | ||
/** If this time in milliseconds has passed since the last event, the current event is assumed to be user-triggered. */ | ||
delay?: number; | ||
/** Events with high `wheelDelta` usually decay quickly. If `wheelDelta` is above this threshold and doesn't decrease, it's assumed to be user-triggered. */ | ||
highVelocity?: number; | ||
/** If `wheelDelta` has been increasing for this amount of consecutive events, the current event is assumed to be user-triggered. */ | ||
increasingDeltasThreshold?: number; | ||
} |
@@ -10,5 +10,1 @@ import type { Deltas, IWheelEvent, WheelEventLike } from "./types.js"; | ||
export declare const getSign: (num: number, treshhold?: number) => number; | ||
/** Returns true if two vectors are equal */ | ||
export declare const compareVectors: (e1: IWheelEvent, e2: IWheelEvent, treshhold?: number) => boolean; | ||
/** If e2 event is inertia, it's delta will be no more than threshold slower */ | ||
export declare const isAnomalyInertia: (e1: IWheelEvent, e2: IWheelEvent, threshold?: number) => boolean; |
{ | ||
"name": "lethargy-ts", | ||
"version": "0.0.6-beta.0", | ||
"version": "0.0.6-beta.1", | ||
"description": "Distinguish between scroll events initiated by the user, and those by inertial scrolling", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/snelsi/lethargy-ts", |
@@ -42,3 +42,3 @@ # ⭐ Lethargy-TS | ||
You can customize the sensitivity, delay, and inertia decay parameters to better match your application's needs: | ||
You can customize the sensitivity, delay, and [other parameters](https://github.com/snelsi/lethargy-ts/blob/master/src/types.ts) to better match your application's needs: | ||
@@ -49,3 +49,4 @@ ```tsx | ||
delay: 100, | ||
inertiaDecay: 20, | ||
highVelocity: 100, | ||
increasingDeltasThreshold: 3, | ||
}); | ||
@@ -78,6 +79,8 @@ ``` | ||
- `delay` - Threshold for the amount of time between wheel events for them to be deemed separate. | ||
- `delay` - If there was a pause of this amount of milliseconds between two events, the current event is assumed to be user-triggered. | ||
- `inertiaDecay` - Inertia event may be no more than this percent smaller than the previous event. | ||
- `highVelocity` - Events with high `wheelDelta` usually decay quickly. If `wheelDelta` is above this threshold and doesn't decrease, it's assumed to be user-triggered. | ||
- `increasingDeltasThreshold` - If `wheelDelta` has been increasing for this amount of consecutive events, the current event is assumed to be user-triggered. | ||
## What problem does it solve? | ||
@@ -93,12 +96,8 @@ | ||
- The delta of the event is bigger than the delta of the previous event. | ||
- The delta of the event doesn't decrease and immediately follows a known human event. | ||
- The vector of the event differs from the previous event. | ||
- The delta of the event doesn't decrease and has a high velocity. | ||
- The delta of the event has a high velocity and doesn't decrease. | ||
- The delta of the event has been increasing for `n` consecutive events. | ||
- The delta of the event doesn't decrease and immediately follows a known human event. | ||
- The speed of the delta's change suddenly jumped. | ||
If any of these checks are true, the event is considered intentional. Otherwise, it is considered to be initiated by inertial scrolling. | ||
@@ -105,0 +104,0 @@ |
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
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
0
29235
217
123