diff --git a/dist/index.cjs b/dist/index.cjs
index f5f96b3..b80be33 100644
--- a/dist/index.cjs
+++ b/dist/index.cjs
@@ -344,6 +344,8 @@ function getController$1 (config) {
};
}
+const MOVEMENT_RESET_DELAY = 1e3 / 60 * 3; // == 50 (3 frames in 60fps)
+
/**
* @class Pointer
* @param {PointerConfig} config
@@ -409,15 +411,19 @@ class Pointer {
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;
const _measure = (event) => {
- this.progress.x = this.config.root ? event.offsetX : event.x;
- this.progress.y = this.config.root ? event.offsetY : event.y;
- this.progress.vx = event.movementX;
- this.progress.vy = event.movementY;
+ const newX = this.config.root ? event.offsetX : event.x;
+ const newY = this.config.root ? event.offsetY : event.y;
+ this.progress.vx = newX - this.progress.x;
+ this.progress.vy = newY - this.progress.y;
+ this.progress.x = newX;
+ this.progress.y = newY;
this._nextTick = trigger();
};
this._pointerLeave = () => {
this.progress.active = false;
+ this.progress.vx = 0;
+ this.progress.vy = 0;
this._nextTick = trigger();
};
@@ -434,8 +440,6 @@ class Pointer {
cancelable: true,
clientX: e.x * DPR,
clientY: e.y * DPR,
- movementX: e.movementX * DPR,
- movementY: e.movementY * DPR,
});
e.stopPropagation();
@@ -481,11 +485,18 @@ class Pointer {
const duration = this.config.transitionDuration;
const easing = this.config.transitionEasing || ((p) => p);
const now = performance.now();
+ let resetMovement = false;
const tick = (time) => {
const p = (time - this._startTime) / duration;
const t = easing(Math.min(1, p));
+ if (resetMovement) {
+ this.progress.vx = 0;
+ this.progress.vy = 0;
+ resetMovement = false;
+ }
+
this.currentProgress = Object.entries(this.progress).reduce((acc, [key, value]) => {
if (key === 'active') {
acc[key] = value;
@@ -497,9 +508,9 @@ class Pointer {
if (p < 1) {
this._nextTransitionTick = requestAnimationFrame(tick);
- } else {
- this.currentProgress.vx = 0;
- this.currentProgress.vy = 0;
+
+ // reset movement on next frame
+ resetMovement = time - this._startTime > MOVEMENT_RESET_DELAY;
}
this.effect.tick(this.currentProgress);
diff --git a/docs/demo/index.html b/docs/demo/index.html
index c140183..bdf0753 100644
--- a/docs/demo/index.html
+++ b/docs/demo/index.html
@@ -28,8 +28,8 @@
#target {
box-sizing: border-box;
width: 40px;
- margin: -20px 0 0 -20px;
- /*margin: calc(25% - 20px) 0 0 calc(50% - 20px);*/
+ /*margin: -20px 0 0 -20px;*/
+ margin: calc(25% - 20px) 0 0 calc(50% - 20px);
aspect-ratio: 1;
border: 10px solid #007bff;
border-radius: 50%;
@@ -37,7 +37,7 @@
0 0 6px rgb(0 0 0 / 50%),
inset 0 0 4px rgb(0 0 0 / 50%);
pointer-events: none;
- /*transition: transform 1s linear;*/
+ /*transition: transform 0.5s linear;*/
}
#cover {
@@ -66,6 +66,7 @@
+
@@ -84,11 +85,12 @@
const vxmax = document.getElementById('vxmax');
const vy = document.getElementById('vy');
const vymax = document.getElementById('vymax');
+ const active = document.getElementById('active');
let vxmaxValue = 0;
let vymaxValue = 0;
- function log (p, v) {
+ function log (p, v, isActive) {
x.innerText = `X: ${p.x}`;
y.innerText = `Y: ${p.y}`;
vx.innerText = `Vx: ${v.x}`;
@@ -97,21 +99,24 @@
vymaxValue = Math.max(vymaxValue, v.y);
vxmax.innerText = `Vx Max: ${vxmaxValue}`;
vymax.innerText = `Vy Max: ${vymaxValue}`;
+ active.innerText = `Active: ${isActive}`;
}
const WIDTH = root.clientWidth;
const HEIGHT = root.clientHeight;
const pointer = new Pointer({
root,
+ allowActiveEvent: true,
scenes: [{
target,
- effect: (scene, p, v) => {
- log(p, v);
- target.style.transform = `translate(${p.x * WIDTH}px, ${p.y * HEIGHT}px)`;
- // target.style.transform = `translate(${v.x * 5}px, ${v.y * 5}px)`;
+ effect: (scene, p, v, isActive) => {
+ log(p, v, isActive);
+ // target.style.transform = `translate(${p.x * WIDTH}px, ${p.y * HEIGHT}px)`;
+ target.style.transform = `translate(${v.x * 5}px, ${v.y * 5}px)`;
}
}],
- transitionDuration: 1000,
+ // noThrottle: true,
+ transitionDuration: 500,
transitionEasing: (t) => 1 - (1 - t) ** 2, // quadOut
});
diff --git a/docs/demo/index.js b/docs/demo/index.js
index 3b48f53..78a703b 100644
--- a/docs/demo/index.js
+++ b/docs/demo/index.js
@@ -342,6 +342,8 @@ function getController$1 (config) {
};
}
+const MOVEMENT_RESET_DELAY = 1e3 / 60 * 3; // 3 frames
+
/**
* @class Pointer
* @param {PointerConfig} config
@@ -407,15 +409,19 @@ class Pointer {
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;
const _measure = (event) => {
- this.progress.x = this.config.root ? event.offsetX : event.x;
- this.progress.y = this.config.root ? event.offsetY : event.y;
- this.progress.vx = event.movementX;
- this.progress.vy = event.movementY;
+ const newX = this.config.root ? event.offsetX : event.x;
+ const newY = this.config.root ? event.offsetY : event.y;
+ this.progress.vx = newX - this.progress.x;
+ this.progress.vy = newY - this.progress.y;
+ this.progress.x = newX;
+ this.progress.y = newY;
this._nextTick = trigger();
};
this._pointerLeave = () => {
this.progress.active = false;
+ this.progress.vx = 0;
+ this.progress.vy = 0;
this._nextTick = trigger();
};
@@ -432,8 +438,6 @@ class Pointer {
cancelable: true,
clientX: e.x * DPR,
clientY: e.y * DPR,
- movementX: e.movementX * DPR,
- movementY: e.movementY * DPR,
});
e.stopPropagation();
@@ -479,11 +483,18 @@ class Pointer {
const duration = this.config.transitionDuration;
const easing = this.config.transitionEasing || ((p) => p);
const now = performance.now();
+ let resetMovement = false;
const tick = (time) => {
const p = (time - this._startTime) / duration;
const t = easing(Math.min(1, p));
+ if (resetMovement) {
+ this.progress.vx = 0;
+ this.progress.vy = 0;
+ resetMovement = false;
+ }
+
this.currentProgress = Object.entries(this.progress).reduce((acc, [key, value]) => {
if (key === 'active') {
acc[key] = value;
@@ -495,9 +506,9 @@ class Pointer {
if (p < 1) {
this._nextTransitionTick = requestAnimationFrame(tick);
- } else {
- this.currentProgress.vx = 0;
- this.currentProgress.vy = 0;
+
+ // reset movement on next frame
+ resetMovement = time - this._startTime > MOVEMENT_RESET_DELAY;
}
this.effect.tick(this.currentProgress);
diff --git a/package.json b/package.json
index 7195911..431ac37 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "kuliso",
- "version": "0.4.5",
+ "version": "0.4.6",
"sideeffects": true,
"description": "Tiny library for performant pointer-driven or gyroscope-driven effects",
"main": "dist/index.cjs",
diff --git a/src/Pointer.js b/src/Pointer.js
index bf8c35a..9d599ac 100644
--- a/src/Pointer.js
+++ b/src/Pointer.js
@@ -1,6 +1,8 @@
import { getController } from './controller.js';
import { frameThrottle, testPointerOffsetDprBug } from './utilities.js';
+const MOVEMENT_RESET_DELAY = 1e3 / 60 * 3; // == 50 (3 frames in 60fps)
+
/**
* @class Pointer
* @param {PointerConfig} config
@@ -66,15 +68,19 @@ export class Pointer {
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;
const _measure = (event) => {
- this.progress.x = this.config.root ? event.offsetX : event.x;
- this.progress.y = this.config.root ? event.offsetY : event.y;
- this.progress.vx = event.movementX;
- this.progress.vy = event.movementY;
+ const newX = this.config.root ? event.offsetX : event.x;
+ const newY = this.config.root ? event.offsetY : event.y;
+ this.progress.vx = newX - this.progress.x;
+ this.progress.vy = newY - this.progress.y;
+ this.progress.x = newX;
+ this.progress.y = newY;
this._nextTick = trigger();
};
this._pointerLeave = () => {
this.progress.active = false;
+ this.progress.vx = 0;
+ this.progress.vy = 0;
this._nextTick = trigger();
};
@@ -91,8 +97,6 @@ export class Pointer {
cancelable: true,
clientX: e.x * DPR,
clientY: e.y * DPR,
- movementX: e.movementX * DPR,
- movementY: e.movementY * DPR,
});
e.stopPropagation();
@@ -138,11 +142,18 @@ export class Pointer {
const duration = this.config.transitionDuration;
const easing = this.config.transitionEasing || ((p) => p);
const now = performance.now();
+ let resetMovement = false;
const tick = (time) => {
const p = (time - this._startTime) / duration;
const t = easing(Math.min(1, p));
+ if (resetMovement) {
+ this.progress.vx = 0;
+ this.progress.vy = 0;
+ resetMovement = false;
+ }
+
this.currentProgress = Object.entries(this.progress).reduce((acc, [key, value]) => {
if (key === 'active') {
acc[key] = value;
@@ -154,9 +165,9 @@ export class Pointer {
if (p < 1) {
this._nextTransitionTick = requestAnimationFrame(tick);
- } else {
- this.currentProgress.vx = 0;
- this.currentProgress.vy = 0;
+
+ // reset movement on next frame
+ resetMovement = time - this._startTime > MOVEMENT_RESET_DELAY;
}
this.effect.tick(this.currentProgress);