summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/function_box.tsx180
-rw-r--r--src/project.meta2
-rw-r--r--src/scenes/first_box.tsx23
-rw-r--r--src/scenes/hungry_partner.meta5
-rw-r--r--src/scenes/hungry_partner.tsx108
-rw-r--r--src/scenes/index.ts14
6 files changed, 237 insertions, 95 deletions
diff --git a/src/components/function_box.tsx b/src/components/function_box.tsx
index e046d63..43d3985 100644
--- a/src/components/function_box.tsx
+++ b/src/components/function_box.tsx
@@ -1,31 +1,10 @@
-import {
- Img,
- Rect,
- Node,
- Video,
- makeScene2D,
- Txt,
- Line,
- LineSegment,
- NodeProps,
-} from "@motion-canvas/2d";
-import {
- Direction,
- beginSlide,
- createRef,
- map,
- slideTransition,
- tween,
- all,
- waitFor,
- range,
- makeRef,
-} from "@motion-canvas/core";
+import { Rect, Node, Txt, Line, NodeProps } from "@motion-canvas/2d";
+import { createRef, all, range, makeRef } from "@motion-canvas/core";
import { CodeBlock } from "@motion-canvas/2d/lib/components/CodeBlock";
import { theme } from "../theme";
-import * as ts from "typescript";
+import { transpile } from "typescript";
export interface FunctionBoxProps extends NodeProps {
source?: string;
@@ -33,6 +12,9 @@ export interface FunctionBoxProps extends NodeProps {
padding?: number;
delta?: number;
+ inputFontSize?: number;
+ outputFontSize?: number;
+
workingText?: string;
idlingText?: string;
@@ -43,18 +25,6 @@ export interface FunctionBoxProps extends NodeProps {
type FunctionArgs = { node?: Node; val: any }[];
-/*
-<Node ref={this.node} opacity={0}>
- <CodeBlock
- fontFamily={theme.font}
- language="typescript"
- ref={this.block}
- fontSize={1}
- code={this.source}
- ></CodeBlock>
- </Node>
- */
-
export class FunctionBox extends Node {
private readonly source: string;
private readonly workingText: string;
@@ -72,11 +42,14 @@ export class FunctionBox extends Node {
private readonly inputSegments: Line[] = [];
private readonly inputs: Rect[] = [];
private readonly outputSegment = createRef<Line>();
- private readonly output = createRef<Node>();
+ private readonly output = createRef<Rect>();
private readonly child = createRef<FunctionBox>();
private readonly isChild: boolean;
+ private readonly inputFontSize: number;
+ private readonly outputFontSize: number;
+
private currentArgs: FunctionArgs = [];
public constructor(props?: FunctionBoxProps) {
@@ -91,7 +64,7 @@ export class FunctionBox extends Node {
} else {
this.source = props?.source ?? `(x: number): number => x + 2`;
- const functionCode = ts.transpile(this.source);
+ const functionCode = transpile(this.source);
this.function = eval(functionCode);
}
@@ -103,6 +76,9 @@ export class FunctionBox extends Node {
this.isChild = props?.isChild ?? false;
+ this.outputFontSize = props?.outputFontSize ?? 30;
+ this.inputFontSize = props?.inputFontSize ?? 30;
+
this.add(
<Rect
opacity={this.opacity}
@@ -115,6 +91,7 @@ export class FunctionBox extends Node {
<Rect direction={"row"} alignItems={"center"} gap={10}>
<Rect
direction={"row"}
+ fontSize={this.inputFontSize}
ref={makeRef(this.inputs, i)}
justifyContent={"end"}
opacity={1}
@@ -141,11 +118,19 @@ export class FunctionBox extends Node {
padding={60}
direction={"row"}
height={"100%"}
- gap={40}
>
<Txt fontFamily={theme.font} fill={theme.text.hex} ref={this.boxMoji}>
{this.idlingText}
</Txt>
+ <Node ref={this.node} opacity={0}>
+ <CodeBlock
+ fontFamily={theme.font}
+ language="typescript"
+ ref={this.block}
+ fontSize={0}
+ code={this.source}
+ ></CodeBlock>
+ </Node>
</Rect>
<Rect direction={"column"} height={"100%"} alignItems={"end"}>
@@ -163,6 +148,7 @@ export class FunctionBox extends Node {
ref={this.output}
justifyContent={"end"}
opacity={1}
+ fontSize={this.outputFontSize}
></Rect>
</Rect>
</Rect>
@@ -173,22 +159,25 @@ export class FunctionBox extends Node {
public *resetInput(duration: number) {
yield* all(
...this.inputs.map((x) =>
- all(
- x.opacity(0, duration),
- x.height(0, duration),
- x.width(0, duration),
- ),
+ all(x.opacity(0, duration), x.fontSize(0, duration)),
+ ),
+ ...this.inputSegments.map((segment) =>
+ all(segment.points([], duration), segment.opacity(1, duration)),
),
- ...this.inputSegments.map((segment) => segment.points([], duration)),
);
+
+ this.inputs.forEach((x) => x.removeChildren());
}
public *resetOutput(duration: number) {
yield* all(
this.output().opacity(0, duration),
+ this.output().fontSize(0, duration),
this.outputSegment().points([], duration),
+ this.outputSegment().opacity(0, duration),
);
- yield this.output().removeChildren();
+
+ this.output().removeChildren();
}
public *reset(duration: number) {
@@ -204,7 +193,7 @@ export class FunctionBox extends Node {
input.removeChildren();
input.add(
args[i].node ?? (
- <Txt fontFamily={theme.font} fontSize={30} fill={theme.text.hex}>
+ <Txt fontFamily={theme.font} fill={theme.text.hex}>
{args[i].val.toString()}
</Txt>
),
@@ -222,68 +211,99 @@ export class FunctionBox extends Node {
),
...this.inputs.map((input) =>
all(
- input.height(40, duration),
- input.width(40, duration),
input.opacity(1, duration),
+ input.fontSize(this.inputFontSize, duration),
),
),
);
}
public *propogateInput(duration: number) {
- const opacityChangeDuration = 0.1;
-
yield* all(
...this.inputSegments.map((segment) =>
- segment.opacity(0.2, opacityChangeDuration),
+ all(segment.opacity(0.2, duration), segment.points([], duration)),
),
);
-
yield* all(
- ...this.inputSegments.map((segment) => segment.points([], duration)),
- );
-
- yield* all(
- ...this.inputSegments.map((segment) =>
- segment.opacity(1, opacityChangeDuration),
- ),
- ...this.inputs.map((input) => input.opacity(0, opacityChangeDuration)),
+ this.resetInput(duration),
this.boxMoji().text(this.workingText, duration),
);
}
public *propogateOutput(duration: number) {
+ yield* all(
+ this.boxMoji().text(this.idlingText, duration),
+ this.child()?.opacity(0.2, duration),
+ this.output().opacity(0.2, duration),
+ this.outputSegment().opacity(0, duration),
+ );
+
const output = this.function(...this.currentArgs.map((input) => input.val));
- if (typeof output === "function") {
- this.output().add(
- <FunctionBox
- opacity={0}
- isChild={true}
- ref={this.child}
- fn={output}
- ></FunctionBox>,
- );
- } else {
- this.output().add(
- <Txt fontFamily={theme.font} fontSize={30} fill={theme.text.hex}>
- {output.toString()}
- </Txt>,
- );
- }
- yield* this.boxMoji().text(this.idlingText, duration);
+ switch (typeof output) {
+ case "function":
+ yield this.output().add(
+ <FunctionBox
+ opacity={0}
+ isChild={true}
+ ref={this.child}
+ fn={output}
+ ></FunctionBox>,
+ );
+ break;
+ case "number":
+ case "string":
+ yield this.output().add(
+ <Txt fontFamily={theme.font} fill={theme.text.hex}>
+ {output.toString()}
+ </Txt>,
+ );
+ break;
+ default:
+ yield this.output().add(
+ <CodeBlock
+ fontFamily={theme.font}
+ language="typescript"
+ fontSize={15}
+ code={JSON.stringify(output, null, 2)}
+ ></CodeBlock>,
+ );
+ }
yield* all(
this.outputSegment().points(
[
- { x: -this.delta, y: 0 },
+ { x: 0, y: 0 },
{ x: this.padding, y: 0 },
],
duration,
),
+ this.outputSegment().opacity(1, duration),
+ this.output().fontSize(this.outputFontSize, duration),
this.child()?.opacity(1, duration),
this.output().opacity(1, duration),
- this.outputSegment().opacity(1, duration),
);
}
+
+ public *showCode(duration: number) {
+ yield* all(
+ this.boxMoji().text("", duration),
+ this.boxMoji().opacity(0, duration),
+ this.block().fontSize(30, duration),
+ this.node().opacity(1, duration),
+ );
+ }
+
+ public *hideCode(duration: number) {
+ yield* this.boxMoji().text(this.idlingText, 0);
+ yield* all(
+ this.block().fontSize(0, duration),
+ this.node().opacity(0, duration),
+ this.boxMoji().opacity(1, duration),
+ );
+ }
+
+ public getChild() {
+ return this.child;
+ }
}
diff --git a/src/project.meta b/src/project.meta
index 9093235..7c59eb3 100644
--- a/src/project.meta
+++ b/src/project.meta
@@ -25,7 +25,7 @@
"options": {
"fileType": "image/png",
"quality": 100,
- "groupByScene": false
+ "groupByScene": true
}
}
}
diff --git a/src/scenes/first_box.tsx b/src/scenes/first_box.tsx
index b3957af..31ee631 100644
--- a/src/scenes/first_box.tsx
+++ b/src/scenes/first_box.tsx
@@ -4,8 +4,6 @@ import {
beginSlide,
createRef,
slideTransition,
- all,
- waitFor,
} from "@motion-canvas/core";
import { FunctionBox } from "../components/function_box";
@@ -23,14 +21,15 @@ export default makeScene2D(function* (view) {
yield* beginSlide("Black Box");
- for (const [a, b] of [
- [-1, 2],
+ for (const [[a, b], i] of [
+ [1, 2],
[3, 4],
- [5, 6],
- ] as [number, number][]) {
- const inputId = "(" + [a, b].join(",") + ")";
+ [1, 2],
+ [1, 2],
+ ].map((x, i) => [x, i]) as [[number, number], number][]) {
+ const inputId = "(" + [a, b, i].join(",") + ")";
- yield* all(functionBox().reset(0.25));
+ yield* functionBox().reset(0.5);
yield* functionBox().setInputs([{ val: a }, { val: b }], 0.5);
yield* beginSlide("Add Inputs " + inputId);
@@ -41,4 +40,12 @@ export default makeScene2D(function* (view) {
yield* functionBox().propogateOutput(0.5);
yield* beginSlide("Propogate Outputs of " + inputId);
}
+
+ yield* functionBox().reset(0.5);
+
+ yield* functionBox().showCode(0.85);
+ yield* beginSlide("Show Code");
+
+ yield* functionBox().hideCode(0.85);
+ yield* beginSlide("Hide Code");
});
diff --git a/src/scenes/hungry_partner.meta b/src/scenes/hungry_partner.meta
new file mode 100644
index 0000000..cec20cc
--- /dev/null
+++ b/src/scenes/hungry_partner.meta
@@ -0,0 +1,5 @@
+{
+ "version": 0,
+ "timeEvents": [],
+ "seed": 3141613664
+} \ No newline at end of file
diff --git a/src/scenes/hungry_partner.tsx b/src/scenes/hungry_partner.tsx
new file mode 100644
index 0000000..696870e
--- /dev/null
+++ b/src/scenes/hungry_partner.tsx
@@ -0,0 +1,108 @@
+import { Node, Txt, makeScene2D } from "@motion-canvas/2d";
+import {
+ Direction,
+ beginSlide,
+ createRef,
+ slideTransition,
+} from "@motion-canvas/core";
+
+import { FunctionBox } from "../components/function_box";
+import { theme } from "../theme";
+
+const hungryValentine = `(
+ savoryCravingRatio: number, sweetCravingRatio: number,
+ acidityCravingRatio: number, spiceCravingRatio: number,
+): string => {
+ const foods = {
+ "🍕": {savory: 0.8, sweet: 0.1, acidity: 0.5, spice: 0.5},
+ "🧁": {savory: 0.2, sweet: 0.9, acidity: 0.1, spice: 0.1},
+ "🍋🍰": {savory: 0.1, sweet: 0.8, acidity: 0.9, spice: 0.1},
+ "🌮🔥": {savory: 0.6, sweet: 0.2, acidity: 0.5, spice: 0.8},
+ };
+
+ const weight = (foodProfile: Record<string, number>) =>
+ foodProfile["savory"] * savoryCravingRatio
+ + foodProfile["sweet"] * sweetCravingRatio
+ + foodProfile["acidity"] * acidityCravingRatio
+ + foodProfile["spice"] * spiceCravingRatio;
+
+ const bestFood = Object.keys(foods).reduce((a, b) =>
+ weight(foods[a]) > weight(foods[b]) ? a : b
+ );
+
+ const foodNames = Array.from(Object.keys(foods));
+ const shouldChooseRandom = Math.random() > 0.4; // side effect
+ return shouldChooseRandom
+ ? foodNames[Math.floor(Math.random() * foodNames.length)]
+ : bestFood;
+};`;
+
+export default makeScene2D(function* (view) {
+ const functionBox = createRef<FunctionBox>();
+
+ view.add(
+ <FunctionBox
+ arity={4}
+ idlingText={"😴"}
+ workingText={"😋💭"}
+ source={hungryValentine}
+ ref={functionBox}
+ />,
+ );
+
+ yield* slideTransition(Direction.Right);
+
+ yield* beginSlide("Get Best Food For Partner");
+
+ const order = ["savory", "sweet", "acidic", "spice"];
+
+ for (const [[a, b, c, d], i] of [
+ [0.7, 0.1, 0.4, 0.1],
+ [0.7, 0.1, 0.4, 0.1],
+ [0.7, 0.1, 0.4, 0.1],
+ [0.7, 0.1, 0.4, 0.1],
+ ].map((x, i) => [x, i]) as [[number, number, number, number], number][]) {
+ const inputId = "(" + [a, b, c, d, i].join(",") + ")";
+
+ yield* functionBox().reset(0.5);
+ yield* functionBox().setInputs(
+ [a, b, c, d].map((ratio, i) => ({
+ val: ratio,
+ node: (
+ <Txt fontFamily={theme.font} fill={theme.text.hex}>
+ {order[i]}:{" "}
+ <Txt
+ fontFamily={theme.font}
+ fill={
+ ratio > 0.6
+ ? theme.red.hex
+ : ratio < 0.3
+ ? theme.green.hex
+ : theme.lavender.hex
+ }
+ >
+ {ratio.toString()}
+ </Txt>
+ </Txt>
+ ),
+ })),
+ 0.5,
+ );
+
+ yield* beginSlide("Add Inputs " + inputId);
+
+ yield* functionBox().propogateInput(0.5);
+ yield* beginSlide("Propogate Inputs " + inputId);
+
+ yield* functionBox().propogateOutput(0.5);
+ yield* beginSlide("Propogate Outputs of " + inputId);
+ }
+
+ yield* functionBox().reset(0.5);
+
+ yield* functionBox().showCode(0.85);
+ yield* beginSlide("Show Code");
+
+ yield* functionBox().hideCode(0.85);
+ yield* beginSlide("Hide Code");
+});
diff --git a/src/scenes/index.ts b/src/scenes/index.ts
index 56fda2b..d21da3b 100644
--- a/src/scenes/index.ts
+++ b/src/scenes/index.ts
@@ -4,12 +4,14 @@ import partone from "./partone?scene";
import flirtingwithfunctions from "./flirtingwithfunctions?scene";
import doctor from "./doctor?scene";
import first_box from "./first_box?scene";
+import hungry_partner from "./hungry_partner?scene";
export const scenes = [
- title,
- me,
- partone,
- flirtingwithfunctions,
- doctor,
- first_box,
+ // title,
+ // me,
+ // partone,
+ // flirtingwithfunctions,
+ // doctor,
+ // first_box,
+ hungry_partner,
];