Public Access
68 lines
3.5 KiB
React
68 lines
3.5 KiB
React
import {useId} from 'react';
|
|
|
|
import {BODY, CHECKLIST, DPAD, OUTLINE, PROGRESS_BAR} from './logoPaths.js';
|
|
|
|
/**
|
|
* The three logo colors as [CSS variable, hex as designed]; style.css sets the variables per accent.
|
|
*/
|
|
export const LOGO_COLORS = [['--logo-violet', '#7467f9'], ['--logo-blue', '#0192ef'], ['--logo-teal', '#17c7a4']];
|
|
|
|
// Each color is [themed CSS, fixed hex]. The hex also stands in where a browser cannot read color-mix, which
|
|
// would otherwise make that stop black.
|
|
const [violet, blue, teal] = LOGO_COLORS.map(([name, hex]) => [`var(${name}, ${hex})`, hex]);
|
|
const mix = ([a], [b], percentOfB, hex) => [`color-mix(in oklch, ${a}, ${b} ${percentOfB}%)`, hex];
|
|
|
|
function Gradient({id, from, to, stops}) {
|
|
return (
|
|
<linearGradient id={id} gradientUnits="userSpaceOnUse" x1={from[0]} y1={from[1]} x2={to[0]} y2={to[1]}>
|
|
{stops.map(([offset, [color, hex]]) => <stop key={offset} offset={offset} stopColor={hex} style={{stopColor: color}}/>)}
|
|
</linearGradient>
|
|
);
|
|
}
|
|
|
|
/**
|
|
* The ToBePlayed logo. Its three colors come from --logo-violet, --logo-blue and --logo-teal, which style.css sets
|
|
* per accent color.
|
|
*/
|
|
export default function Logo({className, title}) {
|
|
// Every copy on the page needs its own ids, or a hidden copy can take the gradients of a visible one with it.
|
|
const id = useId().replace(/[^a-zA-Z0-9_-]/g, '');
|
|
const ref = (name) => `${name}-${id}`;
|
|
const url = (name) => `url(#${ref(name)})`;
|
|
|
|
return (
|
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="255 225 690 445" className={className}
|
|
role={title ? 'img' : undefined} aria-label={title} aria-hidden={title ? undefined : true}>
|
|
<defs>
|
|
<clipPath id={ref('outline')}><path d={OUTLINE}/></clipPath>
|
|
<Gradient id={ref('ring')} from={[265, 660]} to={[935, 235]}
|
|
stops={[[0, violet], [0.15, violet], [0.42, blue], [0.7, teal], [1, teal]]}/>
|
|
<Gradient id={ref('list')} from={[674, 326]} to={[525, 489]}
|
|
stops={[[0, teal], [0.45, mix(blue, teal, 45, '#1dacad')], [0.7, blue], [1, mix(violet, blue, 50, '#4f6ad1')]]}/>
|
|
<Gradient id={ref('dpad')} from={[478, 336]} to={[363, 451]}
|
|
stops={[[0, blue], [1, mix(blue, violet, 20, '#2a83e4')]]}/>
|
|
<Gradient id={ref('buttons')} from={[843, 326]} to={[708, 463]}
|
|
stops={[[0, teal], [1, mix(teal, blue, 25, '#15b4ae')]]}/>
|
|
<Gradient id={ref('bar')} from={[476, 610]} to={[723, 610]}
|
|
stops={[[0, violet], [0.45, blue], [0.75, mix(blue, teal, 45, '#1dacad')], [1, teal]]}/>
|
|
</defs>
|
|
<path fill={url('ring')} d={OUTLINE}/>
|
|
<path fill="#2d3641" d={BODY}/>
|
|
<g fill="#192330" clipPath={url('outline')}>
|
|
<rect x="502" y="289" width="195" height="233"/>
|
|
<path d="M593.6 250H616.6L588 295H563Z"/>
|
|
<path d="M595.3 516H620.3L591.4 560H567.4Z"/>
|
|
</g>
|
|
<path fill={url('dpad')} d={DPAD}/>
|
|
<g fill={url('buttons')}>
|
|
<circle cx="775.5" cy="347.5" r="22"/>
|
|
<circle cx="729.5" cy="394" r="22"/>
|
|
<circle cx="821.5" cy="393.5" r="22"/>
|
|
<circle cx="775.5" cy="441" r="22"/>
|
|
</g>
|
|
<path fill={url('list')} fillRule="evenodd" d={CHECKLIST}/>
|
|
<path fill={url('bar')} fillRule="evenodd" d={PROGRESS_BAR}/>
|
|
</svg>
|
|
);
|
|
}
|