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$"
|
||||
|
||||
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 ""
|
||||
|
||||
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 { Mathuscript, parseMathuscript } from "./parse";
|
||||
import katex from "katex";
|
||||
import { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
import { useCallback, useMemo, useRef, useState } from "react";
|
||||
import { MathText } from "./MathText";
|
||||
import { characterData } from "./data";
|
||||
|
||||
@ -9,7 +8,7 @@ type VisualState = {
|
||||
turn: number,
|
||||
characters: {name: string, emotion: string, side: "left" | "right", lastTurn: number}[],
|
||||
board: {text: string},
|
||||
dialog: {name: string | null, text: string},
|
||||
dialog: {name: string | null, emotion: string, text: string},
|
||||
}
|
||||
|
||||
const otherSide = (side: "left" | "right"): "left" | "right" => {
|
||||
@ -42,6 +41,7 @@ const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState =
|
||||
char.lastTurn = newState.turn;
|
||||
char.emotion = step.emotion ?? char.emotion;
|
||||
dialog.name = step.name;
|
||||
dialog.emotion = char.emotion;
|
||||
dialog.text = step.text;
|
||||
}
|
||||
console.log(newState);
|
||||
@ -55,23 +55,34 @@ const getCharData = (name: string | null) => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const allChars = Object.keys(characterData) as (keyof typeof characterData)[];
|
||||
|
||||
export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
const {script} = props;
|
||||
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
||||
const goAgain = useRef(false);
|
||||
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(() => {
|
||||
goAgain.current = false;
|
||||
const step = parsedScript[index];
|
||||
if (step) {
|
||||
console.log(step);
|
||||
setIndex(i => i+1);
|
||||
setVisualState(state => afterStep(state, step));
|
||||
if (step.name === "board") {
|
||||
goAgain.current = true;
|
||||
}
|
||||
} else {
|
||||
console.log("the end");
|
||||
}
|
||||
}, [index, parsedScript, setIndex, setVisualState]);
|
||||
|
||||
if (goAgain.current) {
|
||||
doStep();
|
||||
}
|
||||
|
||||
const speakingChar = getCharData(visualState.dialog.name);
|
||||
|
||||
return (
|
||||
@ -99,7 +110,6 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
/* background-color: rgba(255, 0, 0, 0.3); */
|
||||
padding: 1em;
|
||||
`}>
|
||||
<div>
|
||||
@ -114,26 +124,57 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
left: 0;
|
||||
`}>
|
||||
{
|
||||
visualState.characters.map(c => {
|
||||
allChars.map(name => {
|
||||
const visChar = visualState.characters.find(ch => ch.name === name);
|
||||
// TODO: make it change with emotion
|
||||
const char = getCharData(c.name);
|
||||
if (!char) {
|
||||
const charDat = getCharData(name);
|
||||
if (!charDat) {
|
||||
return null;
|
||||
}
|
||||
return <img
|
||||
className={css`
|
||||
position: absolute;
|
||||
${
|
||||
c.side === "left" ? css`left: -20%;` : css`right: -20%; transform: scaleX(-1);`
|
||||
}
|
||||
height: 90%;
|
||||
bottom: 0;
|
||||
--outline-color: black;
|
||||
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}
|
||||
src={char.assets["default"]}
|
||||
/>
|
||||
const visualInactive = visChar && visualState.dialog.name !== name;
|
||||
return [
|
||||
<img
|
||||
className={css`
|
||||
position: absolute;
|
||||
transition: all 0.25s;
|
||||
left: -60%;
|
||||
${
|
||||
visChar?.side === "left" && css`left: -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}-left`}
|
||||
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>
|
||||
@ -168,7 +209,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
`}>
|
||||
<strong>{speakingChar.displayName}</strong>
|
||||
</div>
|
||||
<MathText>{visualState.dialog.text}</MathText>
|
||||
{visualState.dialog.emotion && <em>({visualState.dialog.emotion})</em>} <MathText>{visualState.dialog.text}</MathText>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
|
@ -17,4 +17,16 @@ export const characterData = {
|
||||
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