Skip to content

Commit bd23982

Browse files
committed
work
1 parent f50bbdf commit bd23982

9 files changed

Lines changed: 207 additions & 26 deletions

File tree

packages/frontend/navi/dist/dev/jsenv_navi.js

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27871,7 +27871,7 @@ installImportMetaCssBuild(import.meta);
2787127871

2787227872
/**
2787327873
* The window two pages are seen through while one replaces the other, measured
27874-
* once and published for the length of the movement.
27874+
* at the one moment both exist and published for the length of the movement.
2787527875
*
2787627876
* Both ways of moving from one route to another need the same numbers, so they
2787727877
* are written under the same names and read by the same CSS formulas —
@@ -27896,6 +27896,18 @@ installImportMetaCssBuild(import.meta);
2789627896
* in the window — one page is scrolled and the other is not, one has a top
2789727897
* bar over it and the other has the screen. Each picture is placed at its
2789827898
* own corner inside the window.
27899+
* - **where the arriving state IS, frame after frame.** The browser places the
27900+
* group from the live arriving element on every frame of the movement — that
27901+
* is what makes a picture pair follow an element that moves — and the
27902+
* formula that moves the group back to the window's corner cancels that
27903+
* placement with this corner. Read once, the two stop cancelling the moment
27904+
* anything scrolls the document under the movement (a slice landing and
27905+
* putting a row back, a list placing its default row, a height growing under
27906+
* a restored offset): the window drifts by as much, and both pictures with
27907+
* it — the photograph of the page being left included. So this corner alone
27908+
* is kept live, as often as the browser reads its side of it. It is also
27909+
* the arriving picture's own corner, which then stays where the page really
27910+
* is and lands with no jump when the pictures are dropped.
2789927911
* - **the band the state being left kept free**, next to the one the arriving
2790027912
* state keeps free. A band is furniture — a fixed bar, a sticky row — and
2790127913
* the pictures are cut at it so they are not watched painting over it. Read
@@ -27905,8 +27917,11 @@ installImportMetaCssBuild(import.meta);
2790527917
* at the one moment the state being left still exists, the cut can be taken
2790627918
* at what is furniture on BOTH sides (see the clip formulas).
2790727919
*
27908-
* Only the measuring needs JS, and only for the one moment both states exist:
27909-
* the page arriving is in the DOM and the transition has not started playing.
27920+
* Only the measuring needs JS, and apart from the arriving corner it happens
27921+
* at the one moment both states exist: the page arriving is in the DOM and the
27922+
* transition has not started playing. The window, the corner of the state
27923+
* being left and its band describe a state that no longer exists, and reading
27924+
* them again is what must never happen.
2791027925
* Everything DERIVED from these numbers — the band a fixed bar covers, how far
2791127926
* a page travels — is derived in CSS, so the application's own numbers (the
2791227927
* room its bars give back, see layout/safe_area.js; what covers the box from
@@ -28007,6 +28022,8 @@ const WINDOW_PROPERTIES = [
2800728022
// after another has replaced it must not wipe numbers the new one is standing
2800828023
// on.
2800928024
let windowOwner = null;
28025+
// Stops re-reading the arriving state's corner, when a movement is on.
28026+
let unfollowArrivingState = null;
2801028027

2801128028
/**
2801228029
* The state being left, taken while rendering is held — the page arriving is
@@ -28052,6 +28069,7 @@ const holdTransitionWindow = (owner, element, stateBefore) => {
2805228069
style.setProperty(OLD_BAND_RIGHT_PROPERTY, `${oldBand.right}px`);
2805328070
style.setProperty(OLD_BAND_BOTTOM_PROPERTY, `${oldBand.bottom}px`);
2805428071
style.setProperty(OLD_BAND_LEFT_PROPERTY, `${oldBand.left}px`);
28072+
followArrivingState(element, rectAfter);
2805528073
};
2805628074

2805728075
// The live layout takes the box back. A discontinuity by construction — the
@@ -28063,12 +28081,45 @@ const releaseTransitionWindow = (owner) => {
2806328081
return;
2806428082
}
2806528083
windowOwner = null;
28084+
if (unfollowArrivingState) {
28085+
unfollowArrivingState();
28086+
}
2806628087
const { style } = document.documentElement;
2806728088
for (const property of WINDOW_PROPERTIES) {
2806828089
style.removeProperty(property);
2806928090
}
2807028091
};
2807128092

28093+
// The arriving state's corner, re-read every frame — as often as the browser
28094+
// refreshes the group's placement from the same element (see the top of the
28095+
// file). Requested, never awaited: the first call runs inside the update
28096+
// callback, where a frame cannot come. Written only when it moved: a custom
28097+
// property set on the root recomputes the style of the whole document.
28098+
const followArrivingState = (element, rectAtHold) => {
28099+
if (unfollowArrivingState) {
28100+
unfollowArrivingState();
28101+
}
28102+
const { style } = document.documentElement;
28103+
let top = rectAtHold.top;
28104+
let left = rectAtHold.left;
28105+
let frame = requestAnimationFrame(function read() {
28106+
const rect = element.getBoundingClientRect();
28107+
if (rect.top !== top) {
28108+
top = rect.top;
28109+
style.setProperty(WINDOW_NEW_TOP_PROPERTY, `${top}px`);
28110+
}
28111+
if (rect.left !== left) {
28112+
left = rect.left;
28113+
style.setProperty(WINDOW_NEW_LEFT_PROPERTY, `${left}px`);
28114+
}
28115+
frame = requestAnimationFrame(read);
28116+
});
28117+
unfollowArrivingState = () => {
28118+
unfollowArrivingState = null;
28119+
cancelAnimationFrame(frame);
28120+
};
28121+
};
28122+
2807228123
// A band nothing can be wider than, published for an edge nothing is known
2807328124
// about: taken as the smaller of the two, it leaves the live band standing on
2807428125
// its own, which is the movement navi played before it knew any of this.
@@ -76098,6 +76149,14 @@ function WheelUI(props) {
7609876149
if (trackedItemsRef.current.length === 0) {
7609976150
return;
7610076151
}
76152+
// Without a box (display: none, rows not laid out yet) every position below
76153+
// multiplies by an item size of 0: nothing can be placed. Leave
76154+
// centeredIndexRef null rather than claim a row is centered, so the render
76155+
// that brings the wheel back on screen doesn't read it as "already there".
76156+
if (getItemSize(viewportEl) === 0) {
76157+
centeredIndexRef.current = null;
76158+
return;
76159+
}
7610176160
let selectedIndex = getIndexForValue(currentValueRef.current);
7610276161
if (selectedIndex < 0) {
7610376162
selectedIndex = 0;
@@ -76144,7 +76203,7 @@ function WheelUI(props) {
7614476203
const requestedBehavior = pendingBehaviorRef.current;
7614576204
pendingBehaviorRef.current = null;
7614676205
const viewportEl = getViewport();
76147-
if (!viewportEl || viewportEl.offsetParent === null) {
76206+
if (!viewportEl) {
7614876207
return;
7614976208
}
7615076209
let behavior = "auto";

packages/frontend/navi/dist/dev/jsenv_navi.js.map

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/frontend/navi/dist/jsenv_navi.js

Lines changed: 63 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27435,7 +27435,7 @@ installImportMetaCssBuild(import.meta);
2743527435

2743627436
/**
2743727437
* The window two pages are seen through while one replaces the other, measured
27438-
* once and published for the length of the movement.
27438+
* at the one moment both exist and published for the length of the movement.
2743927439
*
2744027440
* Both ways of moving from one route to another need the same numbers, so they
2744127441
* are written under the same names and read by the same CSS formulas —
@@ -27460,6 +27460,18 @@ installImportMetaCssBuild(import.meta);
2746027460
* in the window — one page is scrolled and the other is not, one has a top
2746127461
* bar over it and the other has the screen. Each picture is placed at its
2746227462
* own corner inside the window.
27463+
* - **where the arriving state IS, frame after frame.** The browser places the
27464+
* group from the live arriving element on every frame of the movement — that
27465+
* is what makes a picture pair follow an element that moves — and the
27466+
* formula that moves the group back to the window's corner cancels that
27467+
* placement with this corner. Read once, the two stop cancelling the moment
27468+
* anything scrolls the document under the movement (a slice landing and
27469+
* putting a row back, a list placing its default row, a height growing under
27470+
* a restored offset): the window drifts by as much, and both pictures with
27471+
* it — the photograph of the page being left included. So this corner alone
27472+
* is kept live, as often as the browser reads its side of it. It is also
27473+
* the arriving picture's own corner, which then stays where the page really
27474+
* is and lands with no jump when the pictures are dropped.
2746327475
* - **the band the state being left kept free**, next to the one the arriving
2746427476
* state keeps free. A band is furniture — a fixed bar, a sticky row — and
2746527477
* the pictures are cut at it so they are not watched painting over it. Read
@@ -27469,8 +27481,11 @@ installImportMetaCssBuild(import.meta);
2746927481
* at the one moment the state being left still exists, the cut can be taken
2747027482
* at what is furniture on BOTH sides (see the clip formulas).
2747127483
*
27472-
* Only the measuring needs JS, and only for the one moment both states exist:
27473-
* the page arriving is in the DOM and the transition has not started playing.
27484+
* Only the measuring needs JS, and apart from the arriving corner it happens
27485+
* at the one moment both states exist: the page arriving is in the DOM and the
27486+
* transition has not started playing. The window, the corner of the state
27487+
* being left and its band describe a state that no longer exists, and reading
27488+
* them again is what must never happen.
2747427489
* Everything DERIVED from these numbers — the band a fixed bar covers, how far
2747527490
* a page travels — is derived in CSS, so the application's own numbers (the
2747627491
* room its bars give back, see layout/safe_area.js; what covers the box from
@@ -27571,6 +27586,8 @@ const WINDOW_PROPERTIES = [
2757127586
// after another has replaced it must not wipe numbers the new one is standing
2757227587
// on.
2757327588
let windowOwner = null;
27589+
// Stops re-reading the arriving state's corner, when a movement is on.
27590+
let unfollowArrivingState = null;
2757427591

2757527592
/**
2757627593
* The state being left, taken while rendering is held — the page arriving is
@@ -27616,6 +27633,7 @@ const holdTransitionWindow = (owner, element, stateBefore) => {
2761627633
style.setProperty(OLD_BAND_RIGHT_PROPERTY, `${oldBand.right}px`);
2761727634
style.setProperty(OLD_BAND_BOTTOM_PROPERTY, `${oldBand.bottom}px`);
2761827635
style.setProperty(OLD_BAND_LEFT_PROPERTY, `${oldBand.left}px`);
27636+
followArrivingState(element, rectAfter);
2761927637
};
2762027638

2762127639
// The live layout takes the box back. A discontinuity by construction — the
@@ -27627,12 +27645,45 @@ const releaseTransitionWindow = (owner) => {
2762727645
return;
2762827646
}
2762927647
windowOwner = null;
27648+
if (unfollowArrivingState) {
27649+
unfollowArrivingState();
27650+
}
2763027651
const { style } = document.documentElement;
2763127652
for (const property of WINDOW_PROPERTIES) {
2763227653
style.removeProperty(property);
2763327654
}
2763427655
};
2763527656

27657+
// The arriving state's corner, re-read every frame — as often as the browser
27658+
// refreshes the group's placement from the same element (see the top of the
27659+
// file). Requested, never awaited: the first call runs inside the update
27660+
// callback, where a frame cannot come. Written only when it moved: a custom
27661+
// property set on the root recomputes the style of the whole document.
27662+
const followArrivingState = (element, rectAtHold) => {
27663+
if (unfollowArrivingState) {
27664+
unfollowArrivingState();
27665+
}
27666+
const { style } = document.documentElement;
27667+
let top = rectAtHold.top;
27668+
let left = rectAtHold.left;
27669+
let frame = requestAnimationFrame(function read() {
27670+
const rect = element.getBoundingClientRect();
27671+
if (rect.top !== top) {
27672+
top = rect.top;
27673+
style.setProperty(WINDOW_NEW_TOP_PROPERTY, `${top}px`);
27674+
}
27675+
if (rect.left !== left) {
27676+
left = rect.left;
27677+
style.setProperty(WINDOW_NEW_LEFT_PROPERTY, `${left}px`);
27678+
}
27679+
frame = requestAnimationFrame(read);
27680+
});
27681+
unfollowArrivingState = () => {
27682+
unfollowArrivingState = null;
27683+
cancelAnimationFrame(frame);
27684+
};
27685+
};
27686+
2763627687
// A band nothing can be wider than, published for an edge nothing is known
2763727688
// about: taken as the smaller of the two, it leaves the live band standing on
2763827689
// its own, which is the movement navi played before it knew any of this.
@@ -74880,6 +74931,14 @@ function WheelUI(props) {
7488074931
if (trackedItemsRef.current.length === 0) {
7488174932
return;
7488274933
}
74934+
// Without a box (display: none, rows not laid out yet) every position below
74935+
// multiplies by an item size of 0: nothing can be placed. Leave
74936+
// centeredIndexRef null rather than claim a row is centered, so the render
74937+
// that brings the wheel back on screen doesn't read it as "already there".
74938+
if (getItemSize(viewportEl) === 0) {
74939+
centeredIndexRef.current = null;
74940+
return;
74941+
}
7488374942
let selectedIndex = getIndexForValue(currentValueRef.current);
7488474943
if (selectedIndex < 0) {
7488574944
selectedIndex = 0;
@@ -74926,7 +74985,7 @@ function WheelUI(props) {
7492674985
const requestedBehavior = pendingBehaviorRef.current;
7492774986
pendingBehaviorRef.current = null;
7492874987
const viewportEl = getViewport();
74929-
if (!viewportEl || viewportEl.offsetParent === null) {
74988+
if (!viewportEl) {
7493074989
return;
7493174990
}
7493274991
let behavior = "auto";

0 commit comments

Comments
 (0)