Skip to content

Commit

Permalink
Fix webkit scroll offset bug (#17)
Browse files Browse the repository at this point in the history
* Fixed WebKit bug with synthetic pointer events not accounting for window.scroll offset

* 0.4.7
  • Loading branch information
ydaniv authored Feb 17, 2025
1 parent 8ed7008 commit 6f83f9c
Show file tree
Hide file tree
Showing 7 changed files with 317 additions and 25 deletions.
62 changes: 57 additions & 5 deletions dist/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,56 @@ function testPointerOffsetDprBug () {
return fixRequired;
}

function testPointerOffsetScrollBug () {
return new Promise((resolve) => {
function scrollHandler () {
if (window.scrollY > 0) {
window.removeEventListener('scroll', scrollHandler);

let fixRequired = false;

document.body.addEventListener('pointerdown', (e) => {
fixRequired = e.clientY === e.pageY;
}, { once: true });

const event = new PointerEvent('pointerdown', {
clientX: 10
});

document.body.dispatchEvent(event);

resolve(fixRequired);
}
}

if (window.scrollY > 0) {
scrollHandler();
}

window.addEventListener('scroll', scrollHandler);
});
}

/**
* @see https://bugs.webkit.org/show_bug.cgi?id=287799
*/
function getScrollOffsetsForWebKitPointerBug () {
function scrollHandler () {
scrollOffsets.x = window.scrollX;
scrollOffsets.y = window.scrollY;
}

const scrollOffsets = { x: 0, y: 0, scrollHandler };

testPointerOffsetScrollBug().then((fixRequired) => {
if (fixRequired) {
window.addEventListener('scroll', scrollHandler);
}
});

return scrollOffsets;
}

let listeners = 0;
const pointers = new Set();

Expand Down Expand Up @@ -407,9 +457,6 @@ class Pointer {
this.previousProgress = { ...this.progress };
this.currentProgress = null;

const shouldFixSynthPointer = testPointerOffsetDprBug();
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;

const _measure = (event) => {
const newX = this.config.root ? event.offsetX : event.x;
const newY = this.config.root ? event.offsetY : event.y;
Expand All @@ -433,13 +480,18 @@ class Pointer {
};

if (this.config.root) {
const shouldFixSynthPointer = testPointerOffsetDprBug();
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;

const scrollOffset = getScrollOffsetsForWebKitPointerBug();

this._measure = (e) => {
if (e.target !== this.config.root) {
const event = new PointerEvent('pointermove', {
bubbles: true,
cancelable: true,
clientX: e.x * DPR,
clientY: e.y * DPR,
clientX: e.x * DPR + scrollOffset.x,
clientY: e.y * DPR + scrollOffset.y,
});

e.stopPropagation();
Expand Down
9 changes: 5 additions & 4 deletions docs/demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
body {
margin: 0;
padding: 0;
height: 200vh;
}

main {
Expand All @@ -28,8 +29,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%;
Expand Down Expand Up @@ -111,8 +112,8 @@
target,
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)`;
target.style.transform = `translate(${p.x * WIDTH}px, ${p.y * HEIGHT}px)`;
// target.style.transform = `translate(${v.x * 5}px, ${v.y * 5}px)`;
}
}],
// noThrottle: true,
Expand Down
64 changes: 58 additions & 6 deletions docs/demo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,56 @@ function testPointerOffsetDprBug () {
return fixRequired;
}

function testPointerOffsetScrollBug () {
return new Promise((resolve) => {
function scrollHandler () {
if (window.scrollY > 0) {
window.removeEventListener('scroll', scrollHandler);

let fixRequired = false;

document.body.addEventListener('pointerdown', (e) => {
fixRequired = e.clientY === e.pageY;
}, { once: true });

const event = new PointerEvent('pointerdown', {
clientX: 10
});

document.body.dispatchEvent(event);

resolve(fixRequired);
}
}

if (window.scrollY > 0) {
scrollHandler();
}

window.addEventListener('scroll', scrollHandler);
});
}

/**
* @see https://bugs.webkit.org/show_bug.cgi?id=287799
*/
function getScrollOffsetsForWebKitPointerBug () {
function scrollHandler () {
scrollOffsets.x = window.scrollX;
scrollOffsets.y = window.scrollY;
}

const scrollOffsets = { x: 0, y: 0, scrollHandler };

testPointerOffsetScrollBug().then((fixRequired) => {
if (fixRequired) {
window.addEventListener('scroll', scrollHandler);
}
});

return scrollOffsets;
}

let listeners = 0;
const pointers = new Set();

Expand Down Expand Up @@ -342,7 +392,7 @@ function getController$1 (config) {
};
}

const MOVEMENT_RESET_DELAY = 1e3 / 60 * 3; // 3 frames
const MOVEMENT_RESET_DELAY = 1e3 / 60 * 3; // == 50 (3 frames in 60fps)

/**
* @class Pointer
Expand Down Expand Up @@ -405,9 +455,6 @@ class Pointer {
this.previousProgress = { ...this.progress };
this.currentProgress = null;

const shouldFixSynthPointer = testPointerOffsetDprBug();
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;

const _measure = (event) => {
const newX = this.config.root ? event.offsetX : event.x;
const newY = this.config.root ? event.offsetY : event.y;
Expand All @@ -431,13 +478,18 @@ class Pointer {
};

if (this.config.root) {
const shouldFixSynthPointer = testPointerOffsetDprBug();
const DPR = shouldFixSynthPointer ? window.devicePixelRatio : 1;

const scrollOffset = getScrollOffsetsForWebKitPointerBug();

this._measure = (e) => {
if (e.target !== this.config.root) {
const event = new PointerEvent('pointermove', {
bubbles: true,
cancelable: true,
clientX: e.x * DPR,
clientY: e.y * DPR,
clientX: e.x * DPR + scrollOffset.x,
clientY: e.y * DPR + scrollOffset.y,
});

e.stopPropagation();
Expand Down
138 changes: 136 additions & 2 deletions docs/reference/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset='utf-8'>
<title>kuliso 0.4.2 | Documentation</title>
<title>kuliso 0.4.6 | Documentation</title>
<meta name='description' content='Tiny library for performant pointer-driven or gyroscope-driven effects'>
<meta name='viewport' content='width=device-width,initial-scale=1'>
<link href='assets/bass.css' rel='stylesheet'>
Expand All @@ -15,7 +15,7 @@
<div id='split-left' class='overflow-auto fs0 height-viewport-100'>
<div class='py1 px2'>
<h3 class='mb0 no-anchor'>kuliso</h3>
<div class='mb1'><code>0.4.2</code></div>
<div class='mb1'><code>0.4.6</code></div>
<input
placeholder='Filter'
id='filter-input'
Expand Down Expand Up @@ -313,6 +313,26 @@ <h3 class='mb0 no-anchor'>kuliso</h3>

</li>


<li><a
href='#testpointeroffsetdprbug'
class="">
testPointerOffsetDprBug

</a>

</li>


<li><a
href='#getscrolloffsetsforwebkitpointerbug'
class="">
getScrollOffsetsForWebKitPointerBug

</a>

</li>

</ul>
</div>
<div class='mt1 h6 quiet'>
Expand Down Expand Up @@ -2430,6 +2450,120 @@ <h3 class='fl m0' id='destroy'>












</section>




<section class='p2 mb2 clearfix bg-white minishadow'>


<div class='clearfix'>

<h3 class='fl m0' id='testpointeroffsetdprbug'>
testPointerOffsetDprBug
</h3>


</div>



<div class='pre p1 fill-light mt0'>testPointerOffsetDprBug()</div>

















<div class='py1 quiet mt1 prose-big'>Related</div>


<a href="https://issues.chromium.org/issues/40887601?pli=1">https://issues.chromium.org/issues/40887601?pli=1</a>
















</section>




<section class='p2 mb2 clearfix bg-white minishadow'>


<div class='clearfix'>

<h3 class='fl m0' id='getscrolloffsetsforwebkitpointerbug'>
getScrollOffsetsForWebKitPointerBug
</h3>


</div>



<div class='pre p1 fill-light mt0'>getScrollOffsetsForWebKitPointerBug()</div>

















<div class='py1 quiet mt1 prose-big'>Related</div>


<a href="https://bugs.webkit.org/show_bug.cgi?id=287799">https://bugs.webkit.org/show_bug.cgi?id=287799</a>










Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kuliso",
"version": "0.4.6",
"version": "0.4.7",
"sideeffects": true,
"description": "Tiny library for performant pointer-driven or gyroscope-driven effects",
"main": "dist/index.cjs",
Expand Down
Loading

0 comments on commit 6f83f9c

Please sign in to comment.