PullDownToRefresh: fix trigger many refreshings
This commit fixes that the wheel event path may trigger too many refreshings.
This commit is contained in:
parent
40a785a538
commit
ee39cf8651
1 changed files with 13 additions and 11 deletions
|
@ -28,11 +28,13 @@ const PullDownToRefresh: Component<{
|
|||
let rootElement: HTMLDivElement;
|
||||
const [pullDown, setPullDown] = createSignal(0);
|
||||
|
||||
const pullDownDistance = () => {
|
||||
const stopPos = () => 160
|
||||
|
||||
const indicatorOfsY = () => {
|
||||
if (props.loading) {
|
||||
return 140;
|
||||
return stopPos() * 0.875;
|
||||
}
|
||||
return Math.max(Math.min(160, pullDown()), 0);
|
||||
return pullDown();
|
||||
};
|
||||
|
||||
const obvx = createVisibilityObserver({
|
||||
|
@ -55,7 +57,7 @@ const PullDownToRefresh: Component<{
|
|||
const vspring = holding ? 0 : K * x * dt;
|
||||
v = ds / dt - vspring;
|
||||
|
||||
setPullDown(x + v * dt);
|
||||
setPullDown(Math.max(Math.min(x + v * dt, stopPos()), 0));
|
||||
|
||||
if (Math.abs(x) > 1 || Math.abs(v) > 1) {
|
||||
requestAnimationFrame(updatePullDown);
|
||||
|
@ -66,12 +68,11 @@ const PullDownToRefresh: Component<{
|
|||
|
||||
if (
|
||||
!holding &&
|
||||
untrack(pullDownDistance) >= 160 &&
|
||||
untrack(pullDown) >= stopPos() &&
|
||||
!props.loading &&
|
||||
props.onRefresh
|
||||
) {
|
||||
setTimeout(props.onRefresh, 0);
|
||||
// FIXME: this may trigger at multiple frames
|
||||
}
|
||||
} finally {
|
||||
ds = 0;
|
||||
|
@ -91,11 +92,12 @@ const PullDownToRefresh: Component<{
|
|||
if (scrollTop >= 0 && scrollTop < 1) {
|
||||
event.preventDefault()
|
||||
ds = -(event.deltaY / window.devicePixelRatio / 2);
|
||||
holding = true;
|
||||
holding = untrack(pullDown) < stopPos();
|
||||
if (wheelTimeout) {
|
||||
clearTimeout(wheelTimeout);
|
||||
}
|
||||
wheelTimeout = setTimeout(onWheelNotUpdated, 200);
|
||||
|
||||
if (released) {
|
||||
released = false;
|
||||
requestAnimationFrame(updatePullDown);
|
||||
|
@ -130,7 +132,7 @@ const PullDownToRefresh: Component<{
|
|||
}
|
||||
holding = true;
|
||||
if (lastTouchScreenY !== 0) {
|
||||
ds = (item.screenY - lastTouchScreenY) / window.devicePixelRatio;
|
||||
ds = (item.screenY - lastTouchScreenY) ;
|
||||
}
|
||||
lastTouchScreenY = item.screenY;
|
||||
if (released) {
|
||||
|
@ -143,7 +145,7 @@ const PullDownToRefresh: Component<{
|
|||
lastTouchId = undefined;
|
||||
lastTouchScreenY = 0;
|
||||
holding = false;
|
||||
if (untrack(pullDownDistance) >= 160 && !props.loading && props.onRefresh) {
|
||||
if (untrack(indicatorOfsY) >= 160 && !props.loading && props.onRefresh) {
|
||||
setTimeout(props.onRefresh, 0);
|
||||
} else {
|
||||
if (released) {
|
||||
|
@ -185,14 +187,14 @@ const PullDownToRefresh: Component<{
|
|||
aspect-ratio: 1/1;
|
||||
width: 2rem;
|
||||
color: var(--tutu-color-primary);
|
||||
transform: translateY(${`${pullDownDistance() - 2}px`});
|
||||
transform: translateY(${`${indicatorOfsY() - 2}px`});
|
||||
will-change: transform;
|
||||
z-index: var(--tutu-zidx-nav);
|
||||
background-color: var(--tutu-color-surface);
|
||||
|
||||
> :global(.refresh-icon) {
|
||||
transform: rotate(
|
||||
${`${((pullDownDistance() / 160) * 180).toString()}deg`}
|
||||
${`${((indicatorOfsY() / 160) * 180).toString()}deg`}
|
||||
);
|
||||
will-change: transform;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue