@a2f0/skyline 0.2.63 → 0.2.64
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/README.md +1 -1
- package/docs/package.md +2 -2
- package/package.json +1 -1
- package/site/skyline-animated.svg +37 -4
- package/site/skyline-viewer.js +12 -29
- package/site/skyline-webgl.html +22 -1
package/README.md
CHANGED
|
@@ -23,7 +23,7 @@ Serve `dist/` over HTTP rather than opening files directly: WebGL and the 3D pag
|
|
|
23
23
|
|
|
24
24
|
| Page | Shows | Docs |
|
|
25
25
|
| --- | --- | --- |
|
|
26
|
-
| `index.html` | The viewer, mounted as the package mounts it: opens on the 3D skyline, with the
|
|
26
|
+
| `index.html` | The viewer, mounted as the package mounts it: opens on the 3D skyline, with the original drawing one button away and links to the enhanced drawing and the WebGL prototype | [The viewer](docs/viewer.md) |
|
|
27
27
|
| `skyline-3d.html` | The full-screen 3D skyline on its own: camera views, streets, footprints, celebratory lights, and a building menu | [Full-screen 3D skyline](docs/viewer.md#full-screen-3d-skyline) |
|
|
28
28
|
| `building-detail.html?building=<id>` | One mapped building alone on its platform | [Building menu and detail](docs/viewer.md#building-menu-and-detail) |
|
|
29
29
|
| `skyline-study.html` | The 3D scene over the drawing, in the geographic layout or the original drawing's fit | [3D studies](docs/studies.md#skyline-study) |
|
package/docs/package.md
CHANGED
|
@@ -312,8 +312,8 @@ Before 0.2, the viewer ran in an iframe. Hosts upgrading:
|
|
|
312
312
|
- If the viewer's or scene's code fails to load, as on a dropped connection, the
|
|
313
313
|
browser keeps that failure for the page: later mounts on the same page fail the same
|
|
314
314
|
way until it reloads. A frame used to retry with a new document.
|
|
315
|
-
- The site's own `index.html`
|
|
316
|
-
enhanced drawing and the WebGL prototype, as pages of their own
|
|
315
|
+
- The site's own `index.html` links two prototypes from its toolbar, the hover-scripted
|
|
316
|
+
enhanced drawing and the WebGL prototype, which open as pages of their own; a host's
|
|
317
317
|
viewer never shows them.
|
|
318
318
|
|
|
319
319
|
## Import a scene or a building
|
package/package.json
CHANGED
|
@@ -5,9 +5,6 @@
|
|
|
5
5
|
preserveAspectRatio="xMidYMax meet"
|
|
6
6
|
version="1.1"
|
|
7
7
|
id="svg6766"
|
|
8
|
-
role="img"
|
|
9
|
-
aria-label="Chicago skyline at night"
|
|
10
|
-
aria-describedby="skyline-description"
|
|
11
8
|
style="color-scheme:dark"
|
|
12
9
|
sodipodi:docname="skyline-animated.svg"
|
|
13
10
|
inkscape:version="1.1 (c4e8f9e, 2021-05-24)"
|
|
@@ -144,12 +141,22 @@
|
|
|
144
141
|
.building-tooltip {
|
|
145
142
|
pointer-events: none;
|
|
146
143
|
}
|
|
144
|
+
.back-link text {
|
|
145
|
+
fill: #a8a8a8;
|
|
146
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
|
|
147
|
+
text-decoration: underline;
|
|
148
|
+
}
|
|
149
|
+
.back-link:hover text,
|
|
150
|
+
.back-link:focus-visible text {
|
|
151
|
+
fill: #ffffff;
|
|
152
|
+
}
|
|
147
153
|
@media (prefers-reduced-motion: reduce) {
|
|
148
154
|
.interactive-building.is-active { transition: none; }
|
|
149
155
|
}
|
|
150
156
|
]]></style>
|
|
151
157
|
</defs>
|
|
152
|
-
|
|
158
|
+
<!-- The drawing is one image; the root stays a plain document so the link back reaches assistive technology. -->
|
|
159
|
+
<g id="skyline-position" transform="translate(1105.5923,-87.26366)" role="img" aria-label="Chicago skyline at night" aria-describedby="skyline-description">
|
|
153
160
|
<g
|
|
154
161
|
inkscape:groupmode="layer"
|
|
155
162
|
id="layer4"
|
|
@@ -18670,6 +18677,17 @@
|
|
|
18670
18677
|
style="display:inline;stroke-width:1.33526" />
|
|
18671
18678
|
</g>
|
|
18672
18679
|
</g>
|
|
18680
|
+
<!-- Opened on its own, the drawing links back to the viewer; the script keeps it in the top-left corner. -->
|
|
18681
|
+
<a
|
|
18682
|
+
id="back-link"
|
|
18683
|
+
class="back-link"
|
|
18684
|
+
href="index.html">
|
|
18685
|
+
<text
|
|
18686
|
+
id="back-link-text"
|
|
18687
|
+
font-size="70"
|
|
18688
|
+
x="40"
|
|
18689
|
+
y="110">← back to skyline</text>
|
|
18690
|
+
</a>
|
|
18673
18691
|
<g
|
|
18674
18692
|
id="building-tooltip"
|
|
18675
18693
|
class="building-tooltip"
|
|
@@ -18788,6 +18806,21 @@
|
|
|
18788
18806
|
}
|
|
18789
18807
|
}
|
|
18790
18808
|
|
|
18809
|
+
// The way back to the viewer: 12px text, 12px in from the window's top left, at every
|
|
18810
|
+
// window size.
|
|
18811
|
+
const backLink = document.querySelector("#back-link-text");
|
|
18812
|
+
function placeBackLink() {
|
|
18813
|
+
const matrix = svg.getScreenCTM();
|
|
18814
|
+
if (!matrix) return;
|
|
18815
|
+
const scale = Math.hypot(matrix.a, matrix.b) || 1;
|
|
18816
|
+
const start = svgPoint(0, 0, matrix.inverse());
|
|
18817
|
+
backLink.setAttribute("font-size", 12 / scale);
|
|
18818
|
+
backLink.setAttribute("x", start.x + 12 / scale);
|
|
18819
|
+
backLink.setAttribute("y", start.y + 24 / scale);
|
|
18820
|
+
}
|
|
18821
|
+
placeBackLink();
|
|
18822
|
+
window.addEventListener("resize", placeBackLink, { passive: true });
|
|
18823
|
+
|
|
18791
18824
|
svg.addEventListener("pointerover", updateHover, { passive: true });
|
|
18792
18825
|
svg.addEventListener("pointermove", updateHover, { passive: true });
|
|
18793
18826
|
svg.addEventListener("pointerleave", deactivate);
|
package/site/skyline-viewer.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import { loadMarkup } from "./markup.js";
|
|
2
2
|
import { provideThree } from "./three-engine.js";
|
|
3
|
-
// What
|
|
4
|
-
//
|
|
3
|
+
// What the site toolbar's mode button shows, says and announces. The viewer opens on the 3D
|
|
4
|
+
// skyline; the toggle shows the original drawing and, pressed again, returns to it.
|
|
5
5
|
const home = { label: "3d skyline", title: "Return to the 3D skyline", status: "3D skyline displayed" };
|
|
6
6
|
const toggles = {
|
|
7
7
|
original: { id: "toggle-skyline", label: "show original", title: "Compare with the original skyline SVG", status: "Original skyline displayed" },
|
|
8
|
-
webgl: { id: "toggle-webgl", label: "show webgl", title: "Preview the WebGL skyline prototype", status: "WebGL skyline prototype displayed" },
|
|
9
|
-
enhanced: { id: "toggle-enhanced", label: "show enhanced", title: "Show the enhanced interactive skyline drawing", status: "Enhanced interactive skyline displayed" },
|
|
10
|
-
};
|
|
11
|
-
// The two prototypes the site's toolbar shows in place are pages of their own, as the
|
|
12
|
-
// studies are: the hover-scripted drawing and the WebGL prototype. Only the site's own
|
|
13
|
-
// index.html shows them, in frames; a host's viewer never does.
|
|
14
|
-
const prototypes = {
|
|
15
|
-
enhanced: { src: "skyline-animated.svg", title: "Animated Chicago skyline at night" },
|
|
16
|
-
webgl: { src: "skyline-webgl.html", title: "WebGL Chicago skyline prototype" },
|
|
17
8
|
};
|
|
9
|
+
// The two prototypes are pages of their own, as the studies are: the hover-scripted drawing
|
|
10
|
+
// and the WebGL prototype. The site's toolbar links to them, and each page keeps its own
|
|
11
|
+
// scripts and a way back; a host's viewer never shows them.
|
|
12
|
+
const prototypes = [
|
|
13
|
+
{ id: "link-webgl", href: "skyline-webgl.html", label: "webgl prototype", title: "Open the WebGL skyline prototype", ct: "viewer.webgl" },
|
|
14
|
+
{ id: "link-enhanced", href: "skyline-animated.svg", label: "enhanced drawing", title: "Open the enhanced interactive skyline drawing", ct: "viewer.enhanced" },
|
|
15
|
+
];
|
|
18
16
|
export function sceneTransition(status, event) {
|
|
19
17
|
switch (event) {
|
|
20
18
|
case "ready":
|
|
@@ -66,7 +64,6 @@ export function mount(root, { assets, signal, controls, colour, theme, attributi
|
|
|
66
64
|
// Both show original buttons wait while the scene boots, until its first frame, a failure
|
|
67
65
|
// to load, or a lost graphics context; the drawing stays reachable while it is unavailable.
|
|
68
66
|
let sceneStatus = "booting";
|
|
69
|
-
const frames = {};
|
|
70
67
|
const toolbar = navigation ? createToolbar() : null;
|
|
71
68
|
function updateView() {
|
|
72
69
|
viewer.toggleAttribute("data-booting", sceneStatus !== "ready" && mode === "3d");
|
|
@@ -74,10 +71,6 @@ export function mount(root, { assets, signal, controls, colour, theme, attributi
|
|
|
74
71
|
if (mode === "original" && !drawing.getAttribute("src"))
|
|
75
72
|
drawing.src = new URL("skyline-original-fit.svg", assets).href;
|
|
76
73
|
drawing.hidden = mode !== "original";
|
|
77
|
-
if (mode === "enhanced" || mode === "webgl")
|
|
78
|
-
frames[mode] ??= createPrototype(mode);
|
|
79
|
-
for (const [name, frame] of Object.entries(frames))
|
|
80
|
-
frame.hidden = name !== mode;
|
|
81
74
|
originalReturn.hidden = mode !== "original";
|
|
82
75
|
embeddedOriginal.hidden = navigation || mode !== "3d" || sceneStatus !== "unavailable";
|
|
83
76
|
if (toolbar) {
|
|
@@ -295,6 +288,9 @@ export function mount(root, { assets, signal, controls, colour, theme, attributi
|
|
|
295
288
|
toggleButton.addEventListener("click", () => showMode(mode === name ? "3d" : name), listening);
|
|
296
289
|
nav.append(toggleButton);
|
|
297
290
|
}
|
|
291
|
+
for (const prototype of prototypes) {
|
|
292
|
+
nav.append(element(document, "a", { id: prototype.id, href: new URL(prototype.href, assets).href, title: prototype.title, textContent: prototype.label }, { "data-ct": prototype.ct }));
|
|
293
|
+
}
|
|
298
294
|
nav.append(element(document, "a", { href: new URL("building-study.html", assets).href, textContent: "3d building" }, { "data-ct": "viewer.building-study" }), element(document, "a", { href: new URL("skyline-study.html", assets).href, textContent: "skyline study" }, { "data-ct": "viewer.skyline-study" }));
|
|
299
295
|
const debugButton = button("debug-motion", "debug motion", { "aria-describedby": "stars-motion-status" });
|
|
300
296
|
const motionStatus = element(document, "p", { className: "motion-status", id: "stars-motion-status" }, { role: "status" });
|
|
@@ -329,17 +325,4 @@ export function mount(root, { assets, signal, controls, colour, theme, attributi
|
|
|
329
325
|
resizing.observe(scene);
|
|
330
326
|
signal.addEventListener("abort", () => resizing.disconnect(), { once: true });
|
|
331
327
|
}
|
|
332
|
-
// A prototype's page, in a frame of its own, shown in place the first time it is chosen.
|
|
333
|
-
// Keys pressed inside it go to its own window, so F listens there too.
|
|
334
|
-
function createPrototype(name) {
|
|
335
|
-
const frame = element(document, "iframe", { className: "scene", id: `${name}-scene`, title: prototypes[name].title, src: new URL(prototypes[name].src, assets).href });
|
|
336
|
-
frame.addEventListener("load", () => {
|
|
337
|
-
try {
|
|
338
|
-
frame.contentWindow?.addEventListener("keydown", fullscreenShortcut, listening);
|
|
339
|
-
}
|
|
340
|
-
catch { /* A frame from another origin keeps its keys. */ }
|
|
341
|
-
}, listening);
|
|
342
|
-
viewer.insertBefore(frame, originalReturn);
|
|
343
|
-
return frame;
|
|
344
|
-
}
|
|
345
328
|
}
|
package/site/skyline-webgl.html
CHANGED
|
@@ -73,6 +73,26 @@
|
|
|
73
73
|
white-space: nowrap;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
.back {
|
|
77
|
+
position: fixed;
|
|
78
|
+
z-index: 3;
|
|
79
|
+
top: max(12px, env(safe-area-inset-top));
|
|
80
|
+
left: max(12px, env(safe-area-inset-left));
|
|
81
|
+
color: #a8a8a8;
|
|
82
|
+
font-size: 12px;
|
|
83
|
+
text-decoration: underline;
|
|
84
|
+
text-decoration-thickness: 1px;
|
|
85
|
+
text-underline-offset: 3px;
|
|
86
|
+
}
|
|
87
|
+
.back:hover,
|
|
88
|
+
.back:focus-visible {
|
|
89
|
+
color: #fff;
|
|
90
|
+
text-decoration-thickness: 2px;
|
|
91
|
+
}
|
|
92
|
+
.back:focus-visible {
|
|
93
|
+
outline: 1px solid #fff;
|
|
94
|
+
outline-offset: 4px;
|
|
95
|
+
}
|
|
76
96
|
[hidden] {
|
|
77
97
|
display: none !important;
|
|
78
98
|
}
|
|
@@ -80,6 +100,7 @@
|
|
|
80
100
|
<script type="module" src="click-tracking-page.js"></script>
|
|
81
101
|
</head>
|
|
82
102
|
<body>
|
|
103
|
+
<a class="back" id="back-link" href="index.html">← back to skyline</a>
|
|
83
104
|
<canvas id="skyline" role="img" aria-label="Interactive WebGL rendering of the Chicago skyline"></canvas>
|
|
84
105
|
<p class="loading" id="loading" role="status">preparing WebGL building layers…</p>
|
|
85
106
|
<div class="tooltip" id="tooltip" aria-hidden="true" hidden></div>
|
|
@@ -435,7 +456,7 @@
|
|
|
435
456
|
}
|
|
436
457
|
|
|
437
458
|
const sourceRoot = sourceDocument.documentElement;
|
|
438
|
-
sourceRoot.querySelectorAll("script, #building-tooltip").forEach((element) => element.remove());
|
|
459
|
+
sourceRoot.querySelectorAll("script, #building-tooltip, #back-link").forEach((element) => element.remove());
|
|
439
460
|
sourceRoot.setAttribute("width", "850");
|
|
440
461
|
sourceRoot.setAttribute("height", "278");
|
|
441
462
|
const sourceHost = document.createElement("div");
|