small improvements
This commit is contained in:
parent
c393582978
commit
fd91fe1d31
@ -9,7 +9,19 @@ 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$"
|
||||
|
||||
axelle (happy) "Wow, did you know that $a^2+b^2=c^2$?"
|
||||
calvin (happy) "Wow, did you know that $a^2+b^2=c^2$?"
|
||||
|
||||
calvin (happy) "Something else"
|
||||
|
||||
bridget (happy) "Me again"
|
||||
|
||||
kit (happy) "I'm Kit!"
|
||||
|
||||
board ""
|
||||
|
||||
calvin (happy) "I'm back!"
|
||||
|
||||
bridget (happy) "I'm on the right now!"
|
||||
|
||||
`
|
||||
|
||||
|
@ -6,22 +6,40 @@ import { MathText } from "./MathText";
|
||||
import { characterData } from "./data";
|
||||
|
||||
type VisualState = {
|
||||
characters: {name: string, emotion: string, x: number}[],
|
||||
turn: number,
|
||||
characters: {name: string, emotion: string, side: "left" | "right", lastTurn: number}[],
|
||||
board: {text: string},
|
||||
dialog: {name: string | null, text: string},
|
||||
}
|
||||
|
||||
const otherSide = (side: "left" | "right"): "left" | "right" => {
|
||||
return ({
|
||||
left: "right",
|
||||
right: "left",
|
||||
} as const)[side];
|
||||
}
|
||||
|
||||
const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState => {
|
||||
const newState = structuredClone(state);
|
||||
const {characters, board, dialog} = newState;
|
||||
newState.turn += 1;
|
||||
if (step.name === "board") {
|
||||
board.text = step.text;
|
||||
} else {
|
||||
characters.sort((a, b) => a.lastTurn - b.lastTurn);
|
||||
let char = characters.find(c => c.name === step.name);
|
||||
if (!char) {
|
||||
char = {name: step.name, emotion: "default", x: 0.5};
|
||||
char = {name: step.name, emotion: "default", side: "left", lastTurn: -1};
|
||||
if (characters.length > 1) {
|
||||
characters.splice(0, characters.length-1);
|
||||
}
|
||||
const otherChar = characters[0];
|
||||
if (otherChar) {
|
||||
char.side = otherSide(otherChar.side);
|
||||
}
|
||||
characters.push(char);
|
||||
}
|
||||
char.lastTurn = newState.turn;
|
||||
char.emotion = step.emotion ?? char.emotion;
|
||||
dialog.name = step.name;
|
||||
dialog.text = step.text;
|
||||
@ -41,7 +59,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
const {script} = props;
|
||||
const parsedScript = useMemo(() => parseMathuscript(script), [script]);
|
||||
const [index, setIndex] = useState(0);
|
||||
const [visualState, setVisualState] = useState<VisualState>({characters: [], board: {text: ""}, dialog: {name: null, text: ""}});
|
||||
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, text: ""}});
|
||||
|
||||
const doStep = useCallback(() => {
|
||||
const step = parsedScript[index];
|
||||
@ -105,9 +123,13 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
return <img
|
||||
className={css`
|
||||
position: absolute;
|
||||
left: -20%;
|
||||
${
|
||||
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"]}
|
||||
@ -126,6 +148,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
<div className={css`
|
||||
flex-basis: 0;
|
||||
flex-grow: 1;
|
||||
position: relative;
|
||||
background-color: hsla(220, 50%, 40%, 0.85);
|
||||
border: 2px solid hsla(220, 30%, 60%, 0.85);
|
||||
border-radius: 0.25em;
|
||||
@ -134,7 +157,18 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
||||
`}>
|
||||
{
|
||||
speakingChar && <>
|
||||
<strong>{speakingChar.displayName}.</strong> <MathText>{visualState.dialog.text}</MathText>
|
||||
<div className={css`
|
||||
position: absolute;
|
||||
bottom: 100%;
|
||||
left: 0;
|
||||
background-color: hsla(220, 50%, 40%, 0.85);
|
||||
border: 2px solid hsla(220, 30%, 60%, 0.85);
|
||||
border-radius: 0.25em;
|
||||
padding: 0.25em 0.75em;
|
||||
`}>
|
||||
<strong>{speakingChar.displayName}</strong>
|
||||
</div>
|
||||
<MathText>{visualState.dialog.text}</MathText>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
|
@ -3,14 +3,18 @@ export const characterData = {
|
||||
displayName: "Bridget",
|
||||
assets: {
|
||||
default: "/assets/bridget.png",
|
||||
fallback: "/assets/bridget.png",
|
||||
},
|
||||
},
|
||||
axelle: {
|
||||
displayName: "Axelle",
|
||||
calvin: {
|
||||
displayName: "Calvin",
|
||||
assets: {
|
||||
default: "/assets/bridget.png",
|
||||
fallback: "/assets/bridget.png",
|
||||
default: "/assets/calvin.png",
|
||||
},
|
||||
}
|
||||
},
|
||||
kit: {
|
||||
displayName: "Kit",
|
||||
assets: {
|
||||
default: "/assets/kit.png",
|
||||
},
|
||||
},
|
||||
}
|
BIN
src/server/public/assets/calvin.png
Normal file
BIN
src/server/public/assets/calvin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 411 KiB |
BIN
src/server/public/assets/kit.png
Normal file
BIN
src/server/public/assets/kit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 856 KiB |
Loading…
x
Reference in New Issue
Block a user