diff options
Diffstat (limited to 'src/components/person.tsx')
-rw-r--r-- | src/components/person.tsx | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/components/person.tsx b/src/components/person.tsx new file mode 100644 index 0000000..35aa475 --- /dev/null +++ b/src/components/person.tsx @@ -0,0 +1,105 @@ +import { Layout, Node, NodeProps, SVG, Txt } from "@motion-canvas/2d"; +import { theme } from "../theme"; +import { all, createRef, waitFor } from "@motion-canvas/core"; + +export const PEOPLE: PersonI[] = [ + { + name: "Alan Turing", + birthday: new Date("06/23/1912"), + color: theme.green.hex, + }, + { + name: "Grace Hopper", + birthday: new Date("12/09/1906"), + color: theme.flamingo.hex, + }, + { + name: "Edsger Dijkstra", + birthday: new Date("07/11/1930"), + color: theme.red.hex, + }, + { + name: "Alonzo Church", + birthday: new Date("06/14/1912"), + color: theme.sapphire.hex, + }, + { + name: "Margaret Hamilton", + birthday: new Date("12/09/1902"), + color: theme.yellow.hex, + }, +]; + +const profileSrc = (color: string) => ` +<?xml version="1.0" encoding="utf-8"?> +<svg width="800px" height="800px" viewBox="0 0 72 72" id="emoji" xmlns="http://www.w3.org/2000/svg"> + <g id="color"> +<path fill="${color}" stroke="none" d="M58,61c0,0,0-3-1-7c-1.2109-4.8457-4-8-10-8c-5,0-15,0-22,0c-6,0-8.7891,3.1543-10,8c-1,4-1,7-1,7H58z"/> +<path fill="${color}" stroke="none" d="M26,26c0,3.7246,0.5391,7.8086,2,10c1.8613,2.793,5.0176,4,8,4c3.0957,0,6.1367-1.207,8-4 c1.46-2.1914,2-6.2754,2-10c0-2.7935-1-12-10-12S26,21.3442,26,26z"/> + </g> + <g id="line"> + <path fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M58,60c0,0,0-2-1-6 c-1.2109-4.8457-4-8-10-8c-5,0-15,0-22,0c-6,0-8.7891,3.1543-10,8c-1,4-1,6-1,6"/> + <path fill="none" stroke="#000000" stroke-linejoin="round" stroke-width="2" d="M26,26c0,3.7246,0.5391,7.8086,2,10 c1.8613,2.793,5.0176,4,8,4c3.0957,0,6.1367-1.207,8-4c1.46-2.1914,2-6.2754,2-10c0-2.7935-1-12-10-12S26,21.3442,26,26z"/> + </g> +</svg>`; + +export interface PersonI { + name: string; + birthday: Date; + color: string; +} + +export interface PersonProps extends NodeProps { + person: PersonI; + + width?: number; + height?: number; +} + +export class Person extends Node { + private readonly svg = createRef<SVG>(); + + public constructor(props?: PersonProps) { + super({ ...props }); + + this.add( + <Layout direction="column" alignItems="center" layout> + <SVG + ref={this.svg} + svg={profileSrc(props.person.color)} + fill="green" + width={props.width ?? 150} + height={props.height ?? 150} + ></SVG> + <Txt fontSize={20} fontFamily={theme.font} fill={theme.text.hex}> + {props.person.name} + </Txt> + </Layout>, + ); + } + + public *emit(text: string, duration: number, cleanUp = true) { + const ref = createRef<Txt>(); + + this.insert( + <Txt + position={this.svg().bottomRight()} + ref={ref} + fontSize={0} + opacity={0} + fontFamily={theme.font} + fill={theme.text.hex} + > + {text} + </Txt>, + 0, + ); + + yield* all(ref().fontSize(40, duration), ref().opacity(1, duration)); + if (cleanUp) { + yield* waitFor(duration); + yield* all(ref().fontSize(0, duration), ref().opacity(0, duration)); + yield ref().remove(); + } + } +} |