@johnmorrisdotca/wakusei-planets 0.3.0 → 0.4.0
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/CHANGELOG.md +19 -0
- package/NOTICE.md +2 -1
- package/README.md +5 -2
- package/dist/bodies/all.d.ts +1 -0
- package/dist/bodies/all.js +1 -0
- package/dist/bodies/earth-look.d.ts +1 -0
- package/dist/bodies/earth-look.js +18 -0
- package/dist/bodies/earth.d.ts +1 -1
- package/dist/bodies/earth.js +3 -11
- package/dist/element.d.ts +3 -3
- package/dist/element.js +30 -25
- package/dist/embed.d.ts +96 -0
- package/dist/embed.js +112 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/scene/body.js +1 -1
- package/dist/scene/look.d.ts +2 -0
- package/dist/scene/store.d.ts +1 -7
- package/dist/textures/earth-1024.webp +0 -0
- package/dist/textures/earth-512.webp +0 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +6 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
"Put it in your page" is a configurator.
|
|
6
|
+
|
|
7
|
+
- **Set up a body, copy the code.** The demo's last section follows what is set up above it (body, look, sky and date, moons, turning) and a size (160, 240, 320 or 480), and writes working code for plain HTML from jsDelivr, an ES module, React, Vue, Angular, Svelte and an iframe of the embed page, on tabs that answer the arrow keys, beside a picture made from the same choices, with a Copy button and the credits that go with the picture. The choices are kept in the address (`?embed=react&size=240`).
|
|
8
|
+
- **`embedCode(options, kind, settings)` and `embedCredit(options)`** make the same text for a page of your own (`EMBED_KINDS`: `html`, `module`, `react`, `vue`, `angular`, `svelte`, `iframe`). Pattern: senshu-jerseys' `embedCode` and its tabbed "Put it in your page". Every snippet is tested (`test/embed.test.ts`): the React component is built and rendered, the Vue and Svelte components compiled, the Angular template parsed, the module checked as TypeScript, the iframe's address read the way the embed page reads it, and every body's entry point exists in the package.
|
|
9
|
+
- A guide, "Put it in your page", in English and Japanese.
|
|
10
|
+
- **kazoku-ui 0.11.0**: the view controls' Centre button (it appears once the body is dragged away), a pan that keeps a quarter of the body in sight (told the body's size with `object-size`), and a drag that keeps the touched point under the pointer (`grab-radius`). The 0.3.1 stopgap that made Fit re-centre is gone.
|
|
11
|
+
|
|
12
|
+
## 0.3.1
|
|
13
|
+
|
|
14
|
+
The Earth is a body like the others, and "To scale" is a comparison.
|
|
15
|
+
|
|
16
|
+
- **The Earth draws in every look.** In the realistic and painted looks the big view was empty and the row showed chikyu-earth's line globe, because the Earth was handed to chikyu-earth's own live element (0.7.0 here, a second WebGL context, no still). It is now drawn by this package like every other body, from NASA's Blue Marble picture (`earth-512`, `-1024` and `-2048`; the package grows by 0.08 MB), through the page's one WebGL context, with a still in the row. Both looks use the picture (an honest shaded Earth cannot be worked out from numbers), with a rim of air. Only the line look is chikyu-earth's globe. The Earth is in `/all`. chikyu-earth is now `^0.10.0` (it was `^0.7.0`).
|
|
17
|
+
- **"To scale" is a lineup** (section "To scale" in the demo): every body at the same scale in the same size of picture, a magnified picture joined by a line for each body too small to see, Saturn's rings whole, the Sun as the curved edge it is, the Earth at its true size. The tiles in the row are never scaled any more (the Sun was a flat square, Mercury a dot). New attribute `span-km`: the half-width of a picture in kilometres, the same in every picture of a lineup.
|
|
18
|
+
- **Every moon has a tile and a name** for `body` (`?body=io`), in the demo under its planet, with chips on each planet's and moon's view for its moons, its planet and its sister moons.
|
|
19
|
+
- **The body cannot be dragged out of the view** (a quarter of it stays in), and Fit centres it and returns it to its first angle.
|
|
20
|
+
- The README's pictures are absolute addresses pinned to the release's tag (npm's page showed a different picture from GitHub's), and a test holds it (`pnpm readme:images` pins them after a version bump).
|
|
21
|
+
|
|
3
22
|
## 0.3.0
|
|
4
23
|
|
|
5
24
|
Painted moons, Saturn's rings from Cassini, and a drag that goes the right way up.
|
package/NOTICE.md
CHANGED
|
@@ -15,7 +15,7 @@ The tests compare the Galilean moons and four planets with astronomy-engine (MIT
|
|
|
15
15
|
|
|
16
16
|
## The Earth
|
|
17
17
|
|
|
18
|
-
The Earth
|
|
18
|
+
The Earth's line drawing is chikyu-earth's own globe (MIT, by John Morris; https://github.com/johnmorrisdotca/chikyu-earth), an optional peer dependency: its own NOTICE.md has the terms of its outlines. The Earth's realistic and painted looks are drawn here, like every other body, from NASA's Blue Marble picture (below).
|
|
19
19
|
|
|
20
20
|
## Surface pictures
|
|
21
21
|
|
|
@@ -40,6 +40,7 @@ NASA says its content "generally are not subject to copyright in the United Stat
|
|
|
40
40
|
| `ganymede-*.webp` | Ganymede | [Ganymede equatorial.jpg](https://commons.wikimedia.org/wiki/File:Ganymede_equatorial.jpg) | Public domain | USGS | USGS Voyager and Galileo colour mosaic (I-2762), the Mercator sheet for 57 degrees north and south, redrawn as an equirectangular map with longitude 0 in the middle (the source does not say; Galileo Regio falls at 140 degrees west); the poles are not on that sheet and fade from its edge into its mean colour |
|
|
41
41
|
| `callisto-*.webp` | Callisto | [Callisto equatorial.jpg](https://commons.wikimedia.org/wiki/File:Callisto_equatorial.jpg) | Public domain | USGS | USGS Voyager and Galileo mosaic (I-2770), the Mercator sheet for 57 degrees north and south, redrawn as an equirectangular map with longitude 0 in the middle (the source does not say; Valhalla falls at 56 degrees west); the poles fade from its edge into its mean grey |
|
|
42
42
|
| `titan-*.webp` | Titan | [Titan map April 2011 full.png](https://commons.wikimedia.org/wiki/File:Titan_map_April_2011_full.png) | Public domain | NASA / JPL / Space Science Institute | Cassini ISS 938 nm map (PIA14908), turned so longitude 0 is in the middle (the original is centred on 180). Titan's surface cannot be seen in visible light under its haze, so the picture is a colour for the infrared brightness, with its contrast turned down: it is not a photograph, as with Venus |
|
|
43
|
+
| `earth-*.webp` | Earth | [Blue Marble: Next Generation with topography and bathymetry, September 2004](https://visibleearth.nasa.gov/images/73801) (Visible Earth 73801) | Public domain (NASA) | NASA Earth Observatory (Reto Stockli) | Resized from the 2048 pixel picture chikyu-earth already makes from the 5400 x 2700 original; the realistic and the painted looks both draw it, because an honest shaded Earth cannot be worked out from numbers |
|
|
43
44
|
| `rhea-*.webp` | Rhea | [Rhea Color Map.jpg](https://commons.wikimedia.org/wiki/File:Rhea_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18438), turned half way round so longitude 0 is in the middle (the source does not say where it is centred; the dark trailing side is put at 90 degrees east); the colours are false-colour (infrared, green, ultraviolet) and are turned about half way to grey |
|
|
44
45
|
| `enceladus-*.webp` | Enceladus | [Enceladus Color Map.jpg](https://commons.wikimedia.org/wiki/File:Enceladus_Color_Map.jpg) | Public domain | NASA/JPL-Caltech/Space Science Institute/Lunar and Planetary Institute | Cassini global colour map (PIA18435), turned half way round the same way as Rhea's (the source does not say where it is centred; the fractured trailing terrain is put at 90 degrees east); the colours are false-colour (the blue of the tiger stripes is ultraviolet) and are turned most of the way to grey |
|
|
45
46
|
| `mimas-*.webp` | Mimas | [Map of Mimas 2010-02 PIA12780.jpg](https://commons.wikimedia.org/wiki/File:Map_of_Mimas_2010-02_PIA12780.jpg) | Public domain | NASA/JPL/Space Science Institute | Cassini ISS map of February 2010 (PIA12780), cropped inside its frame and labels; Herschel is at 110 degrees west as its own scale says |
|
package/README.md
CHANGED
|
@@ -11,7 +11,9 @@ A clean line drawing, a shaded realistic drawing, or a painted surface map, with
|
|
|
11
11
|
|
|
12
12
|
<p align="center"><a href="https://johnmorrisdotca.github.io/wakusei-planets/"><strong>Open the demo →</strong></a> · <a href="https://johnmorrisdotca.github.io/wakusei-planets/embed.html">Embed page</a> · <a href="https://johnmorrisdotca.github.io/wakusei-planets/docs/">Docs</a></p>
|
|
13
13
|
|
|
14
|
-
<p align="center"><img alt="Jupiter and Saturn drawn in the realistic look, and Saturn as a line drawing" src="docs/images/hero-desk.png" width="640"></p>
|
|
14
|
+
<p align="center"><img alt="Jupiter and Saturn drawn in the realistic look, and Saturn as a line drawing" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.4.0/docs/images/hero-desk.png" width="640"></p>
|
|
15
|
+
|
|
16
|
+
<p align="center"><img alt="Every body at one scale, the Earth among them: each small body has a magnified picture joined by a line, and the Sun shows only its edge" src="https://raw.githubusercontent.com/johnmorrisdotca/wakusei-planets/v0.4.0/docs/images/lineup-desk.png" width="640"></p>
|
|
15
17
|
|
|
16
18
|
## One minute
|
|
17
19
|
|
|
@@ -74,7 +76,7 @@ A bundled app imports it: `import "@johnmorrisdotca/wakusei-planets/element"` (a
|
|
|
74
76
|
| `realistic` | A shaded sphere drawn from the body's real colours and features, lit from the Sun's side, with the rings casting shadows. No pictures: the surface is worked out in a shader. | `three`, the body's entry point |
|
|
75
77
|
| `painted` | A real surface map from public-domain NASA, USGS and JPL imagery. Small pictures first (1.31 MB for all of them in the package), a sharper one fetched when you zoom in. | `three`, the body's entry point |
|
|
76
78
|
|
|
77
|
-
Every body has its real size relative to the others (`scale-to="jupiter"`), its axial tilt and its rotation. The Sun, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune and Pluto are drawn, and so are 25 moons (the Moon, Phobos and Deimos, the four Galilean moons, Saturn's seven larger moons, Uranus's five, Proteus, Triton and Nereid, Charon, Nix and Hydra). The Earth is [chikyu-earth](https://github.com/johnmorrisdotca/chikyu-earth)'s own globe
|
|
79
|
+
Every body has its real size relative to the others (`scale-to="jupiter"`), its axial tilt and its rotation. The Sun, Mercury, Venus, Mars, Jupiter, Saturn, Uranus, Neptune and Pluto are drawn, and so are 25 moons (the Moon, Phobos and Deimos, the four Galilean moons, Saturn's seven larger moons, Uranus's five, Proteus, Triton and Nereid, Charon, Nix and Hydra). The Earth is drawn like the rest in the realistic and painted looks (NASA's Blue Marble), and its line look is [chikyu-earth](https://github.com/johnmorrisdotca/chikyu-earth)'s own globe: `import "@johnmorrisdotca/wakusei-planets/earth"` (it needs `@johnmorrisdotca/chikyu-earth` 0.10.0 or later installed). The painted looks cover the Sun, the planets from Mercury to Earth and Pluto, the Moon, the four Galilean moons, Titan, Rhea, Enceladus and Mimas, and Saturn's rings are Cassini's own picture of them.
|
|
78
80
|
|
|
79
81
|
## As the Earth sees it
|
|
80
82
|
|
|
@@ -92,6 +94,7 @@ Give a body a `time` and it is drawn as the sky shows it then: its pole and rota
|
|
|
92
94
|
| An ES module in Vite or webpack, only the bodies you need | [bundlers guide](docs/guides/bundlers.md) |
|
|
93
95
|
| React, Vue, Svelte, Angular; Next.js, Nuxt, SvelteKit | [frameworks guide](docs/guides/frameworks.md) |
|
|
94
96
|
| An `<iframe>` of the embed page, no script of your own | [iframe guide](docs/guides/embed-in-an-iframe.md) |
|
|
97
|
+
| Set up a body in the demo and copy the code for HTML, React, Vue, Angular, Svelte or an iframe | [Put it in your page](docs/guides/put-it-in-your-page.md), or `embedCode()` |
|
|
95
98
|
| TypeScript types, an SVG string on a server, Node | [TypeScript and Node guide](docs/guides/typescript-and-node.md) |
|
|
96
99
|
| The looks, the entry points, one WebGL context | [looks and bodies](docs/guides/looks-and-bodies.md) |
|
|
97
100
|
| Moons where they are on a date, time that runs fast | [moons and time](docs/guides/moons-and-time.md) |
|
package/dist/bodies/all.d.ts
CHANGED
package/dist/bodies/all.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { registerLook } from "../scene/look.js";
|
|
2
|
+
// The Earth's realistic and painted looks, drawn like every other body's from the Blue Marble picture, so they share the page's one WebGL context and have stills like the rest.
|
|
3
|
+
registerLook({
|
|
4
|
+
id: "earth",
|
|
5
|
+
surface: `
|
|
6
|
+
vec4 surface(vec3 p) {
|
|
7
|
+
float land = smoothstep(0.52, 0.58, fbm(p * 2.6 + 3.0));
|
|
8
|
+
vec3 sea = vec3(0.05, 0.17, 0.38);
|
|
9
|
+
vec3 ground = mix(vec3(0.22, 0.38, 0.16), vec3(0.62, 0.55, 0.40), smoothstep(0.55, 0.8, fbm(p * 5.0)));
|
|
10
|
+
float ice = smoothstep(radians(66.0), radians(76.0), abs(lat(p)));
|
|
11
|
+
return vec4(mix(mix(sea, ground, land), vec3(0.93, 0.96, 0.98), ice), 0.0);
|
|
12
|
+
}`,
|
|
13
|
+
atmosphere: { colour: [0.32, 0.52, 0.95], strength: 0.5, power: 3 },
|
|
14
|
+
wrap: 0.12,
|
|
15
|
+
limb: 0.12,
|
|
16
|
+
mapped: true,
|
|
17
|
+
painted: { map: "earth", widths: [512, 1024, 2048], far: 2048, relief: 0 },
|
|
18
|
+
});
|
package/dist/bodies/earth.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
import "./earth-look.ts";
|
package/dist/bodies/earth.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import "./earth-look.js";
|
|
1
2
|
import { delegates } from "../scene/store.js";
|
|
2
|
-
// The Earth
|
|
3
|
-
//
|
|
3
|
+
// The Earth's line look is chikyu-earth's own globe with the countries, not a second copy (chikyu-earth is an optional peer, loaded only when that line globe is drawn). The realistic and
|
|
4
|
+
// painted looks are drawn here like every other body's (earth-look.ts, which `/all` also loads).
|
|
4
5
|
const CENTRE = "10,20";
|
|
5
6
|
delegates.set("earth", {
|
|
6
7
|
async line({ center, size }) {
|
|
@@ -11,13 +12,4 @@ delegates.set("earth", {
|
|
|
11
12
|
globe.setAttribute("size", String(size));
|
|
12
13
|
return globe;
|
|
13
14
|
},
|
|
14
|
-
async live({ center, time, textureBase }) {
|
|
15
|
-
await import("@johnmorrisdotca/chikyu-earth/realistic/element");
|
|
16
|
-
const earth = document.createElement("chikyu-earth-realistic");
|
|
17
|
-
earth.setAttribute("center", center || CENTRE);
|
|
18
|
-
earth.setAttribute("time", time);
|
|
19
|
-
if (textureBase !== null)
|
|
20
|
-
earth.setAttribute("texture-base", textureBase);
|
|
21
|
-
return earth;
|
|
22
|
-
},
|
|
23
15
|
});
|
package/dist/element.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ export type WakuseiState = "line" | "loading" | "still" | "live" | "lost" | "una
|
|
|
25
25
|
* console.log(TEXTURE_BASE);
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
export declare const TEXTURE_BASE = "https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets@0.
|
|
28
|
+
export declare const TEXTURE_BASE = "https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets@0.4.0/dist/textures/";
|
|
29
29
|
/**
|
|
30
30
|
* Where the sharpest surface pictures are: the files of this exact version in the repository, on jsDelivr's GitHub address. The npm package holds only the two smaller widths, so a page that
|
|
31
31
|
* never zooms in never fetches them. Set `texture-far-base` on an element to serve them yourself.
|
|
@@ -37,13 +37,13 @@ export declare const TEXTURE_BASE = "https://cdn.jsdelivr.net/npm/@johnmorrisdot
|
|
|
37
37
|
* console.log(TEXTURE_FAR_BASE);
|
|
38
38
|
* ```
|
|
39
39
|
*/
|
|
40
|
-
export declare const TEXTURE_FAR_BASE = "https://cdn.jsdelivr.net/gh/johnmorrisdotca/wakusei-planets@v0.
|
|
40
|
+
export declare const TEXTURE_FAR_BASE = "https://cdn.jsdelivr.net/gh/johnmorrisdotca/wakusei-planets@v0.4.0/textures/";
|
|
41
41
|
/**
|
|
42
42
|
* The `<wakusei-body>` custom element: a body of the solar system, drawn in a look.
|
|
43
43
|
*
|
|
44
44
|
* Attributes: `body` (a name, such as `jupiter`), `look` (`line`, `realistic` or `painted`), `size` (pixels across), `time` (`now` or an ISO date: the body as the Earth sees it then; leave it out for a portrait),
|
|
45
45
|
* `tilt`, `pitch`, `phase` and `meridian` (a portrait's pose, degrees), `turn` (a portrait turns this many degrees a second), `rate` (simulated seconds for each real second), `moons` (draw the planet's moons on their orbits),
|
|
46
|
-
* `range` (planet radii the moons picture reaches), `scale-to` (draw to scale with another body), `live` (`always`, `hover` or `off`: when it takes the page's one WebGL context), `texture-base` (where the surface pictures are) and `lang` (`en` or `ja`).
|
|
46
|
+
* `range` (planet radii the moons picture reaches), `scale-to` (draw to scale with another body), `span-km` (draw to scale: the half-width of the picture in kilometres, the same in every picture of a lineup), `live` (`always`, `hover` or `off`: when it takes the page's one WebGL context), `texture-base` (where the surface pictures are) and `lang` (`en` or `ja`).
|
|
47
47
|
*
|
|
48
48
|
* @example
|
|
49
49
|
* ```ts no-run
|
package/dist/element.js
CHANGED
|
@@ -55,10 +55,18 @@ function extentOf(id, options) {
|
|
|
55
55
|
const far = Math.max(1.8, ringReach(f) * 1.15, ...near.map((m) => m.reach * 1.1));
|
|
56
56
|
return options.range ?? far;
|
|
57
57
|
}
|
|
58
|
+
if (options.spanKm !== undefined)
|
|
59
|
+
return options.spanKm / f.radiusKm;
|
|
58
60
|
if (options.scaleTo !== undefined)
|
|
59
61
|
return (BODIES[options.scaleTo].radiusKm * 1.06) / f.radiusKm;
|
|
60
62
|
return Math.max(id === "sun" ? 1.55 : 1.06, ringReach(f) * 1.04);
|
|
61
63
|
}
|
|
64
|
+
/** Keep the body in the picture: at least a quarter of its width stays inside the edge, however far the view is moved. `pan` is in half-widths of the picture. */
|
|
65
|
+
function clampPan(pan, extent, zoom) {
|
|
66
|
+
const half = extent / Math.max(0.05, zoom);
|
|
67
|
+
const limit = 1 + 0.5 / half;
|
|
68
|
+
return Math.max(-limit, Math.min(limit, pan));
|
|
69
|
+
}
|
|
62
70
|
const TEMPLATE = `<style>
|
|
63
71
|
:host { display: block; width: var(--wakusei-size, 320px); max-width: 100%; aspect-ratio: 1 / 1; position: relative; contain: layout style; }
|
|
64
72
|
#stage { position: absolute; inset: 0; }
|
|
@@ -69,7 +77,7 @@ const TEMPLATE = `<style>
|
|
|
69
77
|
*
|
|
70
78
|
* Attributes: `body` (a name, such as `jupiter`), `look` (`line`, `realistic` or `painted`), `size` (pixels across), `time` (`now` or an ISO date: the body as the Earth sees it then; leave it out for a portrait),
|
|
71
79
|
* `tilt`, `pitch`, `phase` and `meridian` (a portrait's pose, degrees), `turn` (a portrait turns this many degrees a second), `rate` (simulated seconds for each real second), `moons` (draw the planet's moons on their orbits),
|
|
72
|
-
* `range` (planet radii the moons picture reaches), `scale-to` (draw to scale with another body), `live` (`always`, `hover` or `off`: when it takes the page's one WebGL context), `texture-base` (where the surface pictures are) and `lang` (`en` or `ja`).
|
|
80
|
+
* `range` (planet radii the moons picture reaches), `scale-to` (draw to scale with another body), `span-km` (draw to scale: the half-width of the picture in kilometres, the same in every picture of a lineup), `live` (`always`, `hover` or `off`: when it takes the page's one WebGL context), `texture-base` (where the surface pictures are) and `lang` (`en` or `ja`).
|
|
73
81
|
*
|
|
74
82
|
* @example
|
|
75
83
|
* ```ts no-run
|
|
@@ -83,7 +91,7 @@ const TEMPLATE = `<style>
|
|
|
83
91
|
* ```
|
|
84
92
|
*/
|
|
85
93
|
export class WakuseiBody extends HTMLElement {
|
|
86
|
-
static observedAttributes = ["body", "look", "size", "time", "tilt", "pitch", "phase", "meridian", "turn", "rate", "moons", "range", "scale-to", "live", "texture-base", "texture-far-base", "lang", "labels"];
|
|
94
|
+
static observedAttributes = ["body", "look", "size", "time", "tilt", "pitch", "phase", "meridian", "turn", "rate", "moons", "range", "scale-to", "span-km", "live", "texture-base", "texture-far-base", "lang", "labels"];
|
|
87
95
|
#stage;
|
|
88
96
|
#state = "line";
|
|
89
97
|
#renderer;
|
|
@@ -209,10 +217,6 @@ export class WakuseiBody extends HTMLElement {
|
|
|
209
217
|
if (this.look === "line")
|
|
210
218
|
return false;
|
|
211
219
|
this.#wantLive = true;
|
|
212
|
-
if (delegates.has(this.body)) {
|
|
213
|
-
await this.#delegated(delegates.get(this.body));
|
|
214
|
-
return true;
|
|
215
|
-
}
|
|
216
220
|
await this.#ensureView();
|
|
217
221
|
const ok = (await this.#view?.focus()) === true;
|
|
218
222
|
if (ok) {
|
|
@@ -227,10 +231,6 @@ export class WakuseiBody extends HTMLElement {
|
|
|
227
231
|
/** Give the WebGL context back: the picture stays as a still. */
|
|
228
232
|
rest() {
|
|
229
233
|
this.#wantLive = false;
|
|
230
|
-
if (delegates.has(this.body)) {
|
|
231
|
-
this.#queue(true);
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
234
|
this.#stopTick();
|
|
235
235
|
if (this.#view !== undefined) {
|
|
236
236
|
this.#view.blur();
|
|
@@ -292,7 +292,8 @@ export class WakuseiBody extends HTMLElement {
|
|
|
292
292
|
const r = this.#request();
|
|
293
293
|
const scaleTo = this.getAttribute("scale-to");
|
|
294
294
|
const range = this.hasAttribute("range") ? num(this.getAttribute("range"), 0) : undefined;
|
|
295
|
-
const
|
|
295
|
+
const span = num(this.getAttribute("span-km"), 0);
|
|
296
|
+
const extent = extentOf(this.body, { ...(span > 0 ? { spanKm: span } : {}), ...(scaleTo !== null && scaleTo in BODIES ? { scaleTo } : {}), moons: r.moons, ...(range !== undefined && range > 0 ? { range } : {}) });
|
|
296
297
|
const moons = r.moons
|
|
297
298
|
? frame.moons
|
|
298
299
|
.filter((m) => m.distance <= extent * 1.05)
|
|
@@ -302,7 +303,7 @@ export class WakuseiBody extends HTMLElement {
|
|
|
302
303
|
return { id: m.id, x: rotated[0], y: rotated[1], z: rotated[2], ...(orbit !== undefined ? { orbit: tiltBy === 0 ? orbit : this.#tiltedOrbit(m.id, orbit, tiltBy) } : {}) };
|
|
303
304
|
})
|
|
304
305
|
: undefined;
|
|
305
|
-
return { pose: { pole, meridian, light }, extent, zoom: this.#zoom, panX: this.#panX, panY: this.#panY, ...(moons !== undefined ? { moons } : {}) };
|
|
306
|
+
return { pose: { pole, meridian, light }, extent, zoom: this.#zoom, panX: clampPan(this.#panX, extent, this.#zoom), panY: clampPan(this.#panY, extent, this.#zoom), ...(moons !== undefined ? { moons } : {}) };
|
|
306
307
|
}
|
|
307
308
|
#tilted = new Map();
|
|
308
309
|
#tiltedOrbit(id, orbit, tilt) {
|
|
@@ -359,7 +360,7 @@ export class WakuseiBody extends HTMLElement {
|
|
|
359
360
|
this.setAttribute("aria-label", this.#label());
|
|
360
361
|
if (this.hasAttribute("size"))
|
|
361
362
|
this.style.setProperty("--wakusei-size", `${num(this.getAttribute("size"), 320)}px`);
|
|
362
|
-
const delegate = delegates.get(this.body);
|
|
363
|
+
const delegate = this.look === "line" ? delegates.get(this.body) : undefined;
|
|
363
364
|
if (delegate !== undefined) {
|
|
364
365
|
await this.#delegated(delegate);
|
|
365
366
|
return;
|
|
@@ -441,12 +442,12 @@ export class WakuseiBody extends HTMLElement {
|
|
|
441
442
|
size,
|
|
442
443
|
pose: scene.pose,
|
|
443
444
|
...(r.moons ? { moons: true, ...(frame.time !== undefined ? { time: frame.time } : {}), range: scene.extent, moonsAt: (scene.moons ?? []).map((m) => ({ id: m.id, x: m.x, y: m.y, z: m.z, distance: Math.hypot(m.x, m.y, m.z) })), orbits: new Map((scene.moons ?? []).filter((m) => m.orbit !== undefined).map((m) => [m.id, m.orbit])) } : {}),
|
|
444
|
-
...(scaleTo !== null
|
|
445
|
+
...(scaleTo !== null || this.hasAttribute("span-km") ? { fill: this.#fill() } : {}),
|
|
445
446
|
...(this.getAttribute("lang") === "ja" ? { lang: "ja" } : {}),
|
|
446
447
|
...(this.getAttribute("labels") === "off" ? { labels: false } : {}),
|
|
447
448
|
...(stroke !== "" ? { stroke } : {}),
|
|
448
449
|
...(paper !== "" ? { paper } : {}),
|
|
449
|
-
...(this.#zoom !== 1 ? { zoom: this.#zoom, panX:
|
|
450
|
+
...(this.#zoom !== 1 ? { zoom: this.#zoom, panX: scene.panX, panY: scene.panY } : {}),
|
|
450
451
|
});
|
|
451
452
|
this.#stage.innerHTML = html;
|
|
452
453
|
}
|
|
@@ -504,30 +505,34 @@ export class WakuseiBody extends HTMLElement {
|
|
|
504
505
|
if (this.#visible)
|
|
505
506
|
this.#still();
|
|
506
507
|
}
|
|
507
|
-
/** A body another package draws (the Earth
|
|
508
|
+
/** A body whose line look another package draws (the Earth's globe with its countries). It is drawn at the body's size in a scale picture, never larger than the picture. */
|
|
508
509
|
async #delegated(delegate) {
|
|
509
510
|
if (this.#view !== undefined) {
|
|
510
511
|
this.#view.dispose();
|
|
511
512
|
this.#view = undefined;
|
|
512
513
|
this.#viewKey = "";
|
|
513
514
|
}
|
|
514
|
-
const shaded = this.look !== "line" && (this.#wantLive || (this.#hasPriority() && (this.getAttribute("live") ?? "always") === "always"));
|
|
515
|
-
const kind = shaded ? "live" : "line";
|
|
516
|
-
const time = this.#start === undefined ? "now" : new Date(this.#start).toISOString();
|
|
517
|
-
const base = this.getAttribute("texture-base");
|
|
518
515
|
const center = this.hasAttribute("meridian") ? `${num(this.getAttribute("meridian"), 10)},20` : "10,20";
|
|
519
|
-
const
|
|
516
|
+
const size = Math.round(this.clientWidth || 320);
|
|
517
|
+
const fill = this.#fill();
|
|
518
|
+
const key = `line|${center}|${fill}`;
|
|
520
519
|
if (this.#delegateEl !== undefined && this.#delegateKind === key)
|
|
521
520
|
return;
|
|
522
|
-
const
|
|
523
|
-
const el = kind === "live" ? await delegate.live({ center, time, textureBase: base }) : await delegate.line({ center, size });
|
|
521
|
+
const el = await delegate.line({ center, size });
|
|
524
522
|
this.#delegateEl?.remove();
|
|
525
523
|
this.#stage.innerHTML = "";
|
|
526
|
-
el.style.cssText =
|
|
524
|
+
el.style.cssText = `display:block;width:${fill * 100}%;height:${fill * 100}%;aspect-ratio:1;position:absolute;left:${(1 - fill) * 50}%;top:${(1 - fill) * 50}%`;
|
|
527
525
|
this.#stage.append(el);
|
|
528
526
|
this.#delegateEl = el;
|
|
529
527
|
this.#delegateKind = key;
|
|
530
|
-
this.#set(
|
|
528
|
+
this.#set("line");
|
|
529
|
+
}
|
|
530
|
+
/** How much of the picture's width the body's disc takes: 1 alone, less in a scale picture (`scale-to`, `span-km`). */
|
|
531
|
+
#fill() {
|
|
532
|
+
const scaleTo = this.getAttribute("scale-to");
|
|
533
|
+
const span = num(this.getAttribute("span-km"), 0);
|
|
534
|
+
const half = span > 0 ? span : scaleTo !== null && scaleTo in BODIES ? BODIES[scaleTo].radiusKm * 1.06 : 0;
|
|
535
|
+
return half > 0 ? Math.max(0.01, Math.min(1, BODIES[this.body].radiusKm / half)) : 1;
|
|
531
536
|
}
|
|
532
537
|
/** Make the view's still, once, when it is in sight. */
|
|
533
538
|
#still() {
|
package/dist/embed.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { type BodyId, type Look } from "./facts.ts";
|
|
2
|
+
/**
|
|
3
|
+
* The ways `embedCode` writes a body into a page.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* ```ts
|
|
7
|
+
* import { EMBED_KINDS } from "@johnmorrisdotca/wakusei-planets";
|
|
8
|
+
*
|
|
9
|
+
* console.log(EMBED_KINDS.join(", "));
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
export declare const EMBED_KINDS: readonly ["html", "module", "react", "vue", "angular", "svelte", "iframe"];
|
|
13
|
+
/**
|
|
14
|
+
* One of the ways in `EMBED_KINDS`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { EMBED_KINDS, type EmbedKind } from "@johnmorrisdotca/wakusei-planets";
|
|
19
|
+
*
|
|
20
|
+
* const kind: EmbedKind = EMBED_KINDS[2];
|
|
21
|
+
* console.log(kind);
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export type EmbedKind = (typeof EMBED_KINDS)[number];
|
|
25
|
+
/**
|
|
26
|
+
* What the reader chose: the body, how it is drawn, and whether it is a portrait or the sky at a date.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* import { embedCode, type EmbedOptions } from "@johnmorrisdotca/wakusei-planets";
|
|
31
|
+
*
|
|
32
|
+
* const options: EmbedOptions = { body: "saturn", look: "painted", size: 320, turn: 12 };
|
|
33
|
+
* console.log(embedCode(options, "html"));
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export interface EmbedOptions {
|
|
37
|
+
body: BodyId;
|
|
38
|
+
look?: Look;
|
|
39
|
+
/** The date and time as an ISO string, or `now`: the body as the Earth sees it then. Left out, a portrait. */
|
|
40
|
+
time?: string;
|
|
41
|
+
/** A planet with its moons on their orbits (needs `time`). */
|
|
42
|
+
moons?: boolean;
|
|
43
|
+
/** Degrees a second it turns by itself; left out or 0, it is still. */
|
|
44
|
+
turn?: number;
|
|
45
|
+
/** Pixels across. */
|
|
46
|
+
size?: number;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Where the embed code points: the package's version on jsDelivr, and the published demo, where `embed.html` is.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* import { embedCode } from "@johnmorrisdotca/wakusei-planets";
|
|
54
|
+
*
|
|
55
|
+
* console.log(embedCode({ body: "mars", look: "line" }, "iframe", { site: "https://example.com/wakusei/" }));
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export interface EmbedSettings {
|
|
59
|
+
/** The published demo's address, ending in a slash. */
|
|
60
|
+
site?: string;
|
|
61
|
+
/** The package's address on the CDN, with its version. */
|
|
62
|
+
cdn?: string;
|
|
63
|
+
}
|
|
64
|
+
/** The entry point that holds a body's shaded and painted look. */
|
|
65
|
+
export declare function entryOf(id: BodyId): string;
|
|
66
|
+
/**
|
|
67
|
+
* The text that puts a body in a page, for one way of making the page. Each way is built, parsed or run by the package's tests: the plain HTML one with a script tag from jsDelivr, an ES module, a React component,
|
|
68
|
+
* a Vue single-file component, an Angular standalone component, a Svelte component, and an iframe of the demo's `embed.html`.
|
|
69
|
+
*
|
|
70
|
+
* @param options - The body, its look, the date, the moons, the turn and the size.
|
|
71
|
+
* @param kind - The way the page is made; `html` by default.
|
|
72
|
+
* @param settings - The CDN and the demo's address, when they are not the package's own.
|
|
73
|
+
* @returns The text to paste into the page's source.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { embedCode } from "@johnmorrisdotca/wakusei-planets";
|
|
78
|
+
*
|
|
79
|
+
* console.log(embedCode({ body: "jupiter", look: "realistic", time: "now", moons: true }, "react"));
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export declare function embedCode(options: EmbedOptions, kind?: EmbedKind, settings?: EmbedSettings): string;
|
|
83
|
+
/**
|
|
84
|
+
* The credits that travel with a picture of a body: the line and shaded looks are drawn from numbers, the painted look uses public-domain pictures.
|
|
85
|
+
*
|
|
86
|
+
* @param options - The choices, so only what is used is named.
|
|
87
|
+
* @returns A short line of credit to put near the picture.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```ts
|
|
91
|
+
* import { embedCredit } from "@johnmorrisdotca/wakusei-planets";
|
|
92
|
+
*
|
|
93
|
+
* console.log(embedCredit({ body: "mars", look: "painted" }));
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare function embedCredit(options: EmbedOptions): string;
|
package/dist/embed.js
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// The text to put a body in a page, for each way a page is made: a script tag from a CDN, an ES module, React, Vue, Angular, Svelte, or an iframe of `embed.html`. The demo's "Put it in your page"
|
|
2
|
+
// section shows these as the reader changes a choice, and the tests build or parse every one. Pure: no DOM.
|
|
3
|
+
import { BODIES } from "./facts.js";
|
|
4
|
+
import { VERSION } from "./version.js";
|
|
5
|
+
/**
|
|
6
|
+
* The ways `embedCode` writes a body into a page.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { EMBED_KINDS } from "@johnmorrisdotca/wakusei-planets";
|
|
11
|
+
*
|
|
12
|
+
* console.log(EMBED_KINDS.join(", "));
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export const EMBED_KINDS = ["html", "module", "react", "vue", "angular", "svelte", "iframe"];
|
|
16
|
+
const SITE = "https://johnmorrisdotca.github.io/wakusei-planets/";
|
|
17
|
+
const CDN = `https://cdn.jsdelivr.net/npm/@johnmorrisdotca/wakusei-planets@${VERSION}`;
|
|
18
|
+
const PACKAGE = "@johnmorrisdotca/wakusei-planets";
|
|
19
|
+
/** The entry point that holds a body's shaded and painted look. */
|
|
20
|
+
export function entryOf(id) {
|
|
21
|
+
const parent = BODIES[id].parent;
|
|
22
|
+
return parent === undefined ? id : `moons-${parent}`;
|
|
23
|
+
}
|
|
24
|
+
/** The attributes of the element for these choices, in the order they are written. */
|
|
25
|
+
function attributesOf(o) {
|
|
26
|
+
const out = [["body", o.body], ["look", o.look ?? "realistic"]];
|
|
27
|
+
if (o.size !== undefined && o.size !== 320)
|
|
28
|
+
out.push(["size", String(o.size)]);
|
|
29
|
+
if (o.time !== undefined)
|
|
30
|
+
out.push(["time", o.time]);
|
|
31
|
+
if (o.moons === true && o.time !== undefined)
|
|
32
|
+
out.push(["moons", ""]);
|
|
33
|
+
if (o.turn !== undefined && o.turn > 0)
|
|
34
|
+
out.push(["turn", String(o.turn)]);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
const quote = (v) => `"${v.replace(/&/g, "&").replace(/"/g, """)}"`;
|
|
38
|
+
const tagAttrs = (o) => attributesOf(o).map(([k, v]) => (v === "" ? k : `${k}=${quote(v)}`)).join(" ");
|
|
39
|
+
const needsShading = (o) => (o.look ?? "realistic") !== "line";
|
|
40
|
+
/**
|
|
41
|
+
* The text that puts a body in a page, for one way of making the page. Each way is built, parsed or run by the package's tests: the plain HTML one with a script tag from jsDelivr, an ES module, a React component,
|
|
42
|
+
* a Vue single-file component, an Angular standalone component, a Svelte component, and an iframe of the demo's `embed.html`.
|
|
43
|
+
*
|
|
44
|
+
* @param options - The body, its look, the date, the moons, the turn and the size.
|
|
45
|
+
* @param kind - The way the page is made; `html` by default.
|
|
46
|
+
* @param settings - The CDN and the demo's address, when they are not the package's own.
|
|
47
|
+
* @returns The text to paste into the page's source.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { embedCode } from "@johnmorrisdotca/wakusei-planets";
|
|
52
|
+
*
|
|
53
|
+
* console.log(embedCode({ body: "jupiter", look: "realistic", time: "now", moons: true }, "react"));
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function embedCode(options, kind = "html", settings = {}) {
|
|
57
|
+
const cdn = settings.cdn ?? CDN;
|
|
58
|
+
const site = settings.site ?? SITE;
|
|
59
|
+
const shaded = needsShading(options);
|
|
60
|
+
const entry = entryOf(options.body);
|
|
61
|
+
const size = options.size ?? 320;
|
|
62
|
+
if (kind === "iframe") {
|
|
63
|
+
const query = new URLSearchParams({ body: options.body, look: options.look ?? "realistic" });
|
|
64
|
+
if (options.time !== undefined)
|
|
65
|
+
query.set("time", options.time);
|
|
66
|
+
if (options.moons === true && options.time !== undefined)
|
|
67
|
+
query.set("moons", "1");
|
|
68
|
+
if (options.turn !== undefined && options.turn > 0)
|
|
69
|
+
query.set("turn", String(options.turn));
|
|
70
|
+
return `<iframe\n src=${quote(`${site}embed.html?${query.toString()}`)}\n title=${quote(BODIES[options.body].name.en)}\n width="${size}"\n height="${size}"\n loading="lazy"\n style="border: 0"\n></iframe>`;
|
|
71
|
+
}
|
|
72
|
+
if (kind === "html") {
|
|
73
|
+
const scripts = [`<script type="module" src="${cdn}/element/+esm"></script>`, ...(shaded ? [`<script type="module" src="${cdn}/${entry}/+esm"></script>`] : [])];
|
|
74
|
+
return `${scripts.join("\n")}\n\n<wakusei-body ${tagAttrs(options)}></wakusei-body>`;
|
|
75
|
+
}
|
|
76
|
+
const imports = [`import "${PACKAGE}/element";`, ...(shaded ? [`import "${PACKAGE}/${entry}";`] : [])];
|
|
77
|
+
if (kind === "module") {
|
|
78
|
+
const sets = attributesOf(options).map(([k, v]) => `planet.setAttribute(${JSON.stringify(k)}, ${JSON.stringify(v)});`);
|
|
79
|
+
return `${imports.join("\n")}\n\nconst planet = document.createElement("wakusei-body");\n${sets.join("\n")}\ndocument.querySelector("#planet").append(planet);`;
|
|
80
|
+
}
|
|
81
|
+
const dynamic = [`void import("${PACKAGE}/element");`, ...(shaded ? [`void import("${PACKAGE}/${entry}");`] : [])];
|
|
82
|
+
if (kind === "react") {
|
|
83
|
+
const props = attributesOf(options).map(([k, v]) => (v === "" ? k : `${k}=${quote(v)}`)).join(" ");
|
|
84
|
+
return `import { useEffect } from "react";\n\nexport function Planet() {\n useEffect(() => {\n // The element needs a browser, so it is imported in an effect, never at the top of the file.\n${dynamic.map((l) => ` ${l}`).join("\n")}\n }, []);\n return <wakusei-body ${props} />;\n}`;
|
|
85
|
+
}
|
|
86
|
+
if (kind === "vue") {
|
|
87
|
+
return `<script setup lang="ts">\nimport { onMounted } from "vue";\n\nonMounted(() => {\n${dynamic.map((l) => ` ${l}`).join("\n")}\n});\n</script>\n\n<template>\n <wakusei-body ${tagAttrs(options)}></wakusei-body>\n</template>`;
|
|
88
|
+
}
|
|
89
|
+
if (kind === "angular") {
|
|
90
|
+
return `import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit } from "@angular/core";\n\n@Component({\n selector: "app-planet",\n standalone: true,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n template: \`<wakusei-body ${tagAttrs(options)}></wakusei-body>\`,\n})\nexport class PlanetComponent implements OnInit {\n ngOnInit(): void {\n // The element needs a browser: ngOnInit also runs when a server renders.\n if (typeof window !== "undefined") {\n${dynamic.map((l) => ` ${l}`).join("\n")}\n }\n }\n}`;
|
|
91
|
+
}
|
|
92
|
+
return `<script lang="ts">\n import { onMount } from "svelte";\n\n onMount(() => {\n${dynamic.map((l) => ` ${l}`).join("\n")}\n });\n</script>\n\n<wakusei-body ${tagAttrs(options)}></wakusei-body>`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The credits that travel with a picture of a body: the line and shaded looks are drawn from numbers, the painted look uses public-domain pictures.
|
|
96
|
+
*
|
|
97
|
+
* @param options - The choices, so only what is used is named.
|
|
98
|
+
* @returns A short line of credit to put near the picture.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```ts
|
|
102
|
+
* import { embedCredit } from "@johnmorrisdotca/wakusei-planets";
|
|
103
|
+
*
|
|
104
|
+
* console.log(embedCredit({ body: "mars", look: "painted" }));
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export function embedCredit(options) {
|
|
108
|
+
const base = "Wakusei Planets by John Morris (MIT). Sizes, tilt and rotation: IAU and NASA fact sheets.";
|
|
109
|
+
const painted = (options.look ?? "realistic") === "painted" ? " Surface pictures: NASA, USGS and JPL imagery in the public domain (details in the package's NOTICE.md)." : "";
|
|
110
|
+
const earth = options.body === "earth" ? " Earth: NASA Earth Observatory, Blue Marble." : "";
|
|
111
|
+
return `${base}${painted}${earth}`;
|
|
112
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { apparent, moonGeocentric, heliocentric, orbitPath, system, type Apparen
|
|
|
3
3
|
export { drawnTilt, portrait, type PortraitOptions } from "./pose.ts";
|
|
4
4
|
export { lineSvg, mix, type LineOptions } from "./line.ts";
|
|
5
5
|
export { ringStrip, type RingStrip } from "./scene/rings.ts";
|
|
6
|
+
export { embedCode, embedCredit, EMBED_KINDS, type EmbedKind, type EmbedOptions, type EmbedSettings } from "./embed.ts";
|
package/dist/index.js
CHANGED
|
@@ -3,3 +3,4 @@ export { apparent, moonGeocentric, heliocentric, orbitPath, system } from "./eph
|
|
|
3
3
|
export { drawnTilt, portrait } from "./pose.js";
|
|
4
4
|
export { lineSvg, mix } from "./line.js";
|
|
5
5
|
export { ringStrip } from "./scene/rings.js";
|
|
6
|
+
export { embedCode, embedCredit, EMBED_KINDS } from "./embed.js";
|
package/dist/scene/body.js
CHANGED
|
@@ -52,7 +52,7 @@ export function createBodyItem(options) {
|
|
|
52
52
|
key: options.key,
|
|
53
53
|
async build({ three: T, assets, width, height }) {
|
|
54
54
|
const look = lookOf(options.id) ?? fallbackLook(facts);
|
|
55
|
-
const wantPainted = options.look === "painted" && look.painted !== undefined;
|
|
55
|
+
const wantPainted = (options.look === "painted" || look.mapped === true) && look.painted !== undefined;
|
|
56
56
|
const geometry = assets.acquire("wk:sphere", () => new T.SphereGeometry(1, 128, 64), (g) => g.dispose());
|
|
57
57
|
const shader = assets.acquire(`wk:body:${options.id}:r`, () => makeBodyMaterial(T, look, false), (m) => m.dispose());
|
|
58
58
|
const paintedMaterial = wantPainted ? assets.acquire(`wk:body:${options.id}:p`, () => makeBodyMaterial(T, look, true), (m) => m.dispose()) : undefined;
|
package/dist/scene/look.d.ts
CHANGED
|
@@ -74,6 +74,8 @@ export interface BodyLook {
|
|
|
74
74
|
/** How much of the night side shows (0 to 1). Default 0.04. */
|
|
75
75
|
ambient?: number;
|
|
76
76
|
painted?: PaintedMap;
|
|
77
|
+
/** Draw the painted map in the realistic look too: for a body with no honest drawing from numbers (the Earth's continents). */
|
|
78
|
+
mapped?: boolean;
|
|
77
79
|
}
|
|
78
80
|
/**
|
|
79
81
|
* Teach the package how to draw a body in three.js. Each body's entry point (`@johnmorrisdotca/wakusei-planets/jupiter`) calls this once as it loads; call it yourself to add or replace a look.
|
package/dist/scene/store.d.ts
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import type { BodyId } from "../facts.ts";
|
|
2
2
|
import type { BodyLook } from "./look.ts";
|
|
3
|
-
/** A body
|
|
3
|
+
/** A body whose line look another package's element draws (the Earth, by chikyu-earth) instead of this one: the element asks it for what to show. The shaded and painted looks are always this package's. */
|
|
4
4
|
export interface Delegate {
|
|
5
5
|
/** The line look: an element for the body, centred on a longitude and latitude (`"lon,lat"`). */
|
|
6
6
|
line(options: {
|
|
7
7
|
center: string;
|
|
8
8
|
size: number;
|
|
9
9
|
}): Promise<HTMLElement>;
|
|
10
|
-
/** The shaded and painted looks, drawn live: an element lit by the Sun at `time` (`"now"` or an ISO date). */
|
|
11
|
-
live(options: {
|
|
12
|
-
center: string;
|
|
13
|
-
time: string;
|
|
14
|
-
textureBase: string | null;
|
|
15
|
-
}): Promise<HTMLElement>;
|
|
16
10
|
}
|
|
17
11
|
export declare const looks: Map<BodyId, BodyLook>, waiting: Set<() => void>, delegates: Map<BodyId, Delegate>;
|
|
18
12
|
/** Call `wake` whenever a look is registered; returns a function that stops it. */
|
|
Binary file
|
|
Binary file
|
package/dist/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.4.0";
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = "0.
|
|
1
|
+
export const VERSION = "0.4.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@johnmorrisdotca/wakusei-planets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Wakusei Planets 惑星 — The Sun, planets and moons for the web: each as a clean line drawing, a shaded realistic drawing or a painted surface map, with real sizes, axial tilt and rotation as data, and positions of the moons for any date and time. SVG for the lines, three.js (optional) for the rest.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"planets",
|
|
@@ -168,6 +168,7 @@
|
|
|
168
168
|
"check": "pnpm lint && pnpm typecheck && pnpm test && pnpm build && node scripts/check-package.ts",
|
|
169
169
|
"prepublishOnly": "pnpm check",
|
|
170
170
|
"family:readme": "node scripts/family-readme.mjs",
|
|
171
|
+
"readme:images": "node scripts/readme-images.mjs",
|
|
171
172
|
"site": "pnpm build && node scripts/site.ts",
|
|
172
173
|
"dev": "pnpm site && node scripts/dev.ts",
|
|
173
174
|
"test:demo": "pnpm site && node scripts/docs-site.mjs build && playwright test --project=chromium-desk --project=chromium-phone --project=webkit-desk --project=webkit-phone",
|
|
@@ -186,7 +187,7 @@
|
|
|
186
187
|
"@angular/core": "^22.2.4",
|
|
187
188
|
"@angular/platform-browser": "^22.2.4",
|
|
188
189
|
"@eslint/js": "^9.0.0",
|
|
189
|
-
"@johnmorrisdotca/chikyu-earth": "^0.
|
|
190
|
+
"@johnmorrisdotca/chikyu-earth": "^0.10.0",
|
|
190
191
|
"@playwright/test": "1.64.0",
|
|
191
192
|
"@sveltejs/vite-plugin-svelte": "^7.3.1",
|
|
192
193
|
"@types/node": "^24.0.0",
|
|
@@ -216,11 +217,11 @@
|
|
|
216
217
|
},
|
|
217
218
|
"packageManager": "pnpm@10.28.0",
|
|
218
219
|
"dependencies": {
|
|
219
|
-
"@johnmorrisdotca/kazoku-ui": "^0.
|
|
220
|
+
"@johnmorrisdotca/kazoku-ui": "^0.11.0"
|
|
220
221
|
},
|
|
221
222
|
"peerDependencies": {
|
|
222
|
-
"
|
|
223
|
-
"
|
|
223
|
+
"@johnmorrisdotca/chikyu-earth": ">=0.10.0",
|
|
224
|
+
"three": ">=0.160.0"
|
|
224
225
|
},
|
|
225
226
|
"peerDependenciesMeta": {
|
|
226
227
|
"three": {
|