Site: app regions with screenshots, props, downloads, English and Chinese, narrow layout; hit layer follows draw order
This commit is contained in:
29 files changed
+1423
-97
No files matched your search
+48
-19
@@ -1,38 +1,67 @@
|
||||
import "./style.css";
|
||||
import "./iso.css";
|
||||
import { block, stage } from "./iso.ts";
|
||||
import { grow } from "./beat.ts";
|
||||
import { model } from "./model.ts";
|
||||
import { touch } from "./touch.ts";
|
||||
import { regions, reveal } from "./regions.ts";
|
||||
import { said, speak, type Lang } from "./text.ts";
|
||||
|
||||
/** 112 BPM, the film's tempo; blocks land on sixteenths. */
|
||||
const BEAT = 60 / 112;
|
||||
const STEP = BEAT / 4;
|
||||
const RELEASE = "https://github.com/ZacharyZhang-NY/ElyOffice/releases/download/v0.1.0";
|
||||
|
||||
const app = document.querySelector<HTMLElement>("#app");
|
||||
if (!app) throw new Error("index.html has no #app");
|
||||
|
||||
const apps = model.slice(1, -1);
|
||||
const parts = new Map<string, SVGGElement[]>();
|
||||
const blocks: SVGGElement[] = [];
|
||||
let beat = 1;
|
||||
for (const part of model) {
|
||||
const own = part.blocks.map((spec, i) => {
|
||||
const g = block(spec);
|
||||
g.style.setProperty("--land", `${(beat * BEAT + i * STEP).toFixed(3)}s`);
|
||||
return g;
|
||||
});
|
||||
if (apps.includes(part)) parts.set(part.name, own);
|
||||
blocks.push(...own);
|
||||
beat += Math.ceil(part.blocks.length / 4);
|
||||
}
|
||||
const built = model.map((part) => part.blocks.map(block));
|
||||
grow(built);
|
||||
const parts = new Map(apps.map((p) => [p.name, built[model.indexOf(p)]]));
|
||||
|
||||
const hero = document.createElement("header");
|
||||
hero.className = "hero";
|
||||
const title = document.createElement("h1");
|
||||
title.textContent = "Ely Office";
|
||||
const host = document.createElement("div");
|
||||
host.className = "model";
|
||||
const svg = stage(blocks);
|
||||
svg.classList.add("grow");
|
||||
const svg = stage(built.flat());
|
||||
svg.classList.add("grow", "seen");
|
||||
svg.setAttribute("aria-hidden", "true");
|
||||
host.append(svg);
|
||||
app.append(title, host);
|
||||
hero.append(title, said("p", "tagline"), said("p", "platforms"), host);
|
||||
touch(host, svg, parts);
|
||||
|
||||
const sections = regions();
|
||||
|
||||
const footer = document.createElement("footer");
|
||||
footer.id = "download";
|
||||
const version = document.createElement("h2");
|
||||
version.textContent = "Ely Office 0.1.0";
|
||||
const list = document.createElement("ul");
|
||||
for (const p of apps) {
|
||||
const a = document.createElement("a");
|
||||
a.href = `${RELEASE}/${p.name}-0.1.0-arm64.dmg`;
|
||||
a.textContent = p.name;
|
||||
const li = document.createElement("li");
|
||||
li.append(a);
|
||||
list.append(li);
|
||||
}
|
||||
const source = said("a", "source");
|
||||
source.href = `${RELEASE}/ElyOffice-0.1.0-source.tar.gz`;
|
||||
const li = document.createElement("li");
|
||||
li.append(source);
|
||||
list.append(li);
|
||||
footer.append(version, said("p", "platforms"), said("p", "needs"), said("p", "unsigned"), list);
|
||||
|
||||
const toggle = said("button", "other");
|
||||
toggle.className = "lang";
|
||||
let lang: Lang = navigator.language.toLowerCase().startsWith("zh") ? "zh" : "en";
|
||||
toggle.addEventListener("click", () => {
|
||||
lang = lang === "en" ? "zh" : "en";
|
||||
speak(lang);
|
||||
});
|
||||
|
||||
const main = document.createElement("main");
|
||||
main.append(...sections);
|
||||
app.append(toggle, hero, main, footer);
|
||||
speak(lang);
|
||||
reveal(sections);
|
||||
Reference in new issue
Block a user