@jsenv/navi 0.29.372 → 0.29.374
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/dev/jsenv_navi.js +127 -9
- package/dist/dev/jsenv_navi.js.map +3 -3
- package/dist/jsenv_navi.js +127 -9
- package/dist/jsenv_navi.js.map +3 -3
- package/docs/route_transitions.md +20 -1
- package/docs/view_transitions.md +43 -0
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -30029,6 +30029,11 @@ const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
|
|
|
30029
30029
|
const TOP_LAYER_WALL_SELECTOR =
|
|
30030
30030
|
".navi_dialog:modal, .navi_popover_backdrop:popover-open";
|
|
30031
30031
|
const WALL_ATTRIBUTE = "data-navi-transition-wall";
|
|
30032
|
+
// Worn by a bar both states have, from the hold on: its two pictures are one
|
|
30033
|
+
// group, and the group is ordered over the pages (route_transition.jsx). Only
|
|
30034
|
+
// a bar — a popup's class is written by layout/popup_css.js, and a second rule
|
|
30035
|
+
// on the same property would replace it.
|
|
30036
|
+
const SHARED_ATTRIBUTE = "data-navi-transition-furniture-shared";
|
|
30032
30037
|
// What the wall paints, resolved on the matched element in both cases (the
|
|
30033
30038
|
// dialog for its ::backdrop, the popover's wall for itself): the same two
|
|
30034
30039
|
// properties, copied onto the stand-in.
|
|
@@ -30037,7 +30042,11 @@ const WALL_PROPERTIES = ["--backdrop-background", "--backdrop-filter"];
|
|
|
30037
30042
|
// The pictures the wall is painted into: the pages', and every bar's own.
|
|
30038
30043
|
const FIXED_BAR_SELECTOR$1 = ".navi_fixed_bar";
|
|
30039
30044
|
|
|
30040
|
-
const
|
|
30045
|
+
const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition-furniture-shared] {
|
|
30046
|
+
view-transition-class: navi_furniture_shared;
|
|
30047
|
+
}
|
|
30048
|
+
|
|
30049
|
+
[data-navi-transition-wall] {
|
|
30041
30050
|
z-index: var(--navi-z-index-top-layer);
|
|
30042
30051
|
background: var(--backdrop-background);
|
|
30043
30052
|
backdrop-filter: var(--backdrop-filter);
|
|
@@ -30070,7 +30079,7 @@ const TRANSITION_WALL_CSS = /* css */ `[data-navi-transition-wall] {
|
|
|
30070
30079
|
// a page that never travels between routes must not carry this sheet, and a
|
|
30071
30080
|
// build that sees no caller drops the css with the function.
|
|
30072
30081
|
const installTransitionFurnitureCss = () => {
|
|
30073
|
-
import.meta.css = [
|
|
30082
|
+
import.meta.css = [TRANSITION_FURNITURE_CSS, "@jsenv/navi/src/nav/transition_furniture.js"];
|
|
30074
30083
|
};
|
|
30075
30084
|
|
|
30076
30085
|
const nameByElement = new WeakMap();
|
|
@@ -30132,6 +30141,8 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
30132
30141
|
for (const element of namedElements) {
|
|
30133
30142
|
if (!element.isConnected) {
|
|
30134
30143
|
namesLeaving.push(nameByElement.get(element));
|
|
30144
|
+
} else if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
30145
|
+
element.setAttribute(SHARED_ATTRIBUTE, "");
|
|
30135
30146
|
}
|
|
30136
30147
|
}
|
|
30137
30148
|
const namesArriving = nameFurnitureAround(areaElement);
|
|
@@ -30262,6 +30273,7 @@ const releaseTransitionFurniture = (owner) => {
|
|
|
30262
30273
|
furnitureOwner = null;
|
|
30263
30274
|
for (const element of namedElements) {
|
|
30264
30275
|
element.style.removeProperty(NAME_PROPERTY$1);
|
|
30276
|
+
element.removeAttribute(SHARED_ATTRIBUTE);
|
|
30265
30277
|
}
|
|
30266
30278
|
namedElements = new Set();
|
|
30267
30279
|
if (travelStyleElement) {
|
|
@@ -30293,12 +30305,12 @@ const paintTransitionWalls = (areaElement) => {
|
|
|
30293
30305
|
// positioned against an ancestor of it: the wall is placed from
|
|
30294
30306
|
// wherever its containing block turns out to be, by the offset between
|
|
30295
30307
|
// that box and the target's.
|
|
30296
|
-
const targetRect = target
|
|
30308
|
+
const targetRect = pictureRect(target);
|
|
30297
30309
|
const wallRect = wall.getBoundingClientRect();
|
|
30298
30310
|
wall.style.left = `${targetRect.left - wallRect.left}px`;
|
|
30299
30311
|
wall.style.top = `${targetRect.top - wallRect.top}px`;
|
|
30300
|
-
wall.style.width = `${targetRect.
|
|
30301
|
-
wall.style.height = `${targetRect.
|
|
30312
|
+
wall.style.width = `${targetRect.right - targetRect.left}px`;
|
|
30313
|
+
wall.style.height = `${targetRect.bottom - targetRect.top}px`;
|
|
30302
30314
|
wallElements.push(wall);
|
|
30303
30315
|
}
|
|
30304
30316
|
}
|
|
@@ -30352,11 +30364,45 @@ const paintRestWalls = (sources, opacity) => {
|
|
|
30352
30364
|
const measurePictureRects = (areaElement) => {
|
|
30353
30365
|
const rects = new Map();
|
|
30354
30366
|
for (const target of pictureTargets(areaElement)) {
|
|
30355
|
-
rects.set(target, target
|
|
30367
|
+
rects.set(target, pictureRect(target));
|
|
30356
30368
|
}
|
|
30357
30369
|
return rects;
|
|
30358
30370
|
};
|
|
30359
30371
|
|
|
30372
|
+
// What the picture holds, which is what the wall covers at rest: a bar's
|
|
30373
|
+
// picture carries what its content paints outside its box (a button standing
|
|
30374
|
+
// up out of a tab bar), so its rectangle is taken with its descendants'. The
|
|
30375
|
+
// pages' is their own box — the movement cuts them at it anyway.
|
|
30376
|
+
const pictureRect = (target) => {
|
|
30377
|
+
const rect = target.getBoundingClientRect();
|
|
30378
|
+
let { left, top, right, bottom } = rect;
|
|
30379
|
+
if (!target.matches(FIXED_BAR_SELECTOR$1)) {
|
|
30380
|
+
return { left, top, right, bottom };
|
|
30381
|
+
}
|
|
30382
|
+
for (const descendant of target.querySelectorAll("*")) {
|
|
30383
|
+
if (descendant.hasAttribute(WALL_ATTRIBUTE)) {
|
|
30384
|
+
continue;
|
|
30385
|
+
}
|
|
30386
|
+
const descendantRect = descendant.getBoundingClientRect();
|
|
30387
|
+
if (descendantRect.width === 0 || descendantRect.height === 0) {
|
|
30388
|
+
continue;
|
|
30389
|
+
}
|
|
30390
|
+
if (descendantRect.left < left) {
|
|
30391
|
+
left = descendantRect.left;
|
|
30392
|
+
}
|
|
30393
|
+
if (descendantRect.top < top) {
|
|
30394
|
+
top = descendantRect.top;
|
|
30395
|
+
}
|
|
30396
|
+
if (descendantRect.right > right) {
|
|
30397
|
+
right = descendantRect.right;
|
|
30398
|
+
}
|
|
30399
|
+
if (descendantRect.bottom > bottom) {
|
|
30400
|
+
bottom = descendantRect.bottom;
|
|
30401
|
+
}
|
|
30402
|
+
}
|
|
30403
|
+
return { left, top, right, bottom };
|
|
30404
|
+
};
|
|
30405
|
+
|
|
30360
30406
|
// The holes for the movement, and the ones for its last frame (see the CSS).
|
|
30361
30407
|
const cutRestWalls = (holes, holesArriving = null) => {
|
|
30362
30408
|
for (const restWall of restWallElements) {
|
|
@@ -30371,15 +30417,83 @@ const cutRestWalls = (holes, holesArriving = null) => {
|
|
|
30371
30417
|
};
|
|
30372
30418
|
|
|
30373
30419
|
// One evenodd polygon: the window, then each hole entered from and left by
|
|
30374
|
-
// the window's origin, so the bridges between them have no area.
|
|
30420
|
+
// the window's origin, so the bridges between them have no area. The holes
|
|
30421
|
+
// must not overlap — evenodd fills where two of them do — and they do
|
|
30422
|
+
// overlap as measured: the pages run under the bars by design, so a bar's
|
|
30423
|
+
// rectangle lies inside the area's. Each is cut down to what the ones before
|
|
30424
|
+
// it left.
|
|
30375
30425
|
const holesPolygon = (holes) => {
|
|
30376
30426
|
let polygon = "0 0, 100% 0, 100% 100%, 0 100%, 0 0";
|
|
30377
|
-
for (const { left, top, right, bottom } of holes) {
|
|
30427
|
+
for (const { left, top, right, bottom } of disjointRects(holes)) {
|
|
30378
30428
|
polygon += `, ${left}px ${top}px, ${right}px ${top}px, ${right}px ${bottom}px, ${left}px ${bottom}px, ${left}px ${top}px, 0 0`;
|
|
30379
30429
|
}
|
|
30380
30430
|
return `polygon(evenodd, ${polygon})`;
|
|
30381
30431
|
};
|
|
30382
30432
|
|
|
30433
|
+
const disjointRects = (rects) => {
|
|
30434
|
+
const result = [];
|
|
30435
|
+
for (const rect of rects) {
|
|
30436
|
+
let pieces = [rect];
|
|
30437
|
+
for (const placed of result) {
|
|
30438
|
+
const remaining = [];
|
|
30439
|
+
for (const piece of pieces) {
|
|
30440
|
+
remaining.push(...subtractRect(piece, placed));
|
|
30441
|
+
}
|
|
30442
|
+
pieces = remaining;
|
|
30443
|
+
}
|
|
30444
|
+
result.push(...pieces);
|
|
30445
|
+
}
|
|
30446
|
+
return result;
|
|
30447
|
+
};
|
|
30448
|
+
|
|
30449
|
+
// What is left of `rect` outside `hole`: up to four rectangles around it.
|
|
30450
|
+
const subtractRect = (rect, hole) => {
|
|
30451
|
+
if (
|
|
30452
|
+
hole.left >= rect.right ||
|
|
30453
|
+
hole.right <= rect.left ||
|
|
30454
|
+
hole.top >= rect.bottom ||
|
|
30455
|
+
hole.bottom <= rect.top
|
|
30456
|
+
) {
|
|
30457
|
+
return [rect];
|
|
30458
|
+
}
|
|
30459
|
+
const pieces = [];
|
|
30460
|
+
const innerTop = hole.top > rect.top ? hole.top : rect.top;
|
|
30461
|
+
const innerBottom = hole.bottom < rect.bottom ? hole.bottom : rect.bottom;
|
|
30462
|
+
if (hole.top > rect.top) {
|
|
30463
|
+
pieces.push({
|
|
30464
|
+
left: rect.left,
|
|
30465
|
+
top: rect.top,
|
|
30466
|
+
right: rect.right,
|
|
30467
|
+
bottom: hole.top,
|
|
30468
|
+
});
|
|
30469
|
+
}
|
|
30470
|
+
if (hole.bottom < rect.bottom) {
|
|
30471
|
+
pieces.push({
|
|
30472
|
+
left: rect.left,
|
|
30473
|
+
top: hole.bottom,
|
|
30474
|
+
right: rect.right,
|
|
30475
|
+
bottom: rect.bottom,
|
|
30476
|
+
});
|
|
30477
|
+
}
|
|
30478
|
+
if (hole.left > rect.left) {
|
|
30479
|
+
pieces.push({
|
|
30480
|
+
left: rect.left,
|
|
30481
|
+
top: innerTop,
|
|
30482
|
+
right: hole.left,
|
|
30483
|
+
bottom: innerBottom,
|
|
30484
|
+
});
|
|
30485
|
+
}
|
|
30486
|
+
if (hole.right < rect.right) {
|
|
30487
|
+
pieces.push({
|
|
30488
|
+
left: hole.right,
|
|
30489
|
+
top: innerTop,
|
|
30490
|
+
right: rect.right,
|
|
30491
|
+
bottom: innerBottom,
|
|
30492
|
+
});
|
|
30493
|
+
}
|
|
30494
|
+
return pieces;
|
|
30495
|
+
};
|
|
30496
|
+
|
|
30383
30497
|
const removeRestWalls = () => {
|
|
30384
30498
|
for (const restWall of restWallElements) {
|
|
30385
30499
|
restWall.remove();
|
|
@@ -30964,10 +31078,14 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
30964
31078
|
z-index: 1;
|
|
30965
31079
|
}
|
|
30966
31080
|
|
|
30967
|
-
&::view-transition-group(.
|
|
31081
|
+
&::view-transition-group(.navi_furniture_shared) {
|
|
30968
31082
|
z-index: 2;
|
|
30969
31083
|
}
|
|
30970
31084
|
|
|
31085
|
+
&::view-transition-group(.navi_popup) {
|
|
31086
|
+
z-index: 3;
|
|
31087
|
+
}
|
|
31088
|
+
|
|
30971
31089
|
&::view-transition-group(*), &::view-transition-old(*), &::view-transition-new(*) {
|
|
30972
31090
|
animation-duration: var(--navi-route-transition-duration, .3s);
|
|
30973
31091
|
}
|