compiling-the-lambda-calculus/src/scenes/valentines_letters.tsx
2024-02-11 20:44:17 -07:00

123 lines
3.0 KiB
TypeScript

import { Layout, Txt, makeScene2D } from "@motion-canvas/2d";
import {
Direction,
all,
beginSlide,
createRef,
makeRef,
slideTransition,
} from "@motion-canvas/core";
import { FunctionBox } from "../components/function_box";
import { theme } from "../theme";
import { PEOPLE, Person } from "../components/person";
const valentineLetterGenerator = `
interface PersonI {
name: string;
birthday: Date;
color: string;
}
(function valentinesLettersFor(people: PersonI[]) {
const letters: string[] = [];
for (const person of people) {
const letter = "Dear, " + person.name + "\\n"
+ "Your smile lights up my world.\\n"
+ "Happy Valentine's Day!";
letters.push(letter);
}
return letters;
})`;
export default makeScene2D(function* (view) {
const layout = createRef<Layout>();
const functionBox = createRef<FunctionBox>();
const people: Person[] = [];
const peopleLayout: Layout[] = [];
const peopleText: Txt[] = [];
view.add(
<FunctionBox
ref={functionBox}
source={valentineLetterGenerator}
workingText="📝⚙"
outputFontSize={25}
></FunctionBox>,
);
yield* all(slideTransition(Direction.Left), functionBox().showCode(0.75));
yield* functionBox().reset(0.1);
yield* beginSlide("Show code");
yield* functionBox().reset(0.1);
yield* all(
functionBox().hideCode(0.8),
functionBox().setInputs(
[
{
val: PEOPLE,
node: (
<Layout direction="column" gap={5} layout>
{PEOPLE.map((person) => (
<Person person={person} />
))}
</Layout>
),
},
],
0.8,
),
);
yield* beginSlide("Show people");
yield* functionBox().propogateInput(0.6);
yield* functionBox().propogateOutput(0.6);
yield* beginSlide("Generate valentines letters");
yield* functionBox().opacity(0, 0.5);
functionBox().remove();
view.add(
<Layout opacity={0} ref={layout} direction="row" gap={15} layout>
{PEOPLE.map((person, i) => (
<Layout
ref={makeRef(peopleLayout, i)}
alignItems="center"
direction="column"
gap={100}
>
<Person ref={makeRef(people, i)} person={person} />
<Txt
ref={makeRef(peopleText, i)}
fontSize={0}
fontFamily={theme.font}
fill={theme.text.hex}
/>
</Layout>
))}
</Layout>,
);
yield* layout().opacity(1, 0.5);
yield* all(...peopleText.map((text) => text.text("💌", 0)));
yield* all(...peopleText.map((text) => text.fontSize(50, 0.5)));
yield* all(...peopleLayout.map((layout) => layout.gap(0, 0.5)));
yield* all(
...peopleText.map((text) =>
all(text.fontSize(0, 0.5), text.opacity(0, 0.5)),
),
);
yield* beginSlide("Give people valentines letters");
yield* all(...people.map((person) => person.emit("😊", 0.5)));
yield* beginSlide("See their reactions");
yield* all(...people.map((person) => person.opacity(0, 0.5)));
});