[verified] feat: expand public animation library across 12 industries
This commit is contained in:
1 parent
3bb9555e6a
commit
ecbbcf8ba0
144 files changed
+61323
-187
No files matched your search
@@ -38,11 +38,13 @@ For architecture decomposition, modular products and inspect/reassemble interact
|
||||
|
||||
## Runnable Anime.js library
|
||||
|
||||
Start with the [discovery guide](references/industry-catalog.md). Choose by explanatory question and technique, then read only the relevant industry registry. Version 0.6.0 adds 24 substantial conceptual scenarios across oil and gas, pharma, government, retail, logistics, manufacturing, energy, healthcare, finance, telecom, agriculture and infrastructure. Twelve sectors is this release, not a ceiling. Values are illustrative, not verified operating procedures or engineering/clinical advice.
|
||||
|
||||
- [Element registry](references/registry-animejs-elements.md): SVG draw, motion path and spatial stagger.
|
||||
- [Composition registry](references/registry-animejs-compositions.md): dependency flow and assemble/explode/reassemble.
|
||||
- `assets/animejs/examples.js`: editable configurations; `gallery.js`: shared renderer and lifecycle; `index.html`: local source preview.
|
||||
|
||||
Build with `python3 scripts/build-gallery.py` and open `dist/animejs-gallery-0.5.0/index.html`. This portable offline gallery includes Play, Replay, Settle and Seek for all five examples. `npm test` runs the deck, motion, mechanism and gallery suites. Registry coverage and source links are validated so new examples cannot silently go unlisted. Existing deck and mechanism artifact versions remain available.
|
||||
Build with `python3 scripts/build-gallery.py` and open `dist/animejs-gallery-0.6.0/index.html`. This portable offline gallery includes Play, Replay, Settle and Seek for all 29 examples. `npm test` runs the deck, motion, mechanism and gallery suites. Registry coverage and source links are validated so new examples cannot silently go unlisted. Existing deck and mechanism artifact versions remain available.
|
||||
|
||||
## Licenses and scope
|
||||
|
||||
@@ -50,10 +52,10 @@ Original code/documentation: MIT, RootAtSkic and Hermes Agent. Reveal.js and Ani
|
||||
|
||||
Local Chromium verification is included; no hosted CI or cross-browser certification is claimed. No automation credentials belong in this repository.
|
||||
|
||||
### Gallery hierarchy (0.5.0)
|
||||
### Gallery hierarchy (0.6.0)
|
||||
|
||||
Open `dist/animejs-gallery-0.5.0/index.html` for all five previews, or `elements/index.html` and `compositions/index.html` inside that package. Each gallery embeds `examples/<id>.html` through relative iframe `src` and links to that same file. Each individual page is self-contained (CSS, configuration, renderer, pinned Anime.js and full license embedded), so it also plays offline by itself. Breadcrumb links require keeping the package hierarchy together. Extract the complete package before opening its index; no server is needed. Previous version artifacts are retained.
|
||||
Open `dist/animejs-gallery-0.6.0/index.html` for all 29 previews, or `elements/index.html` and `compositions/index.html` inside that package. Each gallery embeds `examples/<id>.html` through relative iframe `src` and links to that same file. Each individual page is self-contained (CSS, configuration, renderer, pinned Anime.js and full license embedded), so it also plays offline by itself. Breadcrumb links require keeping the package hierarchy together. Extract the complete package before opening its index; no server is needed. Previous version artifacts are retained.
|
||||
|
||||
The editable hierarchy mirrors this under `assets/animejs/`, sharing `examples.js`, `gallery.js`, `gallery.css` and `assets/vendor/`. Edit the configuration/renderer once, not the generated dist pages. Individual source documents select exactly one configuration using `body[data-example]`; unknown IDs fail explicitly, with no query-string fallback. Galleries never mount a renderer themselves. Every embedded document owns its lifecycle.
|
||||
The editable hierarchy mirrors this under `assets/animejs/`, sharing generated `catalog-data.js`, `gallery.js`, `gallery.css` and `assets/vendor/`. Industry descriptors in `catalogs/*.json` and renderer registrations in `industries/*.js` are the editable sources; the builder generates all wrappers without duplicated labels. Legacy configs remain in `examples.js`. Edit the configuration/renderer once, not the generated dist pages. Individual source documents select exactly one configuration using `body[data-example]`; unknown IDs fail explicitly, with no query-string fallback. Galleries never mount a renderer themselves. Every embedded document owns its lifecycle.
|
||||
|
||||
`python3 scripts/build-gallery.py` inlines local dependencies and records every page hash plus source hashes in `dist/animejs-gallery-manifest.json`. `scripts/test-gallery.mjs` tests both editable and built hierarchies, iframe identity, navigation, all five examples in normal/reduced motion and deterministic hold/cleanup behavior. Screenshots and exact page hashes are recorded under `evidence/`.
|
||||
`python3 scripts/build-gallery.py` inlines local dependencies and records every page hash plus source hashes in `dist/animejs-gallery-manifest.json`. `scripts/test-gallery.mjs` tests both editable and built hierarchies, iframe identity, navigation, all 29 examples in normal/reduced motion and deterministic hold/cleanup behavior. A compact representative screenshot set and exact page hashes are recorded under `evidence/`. Every normal-motion example gets actual early playback, then accelerated natural completion at engine speed 12; representative legacy/industry examples also complete at speed 1. The report explicitly distinguishes these. Default build/tests fail on missing release sectors; `--allow-partial` is development-only and reports missing coverage. The complete release has 29 individual pages, 14 registry galleries, and the overall index: 44 HTML pages.
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: presentation-html
|
||||
description: Build offline HTML decks with deliberate motion.
|
||||
version: 0.5.0
|
||||
version: 0.6.0
|
||||
author: RootAtSkic, Hermes Agent
|
||||
license: MIT
|
||||
platforms: [linux, macos, windows]
|
||||
@@ -32,12 +32,16 @@ Build editable, offline-first browser presentations using Reveal.js for navigati
|
||||
|
||||
## Read on demand: runnable Anime.js registries
|
||||
|
||||
Start with the [industry catalog discovery guide](references/industry-catalog.md): choose the audience’s explanatory problem, then the mechanism and only the relevant registry. The 0.6.0 library has 24 industry recipes across 12 sectors plus five foundational recipes; these sectors are release coverage, not a permanent ceiling. Do not load the whole library blindly.
|
||||
|
||||
Select examples by the relationship they explain, not just their visual effect:
|
||||
|
||||
- [Element registry](references/registry-animejs-elements.md): SVG connection drawing, motion-path travel and spatial stagger. Read when choosing a single technique.
|
||||
- [Composition registry](references/registry-animejs-compositions.md): dependency flow and assemble/explode/reassemble. Read when explaining a multi-part mechanism.
|
||||
|
||||
Editable configurations, renderer and preview live in `assets/animejs/`. Build the reusable offline gallery package with `python3 scripts/build-gallery.py` through `terminal`, then open `dist/animejs-gallery-0.5.0/index.html`. `npm test` exercises every registered example. Keep the registry ID, source, parameter constraints and verification coverage aligned when adding an example; do not load all examples into context unnecessarily. Gallery controls are for inspecting recipes, not mandatory controls for client slides. Wire slide departure/teardown explicitly when reusing a recipe.
|
||||
Industry registries: [oil and gas](references/registry-animejs-oil-gas.md), [pharma](references/registry-animejs-pharma.md), [government](references/registry-animejs-government.md), [retail](references/registry-animejs-retail.md), [logistics](references/registry-animejs-logistics.md), [manufacturing](references/registry-animejs-manufacturing.md), [energy](references/registry-animejs-energy.md), [healthcare](references/registry-animejs-healthcare.md), [finance](references/registry-animejs-finance.md), [telecom](references/registry-animejs-telecom.md), [agriculture](references/registry-animejs-agriculture.md), [infrastructure](references/registry-animejs-infrastructure.md). Each describes useful audiences/questions, phases, editable parameters, techniques and limits. All are conceptual illustrations with illustrative numbers, not operational or professional certifications.
|
||||
|
||||
Editable configurations, renderer and preview live in `assets/animejs/`. Catalog JSON generates group/individual wrappers and `catalog-data.js`; never duplicate labels or hand-edit generated HTML. Individual pages expose use/avoid/assumptions and meaningful named beat controls. Compact iframe previews reuse the exact same document. Build the reusable offline gallery package with `python3 scripts/build-gallery.py` through `terminal`, then open `dist/animejs-gallery-0.6.0/index.html`. `npm test` exercises every registered example. Keep the registry ID, source, parameter constraints and verification coverage aligned when adding an example; do not load all examples into context unnecessarily. Gallery controls are for inspecting recipes, not mandatory controls for client slides. Wire slide departure/teardown explicitly when reusing a recipe.
|
||||
|
||||
## Read on demand: choreography and deterministic motion
|
||||
|
||||
@@ -78,6 +82,8 @@ Open `dist/presentation-html-demo-0.3.0.html` directly. The six-slide demo is a
|
||||
|
||||
## Pitfalls
|
||||
|
||||
- Global `svg text` CSS font-size/fill (or font shorthand) overrides SVG presentation attributes. Inherit defaults from the SVG root; preserve per-label hierarchy and colors. Check computed styles and inspect screenshots when integrating sector renderers.
|
||||
|
||||
- Reveal's `.reveal-viewport` rule can override a lower-specificity `body` palette; override `body.reveal-viewport` explicitly. Assert computed colors and inspect screenshots.
|
||||
- Reveal hash writes are asynchronous. Wait for the expected hash before testing reload.
|
||||
- Current Anime v4 API differs from legacy demos; some old minified bundles carry a version banner different from their advertised download version. Inspect actual bytes.
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Agriculture — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="agriculture"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Agriculture</span></nav><h1>Agriculture</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "agriculture-irrigation-zones",
|
||||
"group": "agriculture",
|
||||
"groupTitle": "Agriculture",
|
||||
"title": "Irrigation: measure, open, soak, close",
|
||||
"description": "A water header feeds three field zones in sequence; moisture indications rise and a wet zone stays bypassed.",
|
||||
"useWhen": "Explain feedback-based irrigation zoning and why neighboring strips need not receive identical watering.",
|
||||
"avoid": "Not irrigation design, sensor calibration, crop-specific moisture advice, water-rights guidance or pump sizing.",
|
||||
"assumptions": "All phase times and moisture-gauge levels are illustrative without physical units. Soil response is compressed and no weather, runoff or hydraulic model is included.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"wetZone": 1
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Read soil"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Open north"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Soak north"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Open south"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Close valves"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "agriculture-harvest-grading",
|
||||
"group": "agriculture",
|
||||
"groupTitle": "Agriculture",
|
||||
"title": "Harvest: grade, store and distribute",
|
||||
"description": "A crop lot passes an inspection belt, splits into fresh and processing channels and reaches distinct storage routes.",
|
||||
"useWhen": "Use with supply-chain audiences to explain grade-dependent destinations without losing harvest-lot traceability.",
|
||||
"avoid": "Not a food-safety process, storage-temperature prescription, yield forecast or grading standard.",
|
||||
"assumptions": "All timing and illustrated produce are conceptual. Two quality destinations are simplified; disposal, pathogen checks and detailed cold-chain controls are outside scope.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"freshCount": 3
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Receive lot"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Inspect"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Separate"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Store"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Dispatch"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "energy-microgrid-storage",
|
||||
"group": "energy",
|
||||
"groupTitle": "Energy",
|
||||
"title": "Microgrid: balance generation with storage",
|
||||
"description": "Solar and wind feed a common bus; a renewable dip triggers storage dispatch before a flexible load rejoins.",
|
||||
"useWhen": "Explain the distinct roles of generation, storage and flexible demand to a general energy audience.",
|
||||
"avoid": "Not electrical design, dispatch optimization, grid-code compliance or battery-sizing advice.",
|
||||
"assumptions": "All power, storage and time relationships are qualitative and illustrative; original topology omits protection and power electronics.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"storageBars": 3
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Renewables"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Serve load"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Output dips"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Discharge"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Load rejoins"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "energy-feeder-restoration",
|
||||
"group": "energy",
|
||||
"groupTitle": "Energy",
|
||||
"title": "Feeder fault: isolate and restore service",
|
||||
"description": "A faulted feeder section is opened at both ends; a normally open tie restores healthy downstream service.",
|
||||
"useWhen": "Explain sectional isolation versus whole-feeder outage with an accessible single-line conceptual topology.",
|
||||
"avoid": "Never use as switching instructions, protection coordination, load-flow analysis or an operator procedure.",
|
||||
"assumptions": "Original conceptual topology. Switch states and all timings are illustrative; alternate source capacity and safe isolation are assumed, not calculated.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"tieAvailable": 1
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Normal supply"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Fault appears"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Open section"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Close tie"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Restore branch"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "finance-payment-reconciliation",
|
||||
"group": "finance",
|
||||
"groupTitle": "Finance",
|
||||
"title": "Payment: authorization is not settlement",
|
||||
"description": "Follow one payment from card authorization through clearing, settlement and an exception-ledger reconciliation.",
|
||||
"useWhen": "Explain to product and finance teams why an approved payment can still be unsettled or unreconciled.",
|
||||
"avoid": "Do not use to specify payment-network messages, double-entry postings, dispute rights or accounting policy.",
|
||||
"assumptions": "Original conceptual flow; card, merchant and issuer roles are simplified. All timings and entry labels are illustrative; no monetary rates or compliance claims.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"reference": "A"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Authorize"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Capture"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Clear"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Settle"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Reconcile"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "finance-insurance-evidence",
|
||||
"group": "finance",
|
||||
"groupTitle": "Finance",
|
||||
"title": "Insurance: evidence before settlement",
|
||||
"description": "A claim file combines photos, policy context and assessment; a missing item returns for review before payout.",
|
||||
"useWhen": "Use for claims operations audiences discussing evidence completeness, traceability and review handoffs.",
|
||||
"avoid": "Not a coverage determination, fraud score, legal timetable, automated approval policy or claim valuation model.",
|
||||
"assumptions": "All time values are illustrative. The claim and damaged property are fictional; settlement presumes a separate valid coverage and terms decision.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"missingItem": "Signature"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Intake"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Assemble"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Review gap"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Resolve"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Settle"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "government-permit-review-loop",
|
||||
"group": "government",
|
||||
"groupTitle": "Government",
|
||||
"title": "Permit review: parallel checks & correction",
|
||||
"description": "Independent reviews converge; a missing exhibit returns to the applicant before decision.",
|
||||
"useWhen": "Use with public-service designers to distinguish parallel review from a decision gate and show how missing exhibits create an applicant correction loop.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"exhibitPages": 3
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Application"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Parallel review"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Missing exhibit"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Correction"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Decision gate"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "government-budget-execution",
|
||||
"group": "government",
|
||||
"groupTitle": "Government",
|
||||
"title": "Budget allocation: authority before spend",
|
||||
"description": "Approved envelopes become commitments; expenditure follows a separate execution gate.",
|
||||
"useWhen": "Use with public-finance educators to separate allocation, authority, commitment and expenditure; ask why an unspent envelope is not automatically reusable.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"allocationScale": 0.85
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Allocate"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Authorize"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Commit"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Verify delivery"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Record spend"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "healthcare-care-handoffs",
|
||||
"group": "healthcare",
|
||||
"groupTitle": "Healthcare",
|
||||
"title": "Care coordination: triage and handoffs",
|
||||
"description": "Follow registration, triage review, care-team handoff and discharge coordination, with an information gap resolved.",
|
||||
"useWhen": "Explain administrative handoff ownership and missing-information recovery to nonclinical service-design audiences.",
|
||||
"avoid": "Not clinical triage criteria, treatment recommendations, staffing models or emergency-care instructions.",
|
||||
"assumptions": "Nonclinical original process illustration. No patient data. All times and resource counts are illustrative; clinical decisions are intentionally excluded.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"handoffRole": "Care coordinator"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Register"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Triage review"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Resolve gap"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Team accepts"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Coordinate exit"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "healthcare-sample-rejection",
|
||||
"group": "healthcare",
|
||||
"groupTitle": "Healthcare",
|
||||
"title": "Diagnostic sample chain: reject and recollect",
|
||||
"description": "A labeled tube passes accession and inspection; an unsuitable specimen is held while a linked replacement reaches analysis.",
|
||||
"useWhen": "Explain specimen identity and rejection recovery as a nonclinical laboratory coordination illustration.",
|
||||
"avoid": "Not diagnostic interpretation, collection instructions, rejection criteria, patient advice or laboratory accreditation guidance.",
|
||||
"assumptions": "Nonclinical conceptual workflow with invented sample identifiers. All counts and timings are illustrative; suitability is a generic process state.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"sampleId": "S-042"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Label & send"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Accession"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Reject & hold"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Recollect"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Analyze & report"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "infrastructure-bridge-inspection",
|
||||
"group": "infrastructure",
|
||||
"groupTitle": "Infrastructure",
|
||||
"title": "Bridge: load paths and inspection closure",
|
||||
"description": "A conceptual bridge shows load transfer to supports, an inspection finding and a local lane closure for review.",
|
||||
"useWhen": "Use only to introduce the relationship between visible bridge components, conceptual load transfer and controlled access during review.",
|
||||
"avoid": "Never use as structural engineering analysis, load capacity, safety assurance, inspection checklist, repair selection or reopening authorization.",
|
||||
"assumptions": "Original schematic, not a bridge design. Geometry, vehicle load, paths and timing are unscaled illustrations. A qualified professional must determine actual structural behavior and access decisions.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"loadX": 385
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Apply load"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Trace path"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Inspect"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Close lane"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Review repair"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "infrastructure-construction-resequence",
|
||||
"group": "infrastructure",
|
||||
"groupTitle": "Infrastructure",
|
||||
"title": "Construction: dependency and resequencing",
|
||||
"description": "A permit hold blocks a lift; off-site assembly advances without pretending to remove the critical dependency.",
|
||||
"useWhen": "Help project teams distinguish work that can be resequenced from a critical prerequisite that cannot be bypassed.",
|
||||
"avoid": "Not a computed critical-path schedule, construction-method statement, permit prediction, resource model or lift plan.",
|
||||
"assumptions": "All axis values and timings are illustrative without calendar units. Fabrication is assumed independent and resources available; the permit gate remains unresolved rather than implying authorization.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"advanceSlots": 1.5
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Baseline"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Permit hold"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Identify float"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Resequence"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Gate lift"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "logistics-hub-connection-recovery",
|
||||
"group": "logistics",
|
||||
"groupTitle": "Logistics",
|
||||
"title": "Hub sorting: recover a missed connection",
|
||||
"description": "Follow a late parcel from induction through sorting, a missed departure, exception staging and a later connection.",
|
||||
"useWhen": "Explain why physical sorting and departure cutoffs are separate dependencies; useful for hub planning and service design.",
|
||||
"avoid": "Do not present this as a route optimizer, carrier SLA, throughput benchmark or promise of delivery.",
|
||||
"assumptions": "Original conceptual hub. All timings, positions, capacities and departure windows are illustrative; one parcel represents a tracked consignment.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"recoveryConnection": "Later connection"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Induct"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Read & sort"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Cutoff missed"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Stage safely"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Reconnect"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "logistics-port-crane-yard",
|
||||
"group": "logistics",
|
||||
"groupTitle": "Logistics",
|
||||
"title": "Port coordination: berth, crane and yard",
|
||||
"description": "A container moves only after berth access, crane clearance and a yard slot align; a blocked lane prompts reassignment.",
|
||||
"useWhen": "Explain interdependent marine and landside work to planners; show that crane motion alone does not complete a transfer.",
|
||||
"avoid": "Avoid crane operating instruction, nautical guidance, capacity forecasts or safety clearance claims.",
|
||||
"assumptions": "All geometry, timing and resource counts are illustrative. Original conceptual port; not an equipment or safety simulation.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"yardSlot": "B"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Berth ready"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Lift approved"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Lane blocked"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Reassign slot"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Yard receipt"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "manufacturing-takt-buffer",
|
||||
"group": "manufacturing",
|
||||
"groupTitle": "Manufacturing",
|
||||
"title": "Assembly flow: bottleneck and buffer",
|
||||
"description": "Three assembly stations expose an uneven cycle; a small buffer absorbs the mismatch while work is rebalanced.",
|
||||
"useWhen": "Explain work-in-progress and local bottlenecks to operations teams without implying that a buffer creates capacity.",
|
||||
"avoid": "Avoid production forecasting, exact takt design or claims that one buffer universally solves a bottleneck.",
|
||||
"assumptions": "All cycles, buffer sizes, positions and timings are illustrative. Single-piece tokens simplify an original conceptual assembly line.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"bufferSlots": 2
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Feed chassis"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Assemble"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Queue grows"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Rebalance"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Release units"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "manufacturing-fault-rework",
|
||||
"group": "manufacturing",
|
||||
"groupTitle": "Manufacturing",
|
||||
"title": "Machine fault: isolate, inspect and rework",
|
||||
"description": "A machining fault stops the affected cell; a suspect part leaves the main line for inspection, rework and verification.",
|
||||
"useWhen": "Explain containment boundaries, part identity and the difference between repair of a machine and release of a product.",
|
||||
"avoid": "Not lockout/tagout instructions, machine-safety validation or a quality-release standard.",
|
||||
"assumptions": "Conceptual original cell; all timings and counts are illustrative. Animated isolation is a process state, not a certified safety procedure.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"lotId": "LOT A"
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Machine part"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Detect fault"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Contain lot"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Rework"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Verify release"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Resolved overview"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "oil-gas-separator-upset",
|
||||
"group": "oil-gas",
|
||||
"groupTitle": "Oil & gas",
|
||||
"title": "Separator train: contain an upset",
|
||||
"description": "Separate the streams; isolate one train without hiding the recovery route.",
|
||||
"useWhen": "Use with operations educators to explain how separation, upset containment and alternate train availability differ. Ask which paths must stop before recovery.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"feedLevel": 26
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Feed split"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Separation"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Upset held"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Train isolated"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Stable route"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "oil-gas-pipeline-reroute",
|
||||
"group": "oil-gas",
|
||||
"groupTitle": "Oil & gas",
|
||||
"title": "Pipeline leak: isolate and bypass",
|
||||
"description": "Two boundary valves contain the suspect segment before bypass flow resumes.",
|
||||
"useWhen": "Use in resilience workshops to distinguish detection, boundary isolation and alternate delivery. Ask whether a bypass exists before promising restored supply.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"bypassY": 365
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Normal flow"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Leak alarm"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Close bounds"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Open bypass"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Supply restored"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "pharma-batch-genealogy",
|
||||
"group": "pharma",
|
||||
"groupTitle": "Pharma",
|
||||
"title": "Batch genealogy: hold, then release",
|
||||
"description": "A quality hold propagates to descendants; disposition restores only the accepted branch.",
|
||||
"useWhen": "Use with manufacturing quality and data-lineage teams to explain why a hold follows descendants while release requires branch-specific evidence.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"packCount": 3
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Trace inputs"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Blend batch"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Hold lineage"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Review evidence"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Release branch"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "pharma-cold-chain-quarantine",
|
||||
"group": "pharma",
|
||||
"groupTitle": "Pharma",
|
||||
"title": "Cold chain: excursion to quarantine",
|
||||
"description": "A recorded excursion changes custody status, not the historical temperature trace.",
|
||||
"useWhen": "Use with distribution and quality teams to explain why a logger excursion changes custody disposition without erasing the temperature history.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"excursionRise": 48
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Pack & record"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Transport"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Excursion"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Quarantine"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Disposition"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "retail-inventory-reservation",
|
||||
"group": "retail",
|
||||
"groupTitle": "Retail",
|
||||
"title": "Omnichannel: reserve before promising",
|
||||
"description": "Two demand channels compete for one pickable unit; the second order gets an honest alternative.",
|
||||
"useWhen": "Use with commerce product and store operations teams to expose the race between web and store demand and prevent a second promise on one unit.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"parcelSize": 34
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Count stock"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Web reserves"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Store competes"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Offer alternate"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Fulfil promise"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "retail-return-disposition",
|
||||
"group": "retail",
|
||||
"groupTitle": "Retail",
|
||||
"title": "Returns: inspect before restocking",
|
||||
"description": "Refund and inventory disposition are separate branches; damaged goods stay out of sellable stock.",
|
||||
"useWhen": "Use with returns, finance and inventory teams to separate refund eligibility from physical restock eligibility and retain the rejected-goods branch.",
|
||||
"avoid": "Do not use as a live control display, regulatory assurance, numerical model or a substitute for locally approved procedures.",
|
||||
"assumptions": "Original conceptual model. All timings, quantities, rates and capacities are illustrative. Geometry shows relationships, not physical scale. No clinical, compliance or engineering certification claims.",
|
||||
"config": {
|
||||
"phaseMs": 1200,
|
||||
"restockUnits": 2
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Receive return"
|
||||
},
|
||||
{
|
||||
"at": 1200,
|
||||
"label": "Inspect condition"
|
||||
},
|
||||
{
|
||||
"at": 2400,
|
||||
"label": "Route disposition"
|
||||
},
|
||||
{
|
||||
"at": 3600,
|
||||
"label": "Refund record"
|
||||
},
|
||||
{
|
||||
"at": 4800,
|
||||
"label": "Restock accepted"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Settled outcome"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"id": "telecom-congestion-reroute",
|
||||
"group": "telecom",
|
||||
"groupTitle": "Telecommunications",
|
||||
"title": "Packet network: congestion and rerouting",
|
||||
"description": "A saturated transit link queues traffic; an alternate path carries later packets to the same destination.",
|
||||
"useWhen": "Explain topology resilience, queue pressure and alternate-path selection to a non-protocol-specific networking audience.",
|
||||
"avoid": "Not a routing-protocol implementation, QoS SLA, traffic simulator or evidence that rerouting always preserves ordering.",
|
||||
"assumptions": "Packets, queue slots and timings are illustrative. Alternate capacity and route availability are assumed; convergence, loss and retransmission are omitted.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"queuePackets": 4
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Forward"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Queue"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Detect"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Reroute"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Deliver"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "telecom-cell-handover",
|
||||
"group": "telecom",
|
||||
"groupTitle": "Telecommunications",
|
||||
"title": "Cell handover: preserving a session",
|
||||
"description": "A moving handset crosses coverage, prepares a target radio link and switches access while its session remains anchored.",
|
||||
"useWhen": "Use to explain the distinction between radio access and persistent session identity during mobility.",
|
||||
"avoid": "Not a 3GPP message flow, radio-planning calculation, coverage map or promise of zero interruption.",
|
||||
"assumptions": "Coverage ellipses, travel distance and times are illustrative. Target admission and a shared session anchor are assumed; technology-specific procedures are intentionally omitted.",
|
||||
"config": {
|
||||
"duration": 6000,
|
||||
"travelPx": 286
|
||||
},
|
||||
"beats": [
|
||||
{
|
||||
"at": 0,
|
||||
"label": "Serve A"
|
||||
},
|
||||
{
|
||||
"at": 1000,
|
||||
"label": "Measure"
|
||||
},
|
||||
{
|
||||
"at": 2000,
|
||||
"label": "Prepare B"
|
||||
},
|
||||
{
|
||||
"at": 3000,
|
||||
"label": "Switch"
|
||||
},
|
||||
{
|
||||
"at": 4000,
|
||||
"label": "Release A"
|
||||
},
|
||||
{
|
||||
"at": 6000,
|
||||
"label": "Complete"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Compositions — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="compositions"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Compositions</span></nav><h1>Compositions</h1><p>The same individual examples, collected by registry.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-gallery="compositions"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Compositions</span></nav><h1>Compositions</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Elements — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="elements"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Elements</span></nav><h1>Elements</h1><p>The same individual examples, collected by registry.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-gallery="elements"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Elements</span></nav><h1>Elements</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Energy — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="energy"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Energy</span></nav><h1>Energy</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,8 +1,58 @@
|
||||
/* Original examples; Anime.js v4.5.0. No third-party demo source. */
|
||||
/* Original legacy configurations. Keep this array valid JSON for the stdlib builder. */
|
||||
window.animeExamples = [
|
||||
{id:'svg-draw', kind:'element', title:'Draw a connection', description:'A trace reveals a directed connection; labels remain readable.', duration:900, path:'M 55 110 C 140 20 240 200 345 110', start:'Source', end:'Destination'},
|
||||
{id:'motion-path', kind:'element', title:'Follow a route', description:'A packet follows the same coordinate space as its route.', duration:1200, path:'M 55 110 C 140 20 240 200 345 110', start:'Send', end:'Receive'},
|
||||
{id:'spatial-stagger', kind:'element', title:'Propagate from the center', description:'Row-major cells activate outward from the center of a grid.', duration:350, delay:100, columns:5, rows:3},
|
||||
{id:'dependency-flow', kind:'composition', title:'Explain a dependency', description:'Input connects to a check, then the checked result reaches output.', duration:600, labels:['Input','Check','Output']},
|
||||
{id:'assemble-explode', kind:'composition', title:'Separate, inspect, reassemble', description:'Stable parts separate to expose their relationship, then return to one assembly.', duration:700, distance:105, labels:['Interface','Compute','Storage']}
|
||||
{
|
||||
"id": "svg-draw",
|
||||
"kind": "element",
|
||||
"title": "Draw a connection",
|
||||
"description": "A trace reveals a directed connection; labels remain readable.",
|
||||
"duration": 900,
|
||||
"path": "M 55 110 C 140 20 240 200 345 110",
|
||||
"start": "Source",
|
||||
"end": "Destination"
|
||||
},
|
||||
{
|
||||
"id": "motion-path",
|
||||
"kind": "element",
|
||||
"title": "Follow a route",
|
||||
"description": "A packet follows the same coordinate space as its route.",
|
||||
"duration": 1200,
|
||||
"path": "M 55 110 C 140 20 240 200 345 110",
|
||||
"start": "Send",
|
||||
"end": "Receive"
|
||||
},
|
||||
{
|
||||
"id": "spatial-stagger",
|
||||
"kind": "element",
|
||||
"title": "Propagate from the center",
|
||||
"description": "Row-major cells activate outward from the center of a grid.",
|
||||
"duration": 350,
|
||||
"delay": 100,
|
||||
"columns": 5,
|
||||
"rows": 3
|
||||
},
|
||||
{
|
||||
"id": "dependency-flow",
|
||||
"kind": "composition",
|
||||
"title": "Explain a dependency",
|
||||
"description": "Input connects to a check, then the checked result reaches output.",
|
||||
"duration": 600,
|
||||
"labels": [
|
||||
"Input",
|
||||
"Check",
|
||||
"Output"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "assemble-explode",
|
||||
"kind": "composition",
|
||||
"title": "Separate, inspect, reassemble",
|
||||
"description": "Stable parts separate to expose their relationship, then return to one assembly.",
|
||||
"duration": 700,
|
||||
"distance": 105,
|
||||
"labels": [
|
||||
"Interface",
|
||||
"Compute",
|
||||
"Storage"
|
||||
]
|
||||
}
|
||||
];
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Harvest: grade, store and distribute — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="agriculture-harvest-grading"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../agriculture/index.html">Agriculture</a> / <span aria-current="page">Harvest: grade, store and distribute</span></nav><h1>Harvest: grade, store and distribute</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/agriculture.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Irrigation: measure, open, soak, close — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="agriculture-irrigation-zones"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../agriculture/index.html">Agriculture</a> / <span aria-current="page">Irrigation: measure, open, soak, close</span></nav><h1>Irrigation: measure, open, soak, close</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/agriculture.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Separate, inspect, reassemble — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="assemble-explode"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../compositions/index.html">Compositions</a> / <span aria-current="page">Separate, inspect, reassemble</span></nav><h1>Separate, inspect, reassemble</h1><p>Scenes start complete. Play or replay the sequence; seek pauses. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-example="assemble-explode"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../compositions/index.html">Compositions</a> / <span aria-current="page">Separate, inspect, reassemble</span></nav><h1>Separate, inspect, reassemble</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Explain a dependency — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="dependency-flow"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../compositions/index.html">Compositions</a> / <span aria-current="page">Explain a dependency</span></nav><h1>Explain a dependency</h1><p>Scenes start complete. Play or replay the sequence; seek pauses. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-example="dependency-flow"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../compositions/index.html">Compositions</a> / <span aria-current="page">Explain a dependency</span></nav><h1>Explain a dependency</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Feeder fault: isolate and restore service — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="energy-feeder-restoration"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../energy/index.html">Energy</a> / <span aria-current="page">Feeder fault: isolate and restore service</span></nav><h1>Feeder fault: isolate and restore service</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/energy.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Microgrid: balance generation with storage — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="energy-microgrid-storage"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../energy/index.html">Energy</a> / <span aria-current="page">Microgrid: balance generation with storage</span></nav><h1>Microgrid: balance generation with storage</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/energy.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Insurance: evidence before settlement — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="finance-insurance-evidence"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../finance/index.html">Finance</a> / <span aria-current="page">Insurance: evidence before settlement</span></nav><h1>Insurance: evidence before settlement</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/finance.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Payment: authorization is not settlement — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="finance-payment-reconciliation"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../finance/index.html">Finance</a> / <span aria-current="page">Payment: authorization is not settlement</span></nav><h1>Payment: authorization is not settlement</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/finance.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Budget allocation: authority before spend — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="government-budget-execution"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../government/index.html">Government</a> / <span aria-current="page">Budget allocation: authority before spend</span></nav><h1>Budget allocation: authority before spend</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/government.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Permit review: parallel checks & correction — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="government-permit-review-loop"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../government/index.html">Government</a> / <span aria-current="page">Permit review: parallel checks & correction</span></nav><h1>Permit review: parallel checks & correction</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/government.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Care coordination: triage and handoffs — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="healthcare-care-handoffs"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../healthcare/index.html">Healthcare</a> / <span aria-current="page">Care coordination: triage and handoffs</span></nav><h1>Care coordination: triage and handoffs</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/healthcare.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Diagnostic sample chain: reject and recollect — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="healthcare-sample-rejection"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../healthcare/index.html">Healthcare</a> / <span aria-current="page">Diagnostic sample chain: reject and recollect</span></nav><h1>Diagnostic sample chain: reject and recollect</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/healthcare.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Bridge: load paths and inspection closure — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="infrastructure-bridge-inspection"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../infrastructure/index.html">Infrastructure</a> / <span aria-current="page">Bridge: load paths and inspection closure</span></nav><h1>Bridge: load paths and inspection closure</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/infrastructure.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Construction: dependency and resequencing — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="infrastructure-construction-resequence"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../infrastructure/index.html">Infrastructure</a> / <span aria-current="page">Construction: dependency and resequencing</span></nav><h1>Construction: dependency and resequencing</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/infrastructure.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Hub sorting: recover a missed connection — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="logistics-hub-connection-recovery"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../logistics/index.html">Logistics</a> / <span aria-current="page">Hub sorting: recover a missed connection</span></nav><h1>Hub sorting: recover a missed connection</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/logistics.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Port coordination: berth, crane and yard — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="logistics-port-crane-yard"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../logistics/index.html">Logistics</a> / <span aria-current="page">Port coordination: berth, crane and yard</span></nav><h1>Port coordination: berth, crane and yard</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/logistics.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Machine fault: isolate, inspect and rework — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="manufacturing-fault-rework"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../manufacturing/index.html">Manufacturing</a> / <span aria-current="page">Machine fault: isolate, inspect and rework</span></nav><h1>Machine fault: isolate, inspect and rework</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/manufacturing.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Assembly flow: bottleneck and buffer — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="manufacturing-takt-buffer"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../manufacturing/index.html">Manufacturing</a> / <span aria-current="page">Assembly flow: bottleneck and buffer</span></nav><h1>Assembly flow: bottleneck and buffer</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/manufacturing.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Follow a route — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="motion-path"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../elements/index.html">Elements</a> / <span aria-current="page">Follow a route</span></nav><h1>Follow a route</h1><p>Scenes start complete. Play or replay the sequence; seek pauses. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-example="motion-path"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../elements/index.html">Elements</a> / <span aria-current="page">Follow a route</span></nav><h1>Follow a route</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Pipeline leak: isolate and bypass — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="oil-gas-pipeline-reroute"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../oil-gas/index.html">Oil & gas</a> / <span aria-current="page">Pipeline leak: isolate and bypass</span></nav><h1>Pipeline leak: isolate and bypass</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/oil-gas.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Separator train: contain an upset — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="oil-gas-separator-upset"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../oil-gas/index.html">Oil & gas</a> / <span aria-current="page">Separator train: contain an upset</span></nav><h1>Separator train: contain an upset</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/oil-gas.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Batch genealogy: hold, then release — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="pharma-batch-genealogy"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../pharma/index.html">Pharma</a> / <span aria-current="page">Batch genealogy: hold, then release</span></nav><h1>Batch genealogy: hold, then release</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/pharma.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Cold chain: excursion to quarantine — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="pharma-cold-chain-quarantine"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../pharma/index.html">Pharma</a> / <span aria-current="page">Cold chain: excursion to quarantine</span></nav><h1>Cold chain: excursion to quarantine</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/pharma.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Omnichannel: reserve before promising — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="retail-inventory-reservation"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../retail/index.html">Retail</a> / <span aria-current="page">Omnichannel: reserve before promising</span></nav><h1>Omnichannel: reserve before promising</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/retail.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Returns: inspect before restocking — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="retail-return-disposition"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../retail/index.html">Retail</a> / <span aria-current="page">Returns: inspect before restocking</span></nav><h1>Returns: inspect before restocking</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/retail.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Propagate from the center — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="spatial-stagger"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../elements/index.html">Elements</a> / <span aria-current="page">Propagate from the center</span></nav><h1>Propagate from the center</h1><p>Scenes start complete. Play or replay the sequence; seek pauses. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-example="spatial-stagger"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../elements/index.html">Elements</a> / <span aria-current="page">Propagate from the center</span></nav><h1>Propagate from the center</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Draw a connection — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="svg-draw"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../elements/index.html">Elements</a> / <span aria-current="page">Draw a connection</span></nav><h1>Draw a connection</h1><p>Scenes start complete. Play or replay the sequence; seek pauses. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<body data-example="svg-draw"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../elements/index.html">Elements</a> / <span aria-current="page">Draw a connection</span></nav><h1>Draw a connection</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../examples.js"></script><script src="../gallery.js"></script></body></html>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Cell handover: preserving a session — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="telecom-cell-handover"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../telecom/index.html">Telecommunications</a> / <span aria-current="page">Cell handover: preserving a session</span></nav><h1>Cell handover: preserving a session</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/telecom.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Packet network: congestion and rerouting — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-example="telecom-congestion-reroute"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <a href="../telecom/index.html">Telecommunications</a> / <span aria-current="page">Packet network: congestion and rerouting</span></nav><h1>Packet network: congestion and rerouting</h1><p>Scenes start complete. Play or replay; seek a named beat to inspect a phase. Reduced motion keeps the scene complete.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../../vendor/anime.umd.min.js"></script><script src="../catalog-data.js"></script><script src="../industries/telecom.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Finance — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="finance"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Finance</span></nav><h1>Finance</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,3 +1 @@
|
||||
*{box-sizing:border-box}body{margin:0;background:#101823;color:#eef5ff;font:16px/1.5 system-ui,sans-serif}header,main,footer{max-width:1100px;margin:auto;padding:24px}h1{font-size:2.2rem;margin:0}h2{font-size:1.3rem}header p,article p{color:#bfcede}main{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,440px),1fr));gap:22px}article{padding:22px;border:1px solid #425065;border-radius:12px;background:#182333}article p{min-height:3em}svg{width:100%;display:block;background:#111c2b;border-radius:8px}svg text{fill:#eef5ff;font-size:14px}.guide{fill:none;stroke:#425065;stroke-width:5}.trace{fill:none;stroke:#69ded2;stroke-width:4}.cell{fill:#2a6d82;stroke:#85e7df;stroke-width:2}.packet{fill:#ffd787;stroke:#101823;stroke-width:2}.controls{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:16px}button{font:inherit;border:1px solid #8da4be;background:#263b52;color:#fff;border-radius:5px;padding:6px 12px;cursor:pointer}button:focus-visible,input:focus-visible{outline:3px solid #ffd787;outline-offset:3px}label{display:flex;align-items:center;gap:6px}input{width:100px}output{display:block;color:#bfcede;font-size:.85rem;margin-top:8px}footer{color:#bfcede}summary{cursor:pointer}pre{white-space:pre-wrap}@media print{.controls,output{display:none}article{break-inside:avoid}main{display:block}}
|
||||
/* Gallery pages compose the very same individual documents, never a second renderer. */
|
||||
a{color:#85e7df;text-underline-offset:3px}nav{margin-bottom:18px;color:#bfcede}main{display:block}.preview-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,440px),1fr));gap:22px}section{margin-bottom:36px}.preview-grid article{padding:0;overflow:hidden}iframe{width:100%;height:510px;border:0;display:block}.open-example{display:block;padding:16px 22px;border-top:1px solid #425065}body[data-example] main{max-width:850px}body[data-example] article h2{display:none}body[data-example] article p{min-height:0}.embedded header,.embedded footer{display:none}.embedded main{padding:18px}.embedded article{padding:12px;border:0}body[data-example].embedded article h2{display:block;margin-top:0}.embedded article p{min-height:3em}.embedded svg{max-height:255px}a:focus-visible{outline:3px solid #ffd787;outline-offset:3px}@media(max-width:500px){header,main,footer{padding:16px}h1{font-size:1.8rem}}
|
||||
*{box-sizing:border-box}body{margin:0;background:#101823;color:#eef5ff;font:16px/1.5 system-ui,sans-serif}header,main,footer{max-width:1300px;margin:auto;padding:24px}h1{font-size:2.2rem;margin:0}h2{font-size:1.3rem}header p,article p{color:#bfcede}article{padding:22px;border:1px solid #425065;border-radius:12px;background:#182333}svg{width:100%;display:block;background:#111c2b;border-radius:8px}svg{font-family:system-ui,sans-serif;font-size:14px;fill:#eef5ff}.industry svg{font-size:18px}.guide{fill:none;stroke:#425065;stroke-width:5}.trace{fill:none;stroke:#69ded2;stroke-width:4}.cell{fill:#2a6d82;stroke:#85e7df;stroke-width:2}.packet{fill:#ffd787;stroke:#101823;stroke-width:2}.controls,.beats{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:16px}button{font:inherit;border:1px solid #8da4be;background:#263b52;color:#fff;border-radius:5px;padding:6px 12px;cursor:pointer}button:focus-visible,input:focus-visible,a:focus-visible{outline:3px solid #ffd787;outline-offset:3px}label{display:flex;align-items:center;gap:6px}input{width:160px}output{display:block;color:#bfcede;font-size:.85rem;margin-top:8px}footer{color:#bfcede}summary{cursor:pointer}pre{white-space:pre-wrap}a{color:#85e7df;text-underline-offset:3px}nav{margin-bottom:18px;color:#bfcede}.registry-nav{display:flex;flex-wrap:wrap;gap:10px}.registry-nav a{padding:8px 14px;background:#203248;border:1px solid #425065;border-radius:6px}.preview-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,510px),1fr));gap:22px}section{margin-bottom:36px}.preview-grid article{padding:0;overflow:hidden;container-type:inline-size}iframe{width:100%;height:calc(56.25cqw + 150px);min-height:360px;border:0;display:block}.open-example{display:block;padding:16px 22px;border-top:1px solid #425065}body[data-example] main{max-width:1120px}body[data-example] article h2{display:none}.guidance{border-top:1px solid #425065;margin:24px 0 0;padding-top:12px}.guidance h3{font-size:1rem;margin-bottom:4px}.guidance p{margin-top:0}.beats button{font-size:.9rem}.embedded header,.embedded footer,.embedded .guidance,.embedded .beats,.embedded .controls label,.embedded article>p{display:none}.embedded .controls{margin-top:10px}.embedded main{padding:8px}.embedded article{padding:8px;border:0}body[data-example].embedded article h2{display:block;margin:0 0 8px;font-size:1rem}.embedded svg{max-height:none}@media(max-width:500px){header,main,footer{padding:16px}h1{font-size:1.8rem}article{padding:12px}.controls label{width:100%}}@media print{.controls,.beats,output{display:none}article{break-inside:avoid}}
|
||||
@@ -8,24 +8,38 @@
|
||||
host.innerHTML=`<h2></h2><p></p><svg viewBox="0 0 400 220" role="img"></svg><div class="controls"><button data-action="play">Play</button><button data-action="replay">Replay</button><button data-action="settle">Settle</button><label>Seek <input type="range" min="0" max="100" value="100" step="1"></label></div><output aria-live="polite">Complete</output>`;
|
||||
host.querySelector('h2').textContent=c.title; host.querySelector('p').textContent=c.description;
|
||||
const svg=host.querySelector('svg'); svg.setAttribute('aria-label',c.description);
|
||||
const add=(tag,attrs,text)=>{const e=node(tag,attrs,text);svg.append(e);return e;};
|
||||
const industry=c.kind==='industry';
|
||||
host.classList.toggle('industry',industry);
|
||||
if(industry)svg.setAttribute('viewBox','0 0 960 540');
|
||||
const add=(tag,attrs={},text='',parent=svg)=>{const e=node(tag,attrs,text);parent.append(e);return e;};
|
||||
const label=(x,y,text)=>add('text',{x,y,'text-anchor':'middle'},text);
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
let tl, recipeBeats;
|
||||
const beat=(label,at)=>({label,at});
|
||||
if(industry){
|
||||
const renderer=window.industryRenderers?.[c.id];
|
||||
if(typeof renderer!=='function')throw new Error('Missing industry renderer: '+c.id);
|
||||
tl=renderer(svg,c.config,{anime,el:add});
|
||||
}else tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
if(c.id==='svg-draw'||c.id==='motion-path') {
|
||||
add('path',{d:c.path,class:'guide'});
|
||||
const path=add('path',{d:c.path,class:'trace'});
|
||||
label(65,190,c.start); label(325,190,c.end);
|
||||
if(c.id==='svg-draw')tl.add(anime.svg.createDrawable(path),{draw:['0 0','0 1'],duration:c.duration},0);
|
||||
else {const marker=add('circle',{r:9,cx:0,cy:0,class:'packet'});tl.add(marker,{...anime.svg.createMotionPath(path),duration:c.duration},0);}
|
||||
recipeBeats=(c.id==='svg-draw'?['Source','Reveal connection','Connected']:['Send','In transit','Receive']).map((name,i)=>beat(name,i*tl.duration/2));
|
||||
} else if(c.id==='spatial-stagger') {
|
||||
const cells=[];
|
||||
for(let row=0;row<c.rows;row++)for(let col=0;col<c.columns;col++)cells.push(add('rect',{x:35+col*330/c.columns,y:30+row*160/c.rows,width:280/c.columns,height:125/c.rows,rx:5,class:'cell'}));
|
||||
tl.add(cells,{opacity:[0.25,1],duration:c.duration,delay:anime.stagger(c.delay,{grid:[c.columns,c.rows],from:'center'})},0);
|
||||
// Anime owns grid-distance rounding and stagger delays: use its actual end.
|
||||
recipeBeats=[beat('Grid ready',0),beat('Center outward',tl.duration/2),beat('Activated',tl.duration)];
|
||||
} else if(c.id==='dependency-flow') {
|
||||
const a=add('path',{d:'M 85 100 L 180 100',class:'trace'}),b=add('path',{d:'M 220 100 L 315 100',class:'trace'});
|
||||
[60,200,340].forEach((x,i)=>{add('circle',{cx:x,cy:100,r:25,class:'cell'});label(x,155,c.labels[i]);});
|
||||
tl.label('input',0).add(anime.svg.createDrawable(a),{draw:['0 0','0 1'],duration:c.duration},'input').label('output',c.duration).add(anime.svg.createDrawable(b),{draw:['0 0','0 1'],duration:c.duration},'output');
|
||||
recipeBeats=[beat('Input',0),beat('Check',tl.labels.output),beat('Output',tl.duration)];
|
||||
} else if(c.id==='assemble-explode') {
|
||||
const hold=400, returnAt=c.duration+hold;
|
||||
c.labels.forEach((text,i)=>{
|
||||
const part=add('g',{'data-part':i});
|
||||
part.append(node('rect',{x:155+i*30,y:55+i*22,width:60,height:80,rx:6,class:'cell'}));
|
||||
@@ -33,10 +47,26 @@
|
||||
label(80+i*120,195,text);
|
||||
const x=(i-1)*c.distance;
|
||||
tl.add(part,{translateX:[0,x],duration:c.duration},0)
|
||||
.add(part,{translateX:[x,x],duration:400},c.duration)
|
||||
.add(part,{translateX:[x,0],duration:c.duration},c.duration+400);
|
||||
.add(part,{translateX:[x,x],duration:hold},c.duration)
|
||||
.add(part,{translateX:[x,0],duration:c.duration},returnAt);
|
||||
});
|
||||
recipeBeats=[beat('Assembled',0),beat('Separate',c.duration),beat('Inspect hold',returnAt-hold/2),beat('Reassembled',tl.duration)];
|
||||
}
|
||||
if(!tl||!Number.isFinite(tl.duration)||tl.duration<=0)throw new Error('Invalid finite timeline: '+c.id);
|
||||
const beats=document.createElement('div');beats.className='beats';beats.setAttribute('aria-label','Timeline beats');
|
||||
// Legacy positions are computed on every mount, including edited runtime configs.
|
||||
// Industry descriptors retain their explicit authored beat contract unchanged.
|
||||
for(const beat of (industry?c.beats:recipeBeats)||[]){
|
||||
if(!Number.isFinite(beat.at)||beat.at<0||beat.at>tl.duration)throw new Error('Beat outside timeline: '+c.id+' / '+beat.label);
|
||||
const button=document.createElement('button');button.type='button';button.textContent=beat.label;button.dataset.beat=beat.at;
|
||||
button.addEventListener('click',()=>seek(beat.at),{signal});beats.append(button);
|
||||
}
|
||||
host.append(beats);
|
||||
const guidance=document.createElement('section');guidance.className='guidance';guidance.setAttribute('aria-label','Adaptation guidance');
|
||||
for(const [key,title] of [['useWhen','Use when'],['avoid','Avoid'],['assumptions','Assumptions']]){
|
||||
const heading=document.createElement('h3'),p=document.createElement('p');heading.textContent=title;p.textContent=c[key]||'';guidance.append(heading,p);
|
||||
}
|
||||
host.append(guidance);
|
||||
const range=host.querySelector('input'),out=host.querySelector('output');
|
||||
const sync=()=>{range.value=100*tl.currentTime/tl.duration;};
|
||||
tl.onUpdate=sync;
|
||||
@@ -64,13 +94,19 @@
|
||||
window.animeGallery={controllers:{[config.id]:mount(host,config)},mount};
|
||||
} else {
|
||||
const group=document.body.dataset.gallery;
|
||||
if(!['all','elements','compositions'].includes(group))throw new Error('Unknown gallery: '+group);
|
||||
for(const name of ['elements','compositions']) {
|
||||
const groups=[...new Set(window.animeExamples.map(c=>c.group))];
|
||||
if(group!=='all'&&!groups.includes(group))throw new Error('Unknown gallery: '+group);
|
||||
if(group==='all'){
|
||||
const nav=document.createElement('nav');nav.className='registry-nav';nav.setAttribute('aria-label','Choose a registry');
|
||||
for(const name of groups){const link=document.createElement('a');link.href=name+'/index.html';link.textContent=window.animeExamples.find(c=>c.group===name).groupTitle;nav.append(link);}
|
||||
main.append(nav);
|
||||
}
|
||||
for(const name of groups) {
|
||||
if(group!=='all'&&group!==name)continue;
|
||||
const section=document.createElement('section'), heading=document.createElement('h2'), link=document.createElement('a');
|
||||
section.dataset.registry=name;link.href=group==='all'?name+'/index.html':'index.html';link.textContent=name==='elements'?'Elements':'Compositions';heading.append(link);section.append(heading);
|
||||
section.dataset.registry=name;link.href=group==='all'?name+'/index.html':'index.html';link.textContent=window.animeExamples.find(c=>c.group===name).groupTitle;heading.append(link);section.append(heading);
|
||||
const grid=document.createElement('div');grid.className='preview-grid';section.append(grid);
|
||||
for(const config of window.animeExamples.filter(c=>c.kind===(name==='elements'?'element':'composition'))) {
|
||||
for(const config of window.animeExamples.filter(c=>c.group===name)) {
|
||||
const card=document.createElement('article'),frame=document.createElement('iframe'),open=document.createElement('a');
|
||||
const href=(group==='all'?'':'../')+'examples/'+config.id+'.html';
|
||||
frame.src=href;frame.title=config.title;frame.dataset.example=config.id;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Government — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="government"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Government</span></nav><h1>Government</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Healthcare — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="healthcare"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Healthcare</span></nav><h1>Healthcare</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -1,6 +1,7 @@
|
||||
<!doctype html>
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Motion that explains — Anime.js gallery</title><link rel="stylesheet" href="gallery.css"></head>
|
||||
<body data-gallery="all"><header><nav aria-label="Breadcrumb"><span aria-current="page">All examples</span></nav><h1>Motion that explains</h1><p>Five editable, finite examples. Explore a registry or open an individual example.</p></header><main aria-label="Animation examples"></main><footer><p>Original examples · Anime.js 4.5.0 · Offline library 0.5.0</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Motion that explains — Motion that explains</title><link rel="stylesheet" href="gallery.css"></head>
|
||||
<body data-gallery="all"><header><nav aria-label="Breadcrumb"><span aria-current="page">All examples</span></nav><h1>Motion that explains</h1><p>29 editable examples across 14 registries. Choose a question or industry; inspect meaningful timeline beats. All scenes use illustrative models.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
@@ -10,4 +11,4 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="examples.js"></script><script src="gallery.js"></script></body></html>
|
||||
<script src="catalog-data.js"></script><script src="gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,84 @@
|
||||
/* Original conceptual teaching scenes. No operational or engineering model. */
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
const C={bg:'#101d30',panel:'#182b42',line:'#667c95',ink:'#edf5ff',muted:'#aec1d7',cyan:'#57d4ed',green:'#85e0ad',amber:'#ffd178',red:'#ff8c8c'};
|
||||
function scene(svg,config,kit,title,subtitle,phases,note){
|
||||
const {anime,el}=kit, duration=Math.max(3000,Number(config.duration)||6000), unit=duration/6;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const E=(tag,a={},text='',p=svg)=>el(tag,a,text,p);
|
||||
const rect=(x,y,w,h,fill=C.panel,p=svg,extra={})=>E('rect',{x,y,width:w,height:h,rx:8,fill,...extra},'',p);
|
||||
const text=(x,y,t,size=18,fill=C.ink,p=svg,extra={})=>E('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif',style:`fill:${fill};font-size:${size}px;font-family:system-ui,sans-serif`,...extra},t,p);
|
||||
const path=(d,color=C.line,width=3,p=svg,extra={})=>E('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round',...extra},'',p);
|
||||
const circle=(cx,cy,r,fill=C.cyan,p=svg,extra={})=>E('circle',{cx,cy,r,fill,...extra},'',p);
|
||||
const group=()=>E('g');
|
||||
const add=(target,props,at=0,len=.75)=>tl.add(target,{...props,duration:unit*len},unit*at);
|
||||
const reveal=(target,at)=>{target.setAttribute('opacity','0.12');add(target,{opacity:[.12,1]},at);return target;};
|
||||
const draw=(d,at,color=C.cyan,width=4)=>{const p=path(d,color,width);p.setAttribute('pathLength','1');p.setAttribute('stroke-dasharray','1');p.setAttribute('stroke-dashoffset','1');add(p,{'stroke-dashoffset':[1,0]},at);return p;};
|
||||
rect(0,0,960,540,C.bg,svg,{rx:0}); text(32,39,title,26);text(32,69,subtitle,17,C.muted);
|
||||
path('M32 88 H928',C.line,1);
|
||||
phases.forEach((label,i)=>{const x=32+i*181;rect(x,440,172,44);const bar=rect(x,440,172,4,C.cyan,svg,{rx:0});add(bar,{opacity:[.15,1]},i,.65);text(x+10,469,`${i+1} ${label}`,16);});
|
||||
text(32,516,note,16,C.muted);
|
||||
const clock=E('g',{'data-clock':'finite'});add(clock,{opacity:[1,1]},0,6);
|
||||
return {svg,config,tl,E,rect,text,path,circle,group,add,reveal,draw,C};
|
||||
}
|
||||
window.industryRenderers["agriculture-irrigation-zones"] = function(svg, config, kit) {
|
||||
|
||||
const wet=Math.min(2,Math.max(0,Math.round(Number(config.wetZone??1))));
|
||||
const dryNames=['north','middle','south'].filter((_,i)=>i!==wet);
|
||||
const s=scene(svg,config,kit,'IRRIGATION / ZONES, NOT A BLANKET','A conceptual controller waters two dry zones while bypassing an already wet strip.',
|
||||
['Read soil','Open '+dryNames[0],'Soak '+dryNames[0],'Open '+dryNames[1],'Close valves'],'Illustrative only • cyan = water path • green = wet-enough indication • no agronomic thresholds');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// Reservoir with a pump impeller and main water header.
|
||||
path('M43 170 H155 V336 Q99 362 43 336 Z',C.muted,3);rect(47,255,104,76,'#245d78',svg,{rx:0});
|
||||
path('M48 255 Q65 247 82 255 T116 255 T150 255',C.cyan,3);text(48,386,'Reservoir',17);
|
||||
circle(203,301,27,'#28455b',svg,{stroke:C.cyan,'stroke-width':3});path('M189 301 L214 288 L207 314 Z',C.cyan,3);text(177,349,'Pump',17);
|
||||
path('M155 301 H176 M230 301 H264 V152 H843 M264 261 H843 M264 370 H843',C.line,6);
|
||||
// Furrows and crops make three distinct field strips.
|
||||
let order=0;
|
||||
const zones=['North','Middle','South'].map((name,i)=>({y:118+109*i,name:name+(i===wet?' • already wet':' • initially dry'),at:i===wet?null:(order++===0?1:3)}));
|
||||
zones.forEach((z,i)=>{
|
||||
rect(337,z.y,492,91,'#263e32',svg,{stroke:'#58754a'});
|
||||
for(let row=0;row<3;row++){path(`M353 ${z.y+23+row*24} H813`,'#635d3a',2);for(let col=0;col<8;col++){const x=365+col*57,y=z.y+20+row*24;path(`M${x} ${y+9} V${y-1} M${x} ${y+3} L${x-7} ${y-3} M${x} ${y} L${x+7} ${y-6}`,C.green,2);}}
|
||||
const cy=z.y+34;circle(302,cy,15,'#1a2b3d',svg,{stroke:i===wet?C.green:C.amber,'stroke-width':3});path(`M292 ${cy} H312`,C.muted,3);
|
||||
text(345,z.y+86,z.name,16,C.ink);
|
||||
// Sensor/gauge outside the crop geometry, with a clear water-level response.
|
||||
rect(859,z.y+5,22,66,'#122638',svg,{stroke:C.line});const level=rect(862,z.y+(i===wet?18:52),16,i===wet?50:16,i===wet?C.green:C.amber,svg,{rx:1});text(840,z.y+88,['N soil','M soil','S soil'][i],16,C.muted);
|
||||
if(z.at!==null){const flow=draw(`M264 ${cy} H286 M318 ${cy} H815`,z.at,C.cyan,4);add(flow,{opacity:[1,.18]},4.5,.5);add(level,{y:[z.y+52,z.y+18],height:[16,50],fill:[C.amber,C.green]},z.at+.5,1);const handle=path(`M302 ${cy-10} V${cy+10}`,C.cyan,4);reveal(handle,z.at);add(handle,{opacity:[1,1]},z.at+.75,4.2-z.at-.75);add(handle,{opacity:[1,.15]},4.2,.6);}
|
||||
else{text(592,z.y+86,'Bypass • no demand',16,C.green);}
|
||||
});
|
||||
text(44,125,'Stored supply',17);const closed=group();rect(45,398,270,26,'#2d473b',closed);text(55,417,'Cycle complete • valves closed',16,C.green,closed);reveal(closed,4.3);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
window.industryRenderers["agriculture-harvest-grading"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'HARVEST / PRESERVE LOT IDENTITY','Grade at inspection, separate destinations, and keep the origin visible in each branch.',
|
||||
['Receive lot','Inspect','Separate','Store','Dispatch'],'Conceptual produce flow • green = fresh route • amber = processing route • no food-safety claim');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// Orchard rows and reusable harvest crate.
|
||||
[68,112,156].forEach((x,i)=>{path(`M${x} 178 V234`,C.line,7);circle(x,167,26,'#375f42');circle(x-8,163,5,C.amber);circle(x+9,176,5,C.amber);});
|
||||
rect(49,269,140,78,'#5e4930',svg,{stroke:C.amber});[284,306,328].forEach(y=>path(`M54 ${y} H184`,C.muted,2));text(59,371,'Origin lot L',17);text(49,403,'Orchard harvest',16,C.muted);
|
||||
const picked=group();[76,107,138,166].forEach(x=>circle(x,268,10,C.green,picked));reveal(picked,0);
|
||||
// Belt, rollers and inspection light.
|
||||
rect(236,257,278,61,'#304455',svg,{rx:28});for(let i=0;i<7;i++)circle(260+i*37,288,13,'#162738',svg,{stroke:C.line,'stroke-width':2});
|
||||
path('M310 253 V160 H422 V253',C.muted,5);rect(323,162,86,23,'#4b5860');path('M332 190 L311 249 H422 L400 190',C.amber,2,svg,{'stroke-dasharray':'5 5'});
|
||||
text(297,142,'Inspection gate',18);text(266,348,'Size / appearance review',16,C.muted);
|
||||
const fruit=circle(246,247,12,C.green);add(fruit,{cx:[246,493]},.6,1.4);
|
||||
const review=group();circle(363,222,17,'none',review,{stroke:C.amber,'stroke-width':3});reveal(review,1);
|
||||
// Mechanical diverter separates two gravity chutes.
|
||||
path('M514 280 L559 233 L606 192 M514 288 L559 333 L606 367',C.line,7);const gate=path('M520 282 L548 259',C.cyan,5);add(gate,{d:['M520 282 L548 259','M520 282 L548 309']},2,.65);
|
||||
draw('M514 275 L606 184',2,C.green,4);draw('M514 292 L606 375',2.5,C.amber,4);
|
||||
text(510,117,'Fresh grade',16,C.green);text(521,410,'Processing grade',16,C.amber);
|
||||
// Ventilated cold room with crates; separate processing silo.
|
||||
rect(616,123,142,111,'#214659',svg,{stroke:C.cyan});path('M687 124 V233',C.line,2);text(628,150,'Cool store',17);[0,1].forEach(i=>{rect(627+i*61,167,49,48,'#31583f');text(637+i*61,196,'L',20,C.green);});reveal(s.E('path',{d:'M640 115 V101 M634 108 H646 M698 115 V101 M692 108 H704',stroke:C.cyan,'stroke-width':2}),3);
|
||||
path('M632 304 Q684 279 736 304 V372 L684 404 L632 372 Z',C.amber,3);text(641,335,'Process bin',16);text(650,361,'Lot L kept',16,C.amber);
|
||||
const fresh=Math.min(3,Math.max(1,Math.round(Number(config.freshCount)||3)));
|
||||
for(let i=0;i<4;i++){const good=i<fresh,produce=circle(520,282,8,good?C.green:C.amber);reveal(produce,2+i*.18);add(produce,{cx:[520,good?638+i*26:655+(i-fresh)*20],cy:[282,good?206:379]},2+i*.18,.8);}
|
||||
// Two distinct dispatch vehicles retain lot markers.
|
||||
function truck(y,color,label){const g=group();rect(807,y,72,43,'#304961',g);path(`M879 ${y+14} H900 L917 ${y+32} V${y+43} H879 Z`,color,3,g);circle(826,y+46,10,C.line,g);circle(896,y+46,10,C.line,g);text(826,y+29,'L',20,color,g);text(791,y+82,label,16,C.ink,g);reveal(g,4);}
|
||||
truck(146,C.green,'Fresh market');truck(315,C.amber,'Processor');draw('M760 183 H803',4,C.green);draw('M740 349 H803',4.2,C.amber);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,85 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases, note) {
|
||||
const {anime,el}=kit;
|
||||
const C={bg:'#0b1424',panel:'#15243a',line:'#68809d',ink:'#edf4ff',muted:'#b2c4da',cyan:'#57d9ed',green:'#82e0b0',amber:'#ffd078',red:'#ff8a94'};
|
||||
const D=Number.isFinite(+config.duration)&&+config.duration>0?+config.duration:6000;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
function e(t,a={},text='',p=svg){return el(t,a,text,p);}
|
||||
function g(){return e('g');}
|
||||
function rect(x,y,w,h,fill=C.panel,stroke=C.line,p=svg,r=8){return e('rect',{x,y,width:w,height:h,rx:r,fill,stroke,'stroke-width':2},'',p);}
|
||||
function text(x,y,s,fill=C.ink,size=18,p=svg){return e('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif'},s,p);}
|
||||
function path(d,color=C.line,width=3,p=svg){return e('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round'},'',p);}
|
||||
function circle(x,y,r,fill=C.cyan,p=svg){return e('circle',{cx:x,cy:y,r,fill},'',p);}
|
||||
const tracks=new WeakMap();
|
||||
function tween(o,attrs,start,end){
|
||||
let previous=tracks.get(o);if(!previous){previous={};tracks.set(o,previous);}
|
||||
for(const [key,values] of Object.entries(attrs)){
|
||||
const old=previous[key];
|
||||
// Anime v4 needs explicit holds across gaps for reverse seeking.
|
||||
if(old && start>old.end)tl.add(o,{[key]:[old.value,old.value],duration:(start-old.end)*D/6000},old.end*D/6000);
|
||||
previous[key]={end,value:values[values.length-1]};
|
||||
}
|
||||
tl.add(o,{...attrs,duration:(end-start)*D/6000},start*D/6000);
|
||||
}
|
||||
function reveal(o,start,end= start+650){o.setAttribute('opacity','0');tween(o,{opacity:[0,1]},start,end);}
|
||||
function flow(d,start,end,color=C.cyan,width=5){const p=path(d,color,width);const len=p.getTotalLength();p.setAttribute('stroke-dasharray',len);p.setAttribute('stroke-dashoffset',len);tween(p,{strokeDashoffset:[len,0]},start,end);return p;}
|
||||
function parcel(x,y,color=C.amber){const p=g();rect(x,y,36,28,color,'#0b1424',p,3);path(`M${x+18} ${y} V${y+28}`,'#736146',2,p);return p;}
|
||||
function person(x,y,color=C.cyan){const p=g();circle(x,y,10,color,p);path(`M${x} ${y+15} V${y+43} M${x-15} ${y+25} H${x+15} M${x} ${y+43} L${x-12} ${y+60} M${x} ${y+43} L${x+12} ${y+60}`,color,6,p);return p;}
|
||||
function gear(x,y,r,color=C.line){const p=g();for(let i=0;i<12;i++){const a=i*Math.PI/6;path(`M${x+Math.cos(a)*(r-5)} ${y+Math.sin(a)*(r-5)} L${x+Math.cos(a)*(r+7)} ${y+Math.sin(a)*(r+7)}`,color,8,p);}circle(x,y,r,color,p);circle(x,y,r*.45,C.bg,p);return p;}
|
||||
rect(10,10,940,520,C.bg,C.panel,svg,16);
|
||||
const heading=text(32,43,title,C.ink,25);
|
||||
const words=subtitle.split(' ');let line='',row=0;for(const w of words){if((line+' '+w).length>104){text(32,70+row*19,line,C.muted,16);line=w;row++;}else line+=(line?' ':'')+w;}if(line)text(32,70+row*19,line,C.muted,16);
|
||||
path('M32 426 H928',C.line,1);
|
||||
phases.forEach((s,i)=>{const x=47+i*183;circle(x,455,13,C.panel);const dot=circle(x,455,11,C.cyan);dot.setAttribute('opacity','.18');tween(dot,{opacity:[.18,1]},i*1200,i*1200+700);text(x+21,461,s,C.ink,16);});
|
||||
text(32,510,note,C.muted,16);
|
||||
tween(heading,{opacity:[1,1]},0,6000);
|
||||
return {C,D,tl,e,g,rect,text,path,circle,tween,reveal,flow,parcel,person,gear};
|
||||
}
|
||||
window.industryRenderers["energy-microgrid-storage"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Microgrid: balance generation with storage","Solar and wind feed a common bus; a renewable dip triggers storage dispatch before a flexible load rejoins.",["Renewables", "Serve load", "Output dips", "Discharge", "Load rejoins"],"Cyan = renewable supply \u00b7 Amber = storage dispatch \u00b7 Green = restored flexible load");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow}=s;
|
||||
// Tilted solar array, turbine, bus, battery cabinet, and real building loads.
|
||||
path('M50 188 L82 132 H223 L193 188 Z',C.cyan,3);for(let i=0;i<4;i++)path(`M${82+i*35} 132 L${50+i*35} 188`,C.line,2);path('M66 160 H208 M90 189 V215 M174 189 V215',C.line,3);circle(51,116,15,C.amber);
|
||||
text(40,244,'Solar array',C.cyan,17);
|
||||
path('M313 210 V143 M313 143 L290 110 M313 143 L350 133 M313 143 L296 177',C.cyan,5);circle(313,143,7,C.ink);text(269,244,'Wind',C.cyan,17);
|
||||
path('M65 283 H881',C.line,7);text(373,310,'LOCAL ENERGY BUS',C.muted,16);
|
||||
path('M141 217 V283 M313 212 V283',C.line,3);
|
||||
rect(417,120,107,109,C.panel,C.amber);rect(450,109,42,11,C.amber,C.amber);const bars=Math.max(1,Math.min(3,Math.round(+config.storageBars||3)));for(let i=0;i<3;i++){const bar=rect(433,139+i*24,75,15,i>=3-bars?C.amber:C.bg,C.amber,undefined,2);if(i===3-bars)tween(bar,{fill:[C.amber,C.bg]},3600,4900);}text(530,205,'Storage',C.amber,17);path('M470 229 V283',C.line,3);
|
||||
function building(x,y,w,h,label,color){rect(x,y,w,h,C.panel,color);for(let xx=x+12;xx<x+w-10;xx+=24)for(let yy=y+15;yy<y+h-20;yy+=25)rect(xx,yy,12,12,color,color,undefined,1);text(x-6,117,label,color,16);}
|
||||
building(652,145,92,87,'Steady load',C.cyan);path('M699 233 V283',C.line,3);
|
||||
path('M784 165 L807 143 V165 L830 143 V165 L854 143 V165 H896 V232 H784 Z',C.green,3);path('M870 145 V119 H885 V165',C.green,4);text(769,117,'Flexible load',C.green,16);path('M840 233 V283',C.line,3);
|
||||
const solarRoute=flow('M141 218 V283 H699 V234',0,2100);tween(solarRoute,{opacity:[1,.2]},2400,3100);flow('M313 212 V283 H700',600,2200);
|
||||
const cloud=g();circle(142,122,22,C.muted,cloud);circle(172,113,26,C.muted,cloud);circle(202,124,20,C.muted,cloud);reveal(cloud,2400,3000);
|
||||
text(49,344,'RENEWABLE DIP',C.amber,17);path('M50 383 H102 L129 359 L159 380 L186 380 L215 388 H323',C.amber,3);text(52,414,'Illustrative supply trend',C.muted,16);
|
||||
flow('M470 228 V283 H699 V233',3600,4700,C.amber,6);flow('M700 283 H840 V234',4800,5800,C.green,5);
|
||||
const dispatch=text(403,345,'Storage bridges the gap',C.amber,18);reveal(dispatch,3600,4300);text(403,375,'Flexible demand waits for headroom;',C.muted,17);text(403,402,'essential demand remains connected.',C.muted,17);
|
||||
return tl;
|
||||
};
|
||||
window.industryRenderers["energy-feeder-restoration"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Feeder fault: isolate and restore service","A faulted feeder section is opened at both ends; a normally open tie restores healthy downstream service.",["Normal supply", "Fault appears", "Open section", "Close tie", "Restore branch"],"Red = isolated fault section \u00b7 Green = alternate feed \u00b7 Cyan = healthy normal feed");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow}=s;const available=Number(config.tieAvailable)!==0;
|
||||
text(40,118,'SOURCE A',C.cyan,17);text(754,118,'SOURCE B',C.green,17);
|
||||
circle(98,173,38,C.panel);path('M71 173 Q84 141 98 173 T125 173',C.cyan,3);
|
||||
circle(819,173,38,C.panel);path('M792 173 Q805 141 819 173 T846 173',C.green,3);
|
||||
path('M137 173 H277 M315 173 H530 M568 173 H697 V344 H816 V212',C.line,5);
|
||||
// Explicit isolator blades with rotation-like endpoint interpolation.
|
||||
const sw1=path('M277 173 L315 173',C.cyan,5),sw2=path('M530 173 L568 173',C.cyan,5);
|
||||
tween(sw1,{d:['M277 173 L315 173','M277 173 L308 143']},2400,3000);tween(sw2,{d:['M530 173 L568 173','M530 173 L561 143']},2850,3450);
|
||||
for(const x of [277,315,530,568])circle(x,173,5,C.ink);
|
||||
text(256,127,'S1',C.muted,16);text(524,127,'S2',C.muted,16);
|
||||
path('M212 173 V301 M634 173 V301',C.line,4);
|
||||
function house(x,label,color){path(`M${x} 328 L${x+38} 296 L${x+76} 328 V386 H${x} Z`,color,3);rect(x+28,350,20,36,C.panel,color);text(x-5,414,label,color,16);}
|
||||
house(174,'Upstream served',C.cyan);house(596,available?'Service restored':'Await alternate feed',available?C.green:C.amber);
|
||||
path('M697 344 H747 M782 344 H816',C.line,5);const tie=path('M747 344 L772 319',C.green,5);circle(747,344,5,C.ink);circle(782,344,5,C.ink);
|
||||
if(available)tween(tie,{d:['M747 344 L772 319','M747 344 L782 344']},3900,4500);text(735,385,'Tie switch',C.green,17);
|
||||
const fault=g();path('M431 143 L414 172 H437 L421 205',C.red,6,fault);reveal(fault,1200,1800);
|
||||
const zone=rect(339,215,172,62,C.bg,C.red);reveal(zone,2400,3200);text(353,240,'Fault contained',C.red,17);text(353,263,'No re-energization',C.muted,16);
|
||||
flow('M137 173 H212 V301',0,1100);if(available)flow('M819 212 V344 H697 V173 H634 V301',4500,5900,C.green);
|
||||
path('M331 302 H505',C.red,2);text(337,329,'Only healthy sections',C.muted,16);text(337,354,available?'receive alternate supply.':'wait; no tie capacity assumed.',C.muted,16);
|
||||
return tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,100 @@
|
||||
/* Original conceptual teaching scenes. No operational or engineering model. */
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
const C={bg:'#101d30',panel:'#182b42',line:'#667c95',ink:'#edf5ff',muted:'#aec1d7',cyan:'#57d4ed',green:'#85e0ad',amber:'#ffd178',red:'#ff8c8c'};
|
||||
function scene(svg,config,kit,title,subtitle,phases,note){
|
||||
const {anime,el}=kit, duration=Math.max(3000,Number(config.duration)||6000), unit=duration/6;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const E=(tag,a={},text='',p=svg)=>el(tag,a,text,p);
|
||||
const rect=(x,y,w,h,fill=C.panel,p=svg,extra={})=>E('rect',{x,y,width:w,height:h,rx:8,fill,...extra},'',p);
|
||||
const text=(x,y,t,size=18,fill=C.ink,p=svg,extra={})=>E('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif',style:`fill:${fill};font-size:${size}px;font-family:system-ui,sans-serif`,...extra},t,p);
|
||||
const path=(d,color=C.line,width=3,p=svg,extra={})=>E('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round',...extra},'',p);
|
||||
const circle=(cx,cy,r,fill=C.cyan,p=svg,extra={})=>E('circle',{cx,cy,r,fill,...extra},'',p);
|
||||
const group=()=>E('g');
|
||||
const add=(target,props,at=0,len=.75)=>tl.add(target,{...props,duration:unit*len},unit*at);
|
||||
const reveal=(target,at)=>{target.setAttribute('opacity','0.12');add(target,{opacity:[.12,1]},at);return target;};
|
||||
const draw=(d,at,color=C.cyan,width=4)=>{const p=path(d,color,width);p.setAttribute('pathLength','1');p.setAttribute('stroke-dasharray','1');p.setAttribute('stroke-dashoffset','1');add(p,{'stroke-dashoffset':[1,0]},at);return p;};
|
||||
rect(0,0,960,540,C.bg,svg,{rx:0}); text(32,39,title,26);text(32,69,subtitle,17,C.muted);
|
||||
path('M32 88 H928',C.line,1);
|
||||
phases.forEach((label,i)=>{const x=32+i*181;rect(x,440,172,44);const bar=rect(x,440,172,4,C.cyan,svg,{rx:0});add(bar,{opacity:[.15,1]},i,.65);text(x+10,469,`${i+1} ${label}`,16);});
|
||||
text(32,516,note,16,C.muted);
|
||||
const clock=E('g',{'data-clock':'finite'});add(clock,{opacity:[1,1]},0,6);
|
||||
return {svg,config,tl,E,rect,text,path,circle,group,add,reveal,draw,C};
|
||||
}
|
||||
window.industryRenderers["finance-payment-reconciliation"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'PAYMENT / TWO CLOCKS','Approval reserves funds; settlement moves value; reconciliation explains a mismatch.',
|
||||
['Authorize','Capture','Clear','Settle','Reconcile'],'Conceptual payment lifecycle • amber = exception • green = matched ledger');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// A payment card and a physical terminal, not anonymous process tiles.
|
||||
rect(40,123,170,102,'#274764');rect(56,148,28,24,C.amber);path('M56 186 H119',C.muted,4);
|
||||
text(56,216,'Payer card',17);rect(246,126,98,105,'#344b63');rect(258,138,74,36,'#0d2032');
|
||||
for(let r=0;r<2;r++)for(let c=0;c<3;c++)rect(260+c*22,185+r*15,13,8,C.muted,svg,{rx:2});
|
||||
text(245,254,'Merchant',17);text(44,254,'Purchase intent',16,C.muted);
|
||||
// Issuer building: roof, columns and a reserve vault.
|
||||
path('M400 153 L480 115 L560 153 Z',C.muted,3);path('M404 220 H556',C.muted,5);
|
||||
[420,455,490,525].forEach(x=>rect(x,157,12,61,C.line,svg,{rx:1}));text(428,254,'Issuer',17);
|
||||
const reserve=group();rect(405,277,150,49,'#264838',reserve);text(419,307,'Funds reserved',16,C.green,reserve);reveal(reserve,.35);
|
||||
draw('M210 172 H246',0);draw('M344 170 H393',.2);draw('M470 265 V277',.5,C.green);
|
||||
const approved=group();path('M370 192 L379 202 L395 181',C.green,4,approved);reveal(approved,.4);
|
||||
// Batch records correspond to the two captures and fee in the ledgers.
|
||||
text(621,122,'Clearing batch',18);[0,1,2].forEach(i=>{const g=group();rect(619,137+i*26,127,23,'#244058',g,{stroke:C.line});text(629,154+i*26,['Capture '+String(config.reference||'A').slice(0,4),'Capture B','Fee entry'][i],16,C.ink,g);reveal(g,1+i*.25);});
|
||||
draw('M344 210 H587 V172 H615',1,C.cyan);
|
||||
text(783,122,'Settlement rail',18);path('M783 166 H916 M783 178 H916',C.line,3);
|
||||
const money=circle(777,172,9,C.green);add(money,{cx:[777,906]},2.6,1);
|
||||
draw('M744 172 H776',2,C.cyan);text(789,211,'Value transfer',16,C.green);
|
||||
// Dual ledgers and a separate exception entry.
|
||||
rect(606,273,148,126,'#1c3349');rect(777,273,148,126,'#1c3349');
|
||||
text(618,300,'Merchant ledger',16);text(789,300,'Bank statement',16);
|
||||
[321,345,369].forEach(y=>{path(`M620 ${y} H738`,C.line,1);path(`M791 ${y} H909`,C.line,1);});
|
||||
const ref=String(config.reference||'A').slice(0,4);
|
||||
text(622,320,ref+' captured',16,C.muted);text(791,320,ref+' settled',16,C.muted);
|
||||
text(622,344,'B captured',16,C.muted);text(791,344,'B settled',16,C.muted);
|
||||
const feePending=text(622,368,'Fee pending',16,C.amber);add(feePending,{opacity:[1,0]},4,.4);
|
||||
const feeBooked=text(622,368,'Fee booked',16,C.green);feeBooked.setAttribute('opacity','0');add(feeBooked,{opacity:[0,1]},4.4,.3);text(791,368,'Fee posted',16,C.green);
|
||||
draw('M855 220 V268',3,C.green);
|
||||
const match=group();path('M753 314 L763 323 L775 304 M753 338 L763 347 L775 328 M753 362 L763 371 L775 352',C.green,3,match);reveal(match,4);
|
||||
const exception=group();rect(44,349,502,56,'#493d2c',exception);text(59,372,'Exception queue → fee evidence → matched record',17,C.amber,exception);text(59,395,'Approval alone never closes the accounting loop.',16,C.ink,exception);reveal(exception,4.2);
|
||||
draw('M606 375 H566 V380 H549',4,C.amber);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
window.industryRenderers["finance-insurance-evidence"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'CLAIM / EVIDENCE TO DECISION','A missing document delays a decision, not the identity of the claim.',
|
||||
['Intake','Assemble','Review gap','Resolve','Settle'],'Conceptual insurance workflow • amber = incomplete evidence • green = reviewed release');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// Damaged roof with a photographic evidence frame.
|
||||
path('M49 218 L120 155 L185 218 M67 204 V276 H168 V204',C.muted,4);
|
||||
path('M110 164 L120 184 L132 166',C.amber,4);rect(104,233,28,43,'#2b4661');
|
||||
text(45,316,'Reported damage',17);text(45,340,'One claim identity',16,C.muted);
|
||||
const intake=group();circle(190,169,17,C.cyan,intake);text(181,175,'1',18,C.bg,intake);reveal(intake,0);
|
||||
// Evidence documents are individually surfaced into a folio.
|
||||
const docs=[['Photo',139],['Policy',217],['Estimate',295]];
|
||||
docs.forEach(([name,y],i)=>{const g=group();rect(269,y,107,62,'#233e56',g,{stroke:C.line});
|
||||
if(i===0){path(`M280 ${y+45} L296 ${y+24} L312 ${y+40} L328 ${y+19} L365 ${y+47}`,C.muted,2,g);circle(351,y+14,5,C.amber,g);}else{path(`M281 ${y+15} H363 M281 ${y+24} H352`,C.muted,2,g);}
|
||||
text(280,y+57,name,16,C.ink,g);reveal(g,.6+i*.35);});
|
||||
draw('M189 240 H245 V168 H264',.4);draw('M245 240 H264',.8);draw('M245 240 V325 H264',1.1);
|
||||
path('M415 173 H465 L478 189 H579 V330 H415 Z',C.line,3);
|
||||
text(434,222,'Claim dossier',18);text(434,251,'Photos received',16,C.green);text(434,278,'Policy linked',16,C.green);
|
||||
const missing=group();text(434,306,String(config.missingItem||'Signature').slice(0,12)+' needed',16,C.amber,missing);reveal(missing,2);add(missing,{opacity:[1,1]},2.75,.75);add(missing,{opacity:[1,0]},3.5,.3);
|
||||
const complete=text(434,306,'Evidence complete',16,C.green);complete.setAttribute('opacity','0');add(complete,{opacity:[0,1]},3.8,.3);
|
||||
[169,247,325].forEach((y,i)=>draw(`M377 ${y} H397 V245 H412`,1+i*.2));
|
||||
// Reviewer magnifier and missing-evidence return loop.
|
||||
circle(652,202,32,'none',svg,{stroke:C.cyan,'stroke-width':4});path('M674 225 L701 252',C.cyan,8);
|
||||
text(612,287,'Review gate',17);draw('M580 243 H612',2);
|
||||
const gap=group();circle(650,202,16,C.amber,gap);text(646,208,'!',18,C.bg,gap);reveal(gap,2.2);add(gap,{opacity:[1,1]},2.95,.35);add(gap,{opacity:[1,0]},3.3,.3);
|
||||
draw('M650 310 V381 H321 V362',2.5,C.amber);text(385,405,'Request evidence → same dossier → re-review',16,C.amber);
|
||||
const resolved=group();path('M632 204 L646 218 L670 185',C.green,5,resolved);reveal(resolved,3.4);
|
||||
const signature=group();path('M289 330 L301 319 L307 338 L323 323 L352 328',C.green,3,signature);reveal(signature,3);
|
||||
const returned=group();rect(280,302,79,43,'#345a48',returned);text(290,329,'Evidence',16,C.green,returned);reveal(returned,3);add(returned,{translateX:[0,152],translateY:[0,-88]},3,.7);add(returned,{opacity:[1,1]},3.75,.05);add(returned,{opacity:[1,0]},3.8,.2);
|
||||
// A signed settlement document and disbursement coin.
|
||||
rect(773,140,142,167,'#234539',svg,{stroke:C.green});text(786,171,'Settlement',18);path('M787 187 H900 M787 201 H885 M787 215 H900',C.muted,2);
|
||||
text(786,245,'Terms agreed',16,C.green);text(786,278,'Release recorded',16,C.green);
|
||||
draw('M702 243 H768',4,C.green);const paid=group();circle(846,355,27,C.green,paid);text(831,362,'✓',24,C.bg,paid);reveal(paid,4.3);
|
||||
draw('M846 312 V324',4.2,C.green);text(779,405,'Payment + audit trail',16,C.muted);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,66 @@
|
||||
/* Original conceptual industry scenes; Anime.js v4. */
|
||||
(function(){
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases) {
|
||||
const {el,anime}=kit, p=Number.isFinite(Number(config.phaseMs)) && Number(config.phaseMs)>0 ? Number(config.phaseMs) : 1200;
|
||||
const c={ink:'#e5edf7',muted:'#93a8bf',blue:'#63baff',green:'#6ce1b4',amber:'#ffc56b',red:'#ff8091',bg:'#101e30',line:'#314961'};
|
||||
const E=(tag,a={},t='',parent=svg)=>el(tag,a,t,parent);
|
||||
const text=(x,y,t,size=18,color=c.ink)=>E('text',{x,y,fill:color,'font-size':size,'font-family':'system-ui'},t);
|
||||
const path=(d,color=c.line,w=5)=>E('path',{d,fill:'none',stroke:color,'stroke-width':w,'stroke-linecap':'round','stroke-linejoin':'round'});
|
||||
const rect=(x,y,w,h,color=c.bg,stroke=c.line,rx=8)=>E('rect',{x,y,width:w,height:h,rx,fill:color,stroke,'stroke-width':2});
|
||||
const circle=(x,y,r,color=c.blue)=>E('circle',{cx:x,cy:y,r,fill:color});
|
||||
E('rect',{width:960,height:540,fill:'#091321'});
|
||||
text(32,38,title,26);text(32,67,subtitle,16,c.muted);
|
||||
path('M32 88 H928',c.line,1);
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const anchor=E('g');tl.add(anchor,{opacity:[1,1],duration:p*5},0);
|
||||
function show(node,step){node.setAttribute('opacity','.15');tl.add(node,{opacity:[.15,1],duration:p*.65},step*p);return node;}
|
||||
function flow(d,step,color=c.green){const n=path(d,color,5);const len=n.getTotalLength();n.setAttribute('stroke-dasharray',len);n.setAttribute('stroke-dashoffset',len);tl.add(n,{'stroke-dashoffset':[len,0],duration:p*.75},step*p);return n;}
|
||||
function move(n,x0,y0,x1,y1,step){tl.add(n,{cx:[x0,x1],cy:[y0,y1],duration:p*.75},step*p);}
|
||||
function note(x,y,w,heading,detail,color=c.green,step=0){rect(x,y,w,58);show(rect(x,y,5,58,color,color,0),step);text(x+16,y+24,heading,18,color);text(x+16,y+46,detail,16,c.muted);}
|
||||
function valve(x,y,step){const n=path(`M${x-10} ${y-10} L${x+10} ${y+10} M${x+10} ${y-10} L${x-10} ${y+10}`,c.red,4);show(n,step);}
|
||||
phases.forEach((s,i)=>{const x=32+i*182;rect(x,465,174,42,'#132338');show(rect(x,465,4,42,c.blue,c.blue,0),i);text(x+12,491,`${i+1} ${s}`,16);});
|
||||
text(32,529,'Conceptual sequence · illustrative timing · not an operating procedure',16,c.muted);
|
||||
return {E,text,path,rect,circle,tl,show,flow,move,note,valve,c,p};
|
||||
}
|
||||
window.industryRenderers['government-permit-review-loop'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Permit review: parallel checks & correction","Independent reviews converge; a missing exhibit returns to the applicant before decision.",["Application", "Parallel review", "Missing exhibit", "Correction", "Decision gate"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,c}=s;
|
||||
rect(40,177,114,142,'#18314a',c.blue);path('M61 205 H129 M61 227 H129 M61 249 H111',c.muted,3);text(36,348,'Application',18);
|
||||
const ys=[139,248,357];['Land use','Safety review','Public input'].forEach((a,i)=>{circle(421,ys[i],36,'#18314a');const check=path(`M405 ${ys[i]} L416 ${ys[i]+11} L438 ${ys[i]-12}`,i===1?c.amber:c.green,3);if(i===1)s.tl.add(check,{stroke:[c.amber,c.green],duration:s.p*.65},3*s.p);text(473,ys[i]-18,a,18);path(`M154 248 H268 V${ys[i]} H385`);flow(`M154 248 H268 V${ys[i]} H385`,1,c.blue);});
|
||||
show(circle(97,288,9,c.blue),0);
|
||||
path('M457 139 H685 V248 M457 357 H685 V248 M457 248 H685',c.line,3);
|
||||
flow('M421 284 V409 H214 V318',2,c.amber);text(245,438,'Correction loop · missing exhibit',17,c.amber);
|
||||
flow('M214 318 V96 H421 V103',3,c.green);text(228,120,'Evidence resubmitted',16,c.green);
|
||||
path('M685 248 L723 210 L761 248 L723 286 Z',c.blue,3);text(766,253,'Decision',18);
|
||||
flow('M629 139 H685 V248 H723',4,c.green);flow('M629 357 H685 V248 H723',4,c.green);flow('M629 248 H723',4,c.green);
|
||||
note(727,335,198,'Gate, not a promise','Local rules vary',c.green,4);
|
||||
|
||||
const sheets=Math.max(1,Math.min(4,Math.round(Number(config.exhibitPages)||3)));
|
||||
for(let i=0;i<sheets;i++){const n=rect(64+i*7,267+i*4,28,34,'#3b5268',c.blue,1);s.tl.add(n,{x:[64+i*7,312+i*7],y:[267+i*4,385+i*4],duration:s.p*.65},2*s.p);s.tl.add(n,{x:[312+i*7,312+i*7],y:[385+i*4,385+i*4],duration:s.p*.35},2.65*s.p);s.tl.add(n,{x:[312+i*7,340+i*7],y:[385+i*4,221+i*4],duration:s.p*.65},3*s.p);}
|
||||
const stamp=rect(701,228,44,40,'none',c.green,4);s.tl.add(stamp,{opacity:[0,1],y:[211,228],duration:s.p*.6},4*s.p);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
window.industryRenderers['government-budget-execution'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Budget allocation: authority before spend","Approved envelopes become commitments; expenditure follows a separate execution gate.",["Allocate", "Authorize", "Commit", "Verify delivery", "Record spend"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,c}=s;
|
||||
path('M40 163 L138 113 L236 163 Z M43 266 H233 M53 277 H223',c.blue,4);
|
||||
[64,111,158,205].forEach(x=>{rect(x,173,15,80,'#24435c',c.blue,1);});text(49,307,'Public envelope',18);
|
||||
const rows=[149,258,367];const names=['Mobility','Community','Environment'];
|
||||
rows.forEach((y,i)=>{path(`M236 215 H288 V${y} H336`);text(338,y-20,names[i],18);rect(336,y-7,186,26,'#18314a',c.line,2);const n=rect(336,y-7,0,26,c.blue,c.blue,2);s.tl.add(n,{width:[0,[160,125,96][i]],duration:s.p*.7},0);path(`M522 ${y+6} H895`);});
|
||||
text(554,111,'Authority',16,c.muted);text(667,111,'Commit',16,c.muted);text(791,111,'Spend',16,c.muted);
|
||||
rows.forEach((y,i)=>{show(rect(566,y-10,30,30,c.green,c.green,3),1);show(circle(699,y+5,15,c.amber),2);flow(`M714 ${y+5} H805`,3,c.green);show(circle(830,y+5,15,c.green),4);});
|
||||
note(36,351,237,'Unspent ≠ free cash','Envelopes retain purpose',c.amber,2);
|
||||
text(338,431,'Bars are illustrative shares, not currency or real allocations.',16,c.muted);
|
||||
|
||||
const scale=Math.max(.5,Math.min(1,Number(config.allocationScale)||.85));
|
||||
const lock=path('M573 141 V128 Q581 115 589 128 V141',c.amber,3);s.tl.add(lock,{opacity:[1,.15],duration:s.p*.6},s.p);
|
||||
for(let i=0;i<3;i++){const token=circle(600,rows[i]+5,6,c.ink);s.move(token,600,rows[i]+5,830,rows[i]+5,3);}
|
||||
const ledger=rect(788,395,100,12,'#20394c',c.line,1);const posted=rect(788,395,0,12,c.green,'none',1);s.tl.add(posted,{width:[0,100*scale],duration:s.p*.7},4*s.p);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,80 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases, note) {
|
||||
const {anime,el}=kit;
|
||||
const C={bg:'#0b1424',panel:'#15243a',line:'#68809d',ink:'#edf4ff',muted:'#b2c4da',cyan:'#57d9ed',green:'#82e0b0',amber:'#ffd078',red:'#ff8a94'};
|
||||
const D=Number.isFinite(+config.duration)&&+config.duration>0?+config.duration:6000;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
function e(t,a={},text='',p=svg){return el(t,a,text,p);}
|
||||
function g(){return e('g');}
|
||||
function rect(x,y,w,h,fill=C.panel,stroke=C.line,p=svg,r=8){return e('rect',{x,y,width:w,height:h,rx:r,fill,stroke,'stroke-width':2},'',p);}
|
||||
function text(x,y,s,fill=C.ink,size=18,p=svg){return e('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif'},s,p);}
|
||||
function path(d,color=C.line,width=3,p=svg){return e('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round'},'',p);}
|
||||
function circle(x,y,r,fill=C.cyan,p=svg){return e('circle',{cx:x,cy:y,r,fill},'',p);}
|
||||
const tracks=new WeakMap();
|
||||
function tween(o,attrs,start,end){
|
||||
let previous=tracks.get(o);if(!previous){previous={};tracks.set(o,previous);}
|
||||
for(const [key,values] of Object.entries(attrs)){
|
||||
const old=previous[key];
|
||||
// Anime v4 needs explicit holds across gaps for reverse seeking.
|
||||
if(old && start>old.end)tl.add(o,{[key]:[old.value,old.value],duration:(start-old.end)*D/6000},old.end*D/6000);
|
||||
previous[key]={end,value:values[values.length-1]};
|
||||
}
|
||||
tl.add(o,{...attrs,duration:(end-start)*D/6000},start*D/6000);
|
||||
}
|
||||
function reveal(o,start,end= start+650){o.setAttribute('opacity','0');tween(o,{opacity:[0,1]},start,end);}
|
||||
function flow(d,start,end,color=C.cyan,width=5){const p=path(d,color,width);const len=p.getTotalLength();p.setAttribute('stroke-dasharray',len);p.setAttribute('stroke-dashoffset',len);tween(p,{strokeDashoffset:[len,0]},start,end);return p;}
|
||||
function parcel(x,y,color=C.amber){const p=g();rect(x,y,36,28,color,'#0b1424',p,3);path(`M${x+18} ${y} V${y+28}`,'#736146',2,p);return p;}
|
||||
function person(x,y,color=C.cyan){const p=g();circle(x,y,10,color,p);path(`M${x} ${y+15} V${y+43} M${x-15} ${y+25} H${x+15} M${x} ${y+43} L${x-12} ${y+60} M${x} ${y+43} L${x+12} ${y+60}`,color,6,p);return p;}
|
||||
function gear(x,y,r,color=C.line){const p=g();for(let i=0;i<12;i++){const a=i*Math.PI/6;path(`M${x+Math.cos(a)*(r-5)} ${y+Math.sin(a)*(r-5)} L${x+Math.cos(a)*(r+7)} ${y+Math.sin(a)*(r+7)}`,color,8,p);}circle(x,y,r,color,p);circle(x,y,r*.45,C.bg,p);return p;}
|
||||
rect(10,10,940,520,C.bg,C.panel,svg,16);
|
||||
const heading=text(32,43,title,C.ink,25);
|
||||
const words=subtitle.split(' ');let line='',row=0;for(const w of words){if((line+' '+w).length>104){text(32,70+row*19,line,C.muted,16);line=w;row++;}else line+=(line?' ':'')+w;}if(line)text(32,70+row*19,line,C.muted,16);
|
||||
path('M32 426 H928',C.line,1);
|
||||
phases.forEach((s,i)=>{const x=47+i*183;circle(x,455,13,C.panel);const dot=circle(x,455,11,C.cyan);dot.setAttribute('opacity','.18');tween(dot,{opacity:[.18,1]},i*1200,i*1200+700);text(x+21,461,s,C.ink,16);});
|
||||
text(32,510,note,C.muted,16);
|
||||
tween(heading,{opacity:[1,1]},0,6000);
|
||||
return {C,D,tl,e,g,rect,text,path,circle,tween,reveal,flow,parcel,person,gear};
|
||||
}
|
||||
window.industryRenderers["healthcare-care-handoffs"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Care coordination: triage and handoffs","Follow registration, triage review, care-team handoff and discharge coordination, with an information gap resolved.",["Register", "Triage review", "Resolve gap", "Team accepts", "Coordinate exit"],"Cyan = person journey \u00b7 Amber = missing information \u00b7 Green = accepted handoff");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow,person}=s;
|
||||
text(44,117,'ARRIVAL',C.muted,17);text(267,117,'TRIAGE REVIEW',C.muted,17);text(514,117,'CARE TEAM',C.muted,17);text(766,117,'NEXT SETTING',C.muted,17);
|
||||
// Reception counter, review chairs, care bed and exit doorway.
|
||||
path('M52 219 H205 V283 H52 Z',C.line,3);rect(138,174,49,34,C.panel,C.cyan);path('M160 208 V219',C.line,4);person(92,172,C.muted);
|
||||
path('M282 220 V254 H319 V280 M282 254 V280 M343 220 V254 H380 V280 M343 254 V280',C.line,5);person(332,158,C.cyan);
|
||||
path('M510 238 H677 V272 H510 V209 M675 235 V278',C.line,6);rect(524,215,41,21,C.muted,C.muted);path('M567 220 H651 V239',C.cyan,5);circle(532,282,7,C.line);circle(657,282,7,C.line);
|
||||
rect(790,152,89,132,C.bg,C.green);path('M800 160 L852 173 V280',C.green,3);circle(841,227,4,C.green);path('M815 130 H871 M861 122 L871 130 L861 138',C.green,3);
|
||||
path('M69 310 H878',C.line,3);
|
||||
const patient=person(81,288,C.cyan);tween(patient,{translateX:[0,248]},0,1700);tween(patient,{translateX:[248,248]},1700,3500);tween(patient,{translateX:[248,505]},3600,4500);tween(patient,{translateX:[505,749]},4800,5900);
|
||||
flow('M146 151 H261',600,1400);flow('M383 151 H504',3500,4300,C.green);flow('M679 151 H779',4700,5600,C.green);
|
||||
rect(263,369,224,41,C.bg,C.amber);const missing=text(276,396,'Missing referral details',C.amber,16);tween(missing,{opacity:[1,0]},3400,3700);const resolved=text(276,396,'Referral gap resolved',C.green,16);reveal(resolved,3700,4000);
|
||||
const question=text(417,210,'?',C.amber,32);reveal(question,2400,2800);tween(question,{opacity:[1,0]},3400,3700);const accepted=path('M410 201 L420 211 L437 190',C.green,4);reveal(accepted,3700,4000);
|
||||
flow('M423 224 V356 H193 V286',2400,3300,C.amber,3);flow('M203 286 V343 H408 V223',3100,3900,C.green,3);
|
||||
text(519,370,String(config.handoffRole||'Care coordinator').slice(0,22)+' accepts',C.green,17);text(519,398,'before ownership transfers.',C.muted,16);
|
||||
text(47,394,'No treatment logic',C.muted,16);
|
||||
return tl;
|
||||
};
|
||||
window.industryRenderers["healthcare-sample-rejection"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Diagnostic sample chain: reject and recollect","A labeled tube passes accession and inspection; an unsuitable specimen is held while a linked replacement reaches analysis.",["Label & send", "Accession", "Reject & hold", "Recollect", "Analyze & report"],"Amber = held specimen \u00b7 Cyan = replacement specimen \u00b7 Green = accepted result record");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow}=s;
|
||||
text(43,117,'COLLECTION',C.muted,17);text(269,117,'ACCESSION',C.muted,17);text(511,117,'INSPECTION',C.muted,17);text(753,117,'ANALYZER',C.muted,17);
|
||||
function tube(x,y,color){const p=g();path(`M${x} ${y} V${y+46} Q${x+11} ${y+62} ${x+22} ${y+46} V${y} Z`,color,3,p);rect(x-2,y-7,26,10,color,color,p,2);rect(x+4,y+16,14,17,C.ink,C.ink,p,1);return p;}
|
||||
path('M48 263 H195 M62 263 V295 M180 263 V295',C.line,5);for(let x=70;x<180;x+=34)tube(x,209,C.line);
|
||||
rect(280,172,149,99,C.panel,C.line);rect(295,187,117,51,C.bg,C.cyan);for(let x=309;x<396;x+=9)path(`M${x} 197 V226`,C.cyan,x%2?2:4);text(285,295,String(config.sampleId||'S-042').slice(0,10)+' registered',C.muted,16);
|
||||
// Magnifier inspection and containment rack.
|
||||
circle(574,207,35,C.panel);circle(574,207,29,C.bg);path('M599 230 L626 257',C.line,9);path('M560 207 H588 M574 193 V221',C.amber,3);
|
||||
rect(506,323,164,71,C.bg,C.amber);text(520,349,'REJECTED',C.amber,16);text(520,378,String(config.sampleId||'S-042').slice(0,10)+' held',C.muted,16);
|
||||
rect(750,161,155,121,C.panel,C.line);rect(770,179,76,42,C.bg,C.green);path('M779 205 H790 L800 189 L811 213 L823 197 H838',C.green,2);circle(873,198,11,C.cyan);rect(767,240,118,23,C.bg,C.line);text(751,307,'Accepted sample only',C.green,16);
|
||||
path('M190 247 H279 M430 247 H506 M635 247 H747',C.line,3);
|
||||
const original=tube(110,178,C.amber);tween(original,{translateX:[0,228]},0,1300);tween(original,{translateX:[228,453]},1400,2300);tween(original,{translateX:[453,529],translateY:[0,160]},2600,3300);
|
||||
flow('M504 371 H236 V308 H123 V280',3000,3950,C.amber,3);text(241,402,'Recollect: linked replacement',C.cyan,16);
|
||||
const replacement=tube(110,178,C.cyan);reveal(replacement,3600,3900);tween(replacement,{translateX:[0,453]},3900,4700);tween(replacement,{translateX:[453,693]},4800,5500);
|
||||
rect(758,334,146,68,C.bg,C.green);text(773,361,'RESULT RECORD',C.green,16);text(773,386,String(config.sampleId||'S-042').slice(0,10)+'-R linked',C.muted,16);flow('M829 284 V329',5500,6000,C.green);
|
||||
text(43,345,'Do not erase the',C.muted,17);text(43,370,'rejected sample trail.',C.muted,17);
|
||||
return tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,83 @@
|
||||
/* Original conceptual teaching scenes. No operational or engineering model. */
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
const C={bg:'#101d30',panel:'#182b42',line:'#667c95',ink:'#edf5ff',muted:'#aec1d7',cyan:'#57d4ed',green:'#85e0ad',amber:'#ffd178',red:'#ff8c8c'};
|
||||
function scene(svg,config,kit,title,subtitle,phases,note){
|
||||
const {anime,el}=kit, duration=Math.max(3000,Number(config.duration)||6000), unit=duration/6;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const E=(tag,a={},text='',p=svg)=>el(tag,a,text,p);
|
||||
const rect=(x,y,w,h,fill=C.panel,p=svg,extra={})=>E('rect',{x,y,width:w,height:h,rx:8,fill,...extra},'',p);
|
||||
const text=(x,y,t,size=18,fill=C.ink,p=svg,extra={})=>E('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif',style:`fill:${fill};font-size:${size}px;font-family:system-ui,sans-serif`,...extra},t,p);
|
||||
const path=(d,color=C.line,width=3,p=svg,extra={})=>E('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round',...extra},'',p);
|
||||
const circle=(cx,cy,r,fill=C.cyan,p=svg,extra={})=>E('circle',{cx,cy,r,fill,...extra},'',p);
|
||||
const group=()=>E('g');
|
||||
const add=(target,props,at=0,len=.75)=>tl.add(target,{...props,duration:unit*len},unit*at);
|
||||
const reveal=(target,at)=>{target.setAttribute('opacity','0.12');add(target,{opacity:[.12,1]},at);return target;};
|
||||
const draw=(d,at,color=C.cyan,width=4)=>{const p=path(d,color,width);p.setAttribute('pathLength','1');p.setAttribute('stroke-dasharray','1');p.setAttribute('stroke-dashoffset','1');add(p,{'stroke-dashoffset':[1,0]},at);return p;};
|
||||
rect(0,0,960,540,C.bg,svg,{rx:0}); text(32,39,title,26);text(32,69,subtitle,17,C.muted);
|
||||
path('M32 88 H928',C.line,1);
|
||||
phases.forEach((label,i)=>{const x=32+i*181;rect(x,440,172,44);const bar=rect(x,440,172,4,C.cyan,svg,{rx:0});add(bar,{opacity:[.15,1]},i,.65);text(x+10,469,`${i+1} ${label}`,16);});
|
||||
text(32,516,note,16,C.muted);
|
||||
const clock=E('g',{'data-clock':'finite'});add(clock,{opacity:[1,1]},0,6);
|
||||
return {svg,config,tl,E,rect,text,path,circle,group,add,reveal,draw,C};
|
||||
}
|
||||
window.industryRenderers["infrastructure-bridge-inspection"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'BRIDGE / LOAD PATH AND ACCESS CONTROL','Illustrate where load travels, then separate an inspection finding from a repair decision.',
|
||||
['Apply load','Trace path','Inspect','Close lane','Review repair'],'Conceptual only — NOT structural analysis, load rating, inspection instruction or engineering advice.');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// River, abutments, bridge piers and a recognizable truss deck.
|
||||
path('M40 371 Q140 354 240 371 T440 371 T640 371 T840 371 H920', '#315f7a',14);
|
||||
[99,456,813].forEach(x=>{rect(x,281,47,96,'#3b4c60');path(`M${x-13} 381 H${x+60}`,C.muted,7);});
|
||||
rect(72,264,809,18,'#718296',svg,{rx:2});path('M104 254 H851 M104 254 V161 H851 V254 M104 161 L229 254 L354 161 L479 254 L604 161 L729 254 L851 161',C.muted,5);
|
||||
path('M229 161 V254 M354 161 V254 M479 161 V254 M604 161 V254 M729 161 V254',C.line,3);
|
||||
text(59,415,'Abutment',16,C.muted);text(426,415,'Support / ground',16,C.muted);text(791,415,'Abutment',16,C.muted);
|
||||
// Vehicle load and explicit directional load arrows, intentionally unscaled.
|
||||
const loadX=Math.min(420,Math.max(300,Number(config.loadX)||385));
|
||||
const vehicle=group();rect(332,220,79,33,'#375676',vehicle);path('M411 233 H430 L441 252 H411 Z',C.cyan,3,vehicle);circle(349,257,7,C.bg,vehicle);circle(423,257,7,C.bg,vehicle);vehicle.setAttribute('transform',`translate(${loadX-385} 0)`);reveal(vehicle,0);
|
||||
draw(`M${loadX} 112 V211 M${loadX-8} 201 L${loadX} 211 L${loadX+8} 201`,0,C.amber,4);text(440,126,'Illustrative load',17,C.amber);
|
||||
draw(`M${loadX} 281 H479 V366 M471 357 L479 366 L487 357`,1,C.cyan,5);
|
||||
draw('M355 267 L229 164 L119 267 V366 M111 357 L119 366 L127 357',1.2,C.cyan,4);
|
||||
text(197,324,'Deck → members → supports',17,C.cyan);
|
||||
// Inspected member, magnifier and review card. The crack is a symbolic finding.
|
||||
const finding=group();path('M603 196 L595 207 L606 213 L599 224',C.amber,4,finding);circle(601,210,25,'none',finding,{stroke:C.amber,'stroke-width':3});path('M621 229 L642 250',C.amber,5,finding);reveal(finding,2);
|
||||
const inspect=group();rect(519,300,273,104,'#3d382e',inspect);text(533,327,'Finding → qualified review',17,C.amber,inspect);text(533,352,'Access restricted locally',16,C.ink,inspect);text(533,377,'Repair / reopen not assumed',16,C.ink,inspect);reveal(inspect,2.4);
|
||||
// Local closure barrier; physical access marker rather than alleged calculated failure.
|
||||
const closure=group();[648,765].forEach(x=>{path(`M${x} 228 V263`,C.amber,5,closure);});rect(633,223,148,17,'#503e2d',closure,{rx:1,stroke:C.amber});for(let i=0;i<6;i++)path(`M${639+i*24} 238 L${651+i*24} 225`,C.amber,4,closure);text(668,205,'Lane closed',16,C.amber,closure);reveal(closure,3);
|
||||
const repair=group();text(680,125,'Review before reopening',17,C.green,repair);path('M682 136 H902',C.green,2,repair);reveal(repair,4);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
window.industryRenderers["infrastructure-construction-resequence"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'CONSTRUCTION / MOVE WORK, NOT THE GATE','Off-site work can advance during a permit hold; the dependent lift still waits for release.',
|
||||
['Baseline','Permit hold','Identify float','Resequence','Gate lift'],'Illustrative schedule • amber = blocking dependency • green = resequenced work • no date promises');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// Site section with footing, steel frame and tower crane.
|
||||
path('M42 373 H347',C.muted,4);rect(66,350,90,23,'#44566b');path('M86 348 V258 H280 V348 M86 304 H280 M183 258 V350 M280 258 V350',C.line,6);
|
||||
path('M316 350 V130 H51 M316 148 H100 L316 130 L337 148 H316 M316 180 L335 202 L316 224 L335 246 L316 268 L335 290 L316 312',C.amber,3);path('M335 148 V350 M112 132 V207',C.line,3);path('M103 207 Q112 225 120 208',C.amber,3);
|
||||
text(51,404,'Site assembly waits for lift clearance',16,C.muted);
|
||||
// A true time-axis schedule, not a generic process-box flow.
|
||||
text(392,125,'Dependency schedule • illustrative time →',18);
|
||||
const x0=535;[0,1,2,3,4,5].forEach(i=>{path(`M${x0+i*70} 144 V396`,C.line,1,svg,{'stroke-dasharray':'3 7'});text(x0+i*70-4,420,String(i),16,C.muted);});
|
||||
const rows=[['Foundation',166],['Permit review',214],['Fabricate',262],['Site lift',310],['Envelope',358]];
|
||||
rows.forEach(([name,y])=>text(390,y+20,name,16));
|
||||
rect(535,166,98,27,'#316255');rect(535,214,140,27,'#59513d');
|
||||
const baseline=rect(675,262,140,27,'none',svg,{stroke:C.line,'stroke-dasharray':'5 4'});
|
||||
const advance=Math.min(2,Math.max(.5,Number(config.advanceSlots)||1.5))*70;
|
||||
const fabrication=rect(675,262,140,27,C.green);add(fabrication,{x:[675,675-advance]},3,1);
|
||||
text(684,282,'Off-site',16,C.bg); // label follows the moved bar using explicit x tween.
|
||||
const label=svg.lastChild;add(label,{x:[684,684-advance]},3,1);
|
||||
rect(745,310,70,27,'#32516d');rect(815,358,70,27,'#32516d');
|
||||
path('M633 180 H724 V323 H740 M675 228 H727 V323 H740 M815 276 H824 V300 H780 V306 M815 323 H831 V353',C.line,2);
|
||||
// A permit stop-sign interrupts the direct prerequisite, which never disappears.
|
||||
const hold=group();s.E('polygon',{points:'685,204 701,204 712,215 712,231 701,242 685,242 674,231 674,215',fill:'#583e31',stroke:C.amber,'stroke-width':2},'',hold);text(687,231,'!',22,C.amber,hold);reveal(hold,1);
|
||||
draw('M712 228 H727 V323 H741',1.3,C.amber,4);
|
||||
const opportunity=group();path('M573 251 H810 M581 245 L573 251 L581 257',C.green,3,opportunity);text(612,201,'Use available float',16,C.green,opportunity);reveal(opportunity,2);
|
||||
const staged=group();rect(168,321,97,26,'#345e46',staged,{rx:1});path('M179 320 L197 292 L217 320 L239 292 L255 320',C.green,3,staged);text(60,244,'Modules staged off-site',16,C.green,staged);reveal(staged,3.4);
|
||||
const gateNote=group();rect(39,91,311,29,'#493e2d',gateNote);text(49,111,'Lift remains gated until permit release',16,C.amber,gateNote);reveal(gateNote,4);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,97 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases, note) {
|
||||
const {anime,el}=kit;
|
||||
const C={bg:'#0b1424',panel:'#15243a',line:'#68809d',ink:'#edf4ff',muted:'#b2c4da',cyan:'#57d9ed',green:'#82e0b0',amber:'#ffd078',red:'#ff8a94'};
|
||||
const D=Number.isFinite(+config.duration)&&+config.duration>0?+config.duration:6000;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
function e(t,a={},text='',p=svg){return el(t,a,text,p);}
|
||||
function g(){return e('g');}
|
||||
function rect(x,y,w,h,fill=C.panel,stroke=C.line,p=svg,r=8){return e('rect',{x,y,width:w,height:h,rx:r,fill,stroke,'stroke-width':2},'',p);}
|
||||
function text(x,y,s,fill=C.ink,size=18,p=svg){return e('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif'},s,p);}
|
||||
function path(d,color=C.line,width=3,p=svg){return e('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round'},'',p);}
|
||||
function circle(x,y,r,fill=C.cyan,p=svg){return e('circle',{cx:x,cy:y,r,fill},'',p);}
|
||||
const tracks=new WeakMap();
|
||||
function tween(o,attrs,start,end){
|
||||
let previous=tracks.get(o);if(!previous){previous={};tracks.set(o,previous);}
|
||||
for(const [key,values] of Object.entries(attrs)){
|
||||
const old=previous[key];
|
||||
// Anime v4 needs explicit holds across gaps for reverse seeking.
|
||||
if(old && start>old.end)tl.add(o,{[key]:[old.value,old.value],duration:(start-old.end)*D/6000},old.end*D/6000);
|
||||
previous[key]={end,value:values[values.length-1]};
|
||||
}
|
||||
tl.add(o,{...attrs,duration:(end-start)*D/6000},start*D/6000);
|
||||
}
|
||||
function reveal(o,start,end= start+650){o.setAttribute('opacity','0');tween(o,{opacity:[0,1]},start,end);}
|
||||
function flow(d,start,end,color=C.cyan,width=5){const p=path(d,color,width);const len=p.getTotalLength();p.setAttribute('stroke-dasharray',len);p.setAttribute('stroke-dashoffset',len);tween(p,{strokeDashoffset:[len,0]},start,end);return p;}
|
||||
function parcel(x,y,color=C.amber){const p=g();rect(x,y,36,28,color,'#0b1424',p,3);path(`M${x+18} ${y} V${y+28}`,'#736146',2,p);return p;}
|
||||
function person(x,y,color=C.cyan){const p=g();circle(x,y,10,color,p);path(`M${x} ${y+15} V${y+43} M${x-15} ${y+25} H${x+15} M${x} ${y+43} L${x-12} ${y+60} M${x} ${y+43} L${x+12} ${y+60}`,color,6,p);return p;}
|
||||
function gear(x,y,r,color=C.line){const p=g();for(let i=0;i<12;i++){const a=i*Math.PI/6;path(`M${x+Math.cos(a)*(r-5)} ${y+Math.sin(a)*(r-5)} L${x+Math.cos(a)*(r+7)} ${y+Math.sin(a)*(r+7)}`,color,8,p);}circle(x,y,r,color,p);circle(x,y,r*.45,C.bg,p);return p;}
|
||||
rect(10,10,940,520,C.bg,C.panel,svg,16);
|
||||
const heading=text(32,43,title,C.ink,25);
|
||||
const words=subtitle.split(' ');let line='',row=0;for(const w of words){if((line+' '+w).length>104){text(32,70+row*19,line,C.muted,16);line=w;row++;}else line+=(line?' ':'')+w;}if(line)text(32,70+row*19,line,C.muted,16);
|
||||
path('M32 426 H928',C.line,1);
|
||||
phases.forEach((s,i)=>{const x=47+i*183;circle(x,455,13,C.panel);const dot=circle(x,455,11,C.cyan);dot.setAttribute('opacity','.18');tween(dot,{opacity:[.18,1]},i*1200,i*1200+700);text(x+21,461,s,C.ink,16);});
|
||||
text(32,510,note,C.muted,16);
|
||||
tween(heading,{opacity:[1,1]},0,6000);
|
||||
return {C,D,tl,e,g,rect,text,path,circle,tween,reveal,flow,parcel,person,gear};
|
||||
}
|
||||
window.industryRenderers["logistics-hub-connection-recovery"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Hub sorting: recover a missed connection","Follow a late parcel from induction through sorting, a missed departure, exception staging and a later connection.",["Induct", "Read & sort", "Cutoff missed", "Stage safely", "Reconnect"],"Cyan = planned path \u00b7 Amber = late parcel \u00b7 Green = recovery connection");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow,parcel}=s;
|
||||
text(47,117,'INDUCTION',C.muted,17);text(307,117,'SCAN / DIVERT',C.muted,17);text(701,117,'DEPARTURE LANES',C.muted,17);
|
||||
// A real conveyor: twin rails and repeated rollers, not process boxes.
|
||||
rect(45,192,438,74,'#23354a',C.line);
|
||||
for(let x=58;x<475;x+=22) path(`M${x} 200 V258`,C.line,2);
|
||||
path('M465 212 L569 161 H857 M465 246 L569 337 H857',C.line,18);
|
||||
path('M465 212 L569 161 H857 M465 246 L569 337 H857',C.bg,11);
|
||||
path('M303 187 V142 H387 V187',C.cyan,7);path('M317 177 H373',C.cyan,2);
|
||||
text(298,292,'Identity retained',C.muted,16);
|
||||
// Docked truck silhouettes.
|
||||
function truck(x,y,color){const p=g();rect(x,y,116,51,C.panel,color,p,3);path(`M${x+116} ${y+15} H${x+142} L${x+156} ${y+33} V${y+51} H${x+116}`,color,3,p);circle(x+27,y+55,10,C.line,p);circle(x+128,y+55,10,C.line,p);return p;}
|
||||
const first=truck(717,130,C.cyan);tween(first,{opacity:[1,.3]},2400,2900);text(709,215,'Original connection',C.ink,16);
|
||||
const second=truck(717,307,C.green);text(705,395,String(config.recoveryConnection||'Later connection').slice(0,22),C.green,17);
|
||||
rect(516,246,146,44,C.bg,C.amber);text(529,274,'HOLD / ID',C.amber,16);
|
||||
const gate=path('M593 139 V184',C.red,6);reveal(gate,2400,2700);
|
||||
const late=text(511,137,'Cutoff closed',C.red,17);reveal(late,2400,2850);
|
||||
flow('M71 229 H343',0,1300);const oldRoute=flow('M343 229 H462 L566 161 H589',1300,2400);tween(oldRoute,{opacity:[1,.22]},2400,2850);
|
||||
const p=parcel(70,215);tween(p,{translateX:[0,271]},0,1200);tween(p,{translateX:[271,473],translateY:[0,-68]},1200,2300);
|
||||
tween(p,{translateX:[473,544],translateY:[-68,39]},2800,3600);
|
||||
flow('M577 184 V244 M632 290 V337 H709',3000,4700,C.amber);
|
||||
tween(p,{translateX:[544,537],translateY:[39,108]},3800,4500);tween(p,{translateX:[537,680],translateY:[108,108]},4800,5650);
|
||||
const stamp=text(47,369,'Recovery preserves the parcel ID,',C.green,18);text(47,395,'not the original departure.',C.muted,17);reveal(stamp,4800,5500);
|
||||
return tl;
|
||||
};
|
||||
window.industryRenderers["logistics-port-crane-yard"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Port coordination: berth, crane and yard","A container moves only after berth access, crane clearance and a yard slot align; a blocked lane prompts reassignment.",["Berth ready", "Lift approved", "Lane blocked", "Reassign slot", "Yard receipt"],"Amber = container \u00b7 Red = unavailable lane \u00b7 Green = assigned yard slot");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow}=s;
|
||||
rect(32,303,343,105,'#102e46','#102e46');for(let y=325;y<402;y+=23)path(`M44 ${y} Q70 ${y-9} 96 ${y} T148 ${y} T200 ${y} T252 ${y} T304 ${y}`,C.line,1);
|
||||
path('M54 267 H340 L308 326 H90 Z',C.cyan,3);rect(64,226,47,41,C.panel,C.cyan);rect(77,209,21,17,C.panel,C.cyan);
|
||||
for(let x=122;x<306;x+=59)rect(x,238,53,28,C.panel,C.line,undefined,2);
|
||||
text(49,376,'BERTH / VESSEL',C.cyan,17);
|
||||
rect(375,309,547,99,'#23354a','#23354a');path('M386 315 H916',C.muted,3);
|
||||
// Quayside gantry with boom, portal legs and cable.
|
||||
path('M401 309 V137 H630 V309 M389 309 L438 137 M642 309 L595 137 M208 139 H671',C.ink,7);
|
||||
path('M426 138 L516 101 L610 138',C.line,4);
|
||||
const trolley=rect(257,129,42,22,C.cyan,C.cyan);const cable=path('M278 151 V221',C.amber,3);
|
||||
tween(cable,{d:['M278 151 V221','M278 151 V155']},1200,2200);
|
||||
tween(cable,{d:['M278 151 V155','M554 151 V155']},2600,3700);tween(trolley,{translateX:[0,276]},2600,3700);
|
||||
tween(cable,{d:['M554 151 V155','M554 151 V316']},3900,4700);tween(cable,{opacity:[1,0]},4700,4800);
|
||||
const lift=g();rect(253,235,52,30,C.amber,C.amber,lift,2);path('M253 235 L279 221 L305 235',C.amber,2,lift);
|
||||
tween(lift,{translateY:[0,-66]},1200,2200);tween(lift,{translateX:[0,276],translateY:[-66,-66]},2600,3700);tween(lift,{translateX:[276,276],translateY:[-66,95]},3900,4700);
|
||||
text(48,119,'Ship secured',C.green,17);text(446,186,'Lift zone',C.muted,16);
|
||||
rect(467,340,175,28,C.bg,C.line);path('M477 355 H627',C.muted,2);text(468,397,'Transfer vehicle',C.ink,16);
|
||||
const vehicle=g();rect(502,345,90,17,C.panel,C.green,vehicle,3);circle(519,368,7,C.line,vehicle);circle(579,368,7,C.line,vehicle);tween(vehicle,{translateX:[0,263]},4800,5800);tween(lift,{translateX:[276,539],translateY:[95,95]},4800,5800);
|
||||
text(709,117,'YARD ASSIGNMENT',C.muted,17);
|
||||
for(let y=146;y<239;y+=43)for(let x=712;x<881;x+=55)rect(x,y,47,31,C.panel,C.line,undefined,2);
|
||||
path('M733 250 L754 273 M754 250 L733 273',C.red,4);text(767,287,'Lane A held',C.red,16);
|
||||
flow('M646 357 H693 V293 H866 V330',3600,4850,C.green);
|
||||
rect(774,331,109,53,C.bg,C.green);text(783,403,'Slot '+String(config.yardSlot||'B').slice(0,8)+' ready',C.green,16);
|
||||
const ok=text(433,252,'Release → transfer → receipt',C.green,16);reveal(ok,4800,5700);
|
||||
svg.append(vehicle,lift);
|
||||
return tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,87 @@
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases, note) {
|
||||
const {anime,el}=kit;
|
||||
const C={bg:'#0b1424',panel:'#15243a',line:'#68809d',ink:'#edf4ff',muted:'#b2c4da',cyan:'#57d9ed',green:'#82e0b0',amber:'#ffd078',red:'#ff8a94'};
|
||||
const D=Number.isFinite(+config.duration)&&+config.duration>0?+config.duration:6000;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
function e(t,a={},text='',p=svg){return el(t,a,text,p);}
|
||||
function g(){return e('g');}
|
||||
function rect(x,y,w,h,fill=C.panel,stroke=C.line,p=svg,r=8){return e('rect',{x,y,width:w,height:h,rx:r,fill,stroke,'stroke-width':2},'',p);}
|
||||
function text(x,y,s,fill=C.ink,size=18,p=svg){return e('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif'},s,p);}
|
||||
function path(d,color=C.line,width=3,p=svg){return e('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round'},'',p);}
|
||||
function circle(x,y,r,fill=C.cyan,p=svg){return e('circle',{cx:x,cy:y,r,fill},'',p);}
|
||||
const tracks=new WeakMap();
|
||||
function tween(o,attrs,start,end){
|
||||
let previous=tracks.get(o);if(!previous){previous={};tracks.set(o,previous);}
|
||||
for(const [key,values] of Object.entries(attrs)){
|
||||
const old=previous[key];
|
||||
// Anime v4 needs explicit holds across gaps for reverse seeking.
|
||||
if(old && start>old.end)tl.add(o,{[key]:[old.value,old.value],duration:(start-old.end)*D/6000},old.end*D/6000);
|
||||
previous[key]={end,value:values[values.length-1]};
|
||||
}
|
||||
tl.add(o,{...attrs,duration:(end-start)*D/6000},start*D/6000);
|
||||
}
|
||||
function reveal(o,start,end= start+650){o.setAttribute('opacity','0');tween(o,{opacity:[0,1]},start,end);}
|
||||
function flow(d,start,end,color=C.cyan,width=5){const p=path(d,color,width);const len=p.getTotalLength();p.setAttribute('stroke-dasharray',len);p.setAttribute('stroke-dashoffset',len);tween(p,{strokeDashoffset:[len,0]},start,end);return p;}
|
||||
function parcel(x,y,color=C.amber){const p=g();rect(x,y,36,28,color,'#0b1424',p,3);path(`M${x+18} ${y} V${y+28}`,'#736146',2,p);return p;}
|
||||
function person(x,y,color=C.cyan){const p=g();circle(x,y,10,color,p);path(`M${x} ${y+15} V${y+43} M${x-15} ${y+25} H${x+15} M${x} ${y+43} L${x-12} ${y+60} M${x} ${y+43} L${x+12} ${y+60}`,color,6,p);return p;}
|
||||
function gear(x,y,r,color=C.line){const p=g();for(let i=0;i<12;i++){const a=i*Math.PI/6;path(`M${x+Math.cos(a)*(r-5)} ${y+Math.sin(a)*(r-5)} L${x+Math.cos(a)*(r+7)} ${y+Math.sin(a)*(r+7)}`,color,8,p);}circle(x,y,r,color,p);circle(x,y,r*.45,C.bg,p);return p;}
|
||||
rect(10,10,940,520,C.bg,C.panel,svg,16);
|
||||
const heading=text(32,43,title,C.ink,25);
|
||||
const words=subtitle.split(' ');let line='',row=0;for(const w of words){if((line+' '+w).length>104){text(32,70+row*19,line,C.muted,16);line=w;row++;}else line+=(line?' ':'')+w;}if(line)text(32,70+row*19,line,C.muted,16);
|
||||
path('M32 426 H928',C.line,1);
|
||||
phases.forEach((s,i)=>{const x=47+i*183;circle(x,455,13,C.panel);const dot=circle(x,455,11,C.cyan);dot.setAttribute('opacity','.18');tween(dot,{opacity:[.18,1]},i*1200,i*1200+700);text(x+21,461,s,C.ink,16);});
|
||||
text(32,510,note,C.muted,16);
|
||||
tween(heading,{opacity:[1,1]},0,6000);
|
||||
return {C,D,tl,e,g,rect,text,path,circle,tween,reveal,flow,parcel,person,gear};
|
||||
}
|
||||
window.industryRenderers["manufacturing-takt-buffer"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Assembly flow: bottleneck and buffer","Three assembly stations expose an uneven cycle; a small buffer absorbs the mismatch while work is rebalanced.",["Feed chassis", "Assemble", "Queue grows", "Rebalance", "Release units"],"Amber = waiting work \u00b7 Cyan = active assembly \u00b7 Green = completed unit");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow,gear}=s;
|
||||
text(48,120,'01 CHASSIS',C.muted,18);text(352,120,'02 FIT & FASTEN',C.cyan,18);text(714,120,'03 VERIFY',C.muted,18);
|
||||
rect(42,282,870,63,'#23354a',C.line);for(let x=55;x<900;x+=25)circle(x,315,8,C.line);
|
||||
path('M72 280 V191 H228 V280',C.line,7);path('M116 194 V222 H182 V194',C.cyan,5);
|
||||
// Articulated assembly arm, gripper and component rack.
|
||||
rect(386,236,62,43,C.panel,C.cyan);path('M416 239 L461 190 L506 226 L526 212',C.cyan,11);circle(461,190,13,C.ink);circle(506,226,9,C.ink);path('M517 209 L526 228 L538 213',C.amber,4);
|
||||
gear(360,215,18,C.line);rect(538,152,53,65,C.panel,C.line);for(let y=165;y<209;y+=17)path(`M546 ${y} H584`,C.amber,4);
|
||||
path('M744 281 V177 H855 V281',C.green,7);path('M760 197 H840',C.green,3);
|
||||
function chassis(x,y,color){const p=g();rect(x,y,66,26,C.panel,color,p,5);circle(x+13,y+28,7,C.line,p);circle(x+53,y+28,7,C.line,p);return p;}
|
||||
const unit=chassis(97,256,C.cyan);tween(unit,{translateX:[0,306]},0,1600);tween(unit,{translateX:[306,306]},1600,3600);tween(unit,{translateX:[306,654]},4000,5600);
|
||||
const top=path('M112 255 L124 240 H147 L158 255',C.green,4);top.setAttribute('opacity',0);tween(top,{opacity:[0,1],translateX:[306,306]},1700,2300);tween(top,{translateX:[306,654]},4000,5600);
|
||||
const slots=Math.max(1,Math.min(3,Math.round(+config.bufferSlots||2)));const queue=[];for(let i=0;i<slots;i++){const q=chassis(130+i*72,256,C.amber);reveal(q,2200+i*250,2600+i*250);queue.push(q);}
|
||||
path('M127 353 V365 H353 V353',C.amber,3);text(143,391,'Buffer: '+slots+' slots',C.amber,17);
|
||||
const warn=text(352,153,'Longer station cycle',C.amber,16);reveal(warn,2200,2800);
|
||||
flow('M614 178 Q661 133 702 178',3500,4300,C.green);text(604,214,'Shift checks',C.green,16);text(604,237,'downstream',C.muted,16);
|
||||
queue.forEach((q,i)=>tween(q,{translateX:[0,222]},4300+i*200,6000));
|
||||
text(51,391,'Buffer buys time, not capacity.',C.muted,16); // moved below by explicit position adjustment
|
||||
const labels=svg.querySelectorAll('text');labels[labels.length-1].setAttribute('y','414');
|
||||
text(718,391,'Verification gate',C.green,17);
|
||||
return tl;
|
||||
};
|
||||
window.industryRenderers["manufacturing-fault-rework"] = function(svg, config, kit) {
|
||||
const s=scene(svg,config,kit,"Machine fault: isolate, inspect and rework","A machining fault stops the affected cell; a suspect part leaves the main line for inspection, rework and verification.",["Machine part", "Detect fault", "Contain lot", "Rework", "Verify release"],"Red = isolated cell \u00b7 Amber = suspect part \u00b7 Green = verified return path");
|
||||
|
||||
const {C,tl,g,rect,text,path,circle,tween,reveal,flow,gear}=s;
|
||||
text(49,118,'MACHINING CELL',C.muted,17);text(702,118,'QUALITY GATE',C.muted,17);
|
||||
rect(59,139,258,190,C.panel,C.line);rect(82,160,211,123,C.bg,C.line);path('M105 296 H273',C.line,8);
|
||||
path('M185 161 V194 M164 194 H206 L198 219 H172 Z',C.cyan,7);path('M112 262 H258',C.line,5);gear(111,183,14,C.line);
|
||||
const spindle=path('M184 219 V242',C.cyan,7);tween(spindle,{translateY:[0,12]},0,900);tween(spindle,{translateY:[12,0]},900,1500);
|
||||
const fault=circle(284,148,9,C.red);reveal(fault,1500,2100);const isolation=path('M63 136 L310 324 M310 136 L63 324',C.red,3);reveal(isolation,2400,3000);
|
||||
text(60,357,'Cell isolated; lot retained',C.red,16);text(60,383,'Repair ≠ product release',C.muted,16);
|
||||
path('M320 249 H701',C.line,6);path('M346 232 V266',C.red,6);
|
||||
rect(396,158,266,64,C.bg,C.amber);text(411,184,'CONTAINMENT',C.amber,17);text(411,207,String(config.lotId||'LOT A').slice(0,14)+' · inspect',C.muted,16);
|
||||
// A rework bench with vise, tool and part cradle.
|
||||
path('M439 350 H657 M457 350 V405 M638 350 V405',C.line,6);rect(473,324,69,24,C.panel,C.amber);path('M487 323 V309 H528 V323',C.amber,4);path('M583 306 L609 333 M576 296 L583 306 L595 299',C.cyan,6);
|
||||
text(458,389,'REWORK BENCH',C.amber,17);
|
||||
path('M731 291 V156 H865 V291',C.green,6);path('M754 181 H841 M766 194 H831',C.green,2);
|
||||
text(716,325,'Recheck required',C.green,17);text(716,352,'before line return',C.muted,16);
|
||||
const part=g();circle(185,248,17,C.amber,part);circle(185,248,7,C.bg,part);
|
||||
tween(part,{translateX:[0,447],translateY:[0,0]},1600,2400);tween(part,{translateX:[447,447],translateY:[0,-56]},2400,2700);tween(part,{translateX:[447,447],translateY:[-56,28]},3200,3500);tween(part,{translateX:[447,322],translateY:[28,72]},3500,4200);tween(part,{translateX:[322,610],translateY:[72,0]},4800,5800);
|
||||
flow('M490 224 V290 H510 V310',3100,4000,C.amber);flow('M550 333 H682 V249 H788',4400,5800,C.green);
|
||||
const check=path('M779 277 L791 287 L818 263',C.green,4);reveal(check,5400,6000);
|
||||
return tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,93 @@
|
||||
/* Original conceptual industry scenes; Anime.js v4. */
|
||||
(function(){
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases) {
|
||||
const {el,anime}=kit, p=Number.isFinite(Number(config.phaseMs)) && Number(config.phaseMs)>0 ? Number(config.phaseMs) : 1200;
|
||||
const c={ink:'#e5edf7',muted:'#93a8bf',blue:'#63baff',green:'#6ce1b4',amber:'#ffc56b',red:'#ff8091',bg:'#101e30',line:'#314961'};
|
||||
const E=(tag,a={},t='',parent=svg)=>el(tag,a,t,parent);
|
||||
const text=(x,y,t,size=18,color=c.ink)=>E('text',{x,y,fill:color,'font-size':size,'font-family':'system-ui'},t);
|
||||
const path=(d,color=c.line,w=5)=>E('path',{d,fill:'none',stroke:color,'stroke-width':w,'stroke-linecap':'round','stroke-linejoin':'round'});
|
||||
const rect=(x,y,w,h,color=c.bg,stroke=c.line,rx=8)=>E('rect',{x,y,width:w,height:h,rx,fill:color,stroke,'stroke-width':2});
|
||||
const circle=(x,y,r,color=c.blue)=>E('circle',{cx:x,cy:y,r,fill:color});
|
||||
E('rect',{width:960,height:540,fill:'#091321'});
|
||||
text(32,38,title,26);text(32,67,subtitle,16,c.muted);
|
||||
path('M32 88 H928',c.line,1);
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const anchor=E('g');tl.add(anchor,{opacity:[1,1],duration:p*5},0);
|
||||
function show(node,step){node.setAttribute('opacity','.15');tl.add(node,{opacity:[.15,1],duration:p*.65},step*p);return node;}
|
||||
function flow(d,step,color=c.green){const n=path(d,color,5);const len=n.getTotalLength();n.setAttribute('stroke-dasharray',len);n.setAttribute('stroke-dashoffset',len);tl.add(n,{'stroke-dashoffset':[len,0],duration:p*.75},step*p);return n;}
|
||||
function move(n,x0,y0,x1,y1,step){tl.add(n,{cx:[x0,x1],cy:[y0,y1],duration:p*.75},step*p);}
|
||||
function note(x,y,w,heading,detail,color=c.green,step=0){rect(x,y,w,58);show(rect(x,y,5,58,color,color,0),step);text(x+16,y+24,heading,18,color);text(x+16,y+46,detail,16,c.muted);}
|
||||
function valve(x,y,step){const n=path(`M${x-10} ${y-10} L${x+10} ${y+10} M${x+10} ${y-10} L${x-10} ${y+10}`,c.red,4);show(n,step);}
|
||||
phases.forEach((s,i)=>{const x=32+i*182;rect(x,465,174,42,'#132338');show(rect(x,465,4,42,c.blue,c.blue,0),i);text(x+12,491,`${i+1} ${s}`,16);});
|
||||
text(32,529,'Conceptual sequence · illustrative timing · not an operating procedure',16,c.muted);
|
||||
return {E,text,path,rect,circle,tl,show,flow,move,note,valve,c,p};
|
||||
}
|
||||
window.industryRenderers['oil-gas-separator-upset'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Separator train: contain an upset","Separate the streams; isolate one train without hiding the recovery route.",["Feed split", "Separation", "Upset held", "Train isolated", "Stable route"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,valve,c}=s;
|
||||
text(34,141,'Mixed feed',18);path('M45 212 H180 M180 173 V343 H240 M180 173 H240');
|
||||
function vessel(y,label){rect(240,y,280,90,'#172b40',c.blue,45);path(`M335 ${y+4} V${y+86}`,c.line,2);path(`M420 ${y+4} V${y+86}`,c.line,2);text(258,y+35,label,18);text(258,y+66,'gas / oil / water',16,c.muted);path(`M520 ${y+25} H595 M520 ${y+65} H640`);}
|
||||
vessel(125,'Train A');vessel(295,'Train B');
|
||||
const aFeed=flow('M45 212 H180 V173 H240',0,c.blue);s.tl.add(aFeed,{opacity:[1,.15],duration:s.p*.5},3*s.p);flow('M180 212 V343 H240',0,c.blue);
|
||||
text(609,112,'Gas header',18);text(653,177,'Oil header',18);text(658,247,'Water handling',18);
|
||||
path('M595 125 V320 M640 190 V360 M520 200 H625 V255 H820');
|
||||
const aGas=flow('M520 150 H595 V125 H825',1,c.amber);s.tl.add(aGas,{opacity:[1,.15],duration:s.p*.5},3*s.p);const aOil=flow('M520 190 H825',1,c.green), aWater=flow('M520 200 H625 V255 H820',1,c.blue);s.tl.add([aOil,aWater],{opacity:[1,.15],duration:s.p*.5},3*s.p);
|
||||
const alarm=circle(475,142,10,c.red);show(alarm,2);text(310,237,'A: level upset → hold',16,c.red);
|
||||
valve(216,173,3);valve(555,150,3);text(35,293,'Isolate A',18,c.red);text(35,317,'Keep B available',16,c.muted);
|
||||
flow('M520 320 H595 V125 H825',4,c.green);flow('M520 360 H640 V190 H825',4,c.green);flow('M520 377 H615 V255 H820',4,c.blue);
|
||||
note(660,307,265,'B carries accepted flow','Capacity not quantified',c.green,4);
|
||||
text(242,422,'Blue: feed / water Gold: gas Green: accepted route',16,c.muted);
|
||||
|
||||
const level=Math.max(12,Math.min(40,Number(config.feedLevel)||26));
|
||||
// Phase bands visibly rise in A, then drain after isolation. B stays stable.
|
||||
const fluidA=rect(428,201-level,67,level,'#4386a1','none',3);
|
||||
const oilA=rect(428,181-level,67,20,'#d3ac62','none',3);
|
||||
s.tl.add(fluidA,{height:[level,level+25],y:[201-level,176-level],duration:s.p*.65},2*s.p);
|
||||
s.tl.add(oilA,{y:[181-level,156-level],duration:s.p*.65},2*s.p);
|
||||
s.tl.add(fluidA,{height:[level+25,level+25],y:[176-level,176-level],duration:s.p*.35},2.65*s.p);
|
||||
s.tl.add(oilA,{y:[156-level,156-level],duration:s.p*.35},2.65*s.p);
|
||||
s.tl.add(fluidA,{height:[level+25,12],y:[176-level,189],duration:s.p*.7},3*s.p);
|
||||
s.tl.add(oilA,{y:[156-level,169],duration:s.p*.7},3*s.p);
|
||||
rect(428,371-level,67,level,'#4386a1','none',3);rect(428,351-level,67,20,'#d3ac62','none',3);
|
||||
const arm=path('M207 173 H225',c.amber,4);arm.style.transformBox='fill-box';arm.style.transformOrigin='center';
|
||||
s.tl.add(arm,{rotate:[0,90],duration:s.p*.4},3*s.p);
|
||||
const bead=circle(45,212,6,c.ink);s.move(bead,45,212,175,212,0);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
window.industryRenderers['oil-gas-pipeline-reroute'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Pipeline leak: isolate and bypass","Two boundary valves contain the suspect segment before bypass flow resumes.",["Normal flow", "Leak alarm", "Close bounds", "Open bypass", "Supply restored"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,valve,c}=s;
|
||||
rect(38,181,100,115,'#172b40',c.blue,35);text(48,319,'Pump station',16);circle(88,235,28,'#263f58');path('M74 220 L104 235 L74 250 Z',c.blue,3);
|
||||
rect(815,176,108,118,'#172b40',c.blue,5);path('M815 176 L869 142 L923 176',c.blue,3);text(821,318,'Delivery',18);
|
||||
const by=Math.max(345,Math.min(380,Number(config.bypassY)||365));
|
||||
path('M138 235 H815',c.line,14);path(`M255 235 V${by} H700 V235`,c.line,12);
|
||||
text(355,199,'Monitored main segment',18);text(393,397,'Bypass corridor',18,c.green);
|
||||
const originalFlow=flow('M138 235 H815',0,c.blue);s.tl.add(originalFlow,{opacity:[1,.12],duration:s.p*.5},2*s.p);
|
||||
path('M436 224 L447 246 L457 223 L466 246',c.red,3);show(circle(452,268,9,c.red),1);
|
||||
text(379,297,'Suspected loss',18,c.red);valve(300,235,2);valve(650,235,2);
|
||||
text(263,155,'Boundary A',16,c.muted);text(611,155,'Boundary B',16,c.muted);
|
||||
show(circle(255,by,9,c.green),3);show(circle(700,by,9,c.green),3);
|
||||
flow(`M138 235 H255 V${by} H700 V235 H815`,4,c.green);
|
||||
note(35,101,206,'Detect ≠ locate','Alarm triggers review',c.amber,1);
|
||||
text(35,437,'Red crosses: closed boundaries · Green: alternate delivery path',16,c.muted);
|
||||
|
||||
// One finite packet follows each permitted route; the closed main dims.
|
||||
const depth=Math.max(345,Math.min(380,Number(config.bypassY)||365));
|
||||
const main=path('M138 235 H815',c.blue,3);
|
||||
s.tl.add(main,{opacity:[1,.12],duration:s.p*.5},2*s.p);
|
||||
const route=s.E('path',{d:`M138 235 H255 V${depth} H700 V235 H815`,fill:'none',stroke:c.green,'stroke-width':2});
|
||||
s.show(route,3);
|
||||
const first=circle(0,0,7,c.ink);
|
||||
s.tl.add(first,{...kit.anime.svg.createMotionPath(main),duration:s.p*.8},0);
|
||||
s.tl.add(first,{opacity:[1,0],duration:s.p*.1},s.p);
|
||||
const second=circle(0,0,7,c.ink);second.setAttribute('opacity','0');
|
||||
s.tl.add(second,{opacity:[0,1],duration:1},4*s.p);
|
||||
s.tl.add(second,{...kit.anime.svg.createMotionPath(route),duration:s.p*.85},4*s.p);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,81 @@
|
||||
/* Original conceptual industry scenes; Anime.js v4. */
|
||||
(function(){
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases) {
|
||||
const {el,anime}=kit, p=Number.isFinite(Number(config.phaseMs)) && Number(config.phaseMs)>0 ? Number(config.phaseMs) : 1200;
|
||||
const c={ink:'#e5edf7',muted:'#93a8bf',blue:'#63baff',green:'#6ce1b4',amber:'#ffc56b',red:'#ff8091',bg:'#101e30',line:'#314961'};
|
||||
const E=(tag,a={},t='',parent=svg)=>el(tag,a,t,parent);
|
||||
const text=(x,y,t,size=18,color=c.ink)=>E('text',{x,y,fill:color,'font-size':size,'font-family':'system-ui'},t);
|
||||
const path=(d,color=c.line,w=5)=>E('path',{d,fill:'none',stroke:color,'stroke-width':w,'stroke-linecap':'round','stroke-linejoin':'round'});
|
||||
const rect=(x,y,w,h,color=c.bg,stroke=c.line,rx=8)=>E('rect',{x,y,width:w,height:h,rx,fill:color,stroke,'stroke-width':2});
|
||||
const circle=(x,y,r,color=c.blue)=>E('circle',{cx:x,cy:y,r,fill:color});
|
||||
E('rect',{width:960,height:540,fill:'#091321'});
|
||||
text(32,38,title,26);text(32,67,subtitle,16,c.muted);
|
||||
path('M32 88 H928',c.line,1);
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const anchor=E('g');tl.add(anchor,{opacity:[1,1],duration:p*5},0);
|
||||
function show(node,step){node.setAttribute('opacity','.15');tl.add(node,{opacity:[.15,1],duration:p*.65},step*p);return node;}
|
||||
function flow(d,step,color=c.green){const n=path(d,color,5);const len=n.getTotalLength();n.setAttribute('stroke-dasharray',len);n.setAttribute('stroke-dashoffset',len);tl.add(n,{'stroke-dashoffset':[len,0],duration:p*.75},step*p);return n;}
|
||||
function move(n,x0,y0,x1,y1,step){tl.add(n,{cx:[x0,x1],cy:[y0,y1],duration:p*.75},step*p);}
|
||||
function note(x,y,w,heading,detail,color=c.green,step=0){rect(x,y,w,58);show(rect(x,y,5,58,color,color,0),step);text(x+16,y+24,heading,18,color);text(x+16,y+46,detail,16,c.muted);}
|
||||
function valve(x,y,step){const n=path(`M${x-10} ${y-10} L${x+10} ${y+10} M${x+10} ${y-10} L${x-10} ${y+10}`,c.red,4);show(n,step);}
|
||||
phases.forEach((s,i)=>{const x=32+i*182;rect(x,465,174,42,'#132338');show(rect(x,465,4,42,c.blue,c.blue,0),i);text(x+12,491,`${i+1} ${s}`,16);});
|
||||
text(32,529,'Conceptual sequence · illustrative timing · not an operating procedure',16,c.muted);
|
||||
return {E,text,path,rect,circle,tl,show,flow,move,note,valve,c,p};
|
||||
}
|
||||
window.industryRenderers['pharma-batch-genealogy'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Batch genealogy: hold, then release","A quality hold propagates to descendants; disposition restores only the accepted branch.",["Trace inputs", "Blend batch", "Hold lineage", "Review evidence", "Release branch"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,c}=s;
|
||||
function drum(x,y,label){rect(x,y,94,72,'#18314a',c.blue,12);path(`M${x} ${y+16} H${x+94} M${x} ${y+56} H${x+94}`,c.line,2);text(x+10,y+42,label,18);}
|
||||
drum(40,123,'Lot A');drum(40,256,'Lot B');
|
||||
path('M134 159 H220 V215 H290 M134 292 H220 V215');
|
||||
rect(290,151,150,140,'#1b3044',c.blue,35);path('M365 125 V247 M335 234 L395 256 M335 256 L395 234',c.blue,4);text(309,324,'Blend batch',18);
|
||||
flow('M134 159 H220 V215 H290',0,c.blue);flow('M134 292 H220 V215 H290',0,c.blue);
|
||||
path('M440 215 H510 V155 H577 M510 215 V300 H577');flow('M440 215 H510 V155 H577 M510 215 V300 H577',1,c.blue);
|
||||
function pack(y,label){rect(577,y,100,72,'#18314a',c.blue);path(`M602 ${y} V${y+72}`,c.line,2);text(614,y+42,label,18);}
|
||||
pack(119,'P1');pack(264,'P2');
|
||||
show(rect(555,103,145,105,'none',c.amber),2);show(rect(555,249,145,105,'none',c.amber),2);
|
||||
text(704,131,'P1 · evidence accepted',16,c.green);text(717,288,'P2 · hold retained',16,c.amber);
|
||||
flow('M677 155 H885',4,c.green);show(circle(889,155,8,c.green),4);
|
||||
note(274,366,350,'Disposition follows evidence','Not every descendant is released',c.green,4);
|
||||
note(39,366,218,'Quality review','Trace the affected lots',c.amber,3);
|
||||
|
||||
const count=Math.max(2,Math.min(5,Math.round(Number(config.packCount)||3)));
|
||||
const packs=[];
|
||||
for(let i=0;i<count;i++){const n=rect(727+i*31,185,19,33,'#254a50',c.green,3);packs.push(n);}
|
||||
s.tl.add(packs,{y:[165,185],opacity:[.15,1],delay:kit.anime.stagger(s.p*.075),duration:s.p*.5},4*s.p);
|
||||
const sample=circle(365,215,7,c.ink);s.move(sample,365,215,531,215,1);
|
||||
const paddle=path('M348 267 H382',c.blue,4);paddle.style.transformBox='fill-box';paddle.style.transformOrigin='center';s.tl.add(paddle,{rotate:[0,180],duration:s.p*.8},s.p);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
window.industryRenderers['pharma-cold-chain-quarantine'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Cold chain: excursion to quarantine","A recorded excursion changes custody status, not the historical temperature trace.",["Pack & record", "Transport", "Excursion", "Quarantine", "Disposition"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,c}=s;
|
||||
rect(38,128,160,130,'#18314a',c.blue);path('M55 145 H181 V240 H55 Z M118 145 V240',c.blue,2);text(56,284,'Origin storage',18);
|
||||
rect(306,172,180,78,'#18314a',c.blue);path('M486 195 H535 L559 223 V250 H486 Z',c.blue,3);circle(347,255,17,c.muted);circle(516,255,17,c.muted);text(340,288,'Transit logger',18);
|
||||
rect(714,127,190,131,'#18314a',c.amber);path('M714 127 L809 105 L904 127 M737 146 V241 M765 146 V241 M793 146 V241 M821 146 V241 M849 146 V241 M877 146 V241',c.line,2);text(731,284,'Quarantine bay',18,c.amber);
|
||||
flow('M198 211 H306',0,c.blue);flow('M559 211 H714',3,c.amber);
|
||||
text(39,330,'Recorded condition',18);rect(40,347,512,68,'#152f35','#264c50');text(565,419,'Illustrative acceptance band',16,c.muted);
|
||||
path('M40 426 H552 M40 343 V426',c.muted,1);
|
||||
flow('M43 382 L120 380 L194 386 L268 376',1,c.blue);
|
||||
flow('M268 376 L325 351 L369 325 L411 330 L454 375 L548 383',2,c.red);
|
||||
text(304,316,'Excursion',16,c.red);
|
||||
note(662,332,260,'Evidence → disposition','Return / release / reject',c.green,4);
|
||||
show(circle(809,192,17,c.amber),3);text(37,448,'No thresholds, stability claims or product-release rules are encoded.',16,c.muted);
|
||||
|
||||
const rise=Math.max(18,Math.min(58,Number(config.excursionRise)||48));
|
||||
rect(602,115,18,85,'#1c344b',c.muted,9);circle(611,203,15,c.red);
|
||||
const mercury=rect(607,172,8,28,c.red,c.red,3);
|
||||
s.tl.add(mercury,{height:[28,28+rise],y:[172,172-rise],duration:s.p*.7},2*s.p);
|
||||
const payload=rect(139,202,34,28,'#37556a',c.blue,2);
|
||||
s.tl.add(payload,{x:[139,409],y:[202,207],duration:s.p*.75},s.p);
|
||||
s.tl.add(payload,{x:[409,409],y:[207,207],duration:s.p*1.25},s.p*1.75);
|
||||
s.tl.add(payload,{x:[409,758],y:[207,212],duration:s.p*.75},3*s.p);
|
||||
const latch=path('M787 167 H831',c.amber,5);latch.style.transformBox='fill-box';latch.style.transformOrigin='center';s.tl.add(latch,{rotate:[90,0],duration:s.p*.5},3*s.p);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,72 @@
|
||||
/* Original conceptual industry scenes; Anime.js v4. */
|
||||
(function(){
|
||||
window.industryRenderers ??= {};
|
||||
function scene(svg, config, kit, title, subtitle, phases) {
|
||||
const {el,anime}=kit, p=Number.isFinite(Number(config.phaseMs)) && Number(config.phaseMs)>0 ? Number(config.phaseMs) : 1200;
|
||||
const c={ink:'#e5edf7',muted:'#93a8bf',blue:'#63baff',green:'#6ce1b4',amber:'#ffc56b',red:'#ff8091',bg:'#101e30',line:'#314961'};
|
||||
const E=(tag,a={},t='',parent=svg)=>el(tag,a,t,parent);
|
||||
const text=(x,y,t,size=18,color=c.ink)=>E('text',{x,y,fill:color,'font-size':size,'font-family':'system-ui'},t);
|
||||
const path=(d,color=c.line,w=5)=>E('path',{d,fill:'none',stroke:color,'stroke-width':w,'stroke-linecap':'round','stroke-linejoin':'round'});
|
||||
const rect=(x,y,w,h,color=c.bg,stroke=c.line,rx=8)=>E('rect',{x,y,width:w,height:h,rx,fill:color,stroke,'stroke-width':2});
|
||||
const circle=(x,y,r,color=c.blue)=>E('circle',{cx:x,cy:y,r,fill:color});
|
||||
E('rect',{width:960,height:540,fill:'#091321'});
|
||||
text(32,38,title,26);text(32,67,subtitle,16,c.muted);
|
||||
path('M32 88 H928',c.line,1);
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const anchor=E('g');tl.add(anchor,{opacity:[1,1],duration:p*5},0);
|
||||
function show(node,step){node.setAttribute('opacity','.15');tl.add(node,{opacity:[.15,1],duration:p*.65},step*p);return node;}
|
||||
function flow(d,step,color=c.green){const n=path(d,color,5);const len=n.getTotalLength();n.setAttribute('stroke-dasharray',len);n.setAttribute('stroke-dashoffset',len);tl.add(n,{'stroke-dashoffset':[len,0],duration:p*.75},step*p);return n;}
|
||||
function move(n,x0,y0,x1,y1,step){tl.add(n,{cx:[x0,x1],cy:[y0,y1],duration:p*.75},step*p);}
|
||||
function note(x,y,w,heading,detail,color=c.green,step=0){rect(x,y,w,58);show(rect(x,y,5,58,color,color,0),step);text(x+16,y+24,heading,18,color);text(x+16,y+46,detail,16,c.muted);}
|
||||
function valve(x,y,step){const n=path(`M${x-10} ${y-10} L${x+10} ${y+10} M${x+10} ${y-10} L${x-10} ${y+10}`,c.red,4);show(n,step);}
|
||||
phases.forEach((s,i)=>{const x=32+i*182;rect(x,465,174,42,'#132338');show(rect(x,465,4,42,c.blue,c.blue,0),i);text(x+12,491,`${i+1} ${s}`,16);});
|
||||
text(32,529,'Conceptual sequence · illustrative timing · not an operating procedure',16,c.muted);
|
||||
return {E,text,path,rect,circle,tl,show,flow,move,note,valve,c,p};
|
||||
}
|
||||
window.industryRenderers['retail-inventory-reservation'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Omnichannel: reserve before promising","Two demand channels compete for one pickable unit; the second order gets an honest alternative.",["Count stock", "Web reserves", "Store competes", "Offer alternate", "Fulfil promise"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,c}=s;
|
||||
rect(40,131,148,97,'#18314a',c.blue);rect(51,143,126,66,'#0d2033',c.line);path('M114 228 V246 M83 246 H145',c.blue,3);text(51,276,'Web order A',18);
|
||||
path('M42 355 H188 V417 H42 Z M35 355 L55 320 H175 L195 355',c.blue,3);[55,85,115,145,175].forEach(x=>path(`M${x} 327 V353`,c.amber,8));text(48,445,'Store order B',18);
|
||||
rect(348,127,226,215,'#112539',c.blue,2);path('M348 199 H574 M348 271 H574 M423 127 V342 M499 127 V342',c.line,3);
|
||||
rect(437,217,47,39,'none',c.line,1);text(365,368,'One pickable unit',18);show(rect(431,211,59,51,'none',c.green,2),0);
|
||||
flow('M188 181 H289 V236 H431',1,c.green);text(208,161,'A reserves',16,c.green);
|
||||
flow('M188 381 H289 V287 H336',2,c.amber);path('M322 277 L338 293 M338 277 L322 293',c.amber,3);text(199,414,'B cannot double-sell',16,c.amber);
|
||||
rect(743,143,152,104,'#18314a',c.blue,3);path('M743 143 L819 112 L895 143 M819 143 V247',c.blue,2);text(750,277,'Pick & dispatch A',17);
|
||||
flow('M484 236 H650 V195 H743',4,c.green);
|
||||
note(646,331,276,'B: alternate location','Or explicit wait / cancel',c.amber,3);
|
||||
|
||||
const size=Math.max(22,Math.min(44,Number(config.parcelSize)||34));
|
||||
const parcel=rect(444,222,size,size,'#294f66',c.green,2);
|
||||
s.tl.add(parcel,{x:[444,827],y:[222,184],duration:s.p*.8},4*s.p);
|
||||
const reserved=path('M443 219 V209 Q461 188 479 209 V219',c.green,3);s.show(reserved,1);
|
||||
s.tl.add(reserved,{opacity:[1,1],duration:s.p*2.35},s.p*1.65);
|
||||
s.tl.add(reserved,{opacity:[1,.15],duration:s.p*.5},4*s.p);
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
window.industryRenderers['retail-return-disposition'] = function(svg,config,kit){
|
||||
const s=scene(svg,config,kit,"Returns: inspect before restocking","Refund and inventory disposition are separate branches; damaged goods stay out of sellable stock.",["Receive return", "Inspect condition", "Route disposition", "Refund record", "Restock accepted"]);
|
||||
|
||||
const {text,path,rect,circle,show,flow,note,c}=s;
|
||||
path('M43 179 L108 154 L173 179 V251 L108 278 L43 251 Z M43 179 L108 206 L173 179 M108 206 V278',c.blue,3);text(44,311,'Returned parcel',18);
|
||||
rect(293,194,164,15,'#29475f',c.blue,1);path('M307 209 V280 M442 209 V280',c.blue,5);circle(369,151,29,'none');path('M389 172 L413 197',c.amber,7);text(294,313,'Inspect & classify',18);
|
||||
flow('M173 220 H293',0,c.blue);show(circle(369,151,22,c.amber),1);
|
||||
path('M457 202 H533 V142 H643 M533 202 V278 H643');
|
||||
rect(643,109,246,71,'#18314a',c.green,2);path('M658 144 H873 M725 110 V179 M805 110 V179',c.line,2);text(652,98,'Sellable shelf',18,c.green);
|
||||
flow('M457 202 H533 V142 H643',2,c.green);show(rect(748,118,34,25,c.green,c.green,1),4);
|
||||
rect(645,246,239,65,'#302633',c.red);path('M651 246 L877 311 M877 246 L651 311',c.red,1);text(663,340,'Damage / quarantine',18,c.red);flow('M533 202 V278 H643',2,c.red);
|
||||
path('M478 281 V374 H579',c.line,3);flow('M478 281 V374 H579',3,c.blue);
|
||||
rect(580,351,305,65,'#18314a',c.blue);text(599,378,'Refund record',18,c.blue);text(599,401,'Financial state ≠ stock state',16,c.muted);
|
||||
text(39,437,'Condition drives disposition · policy determines refund eligibility',16,c.muted);
|
||||
|
||||
const units=Math.max(1,Math.min(3,Math.round(Number(config.restockUnits)||2)));
|
||||
const flap=path('M43 179 L108 154 L173 179',c.amber,4);
|
||||
const opened=s.E('path',{d:'M43 179 L88 128 L153 153',visibility:'hidden'});
|
||||
s.tl.add(flap,{d:kit.anime.svg.morphTo(opened),duration:s.p*.65},s.p);
|
||||
for(let i=0;i<units;i++){const unit=rect(327+i*30,166,23,25,'#2d5a5a',c.green,2);s.tl.add(unit,{x:[327+i*30,735+i*34],y:[166,148],duration:s.p*.75},4*s.p);}
|
||||
|
||||
s.tl.seek(s.tl.duration);s.tl.seek(0);return s.tl;
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,81 @@
|
||||
/* Original conceptual teaching scenes. No operational or engineering model. */
|
||||
(function () {
|
||||
'use strict';
|
||||
window.industryRenderers ??= {};
|
||||
const C={bg:'#101d30',panel:'#182b42',line:'#667c95',ink:'#edf5ff',muted:'#aec1d7',cyan:'#57d4ed',green:'#85e0ad',amber:'#ffd178',red:'#ff8c8c'};
|
||||
function scene(svg,config,kit,title,subtitle,phases,note){
|
||||
const {anime,el}=kit, duration=Math.max(3000,Number(config.duration)||6000), unit=duration/6;
|
||||
const tl=anime.createTimeline({autoplay:false,defaults:{ease:'linear'}});
|
||||
const E=(tag,a={},text='',p=svg)=>el(tag,a,text,p);
|
||||
const rect=(x,y,w,h,fill=C.panel,p=svg,extra={})=>E('rect',{x,y,width:w,height:h,rx:8,fill,...extra},'',p);
|
||||
const text=(x,y,t,size=18,fill=C.ink,p=svg,extra={})=>E('text',{x,y,fill,'font-size':size,'font-family':'system-ui, sans-serif',style:`fill:${fill};font-size:${size}px;font-family:system-ui,sans-serif`,...extra},t,p);
|
||||
const path=(d,color=C.line,width=3,p=svg,extra={})=>E('path',{d,fill:'none',stroke:color,'stroke-width':width,'stroke-linecap':'round','stroke-linejoin':'round',...extra},'',p);
|
||||
const circle=(cx,cy,r,fill=C.cyan,p=svg,extra={})=>E('circle',{cx,cy,r,fill,...extra},'',p);
|
||||
const group=()=>E('g');
|
||||
const add=(target,props,at=0,len=.75)=>tl.add(target,{...props,duration:unit*len},unit*at);
|
||||
const reveal=(target,at)=>{target.setAttribute('opacity','0.12');add(target,{opacity:[.12,1]},at);return target;};
|
||||
const draw=(d,at,color=C.cyan,width=4)=>{const p=path(d,color,width);p.setAttribute('pathLength','1');p.setAttribute('stroke-dasharray','1');p.setAttribute('stroke-dashoffset','1');add(p,{'stroke-dashoffset':[1,0]},at);return p;};
|
||||
rect(0,0,960,540,C.bg,svg,{rx:0}); text(32,39,title,26);text(32,69,subtitle,17,C.muted);
|
||||
path('M32 88 H928',C.line,1);
|
||||
phases.forEach((label,i)=>{const x=32+i*181;rect(x,440,172,44);const bar=rect(x,440,172,4,C.cyan,svg,{rx:0});add(bar,{opacity:[.15,1]},i,.65);text(x+10,469,`${i+1} ${label}`,16);});
|
||||
text(32,516,note,16,C.muted);
|
||||
const clock=E('g',{'data-clock':'finite'});add(clock,{opacity:[1,1]},0,6);
|
||||
return {svg,config,tl,E,rect,text,path,circle,group,add,reveal,draw,C};
|
||||
}
|
||||
window.industryRenderers["telecom-congestion-reroute"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'NETWORK / ROUTE AROUND A QUEUE','The destination stays fixed while forwarding shifts to an alternate transit path.',
|
||||
['Forward','Queue','Detect','Reroute','Deliver'],'Conceptual topology • amber = congested segment • cyan = initial route • green = alternate');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
const router=(x,y,name)=>{circle(x,y,29,'#25435e',svg,{stroke:C.line,'stroke-width':2});path(`M${x-15} ${y} H${x+15} M${x} ${y-15} V${y+15} M${x+9} ${y-5} L${x+15} ${y} L${x+9} ${y+5} M${x-5} ${y-9} L${x} ${y-15} L${x+5} ${y-9}`,C.muted,2);text(x-29,y+54,name,16);};
|
||||
// Client, a routed diamond and a destination rack.
|
||||
rect(39,217,100,68,'#2b465f');rect(48,226,82,46,'#122237');path('M89 286 V302 M65 303 H114',C.muted,4);text(39,328,'Source',17);
|
||||
path('M140 251 H240 M270 222 L440 151 M499 151 L672 222 M270 280 L440 351 M499 351 L672 280 M701 251 H806',C.line,3);
|
||||
router(240,251,'Edge A');router(470,141,'Transit B');router(470,361,'Transit C');router(701,251,'Edge D');
|
||||
rect(814,191,104,134,'#283e53');[205,241,277].forEach(y=>{rect(825,y,82,27,'#101e30');circle(895,y+13,4,C.green);});text(812,355,'Destination',17);
|
||||
const originalRoute=draw('M140 251 H210 M264 235 L443 153 M498 153 L674 235',0);add(originalRoute,{opacity:[1,.2]},3,1);
|
||||
const p=circle(156,251,7,C.cyan);add(p,{cx:[156,232]},0,.7);
|
||||
// Queue slots explicitly expose finite waiting capacity (no implied rates).
|
||||
const queued=Math.min(4,Math.max(1,Math.round(Number(config.queuePackets)||4)));
|
||||
text(547,115,'Transit queue',17);[0,1,2,3].forEach(i=>{rect(552+i*28,133,22,20,'#263a4e');if(i<queued){const q=rect(554+i*28,135,18,16,C.amber);reveal(q,1+i*.15);}});
|
||||
const hot=path('M502 158 L669 231',C.amber,8);reveal(hot,1.7);
|
||||
const alert=group();path('M734 124 L754 160 H714 Z',C.amber,3,alert);text(730,151,'!',18,C.amber,alert);text(765,151,'Queue pressure',16,C.amber,alert);reveal(alert,2);
|
||||
// Reroute physically draws through the lower transit rather than recoloring boxes.
|
||||
draw('M264 269 L443 348 M497 348 L675 269',3,C.green,6);
|
||||
const alternate=circle(278,278,8,C.green);add(alternate,{cx:[278,442],cy:[278,348]},3,.6);add(alternate,{cx:[442,672],cy:[348,269]},3.6,.7);add(alternate,{cx:[672,807],cy:[269,251]},4.3,.6);
|
||||
text(338,306,'Alternate transit selected',16,C.green);
|
||||
draw('M730 251 H808',4,C.green,5);
|
||||
const receipt=group();rect(48,371,260,44,'#264738',receipt);text(62,399,'Delivered to the same endpoint',16,C.green,receipt);reveal(receipt,4.4);
|
||||
text(604,405,'Route choice ≠ capacity guarantee',16,C.muted);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
window.industryRenderers["telecom-cell-handover"] = function(svg, config, kit) {
|
||||
|
||||
const s=scene(svg,config,kit,'MOBILITY / CHANGE ACCESS, KEEP SESSION','Radio attachment changes; the session anchor remains the stable reference.',
|
||||
['Serve A','Measure','Prepare B','Switch','Release A'],'Conceptual handover • cyan = serving cell • amber = preparation • green = target link');
|
||||
const {rect,text,path,circle,group,add,reveal,draw,C}=s;
|
||||
// Two overlapping coverage envelopes and original radio masts.
|
||||
ELLIPSE();
|
||||
function ELLIPSE(){s.E('ellipse',{cx:285,cy:326,rx:211,ry:79,fill:'#193e55',stroke:C.cyan,'stroke-width':1});s.E('ellipse',{cx:665,cy:326,rx:211,ry:79,fill:'#203d3c',stroke:C.green,'stroke-width':1});}
|
||||
function mast(x,name,color){path(`M${x} 178 L${x-30} 316 H${x+30} Z M${x-22} 279 H${x+22} M${x-14} 242 H${x+14} M${x-22} 279 L${x+14} 242 M${x+22} 279 L${x-14} 242`,C.muted,3);circle(x,174,6,color);path(`M${x-19} 153 Q${x-38} 174 ${x-19} 195 M${x+19} 153 Q${x+38} 174 ${x+19} 195`,color,3);text(x-28,345,name,18,color);}
|
||||
mast(230,'Cell A',C.cyan);mast(730,'Cell B',C.green);
|
||||
rect(391,112,178,64,'#2b3d59');text(408,139,'Session anchor',18);text(408,163,'Identity retained',16,C.muted);
|
||||
path('M391 142 H230 V151 M569 142 H730 V151',C.line,2);
|
||||
text(45,128,'Access changes',16,C.muted);text(45,151,'Session persists',16,C.muted);
|
||||
path('M305 374 H659 M650 367 L659 374 L650 381',C.line,3);text(374,404,'Direction of travel',16,C.muted);
|
||||
// Handset moves as one local group; radio lines independently interpolate endpoints.
|
||||
const phone=group();rect(316,289,36,64,'#e5effb',phone);rect(321,298,26,40,'#173149',phone);circle(334,346,3,'#173149',phone);
|
||||
const travel=Math.min(320,Math.max(220,Number(config.travelPx)||286)),end=334+travel;
|
||||
add(phone,{translateX:[0,travel]},.2,4.4);
|
||||
const a=path('M230 182 L334 290',C.cyan,3);add(a,{d:['M230 182 L334 290',`M230 182 L${end} 290`]},.2,4.4);add(a,{opacity:[1,.16]},3.4,.8);
|
||||
const b=path('M730 182 L334 290',C.green,4);b.setAttribute('opacity','.08');add(b,{d:['M730 182 L334 290',`M730 182 L${end} 290`]},.2,4.4);add(b,{opacity:[.08,1]},2.5,1);
|
||||
const measure=group();rect(380,203,196,53,'#3c3c32',measure);text(392,225,'Neighbor measured',16,C.amber,measure);text(392,246,'Target prepared',16,C.amber,measure);reveal(measure,1.4);
|
||||
draw('M568 174 L695 211',2,C.amber,3);
|
||||
const context=group();circle(615,151,10,C.amber,context);reveal(context,2.1);add(context,{translateX:[0,90]},2.1,.65);
|
||||
const switchNote=group();rect(746,366,176,49,'#264738',switchNote);text(757,388,'B serving',17,C.green,switchNote);text(757,407,'A resources freed',16,C.ink,switchNote);reveal(switchNote,4);
|
||||
text(54,405,'Overlap enables preparation',16,C.muted);
|
||||
return s.tl;
|
||||
|
||||
};
|
||||
})();
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Infrastructure — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="infrastructure"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Infrastructure</span></nav><h1>Infrastructure</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Logistics — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="logistics"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Logistics</span></nav><h1>Logistics</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Manufacturing — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="manufacturing"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Manufacturing</span></nav><h1>Manufacturing</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Oil & gas — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="oil-gas"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Oil & gas</span></nav><h1>Oil & gas</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Pharma — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="pharma"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Pharma</span></nav><h1>Pharma</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Retail — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="retail"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Retail</span></nav><h1>Retail</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<!-- Generated from catalog metadata by scripts/build-gallery.py. -->
|
||||
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Telecommunications — Motion that explains</title><link rel="stylesheet" href="../gallery.css"></head>
|
||||
<body data-gallery="telecom"><header><nav aria-label="Breadcrumb"><a href="../index.html">All examples</a> / <span aria-current="page">Telecommunications</span></nav><h1>Telecommunications</h1><p>Open an example for use/avoid guidance, assumptions and named timeline beats.</p></header><main aria-label="Animation examples"></main><footer><p>Original conceptual examples · Anime.js 4.5.0 · Offline library 0.6.0. Not operational, clinical or engineering advice.</p><details><summary>Anime.js license</summary><pre>The MIT License
|
||||
|
||||
Copyright (c) 2025 Julian Garnier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
</pre></details></footer>
|
||||
<script src="../catalog-data.js"></script><script src="../gallery.js"></script></body></html>
|
||||
+1206
File diff suppressed because it is too large.
Load diff
+1206
File diff suppressed because it is too large.
Load diff
+1206
File diff suppressed because it is too large.
Load diff
+1206
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1296
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1213
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
Loaded 100 of 144 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user