@rr0/ufoathome 0.1.0 → 0.3.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/README.md +301 -2
- package/dist-embed/assets/UfoMessages_fr-COCxf8Q_.js +1 -0
- package/dist-embed/assets/UfoRecorderMessages_fr-DRl6tTYJ.js +1 -0
- package/dist-embed/assets/stars-mag7.5-DDr9QasD.bin +0 -0
- package/dist-embed/rr0-ufo-recorder.mjs +4385 -448
- package/dist-embed-scene/assets/UfoMessages_fr-COCxf8Q_.js +1 -0
- package/dist-embed-scene/assets/stars-mag7.5-DDr9QasD.bin +0 -0
- package/dist-embed-scene/rr0-scene.mjs +4354 -0
- package/dist-embed-ufo/assets/UfoMessages_fr-COCxf8Q_.js +1 -0
- package/dist-embed-ufo/rr0-ufo.mjs +133 -0
- package/dist-embed-witnesses/assets/UfoMessages_fr-COCxf8Q_.js +1 -0
- package/dist-embed-witnesses/assets/WitnessSelectorMessages_en-D8xgZDfY.js +1 -0
- package/dist-embed-witnesses/assets/WitnessSelectorMessages_fr-C0GHqC_J.js +1 -0
- package/dist-embed-witnesses/rr0-ufo-witnesses.mjs +146 -0
- package/package.json +20 -9
- package/dist-embed-player/rr0-ufo-player.mjs +0 -275
package/README.md
CHANGED
|
@@ -1,5 +1,304 @@
|
|
|
1
1
|
<img src="doc/web/ufoathome/UFOAtHome.png" align=right alt="UFO@home logo">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# UFO@home
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**UFO@home** lets a UFO witness record the shape, appearance and movement of what they saw — and replay it like a VCR —
|
|
6
|
+
instead of relying only on a written or spoken account. The approach follows [Roger Shepard's
|
|
7
|
+
recommendation](https://rr0.org/time/1/9/6/8/07/29/Symposium/Shepard/index_fr.html) that a visual reconstruction of a
|
|
8
|
+
testimony is more faithful than an oral or written one.
|
|
9
|
+
|
|
10
|
+
Originally a Java applet (2003), the project has been rewritten from scratch in TypeScript: a small,
|
|
11
|
+
dependency-light engine (keyframe timeline, recording, playback, Canvas2D rendering) wrapped in four vanilla
|
|
12
|
+
[Web Components](https://developer.mozilla.org/en-US/docs/Web/API/Web_components) — no UI framework, no build step
|
|
13
|
+
required by the consuming page. One of the four (`<rr0-scene>`) does pull in [Three.js](https://threejs.org/)
|
|
14
|
+
for an optional 3D backdrop — see [`<rr0-scene>`](#rr0-scene--3d-decor) below for why that's an isolated,
|
|
15
|
+
opt-in bundle rather than a project-wide dependency.
|
|
16
|
+
|
|
17
|
+
### Naming
|
|
18
|
+
|
|
19
|
+
`<rr0-ufo>` is the UFO's own 2D shape/appearance/movement layer — no "player" suffix, since read-only playback is
|
|
20
|
+
its default behavior and `<rr0-ufo-recorder>` is the one that needs a qualifier (it *adds* recording on top).
|
|
21
|
+
`<rr0-scene>` is named without "ufo" on purpose: it only renders a generic 3D decor (sky/horizon/stars) from a
|
|
22
|
+
real-world time and place, with no UFO-specific logic of its own — today it composes a nested `<rr0-ufo>` for the
|
|
23
|
+
common case (see its section below), but the decor itself could back other kinds of reconstructions later. A fully
|
|
24
|
+
generic version (accepting arbitrary overlay content instead of always creating its own `<rr0-ufo>`) is a natural
|
|
25
|
+
follow-up, not implemented yet. `<rr0-ufo-witnesses>` follows the same "adds a qualifier" logic as the recorder:
|
|
26
|
+
it *adds* a multi-witness selector on top of `<rr0-ufo>`, for cases that have more than one witness's own
|
|
27
|
+
recording of the same sighting.
|
|
28
|
+
|
|
29
|
+
See the [Wiki](https://github.com/RR0/UfoAtHome/wiki) for the project's history, and a live example embedded in
|
|
30
|
+
[rr0.org's UFO@home page](https://rr0.org/science/crypto/ufo/enquete/projet/UfoAtHome.html) and in its
|
|
31
|
+
[Chiles-Whitted case reconstruction](https://rr0.org/science/crypto/ufo/enquete/dossier/ChilesWhitted/index.html).
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm install @rr0/ufoathome
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Four self-contained, pre-built ES modules are published — each self-registers its custom element as soon as it's
|
|
40
|
+
imported, no explicit setup call needed:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<script type="module" src="/node_modules/@rr0/ufoathome/dist-embed-ufo/rr0-ufo.mjs"></script>
|
|
44
|
+
<script type="module" src="/node_modules/@rr0/ufoathome/dist-embed/rr0-ufo-recorder.mjs"></script>
|
|
45
|
+
<script type="module" src="/node_modules/@rr0/ufoathome/dist-embed-scene/rr0-scene.mjs"></script>
|
|
46
|
+
<script type="module" src="/node_modules/@rr0/ufoathome/dist-embed-witnesses/rr0-ufo-witnesses.mjs"></script>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
or, from a bundler:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import "@rr0/ufoathome/ufo" // registers <rr0-ufo>
|
|
53
|
+
import "@rr0/ufoathome/recorder" // registers <rr0-ufo-recorder> (and <rr0-ufo>, which it composes)
|
|
54
|
+
import "@rr0/ufoathome/scene" // registers <rr0-scene> (and <rr0-ufo>, which it composes)
|
|
55
|
+
import "@rr0/ufoathome/witnesses" // registers <rr0-ufo-witnesses> (and <rr0-ufo>, which it composes)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Only load the one(s) a given page actually needs — `rr0-scene.mjs` in particular pulls in Three.js and is far
|
|
59
|
+
heavier than the others (see its section below), so pages that just need playback should stick to `rr0-ufo.mjs`.
|
|
60
|
+
|
|
61
|
+
## `<rr0-ufo>` — read-only playback
|
|
62
|
+
|
|
63
|
+
The lightweight component (~9KB): a canvas plus Play/Pause/Loop/seek controls. Use it wherever a page only needs to
|
|
64
|
+
*replay* an already-recorded sighting — this is the one to embed in content pages.
|
|
65
|
+
|
|
66
|
+
```html
|
|
67
|
+
<rr0-ufo src="sighting.json"></rr0-ufo>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Member | Kind | Description |
|
|
71
|
+
|---|---|---|
|
|
72
|
+
| `src` | attribute | URL of a [`SightingRecordingJson`](#data-format) file, fetched automatically on connect and whenever the attribute changes |
|
|
73
|
+
| `sightingData` | property (get/set) | The current recording as a plain [`SightingRecordingJson`](#data-format) object |
|
|
74
|
+
| `sighting` | property (readonly) | The live `Sighting` model (real-world time/place + the recording's `Timeline`) |
|
|
75
|
+
| `canvasElement` | property (readonly) | The underlying `<canvas>` element |
|
|
76
|
+
| `renderer` | property (readonly) | The `CanvasRenderer` instance painting onto that canvas |
|
|
77
|
+
| `refresh()` | method | Re-reads the timeline's duration into the seek slider and repaints the current frame — call after externally mutating `sighting.timeline` |
|
|
78
|
+
| `loadFromSrc(url)` | method (async) | What the `src` attribute triggers internally; can be called directly too |
|
|
79
|
+
| `enableClickToPlay` | property (get/set, default `true`) | Whether clicking the canvas toggles Play/Pause (see below). Composing elements that need the canvas's own click for something else set this to `false` — see `<rr0-ufo-recorder>`. |
|
|
80
|
+
| `fullscreenTarget` | property (get/set, default: the component's own stage) | The element the fullscreen button requests fullscreen on. Composing elements that need a *different* element fullscreened set this — see `<rr0-scene>`. |
|
|
81
|
+
|
|
82
|
+
Playback matches the observation's *real reported duration* when it's known: set `time`/`endTime`, or `time`/
|
|
83
|
+
`durationSeconds`, in the [data format](#data-format) (`durationSeconds` takes precedence over `endTime` if both are
|
|
84
|
+
given). Watching a 5-minute sighting then takes 5 real minutes, not however long the recording itself took to
|
|
85
|
+
author (e.g. a quick mouse drag) — drag the seek bar directly to skip ahead. The start/end labels around the seek
|
|
86
|
+
bar show real clock times when `time` has an hour (e.g. `02:45` → `02:50`); otherwise they show `0:00` → the
|
|
87
|
+
duration actually available (the declared one if known, else the recording's own length). Playback loops by
|
|
88
|
+
default — click the loop button (pressed = looping) to play once and stop instead.
|
|
89
|
+
|
|
90
|
+
Clicking anywhere on the canvas also toggles Play/Pause (not just the button), matching common video-player UX.
|
|
91
|
+
While playing, the toolbar and the fullscreen button (top-right, semi-transparent over the content) auto-hide and
|
|
92
|
+
only reappear on hover — always shown while paused/stopped. The fullscreen button uses the standard Fullscreen API
|
|
93
|
+
(`requestFullscreen`/`exitFullscreen`); exiting with Escape is native browser behavior, nothing custom.
|
|
94
|
+
|
|
95
|
+
Labels (Play/Pause, Auto-replay, Current position, Duration, Fullscreen) are translated (English/French) based on
|
|
96
|
+
the visitor's `navigator.languages`, falling back to English — there's no language-picker UI, this is the only
|
|
97
|
+
mechanism.
|
|
98
|
+
|
|
99
|
+
## `<rr0-ufo-recorder>` — full editor
|
|
100
|
+
|
|
101
|
+
The authoring component (~540KB gzip — see below for why): everything `<rr0-ufo>` has, plus a shape/appearance
|
|
102
|
+
toolbar (oval/saucer/triangle presets, color, transparency, halo) and drag-to-record. It composes a nested
|
|
103
|
+
`<rr0-scene>` internally — not a bare `<rr0-ufo>` — so the shape being drawn is always seen against the
|
|
104
|
+
sighting's own real sky, computed live from whatever latitude/longitude/heading/orientation/observation-time
|
|
105
|
+
fields the toolbar currently holds (see [Architecture](#architecture)). This absorbs `<rr0-scene>`'s own
|
|
106
|
+
Three.js/`astronomy-engine` weight on top of the authoring-only code this element already carried (Recorder
|
|
107
|
+
engine, SamplingClock, appearance toolbar) — a page that only needs to *play* a sighting (the common case: an
|
|
108
|
+
rr0.org case dossier) should still embed the much lighter `<rr0-ufo>` (or `<rr0-scene>` alone) directly, never
|
|
109
|
+
this heavier authoring component.
|
|
110
|
+
|
|
111
|
+
```html
|
|
112
|
+
<rr0-ufo-recorder></rr0-ufo-recorder>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Usage: click **Record**, move the pointer over the canvas to draw the UFO's path, click **Stop**, then **Play** to
|
|
116
|
+
replay it. The nested `<rr0-ufo>`'s `enableClickToPlay` is set to `false` here — a completed recording drag also
|
|
117
|
+
fires a native "click" on the canvas, which would otherwise spuriously toggle playback right after recording.
|
|
118
|
+
|
|
119
|
+
All of the toolbar's own labels (shape presets, Color/Transparency/Halo, Add shape, Record/Stop, Export JSON,
|
|
120
|
+
Duration) are translated (English/French) the same way `<rr0-ufo>`'s own labels are — based on
|
|
121
|
+
`navigator.languages`, no picker UI.
|
|
122
|
+
|
|
123
|
+
| Member | Kind | Description |
|
|
124
|
+
|---|---|---|
|
|
125
|
+
| `sightingData` | property (get/set) | Delegates to the nested `<rr0-ufo>`'s `sightingData` |
|
|
126
|
+
| `appearance` | property (get/set, accepts a partial object on set) | `{ presetId: "oval" \| "saucer" \| "triangle", color: string, transparency: number, haloScale: number }` — the UFO's appearance used for the next recording |
|
|
127
|
+
|
|
128
|
+
## `<rr0-scene>` — 3D decor
|
|
129
|
+
|
|
130
|
+
The environmental variant (~530KB gzip — [Three.js](https://threejs.org/) plus
|
|
131
|
+
[`astronomy-engine`](https://github.com/cosinekitty/astronomy)'s planetary/lunar position tables, which don't
|
|
132
|
+
tree-shake since they're one shared data table used internally for every body — this is by far the heaviest
|
|
133
|
+
of the four bundles, load it only on pages that want it): everything `<rr0-ufo>` has, composited over a 3D
|
|
134
|
+
sky/horizon/starfield backdrop instead of a plain background. Same markup and members as `<rr0-ufo>` (`src`,
|
|
135
|
+
`sightingData`, `loadFromSrc`, `enableClickToPlay`) — it's a drop-in upgrade, including click-to-play/pause
|
|
136
|
+
anywhere on the scene (the nested `<rr0-ufo>`'s transparent canvas covers the whole stage). The fullscreen button
|
|
137
|
+
fullscreens the *whole* scene (3D backdrop included), not just the nested `<rr0-ufo>`'s own overlay — it sets the
|
|
138
|
+
nested element's `fullscreenTarget` to its own outer stage for this.
|
|
139
|
+
|
|
140
|
+
```html
|
|
141
|
+
<rr0-scene src="sighting.json"></rr0-scene>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**Real astronomy for misidentification spotting.** A recurring cause of UFO reports is a mundane astronomical
|
|
145
|
+
object or atmospheric optical effect — Venus (by far the most commonly misreported "UFO"), other planets, the
|
|
146
|
+
Moon, lens flare, or halo phenomena like sun dogs/moon dogs. `<rr0-scene>` renders the sky astronomically: real
|
|
147
|
+
Sun/Moon/Venus/Mars/Jupiter/Saturn positions and the Moon's phase via
|
|
148
|
+
[`astronomy-engine`](https://github.com/cosinekitty/astronomy) (see `src/engine/astronomy/CelestialPositions.ts`),
|
|
149
|
+
and a real star catalog (see below) instead of a randomized field, filtered to naked-eye visibility
|
|
150
|
+
(magnitude ≤ 7.5) since these are human eyewitness observations, not instrument-assisted ones. The sky's
|
|
151
|
+
darkness/color follows the sun's altitude (day/twilight bands/night), and its dawn/dusk glow is anchored on the
|
|
152
|
+
sun's real compass direction, not spread uniformly around the horizon — see `src/render3d/skyColors.ts`.
|
|
153
|
+
|
|
154
|
+
The witness's own pose — geographic position, elevation, and viewing heading/pitch/field of view — can vary over
|
|
155
|
+
the sighting's timeline via `observerTrack` in the sighting JSON (a keyframe array alongside `timeline`, same
|
|
156
|
+
hold-last/interpolated-lookup shape — see `src/engine/model/ObserverTrack.ts`), driving both the camera's own
|
|
157
|
+
orientation and which real-world instant the astronomy is computed for as playback advances. Older recordings
|
|
158
|
+
with no `observerTrack` fall back to the legacy static `place[0]` (see `resolveObserverPoseAt` in
|
|
159
|
+
`src/engine/model/Sighting.ts`) — usable for sky darkness/color and camera pitch/fov, but with no compass heading
|
|
160
|
+
to orient the camera by.
|
|
161
|
+
|
|
162
|
+
`src/engine/astronomy/SunPosition.ts` (the original vanilla, dependency-free NOAA/Spencer solar position
|
|
163
|
+
approximation) stays in the repo, tested, and still backs `skyBrightness()`'s twilight-band classification — but
|
|
164
|
+
the live rendering path now uses `astronomy-engine` for the Sun too, for a single source of truth and to get the
|
|
165
|
+
Sun's azimuth from the same call used for the sky's directional glow.
|
|
166
|
+
|
|
167
|
+
`<rr0-ufo-recorder>` has editor fields for the witness's latitude/longitude/heading and the observation's start
|
|
168
|
+
date/time (all optional) — filling in lat+lng writes both the legacy `place` and a single t=0 `observerTrack`
|
|
169
|
+
keyframe (elevation/pitch/field of view stay at neutral defaults; there's no UI yet for authoring the observer
|
|
170
|
+
*moving* over time, only a single static pose per recording).
|
|
171
|
+
|
|
172
|
+
Not yet done: sun dog/moon dog/halo rendering, a real (non-flat) ground/terrain, precipitation and other optical
|
|
173
|
+
effects (lens flare, mirage), and a multi-keyframe `observerTrack` authoring UI (today the recorder can only set
|
|
174
|
+
one static pose; an observer that moves/re-orients mid-recording still needs hand-authored or scripted JSON). The
|
|
175
|
+
Moon's phase currently only dims/brightens its disc's overall
|
|
176
|
+
color rather than rendering a geometrically accurate crescent shape — a natural follow-up.
|
|
177
|
+
|
|
178
|
+
**Regenerating the star catalog.** `src/assets/stars-mag7.5.bin` (a compact binary asset, four concatenated
|
|
179
|
+
`Float32Array` sections: ra/dec/mag/ci — see `src/render3d/StarCatalog.ts` for the exact layout) is generated
|
|
180
|
+
from the [HYG Database v4.1](https://github.com/astronexus/HYG-Database) (CC BY-SA), filtered to magnitude ≤ 7.5.
|
|
181
|
+
To regenerate it: download `hyg/CURRENT/hygdata_v41.csv` from that repo into `scripts/data/hygdata_v41.csv`
|
|
182
|
+
(gitignored — not checked in, ~34MB), then run `npm run build:stars`. The generated `.bin`/`.json` pair *is*
|
|
183
|
+
checked in (~400KB) since it's small and doesn't need regenerating on every install.
|
|
184
|
+
|
|
185
|
+
The UFO shape itself deliberately stays a 2D overlay on top of the 3D decor, never "upgraded" to a 3D object: it's
|
|
186
|
+
what the witness reported — possibly a misidentification or optical effect — not something to interpret as a real
|
|
187
|
+
3D shape. Only the surrounding environment, independently computable from real astronomy, is rendered in 3D.
|
|
188
|
+
|
|
189
|
+
## `<rr0-ufo-witnesses>` — multi-witness selector
|
|
190
|
+
|
|
191
|
+
A case can have more than one witness, each with their own recording (their own `sighting.json`) of the same
|
|
192
|
+
event. This component lets a page switch between them instead of only ever embedding one fixed `<rr0-ufo>` — it
|
|
193
|
+
composes a nested `<rr0-ufo>` the same way `<rr0-scene>` does, and is otherwise just as lightweight.
|
|
194
|
+
|
|
195
|
+
```html
|
|
196
|
+
<rr0-ufo-witnesses src="witnesses.json"></rr0-ufo-witnesses>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`src` points not at a `sighting.json` directly, but at a small manifest — a plain JSON array of each witness's own
|
|
200
|
+
`SightingRecordingJson` URL (typically relative to the case's own page, same as `<rr0-ufo>`'s own `src`):
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
["chiles-sighting.json", "whitted-sighting.json"]
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
No labels or ids are duplicated in the manifest itself — each witness's display name and the shared case id
|
|
207
|
+
grouping them together are read from that witness's *own* file (`witnessName`/`caseId`, see
|
|
208
|
+
[Data format](#data-format)), so there's a single source of truth and nothing to drift out of sync. This means
|
|
209
|
+
every listed witness's recording is fetched upfront (to read its name), not lazily on selection — fine at the
|
|
210
|
+
scale a case's witness list actually has. If a witness has no `witnessName`, its `witnessId` is shown instead, or
|
|
211
|
+
the URL itself as a last resort. A mismatched `caseId` across the listed witnesses logs a console warning (doesn't
|
|
212
|
+
block) — likely means unrelated recordings got listed together by mistake.
|
|
213
|
+
|
|
214
|
+
| Member | Kind | Description |
|
|
215
|
+
|---|---|---|
|
|
216
|
+
| `src` | attribute | URL of a witness manifest (above), fetched automatically on connect and whenever the attribute changes |
|
|
217
|
+
| `witnessUrls` | property (get/set) | The manifest as a plain array of URLs, for programmatic use instead of `src` |
|
|
218
|
+
| `loadFromSrc(url)` | method (async) | What the `src` attribute triggers internally; can be called directly too |
|
|
219
|
+
|
|
220
|
+
The selector (a plain `<select>` of witness labels) is hidden entirely when there are 0 or 1 witnesses — no point
|
|
221
|
+
showing a dropdown with nothing to actually choose between. The first witness loads automatically once the list is
|
|
222
|
+
known; switching the selector loads that witness's already-fetched recording into the nested `<rr0-ufo>` (no
|
|
223
|
+
re-fetch). Setting `witnessUrls` again (e.g. a manifest refresh) keeps the current selection if that witness is
|
|
224
|
+
still present, instead of resetting back to the first.
|
|
225
|
+
|
|
226
|
+
The "Witness" label itself is translated (English/French) the same way as `<rr0-ufo>`'s own labels.
|
|
227
|
+
|
|
228
|
+
## Data format
|
|
229
|
+
|
|
230
|
+
Both components read/write a plain, JSON-serializable `SightingRecordingJson`:
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
interface SightingRecordingJson {
|
|
234
|
+
version: 1
|
|
235
|
+
time?: { year?: number, month?: number, day?: number, hour?: number, minute?: number, second?: number }
|
|
236
|
+
endTime?: { year?: number, month?: number, day?: number, hour?: number, minute?: number, second?: number } // alternative to durationSeconds
|
|
237
|
+
durationSeconds?: number // alternative to endTime; takes precedence if both are set
|
|
238
|
+
place?: { lat: number, lng: number }[]
|
|
239
|
+
witnessId?: string // opaque internal reference — no PII beyond a display name (see witnessName)
|
|
240
|
+
witnessName?: string // for cases where the witness is already publicly named in the published material (e.g. Chiles-Whitted) — omit for anonymous witnesses
|
|
241
|
+
caseId?: string // shared by every witness's own sighting.json for the same case — see <rr0-ufo-witnesses>
|
|
242
|
+
timeline: {
|
|
243
|
+
keyframes: Array<{
|
|
244
|
+
t: number // milliseconds since recording start
|
|
245
|
+
shapes: Array<{
|
|
246
|
+
sourceId: string // e.g. "ufo-1" — lets several shapes (a UFO, a landmark, a trailing flame...) share one timeline
|
|
247
|
+
shape: {
|
|
248
|
+
kind: "oval" | "polygon"
|
|
249
|
+
bounds: { x: number, y: number, width: number, height: number }
|
|
250
|
+
color: string // CSS color
|
|
251
|
+
angle: number // radians
|
|
252
|
+
transparency: number // 0 = opaque, 1 = fully transparent
|
|
253
|
+
haloScale: number // 0 = no glow
|
|
254
|
+
selected: boolean
|
|
255
|
+
points?: { x: number, y: number }[] // "polygon" shapes only
|
|
256
|
+
}
|
|
257
|
+
}>
|
|
258
|
+
}>
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
This format is deliberately independent of [`@rr0/data`](https://github.com/RR0/data)'s `RR0Event`/`@rr0/time`'s
|
|
264
|
+
`Level2Date`/`@rr0/place`'s `Place` classes, even though its `time`/`place` fields are structurally aligned with
|
|
265
|
+
them — importing those classes into browser-bundled code pulls in Node-only file-scanning dependencies that break a
|
|
266
|
+
`vite build`. `src/engine/interop/rr0Data.ts` converts between the two for Node-side tooling (e.g. generating a
|
|
267
|
+
case's `sighting.json` from its `RR0Event`).
|
|
268
|
+
|
|
269
|
+
## Architecture
|
|
270
|
+
|
|
271
|
+
- `src/engine/` — framework-agnostic core: `model/` (`Shape`, `Timeline`, `Sighting`), `record/` (`Recorder`,
|
|
272
|
+
`SamplingClock`), `playback/` (`Player`), `persistence/` (JSON (de)serialization), `astronomy/` (vanilla solar
|
|
273
|
+
position), `interop/` (real `@rr0/data` conversion, Node-only).
|
|
274
|
+
- `src/render/CanvasRenderer.ts` — paints shapes onto a `<canvas>` 2D context.
|
|
275
|
+
- `src/render3d/` — the Three.js decor renderer (`SceneRenderer`) and its pure, dependency-free color logic
|
|
276
|
+
(`skyColors.ts`), kept separate so the latter is unit-testable without a WebGL context.
|
|
277
|
+
- `src/component/` — the four Web Components. `UfoElement` (`<rr0-ufo>`) owns the canvas/playback; `SceneElement`
|
|
278
|
+
(`<rr0-scene>`) and `WitnessSelectorElement` (`<rr0-ufo-witnesses>`) compose it directly (via
|
|
279
|
+
`document.createElement`, not an inline template tag — see the comment at that call site) rather than duplicating
|
|
280
|
+
it, adding the 3D decor or the multi-witness selector on top, respectively. `UfoRecorderElement` composes a
|
|
281
|
+
`SceneElement` (not `UfoElement` directly) and reaches through to its public `ufoElement` property for the
|
|
282
|
+
actual canvas/timeline/appearance work — the toolbar edits the exact same `Sighting` instance the nested scene
|
|
283
|
+
renders from, so an observer/time/appearance change needs no separate sync step to reach the sky.
|
|
284
|
+
- Playback linearly interpolates shapes between a source's surrounding keyframes for smooth motion
|
|
285
|
+
(`Timeline.getInterpolatedShapeAt`/`Shape.lerpShape`), holding at the ends of its recorded range.
|
|
286
|
+
- Recording samples the pointer position at a configurable rate via `requestAnimationFrame`, not on every
|
|
287
|
+
`pointermove` event.
|
|
288
|
+
|
|
289
|
+
## Development
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
npm install
|
|
293
|
+
npm run dev # local demo (record + play), Vite dev server
|
|
294
|
+
npm test # vitest
|
|
295
|
+
npm run build # type-check + build the demo
|
|
296
|
+
npm run build:embed # build dist-embed/rr0-ufo-recorder.mjs
|
|
297
|
+
npm run build:embed-ufo # build dist-embed-ufo/rr0-ufo.mjs
|
|
298
|
+
npm run build:embed-scene # build dist-embed-scene/rr0-scene.mjs
|
|
299
|
+
npm run build:all # all four
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
## License
|
|
303
|
+
|
|
304
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={play:"Lecture",pause:"Pause",autoReplay:"Lecture automatique",currentPosition:"Position actuelle",duration:"Durée",fullscreen:"Plein écran",exitFullscreen:"Quitter le plein écran"};export{e as ufoMessages_fr};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e={oval:"Ovale",saucer:"Soucoupe",triangle:"Triangle",color:"Couleur",transparency:"Transparence",halo:"Halo",shape:"Forme",addShape:"Ajouter une forme",samplingRate:"Fréquence d'échantillonnage (ms)",duration:"Durée (s)",durationPlaceholder:"durée de l'enregistrement",export:"Exporter le JSON",record:"Enregistrer",stop:"Arrêter",latitude:"Latitude",longitude:"Longitude",heading:"Orientation (°)",headingPlaceholder:"inconnu",pitch:"Inclinaison (°)",observationTime:"Début de l'observation (optionnel)",yearPlaceholder:"année",monthPlaceholder:"mois",dayPlaceholder:"jour",hourPlaceholder:"heure",minutePlaceholder:"min"};export{e as ufoRecorderMessages_fr};
|
|
Binary file
|