clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

feat/atlas-next-horizon
atlas / internal / app / templates / viewport.tmpl
viewport.tmpl 2.9K
1{{/*2 viewport — the seam's surface, and the inert state node it reads.34 Two templates, one region, and the split is the swap. `viewport` is the5 partial: it renders the state node alone, because that node is what an6 interaction moves and outerMorph replaces it whole. `viewport-surface` is7 the shell's alone and is never swapped: the custom elements carry8 hx-morph-skip-children, so a swap may touch their attributes and can never9 reach their internals, which is the difference between a re-render and10 tearing down a WebGL context mid-gesture (issue #5 §4.3).1112 Data flows one way through the node below. Two things come back and no13 more: a pick, which arrives as an ordinary POST /session/select, and a14 settled camera, which arrives debounced at POST /session/view.15*/}}16{{/*17 ORDER IS PAINT ORDER, and it is the whole reason this looked broken.1819 #map and <atlas-viewport> are absolutely positioned siblings filling the20 same box. In the reference implementation #map *was* the map -- the renderer21 drew into it -- and it carries the backdrop the map sits on. Here the panes22 are the custom elements and #map is what is left: the focusable surface the23 keyboard is heard on, and the home of the loading scrim. Rendered after the24 panes, its backdrop covered them completely: every count was right, every25 tile was fetched, and the page showed an empty rectangle.2627 So it goes first, and the scrim comes out of it and goes last, because a28 message about loading has to be readable over the thing that is loading.29*/}}30{{define "viewport-surface"}}<div class="map" id="map" tabindex="0"31 aria-label="Interactive world map" hx-morph-skip-children></div>32<atlas-viewport state-src="#atlas-viewport-state" hx-morph-skip-children>33 <atlas-chart></atlas-chart>34 <atlas-globe hidden></atlas-globe>35</atlas-viewport>36<div class="map-loading" id="map-loading" hidden>37 <span class="spinner"></span>38 <strong>Unfolding map</strong>39 <small>Loading visible embedded tiles…</small>40</div>41{{end}}4243{{define "viewport"}}<div id="atlas-viewport-state" hidden44 data-volume="{{.Viewport.Volume}}"45 data-base="{{.Viewport.Base}}"46 data-world="{{.Viewport.World}}"47 data-lens="{{.Viewport.Lens}}"48 data-lens-index="{{.Viewport.LensIndex}}"49 data-surface="{{.Viewport.Surface}}"50 data-selected="{{.Viewport.Selected}}"51 data-search="{{.Viewport.Search}}"52 data-grid-system="{{.Viewport.GridSystem}}"53 data-grid-cell="{{.Viewport.GridCell}}"54 data-subgrid="{{.Viewport.Subgrid}}"55 {{with .Viewport.Camera}}data-camera="{{.X}},{{.Y}},{{.Zoom}},{{.Rotation}}"{{end}}>56 {{range .Viewport.Hidden}}<data class="hidden-collection" value="{{.}}"></data>57 {{end}}{{range .Viewport.Highlighted}}<data class="highlighted-feature" value="{{.}}"></data>58 {{end}}{{range .Viewport.Overrides}}<data class="label-override" value="{{.Collection}}={{.Policy}}"></data>59 {{end}}60</div>61{{end}}