Organize the lighting project and ship the combined XCHC show.
Group workspaces, generators, stage map, and tests into clear folders, and add the unified cans+movers show plus a simple shared/individual RGBW control board. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,279 @@
|
||||
import {
|
||||
Card,
|
||||
CardBody,
|
||||
CardHeader,
|
||||
H1,
|
||||
H2,
|
||||
Stack,
|
||||
Table,
|
||||
Text,
|
||||
useHostTheme,
|
||||
} from "cursor/canvas";
|
||||
|
||||
/** Y=0 = row of 4; +Y toward audience. Side cans on walls at ±3.5 m. */
|
||||
const WALL = 3.5;
|
||||
const FIXTURES: {
|
||||
key: string;
|
||||
label: string;
|
||||
kind: "can" | "mover";
|
||||
x: number;
|
||||
y: number;
|
||||
}[] = [
|
||||
{ key: "c3", label: "#3", kind: "can", x: -1.8, y: 0.0 },
|
||||
{ key: "c4", label: "#4", kind: "can", x: -0.6, y: 0.0 },
|
||||
{ key: "c5", label: "#5", kind: "can", x: 0.6, y: 0.0 },
|
||||
{ key: "c6", label: "#6", kind: "can", x: 1.8, y: 0.0 },
|
||||
{ key: "c2", label: "#2", kind: "can", x: -WALL, y: 1.2 },
|
||||
{ key: "c7", label: "#7", kind: "can", x: WALL, y: 1.2 },
|
||||
{ key: "m1", label: "M1", kind: "mover", x: -0.3, y: 1.1 },
|
||||
{ key: "m2", label: "M2", kind: "mover", x: 0.3, y: 1.1 },
|
||||
{ key: "c1", label: "#1", kind: "can", x: -WALL, y: 2.4 },
|
||||
{ key: "c8", label: "#8", kind: "can", x: WALL, y: 2.4 },
|
||||
];
|
||||
|
||||
const BUILDING_W = 7;
|
||||
const DEPTH = 2.4;
|
||||
|
||||
export default function StageMap() {
|
||||
const theme = useHostTheme();
|
||||
|
||||
const pad = 0.55;
|
||||
const x0 = -BUILDING_W / 2 - pad;
|
||||
const x1 = BUILDING_W / 2 + pad;
|
||||
const y0 = -0.45;
|
||||
const y1 = DEPTH + 0.55;
|
||||
const vbW = x1 - x0;
|
||||
const vbH = y1 - y0;
|
||||
const px = 88;
|
||||
const svgW = vbW * px;
|
||||
const svgH = vbH * px;
|
||||
|
||||
const sx = (x: number) => ((x - x0) / vbW) * svgW;
|
||||
const sy = (y: number) => ((y1 - y) / vbH) * svgH;
|
||||
|
||||
const dim = theme.text.tertiary;
|
||||
const ink = theme.text.primary;
|
||||
const accent = theme.accent.primary;
|
||||
const canFill = theme.fill.tertiary;
|
||||
const stroke = theme.stroke.primary;
|
||||
const onAccent = theme.text.onAccent;
|
||||
|
||||
function DimH(
|
||||
xA: number,
|
||||
xB: number,
|
||||
y: number,
|
||||
label: string,
|
||||
side: "above" | "below" = "above",
|
||||
) {
|
||||
const ya = sy(y);
|
||||
const x1p = sx(Math.min(xA, xB));
|
||||
const x2p = sx(Math.max(xA, xB));
|
||||
const mid = (x1p + x2p) / 2;
|
||||
const ty = side === "above" ? ya - 8 : ya + 14;
|
||||
return (
|
||||
<g stroke={dim} fill={dim} strokeWidth={1}>
|
||||
<line x1={x1p} y1={ya} x2={x2p} y2={ya} />
|
||||
<line x1={x1p} y1={ya - 4} x2={x1p} y2={ya + 4} />
|
||||
<line x1={x2p} y1={ya - 4} x2={x2p} y2={ya + 4} />
|
||||
<text x={mid} y={ty} textAnchor="middle" fontSize={11} fill={dim} stroke="none">
|
||||
{label}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
function DimV(
|
||||
yA: number,
|
||||
yB: number,
|
||||
x: number,
|
||||
label: string,
|
||||
side: "left" | "right" = "right",
|
||||
) {
|
||||
const xa = sx(x);
|
||||
const y1p = sy(Math.max(yA, yB));
|
||||
const y2p = sy(Math.min(yA, yB));
|
||||
const mid = (y1p + y2p) / 2;
|
||||
const tx = side === "right" ? xa + 8 : xa - 8;
|
||||
return (
|
||||
<g stroke={dim} fill={dim} strokeWidth={1}>
|
||||
<line x1={xa} y1={y1p} x2={xa} y2={y2p} />
|
||||
<line x1={xa - 4} y1={y1p} x2={xa + 4} y2={y1p} />
|
||||
<line x1={xa - 4} y1={y2p} x2={xa + 4} y2={y2p} />
|
||||
<text
|
||||
x={tx}
|
||||
y={mid + 4}
|
||||
textAnchor={side === "right" ? "start" : "end"}
|
||||
fontSize={11}
|
||||
fill={dim}
|
||||
stroke="none"
|
||||
>
|
||||
{label}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Stack gap={20} style={{ padding: 20, maxWidth: 960 }}>
|
||||
<Stack gap={6}>
|
||||
<H1>Stage map</H1>
|
||||
<Text tone="secondary">
|
||||
Building {BUILDING_W} m wide · walls at ±{WALL} m · Y = 0 at row of 4 ·
|
||||
+Y toward audience
|
||||
</Text>
|
||||
</Stack>
|
||||
|
||||
<Card>
|
||||
<CardHeader>Plan (audience at bottom)</CardHeader>
|
||||
<CardBody>
|
||||
<svg
|
||||
width="100%"
|
||||
viewBox={`0 0 ${svgW} ${svgH}`}
|
||||
style={{ display: "block", maxWidth: svgW, background: theme.bg.editor }}
|
||||
>
|
||||
<rect
|
||||
x={sx(-BUILDING_W / 2)}
|
||||
y={sy(DEPTH)}
|
||||
width={BUILDING_W * px}
|
||||
height={DEPTH * px}
|
||||
fill="none"
|
||||
stroke={stroke}
|
||||
strokeWidth={2}
|
||||
/>
|
||||
{/* Wall labels */}
|
||||
<text
|
||||
x={sx(-WALL) + 4}
|
||||
y={sy(1.8)}
|
||||
fontSize={10}
|
||||
fill={dim}
|
||||
stroke="none"
|
||||
transform={`rotate(-90 ${sx(-WALL) + 4} ${sy(1.8)})`}
|
||||
>
|
||||
3.5 m from centre
|
||||
</text>
|
||||
<text
|
||||
x={sx(WALL) - 4}
|
||||
y={sy(1.8)}
|
||||
fontSize={10}
|
||||
fill={dim}
|
||||
stroke="none"
|
||||
textAnchor="end"
|
||||
transform={`rotate(90 ${sx(WALL) - 4} ${sy(1.8)})`}
|
||||
>
|
||||
3.5 m from centre
|
||||
</text>
|
||||
{DimH(0, -WALL, 1.8, "3.5 m", "above")}
|
||||
{DimH(0, WALL, 1.8, "3.5 m", "below")}
|
||||
<line
|
||||
x1={sx(0)}
|
||||
y1={sy(-0.15)}
|
||||
x2={sx(0)}
|
||||
y2={sy(DEPTH + 0.2)}
|
||||
stroke={dim}
|
||||
strokeWidth={1}
|
||||
strokeDasharray="3 5"
|
||||
/>
|
||||
<text x={sx(0) + 6} y={sy(-0.05)} fontSize={10} fill={dim} stroke="none">
|
||||
centre
|
||||
</text>
|
||||
<text
|
||||
x={sx(0)}
|
||||
y={sy(DEPTH + 0.38)}
|
||||
textAnchor="middle"
|
||||
fontSize={12}
|
||||
fill={ink}
|
||||
fontWeight={600}
|
||||
stroke="none"
|
||||
>
|
||||
AUDIENCE
|
||||
</text>
|
||||
<text
|
||||
x={sx(0)}
|
||||
y={sy(-0.28)}
|
||||
textAnchor="middle"
|
||||
fontSize={11}
|
||||
fill={dim}
|
||||
stroke="none"
|
||||
>
|
||||
row of 4
|
||||
</text>
|
||||
|
||||
{DimH(-3.5, 3.5, DEPTH + 0.32, "7.0 m building", "below")}
|
||||
{DimH(0, 0.6, 0, "0.6", "above")}
|
||||
{DimH(0, 1.8, 0, "1.8", "above")}
|
||||
{DimH(0, -0.6, 0, "0.6", "below")}
|
||||
{DimH(0, -1.8, 0, "1.8", "below")}
|
||||
{DimH(0, 0.3, 1.1, "0.3", "above")}
|
||||
{DimV(0, 1.1, 2.4, "1.1 m movers")}
|
||||
{DimV(0, 1.2, 2.4, "1.2 m")}
|
||||
{DimV(0, 2.4, -2.4, "2.4 m", "left")}
|
||||
|
||||
{FIXTURES.map((f) => {
|
||||
const cx = sx(f.x);
|
||||
const cy = sy(f.y);
|
||||
const r = f.kind === "mover" ? 14 : 12;
|
||||
return (
|
||||
<g key={f.key}>
|
||||
{f.kind === "mover" ? (
|
||||
<rect
|
||||
x={cx - r}
|
||||
y={cy - r}
|
||||
width={r * 2}
|
||||
height={r * 2}
|
||||
rx={3}
|
||||
fill={accent}
|
||||
stroke={stroke}
|
||||
strokeWidth={1}
|
||||
/>
|
||||
) : (
|
||||
<circle
|
||||
cx={cx}
|
||||
cy={cy}
|
||||
r={r}
|
||||
fill={canFill}
|
||||
stroke={stroke}
|
||||
strokeWidth={1.5}
|
||||
/>
|
||||
)}
|
||||
<text
|
||||
x={cx}
|
||||
y={cy + 4}
|
||||
textAnchor="middle"
|
||||
fontSize={11}
|
||||
fontWeight={600}
|
||||
fill={f.kind === "mover" ? onAccent : ink}
|
||||
stroke="none"
|
||||
>
|
||||
{f.label}
|
||||
</text>
|
||||
</g>
|
||||
);
|
||||
})}
|
||||
</svg>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
<Stack gap={12}>
|
||||
<H2>Coordinates</H2>
|
||||
<Table
|
||||
headers={["Fixture", "Type", "X (m)", "Y (m)", "Notes"]}
|
||||
rows={[
|
||||
["#3", "Can", "−1.8", "0.0", "Row of 4"],
|
||||
["#4", "Can", "−0.6", "0.0", "Row of 4"],
|
||||
["#5", "Can", "+0.6", "0.0", "Row of 4"],
|
||||
["#6", "Can", "+1.8", "0.0", "Row of 4"],
|
||||
["#2", "Can", "−3.5", "1.2", "Side · 3.5 m from centre · 1.2 m in front of the 4"],
|
||||
["#7", "Can", "+3.5", "1.2", "Side · 3.5 m from centre · 1.2 m in front of the 4"],
|
||||
["M1", "Mover", "−0.3", "1.1", "0.3 m off centre · 1.1 m in front of the 4"],
|
||||
["M2", "Mover", "+0.3", "1.1", "0.3 m off centre · 1.1 m in front of the 4"],
|
||||
["#1", "Can", "−3.5", "2.4", "Side · 3.5 m from centre · front left · 2.4 m in front"],
|
||||
["#8", "Can", "+3.5", "2.4", "Side · 3.5 m from centre · front right · 2.4 m in front"],
|
||||
]}
|
||||
/>
|
||||
<Text tone="secondary" size="small">
|
||||
Source: integrate_u_patterns.py LAYOUT_M
|
||||
</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"units": "metres",
|
||||
"building_width": 7.0,
|
||||
"origin": "Y=0 at row of 4; +Y toward audience; X=0 centre",
|
||||
"fixtures": {
|
||||
"#1": {
|
||||
"x": -3.5,
|
||||
"y": 2.4,
|
||||
"label": "#1",
|
||||
"kind": "can"
|
||||
},
|
||||
"#2": {
|
||||
"x": -3.5,
|
||||
"y": 1.2,
|
||||
"label": "#2",
|
||||
"kind": "can"
|
||||
},
|
||||
"#3": {
|
||||
"x": -1.8,
|
||||
"y": 0.0,
|
||||
"label": "#3",
|
||||
"kind": "can"
|
||||
},
|
||||
"#4": {
|
||||
"x": -0.6,
|
||||
"y": 0.0,
|
||||
"label": "#4",
|
||||
"kind": "can"
|
||||
},
|
||||
"#5": {
|
||||
"x": 0.6,
|
||||
"y": 0.0,
|
||||
"label": "#5",
|
||||
"kind": "can"
|
||||
},
|
||||
"#6": {
|
||||
"x": 1.8,
|
||||
"y": 0.0,
|
||||
"label": "#6",
|
||||
"kind": "can"
|
||||
},
|
||||
"#7": {
|
||||
"x": 3.5,
|
||||
"y": 1.2,
|
||||
"label": "#7",
|
||||
"kind": "can"
|
||||
},
|
||||
"#8": {
|
||||
"x": 3.5,
|
||||
"y": 2.4,
|
||||
"label": "#8",
|
||||
"kind": "can"
|
||||
},
|
||||
"M1": {
|
||||
"x": -0.3,
|
||||
"y": 1.1,
|
||||
"label": "M1",
|
||||
"kind": "mover"
|
||||
},
|
||||
"M2": {
|
||||
"x": 0.3,
|
||||
"y": 1.1,
|
||||
"label": "M2",
|
||||
"kind": "mover"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="840" height="350" viewBox="0 0 840.0 350.0">
|
||||
<title>XCHC stage map — 7 m building</title>
|
||||
<desc>Y=0 row of 4; +Y toward audience. Sides on walls ±3.5 m. Movers ±0.3 m, 1.1 m in front of row of 4.</desc>
|
||||
<rect width="100%" height="100%" fill="#1a1a1a"/>
|
||||
<rect x="70.0" y="60.0" width="700.0" height="240.0" fill="none" stroke="#888" stroke-width="2"/>
|
||||
<line x1="420.0" y1="320.0" x2="420.0" y2="35.0" stroke="#555" stroke-dasharray="4 6"/>
|
||||
<text x="426.0" y="305.0" fill="#888" font-size="12" font-family="system-ui,sans-serif">centre</text>
|
||||
<text x="420.0" y="20.0" text-anchor="middle" fill="#eee" font-size="14" font-weight="600" font-family="system-ui,sans-serif">AUDIENCE</text>
|
||||
<text x="420.0" y="332.0" text-anchor="middle" fill="#888" font-size="12" font-family="system-ui,sans-serif">row of 4</text>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="70.0" y1="25.0" x2="770.0" y2="25.0"/>
|
||||
<line x1="70.0" y1="21.0" x2="70.0" y2="29.0"/>
|
||||
<line x1="770.0" y1="21.0" x2="770.0" y2="29.0"/>
|
||||
<text x="420.0" y="39.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">7.0 m building</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="420.0" y1="300.0" x2="480.0" y2="300.0"/>
|
||||
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||
<line x1="480.0" y1="296.0" x2="480.0" y2="304.0"/>
|
||||
<text x="450.0" y="292.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.6 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="420.0" y1="300.0" x2="600.0" y2="300.0"/>
|
||||
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||
<line x1="600.0" y1="296.0" x2="600.0" y2="304.0"/>
|
||||
<text x="510.0" y="314.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.8 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="360.0" y1="300.0" x2="420.0" y2="300.0"/>
|
||||
<line x1="360.0" y1="296.0" x2="360.0" y2="304.0"/>
|
||||
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||
<text x="390.0" y="314.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.6 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="240.0" y1="300.0" x2="420.0" y2="300.0"/>
|
||||
<line x1="240.0" y1="296.0" x2="240.0" y2="304.0"/>
|
||||
<line x1="420.0" y1="296.0" x2="420.0" y2="304.0"/>
|
||||
<text x="330.0" y="292.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.8 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="420.0" y1="190.0" x2="450.0" y2="190.0"/>
|
||||
<line x1="420.0" y1="186.0" x2="420.0" y2="194.0"/>
|
||||
<line x1="450.0" y1="186.0" x2="450.0" y2="194.0"/>
|
||||
<text x="435.0" y="182.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">0.3 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="70.0" y1="120.0" x2="420.0" y2="120.0"/>
|
||||
<line x1="70.0" y1="116.0" x2="70.0" y2="124.0"/>
|
||||
<line x1="420.0" y1="116.0" x2="420.0" y2="124.0"/>
|
||||
<text x="245.0" y="112.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">3.5 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="420.0" y1="100.0" x2="770.0" y2="100.0"/>
|
||||
<line x1="420.0" y1="96.0" x2="420.0" y2="104.0"/>
|
||||
<line x1="770.0" y1="96.0" x2="770.0" y2="104.0"/>
|
||||
<text x="595.0" y="114.0" text-anchor="middle" font-size="11" stroke="none" font-family="system-ui,sans-serif">3.5 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="640.0" y1="190.0" x2="640.0" y2="300.0"/>
|
||||
<line x1="636.0" y1="190.0" x2="644.0" y2="190.0"/>
|
||||
<line x1="636.0" y1="300.0" x2="644.0" y2="300.0"/>
|
||||
<text x="648.0" y="249.0" text-anchor="start" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.1 m movers</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="640.0" y1="180.0" x2="640.0" y2="300.0"/>
|
||||
<line x1="636.0" y1="180.0" x2="644.0" y2="180.0"/>
|
||||
<line x1="636.0" y1="300.0" x2="644.0" y2="300.0"/>
|
||||
<text x="648.0" y="244.0" text-anchor="start" font-size="11" stroke="none" font-family="system-ui,sans-serif">1.2 m</text>
|
||||
</g>
|
||||
<g stroke="#888" fill="#888" stroke-width="1">
|
||||
<line x1="200.0" y1="60.0" x2="200.0" y2="300.0"/>
|
||||
<line x1="196.0" y1="60.0" x2="204.0" y2="60.0"/>
|
||||
<line x1="196.0" y1="300.0" x2="204.0" y2="300.0"/>
|
||||
<text x="192.0" y="184.0" text-anchor="end" font-size="11" stroke="none" font-family="system-ui,sans-serif">2.4 m</text>
|
||||
</g>
|
||||
<circle cx="70.0" cy="60.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="70.0" y="64.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#1</text>
|
||||
<circle cx="70.0" cy="180.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="70.0" y="184.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#2</text>
|
||||
<circle cx="240.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="240.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#3</text>
|
||||
<circle cx="360.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="360.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#4</text>
|
||||
<circle cx="480.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="480.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#5</text>
|
||||
<circle cx="600.0" cy="300.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="600.0" y="304.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#6</text>
|
||||
<circle cx="770.0" cy="180.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="770.0" y="184.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#7</text>
|
||||
<circle cx="770.0" cy="60.0" r="12" fill="#333" stroke="#ccc" stroke-width="1.5"/>
|
||||
<text x="770.0" y="64.0" text-anchor="middle" fill="#eee" font-size="11" font-weight="600" font-family="system-ui,sans-serif">#8</text>
|
||||
<rect x="376.0" y="176.0" width="28" height="28" rx="3" fill="#3b82f6" stroke="#ccc"/>
|
||||
<text x="390.0" y="194.0" text-anchor="middle" fill="#fff" font-size="11" font-weight="600" font-family="system-ui,sans-serif">M1</text>
|
||||
<rect x="436.0" y="176.0" width="28" height="28" rx="3" fill="#3b82f6" stroke="#ccc"/>
|
||||
<text x="450.0" y="194.0" text-anchor="middle" fill="#fff" font-size="11" font-weight="600" font-family="system-ui,sans-serif">M2</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.9 KiB |
Reference in New Issue
Block a user