More visual improvements
This commit is contained in:
parent
fd91fe1d31
commit
dfc6d1c751
@ -9,19 +9,23 @@ bridget (happy) "Hi, friends!"
|
|||||||
|
|
||||||
board "Given $f: \mathbb{Q} \to \mathbb{R}$ and $x \in \mathbb{Q}$, there is a unique $y \in \mathbb{N}$ such that $f(x)=y$"
|
board "Given $f: \mathbb{Q} \to \mathbb{R}$ and $x \in \mathbb{Q}$, there is a unique $y \in \mathbb{N}$ such that $f(x)=y$"
|
||||||
|
|
||||||
calvin (happy) "Wow, did you know that $a^2+b^2=c^2$?"
|
calvin (mathstruck) "Wow, did you know that $a^2+b^2=c^2$?"
|
||||||
|
|
||||||
calvin (happy) "Something else"
|
calvin (thinking) "Something else"
|
||||||
|
|
||||||
bridget (happy) "Me again"
|
bridget (surprised) "Me again"
|
||||||
|
|
||||||
kit (happy) "I'm Kit!"
|
kit (smiling) "I'm Kit!"
|
||||||
|
|
||||||
board ""
|
board ""
|
||||||
|
|
||||||
calvin (happy) "I'm back!"
|
calvin (happy) "I'm back!"
|
||||||
|
|
||||||
bridget (happy) "I'm on the right now!"
|
bridget (aha) "I'm on the right now!"
|
||||||
|
|
||||||
|
theo (heh) "Oh, hey guys. Didn't see you there."
|
||||||
|
|
||||||
|
axelle "Oh, hi."
|
||||||
|
|
||||||
`
|
`
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { css } from "@emotion/css";
|
import { css } from "@emotion/css";
|
||||||
import { Mathuscript, parseMathuscript } from "./parse";
|
import { Mathuscript, parseMathuscript } from "./parse";
|
||||||
import katex from "katex";
|
import { useCallback, useMemo, useRef, useState } from "react";
|
||||||
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
||||||
import { MathText } from "./MathText";
|
import { MathText } from "./MathText";
|
||||||
import { characterData } from "./data";
|
import { characterData } from "./data";
|
||||||
|
|
||||||
@ -9,7 +8,7 @@ type VisualState = {
|
|||||||
turn: number,
|
turn: number,
|
||||||
characters: {name: string, emotion: string, side: "left" | "right", lastTurn: number}[],
|
characters: {name: string, emotion: string, side: "left" | "right", lastTurn: number}[],
|
||||||
board: {text: string},
|
board: {text: string},
|
||||||
dialog: {name: string | null, text: string},
|
dialog: {name: string | null, emotion: string, text: string},
|
||||||
}
|
}
|
||||||
|
|
||||||
const otherSide = (side: "left" | "right"): "left" | "right" => {
|
const otherSide = (side: "left" | "right"): "left" | "right" => {
|
||||||
@ -42,6 +41,7 @@ const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState =
|
|||||||
char.lastTurn = newState.turn;
|
char.lastTurn = newState.turn;
|
||||||
char.emotion = step.emotion ?? char.emotion;
|
char.emotion = step.emotion ?? char.emotion;
|
||||||
dialog.name = step.name;
|
dialog.name = step.name;
|
||||||
|
dialog.emotion = char.emotion;
|
||||||
dialog.text = step.text;
|
dialog.text = step.text;
|
||||||
}
|
}
|
||||||
console.log(newState);
|
console.log(newState);
|
||||||
@ -55,23 +55,34 @@ const getCharData = (name: string | null) => {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const allChars = Object.keys(characterData) as (keyof typeof characterData)[];
|
||||||
|
|
||||||
export const MathuscriptPlayer = (props: { script: string }) => {
|
export const MathuscriptPlayer = (props: { script: string }) => {
|
||||||
const {script} = props;
|
const {script} = props;
|
||||||
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
||||||
|
const goAgain = useRef(false);
|
||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, text: ""}});
|
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, emotion: "", text: ""}});
|
||||||
|
|
||||||
const doStep = useCallback(() => {
|
const doStep = useCallback(() => {
|
||||||
|
goAgain.current = false;
|
||||||
const step = parsedScript[index];
|
const step = parsedScript[index];
|
||||||
if (step) {
|
if (step) {
|
||||||
console.log(step);
|
console.log(step);
|
||||||
setIndex(i => i+1);
|
setIndex(i => i+1);
|
||||||
setVisualState(state => afterStep(state, step));
|
setVisualState(state => afterStep(state, step));
|
||||||
|
if (step.name === "board") {
|
||||||
|
goAgain.current = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
console.log("the end");
|
console.log("the end");
|
||||||
}
|
}
|
||||||
}, [index, parsedScript, setIndex, setVisualState]);
|
}, [index, parsedScript, setIndex, setVisualState]);
|
||||||
|
|
||||||
|
if (goAgain.current) {
|
||||||
|
doStep();
|
||||||
|
}
|
||||||
|
|
||||||
const speakingChar = getCharData(visualState.dialog.name);
|
const speakingChar = getCharData(visualState.dialog.name);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -99,7 +110,6 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
color: white;
|
color: white;
|
||||||
/* background-color: rgba(255, 0, 0, 0.3); */
|
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
`}>
|
`}>
|
||||||
<div>
|
<div>
|
||||||
@ -114,26 +124,57 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
left: 0;
|
left: 0;
|
||||||
`}>
|
`}>
|
||||||
{
|
{
|
||||||
visualState.characters.map(c => {
|
allChars.map(name => {
|
||||||
|
const visChar = visualState.characters.find(ch => ch.name === name);
|
||||||
// TODO: make it change with emotion
|
// TODO: make it change with emotion
|
||||||
const char = getCharData(c.name);
|
const charDat = getCharData(name);
|
||||||
if (!char) {
|
if (!charDat) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return <img
|
const visualInactive = visChar && visualState.dialog.name !== name;
|
||||||
|
return [
|
||||||
|
<img
|
||||||
className={css`
|
className={css`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
transition: all 0.25s;
|
||||||
|
left: -60%;
|
||||||
${
|
${
|
||||||
c.side === "left" ? css`left: -20%;` : css`right: -20%; transform: scaleX(-1);`
|
visChar?.side === "left" && css`left: -20%;`
|
||||||
}
|
}
|
||||||
height: 90%;
|
height: 90%;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
--outline-color: black;
|
${
|
||||||
|
visualInactive && css`bottom: -3%;`
|
||||||
|
}
|
||||||
|
--outline-color: white;
|
||||||
|
/* --outline-color: hsl(300, 45%, 40%); */
|
||||||
filter: drop-shadow(1px 1px 0 var(--outline-color)) drop-shadow(-1px 1px 0 var(--outline-color)) drop-shadow(1px -1px 0 var(--outline-color)) drop-shadow(-1px -1px 0 var(--outline-color));
|
filter: drop-shadow(1px 1px 0 var(--outline-color)) drop-shadow(-1px 1px 0 var(--outline-color)) drop-shadow(1px -1px 0 var(--outline-color)) drop-shadow(-1px -1px 0 var(--outline-color));
|
||||||
`}
|
`}
|
||||||
key={c.name}
|
key={`${name}-left`}
|
||||||
src={char.assets["default"]}
|
src={charDat.assets["default"]}
|
||||||
|
/>,
|
||||||
|
<img
|
||||||
|
className={css`
|
||||||
|
position: absolute;
|
||||||
|
transition: all 0.25s;
|
||||||
|
transform: scaleX(-1);
|
||||||
|
right: -60%;
|
||||||
|
${
|
||||||
|
visChar?.side === "right" && css`right: -20%;`
|
||||||
|
}
|
||||||
|
height: 90%;
|
||||||
|
bottom: 0;
|
||||||
|
${
|
||||||
|
visualInactive && css`bottom: -3%;`
|
||||||
|
}
|
||||||
|
--outline-color: white;
|
||||||
|
/* --outline-color: hsl(300, 45%, 40%); */
|
||||||
|
filter: drop-shadow(1px 1px 0 var(--outline-color)) drop-shadow(-1px 1px 0 var(--outline-color)) drop-shadow(1px -1px 0 var(--outline-color)) drop-shadow(-1px -1px 0 var(--outline-color));
|
||||||
|
`}
|
||||||
|
key={`${name}-right`}
|
||||||
|
src={charDat.assets["default"]}
|
||||||
/>
|
/>
|
||||||
|
]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
@ -168,7 +209,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
`}>
|
`}>
|
||||||
<strong>{speakingChar.displayName}</strong>
|
<strong>{speakingChar.displayName}</strong>
|
||||||
</div>
|
</div>
|
||||||
<MathText>{visualState.dialog.text}</MathText>
|
{visualState.dialog.emotion && <em>({visualState.dialog.emotion})</em>} <MathText>{visualState.dialog.text}</MathText>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,4 +17,16 @@ export const characterData = {
|
|||||||
default: "/assets/kit.png",
|
default: "/assets/kit.png",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
theo: {
|
||||||
|
displayName: "Theo",
|
||||||
|
assets: {
|
||||||
|
default: "/assets/theo.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axelle: {
|
||||||
|
displayName: "Axelle",
|
||||||
|
assets: {
|
||||||
|
default: "/assets/axelle.png",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
BIN
src/server/public/assets/axelle.png
Normal file
BIN
src/server/public/assets/axelle.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 495 KiB |
BIN
src/server/public/assets/theo.png
Normal file
BIN
src/server/public/assets/theo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 773 KiB |
Loading…
x
Reference in New Issue
Block a user