1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
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();
}
}
}
|