Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
3.1 kB · 153 lines
Vue
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154<script setup lang="ts">import type { Band } from '@/data/canon.generated'import { BAND_ORDER, CANVAS, gapCues, placements, rowY } from '@/data/layout'import { editorial } from '@/data/editorial/figures'
const canvasSize = { width: `${CANVAS.width}px`, height: `${CANVAS.height}px`,}
const TIER_LABELS: Record<Band, string> = { primordial: 'PRIMORDIALS', titan: 'TITANS', second_generation: 'THE SECOND GENERATION', olympian: 'OLYMPIANS', hero: 'HEROES & LEGENDS', mortal: 'MORTALS', monster: 'MONSTERS',}
const SEPARATOR_LIFT = 67const FIRST_SEPARATOR_Y = 22
const rows = BAND_ORDER.map((band, i) => { const y = rowY(band) return { band, label: TIER_LABELS[band], y, lineY: i === 0 ? FIRST_SEPARATOR_Y : y - SEPARATOR_LIFT, }})</script>
<template> <div class="map" :style="canvasSize"> <div class="labels"> <span v-for="row in rows" :key="row.band" class="band-label" :style="{ top: `${row.lineY}px` }" > {{ row.label }} </span> </div> <svg :width="CANVAS.width" :height="CANVAS.height" :viewBox="`0 0 ${CANVAS.width} ${CANVAS.height}`" > <line v-for="row in rows" :key="row.band" class="separator" x1="30" :y1="row.lineY" :x2="CANVAS.width - 30" :y2="row.lineY" /> </svg> <div v-for="p in placements" :key="p.figure" class="pill" :style="{ left: `${p.x}px`, top: `${p.y}px`, '--band': `var(--band-${p.band})` }" > <span class="dot" /> <span class="name">{{ editorial[p.figure].name }}</span> </div> <span v-for="(cue, i) in gapCues" :key="i" class="cue" :style="{ left: `${cue.x}px`, top: `${cue.y}px` }" /> </div></template>
<style scoped>.map { position: relative; flex: none; background: radial-gradient(ellipse at 40% 0%, var(--map1) 0%, var(--map2) 65%);}
.map > svg { display: block;}
.separator { stroke: var(--line); stroke-dasharray: 2 6;}
.labels { position: sticky; left: 0; width: 0; height: 0; z-index: 3;}
.band-label { position: absolute; left: 30px; transform: translateY(-50%); font-family: var(--mono); font-size: 12px; letter-spacing: 2px; color: var(--ink3); background: var(--surface); border: 1px solid var(--line); padding: 3px 9px; border-radius: 10px; white-space: nowrap;}
.pill { position: absolute; transform: translate(-50%, -50%); box-sizing: border-box; height: 34px; padding: 0 14px; display: flex; align-items: center; gap: 8px; border: 1.2px solid var(--band); border-radius: 17px; background: var(--pill); color: var(--ink); font-family: var(--mono); font-size: 12px; white-space: nowrap;}
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--band); flex: none;}
.cue { position: absolute; transform: translate(-50%, -50%); width: 3px; height: 3px; border-radius: 50%; background: var(--line2);}</style>