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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
|
import { Layout, makeScene2D } from "@motion-canvas/2d";
import {
Direction,
all,
beginSlide,
createRef,
slideTransition,
} from "@motion-canvas/core";
import { FunctionBox } from "../components/function_box";
import { PEOPLE, Person, PersonI } from "../components/person";
import { CardI, daysUntilNextDate } from "./birthday_letters";
export const valentineCardFn = (person: PersonI): CardI => {
const valentinesDay = new Date("02/14/2024");
const message =
`Dear, ${person.name}\n.` +
"Your smile lights up my world.\n" +
"Happy Valentine's Day!";
const deliverInDays = daysUntilNextDate(valentinesDay);
return { message, deliverInDays };
};
export const birthdayCardFn = (person: PersonI): CardI => {
const age = new Date().getFullYear() - person.birthday.getFullYear();
const ending =
({ 1: "st", 2: "nd", 3: "rd" } as Record<number, string>)[
parseInt(Array.from(age.toString()).at(-1))
] ?? "th";
const message =
`Happy ${age}${ending} birthday, ${person.name}!\n` +
"I can't believe it's already been a year!";
const deliverInDays = daysUntilNextDate(person.birthday);
return { deliverInDays, message };
};
const valentineCardGenerator = `const valentineCardGenerator = (person: PersonI): CardI => {
const valentinesDay = new Date("02/14/2024");
const message =
\`Dear, \${person.name}\\n.\` +
"Your smile lights up my world.\\n" +
"Happy Valentine's Day!";
const deliverInDays = daysUntilNextDate(valentinesDay);
return { message, deliverInDays };
};`;
const birthdayCardGenerator = `const birthdayCardGenerator = (person: PersonI): CardI => {
const age = new Date().getFullYear() - person.birthday.getFullYear();
const ageEnding = (
{ 1: "st", 2: "nd", 3: "rd" } as Record<number, string>
)[parseInt(Array.from(age.toString()).at(-1))] ?? "th";
const message =
\`Happy \${age}\${ageEnding} birthday, \${person.name}!\\n\` +
"I can't believe it's already been a year!";
const deliverInDays = daysUntilNextDate(person.birthday);
return { deliverInDays, message };
}`;
const cardBuilder = `const buildCards = (
people: PersonI[],
cardGenerator: (person: PersonI) => CardI,
): CardI[] => {
const cards: CardI[] = [];
for (const person of people) {
const card = cardGenerator(person);
cards.push(card);
}
return cards;
};
buildCards;`;
export default makeScene2D(function* (view) {
const valentineFunctionBox = createRef<FunctionBox>();
const birthdayFunctionBox = createRef<FunctionBox>();
const cardBuilderBox = createRef<FunctionBox>();
const layout = createRef<Layout>();
view.add(
<Layout direction="row" gap={200} ref={layout} layout>
<Layout direction="column" alignItems="center" gap={20}>
<FunctionBox
ref={valentineFunctionBox}
source={valentineCardGenerator}
fn={valentineCardFn}
idlingText="❤️"
workingText="📝⚙"
outputFontSize={15}
></FunctionBox>
<FunctionBox
ref={birthdayFunctionBox}
source={birthdayCardGenerator}
fn={birthdayCardFn}
idlingText="🎂"
workingText="📝⚙"
outputFontSize={15}
></FunctionBox>
</Layout>
<Layout direction="column" gap={20}>
<FunctionBox
ref={cardBuilderBox}
source={cardBuilder}
idlingText="🏭"
workingText="📝⚙"
outputFontSize={15}
arity={2}
></FunctionBox>
</Layout>
</Layout>,
);
yield* all(
slideTransition(Direction.Left),
...[valentineFunctionBox, birthdayFunctionBox, cardBuilderBox].map((x) =>
x().reset(0.1),
),
);
yield* beginSlide("show all functions");
yield* all(
...[valentineFunctionBox, birthdayFunctionBox].map((x) =>
x().showCode(0.5),
),
);
yield* beginSlide("show generator functions");
const [p1, p2, p3, p4] = PEOPLE;
yield* all(
...[valentineFunctionBox, birthdayFunctionBox].map((x) =>
x().hideCode(0.5),
),
);
yield* all(
...[valentineFunctionBox, birthdayFunctionBox].map((x) =>
x().setInputs([{ val: p2, node: <Person person={p2} /> }], 0.5),
),
);
yield* beginSlide("show inputs");
yield* all(
...[valentineFunctionBox, birthdayFunctionBox].map((x) =>
x().propogateInput(0.5),
),
);
yield* all(
...[valentineFunctionBox, birthdayFunctionBox].map((x) =>
x().propogateOutput(0.5),
),
);
yield* beginSlide("make cards");
yield* all(
...[valentineFunctionBox, birthdayFunctionBox].map((x) => x().reset(0.5)),
cardBuilderBox().showCode(0.5),
);
yield* beginSlide("hide cards, show card generator");
yield* cardBuilderBox().setInputs(
[
{
val: [p1, p2],
node: (
<Layout direction="row" gap={20}>
<Person person={p1} />
<Person person={p2} />
</Layout>
),
},
{ val: valentineCardFn, node: valentineFunctionBox() },
],
0.5,
);
yield* beginSlide("input function to function");
yield* cardBuilderBox().hideCode(0.5);
yield* cardBuilderBox().propogateInput(0.5);
yield* cardBuilderBox().propogateOutput(0.5);
yield* beginSlide("build valentines cards");
yield* all(layout().gap(0, 0.5), cardBuilderBox().reset(0.5));
yield* cardBuilderBox().setInputs(
[
{
val: [p2, p3, p4],
node: (
<Layout direction="row" gap={20}>
<Person person={p2} />
<Person person={p3} />
<Person person={p4} />
</Layout>
),
},
{ val: birthdayCardFn, node: birthdayFunctionBox() },
],
0.5,
);
yield* beginSlide("show birthday cards input");
yield* cardBuilderBox().propogateInput(0.5);
yield* cardBuilderBox().propogateOutput(0.5);
yield* beginSlide("build cards");
});
|