small improvements
This commit is contained in:
		| @@ -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$" | 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"; | import { characterData } from "./data"; | ||||||
|  |  | ||||||
| type VisualState = { | type VisualState = { | ||||||
| 	characters: {name: string, emotion: string, x: number}[], | 	turn: 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, 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 afterStep = (state: VisualState, step: Mathuscript[number]): VisualState => { | ||||||
| 	const newState = structuredClone(state); | 	const newState = structuredClone(state); | ||||||
| 	const {characters, board, dialog} = newState; | 	const {characters, board, dialog} = newState; | ||||||
|  | 	newState.turn += 1; | ||||||
| 	if (step.name === "board") { | 	if (step.name === "board") { | ||||||
| 		board.text = step.text; | 		board.text = step.text; | ||||||
| 	} else { | 	} else { | ||||||
|  | 		characters.sort((a, b) => a.lastTurn - b.lastTurn); | ||||||
| 		let char = characters.find(c => c.name === step.name); | 		let char = characters.find(c => c.name === step.name); | ||||||
| 		if (!char) { | 		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); | 			characters.push(char); | ||||||
| 		} | 		} | ||||||
|  | 		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.text = step.text; | 		dialog.text = step.text; | ||||||
| @@ -41,7 +59,7 @@ 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 [index, setIndex] = useState(0); | 	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 doStep = useCallback(() => { | ||||||
| 		const step = parsedScript[index]; | 		const step = parsedScript[index]; | ||||||
| @@ -105,9 +123,13 @@ export const MathuscriptPlayer = (props: { script: string }) => { | |||||||
| 							return <img | 							return <img | ||||||
| 								className={css` | 								className={css` | ||||||
| 									position: absolute; | 									position: absolute; | ||||||
| 									left: -20%; | 									${ | ||||||
|  | 										c.side === "left" ? css`left: -20%;` : css`right: -20%; transform: scaleX(-1);` | ||||||
|  | 									} | ||||||
| 									height: 90%; | 									height: 90%; | ||||||
| 									bottom: 0; | 									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} | 								key={c.name} | ||||||
| 								src={char.assets["default"]} | 								src={char.assets["default"]} | ||||||
| @@ -126,6 +148,7 @@ export const MathuscriptPlayer = (props: { script: string }) => { | |||||||
| 					<div className={css` | 					<div className={css` | ||||||
| 						flex-basis: 0; | 						flex-basis: 0; | ||||||
| 						flex-grow: 1; | 						flex-grow: 1; | ||||||
|  | 						position: relative; | ||||||
| 						background-color: hsla(220, 50%, 40%, 0.85); | 						background-color: hsla(220, 50%, 40%, 0.85); | ||||||
| 						border: 2px solid hsla(220, 30%, 60%, 0.85); | 						border: 2px solid hsla(220, 30%, 60%, 0.85); | ||||||
| 						border-radius: 0.25em; | 						border-radius: 0.25em; | ||||||
| @@ -134,7 +157,18 @@ export const MathuscriptPlayer = (props: { script: string }) => { | |||||||
| 					`}> | 					`}> | ||||||
| 						{ | 						{ | ||||||
| 							speakingChar && <> | 							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> | 					</div> | ||||||
|   | |||||||
| @@ -3,14 +3,18 @@ export const characterData = { | |||||||
| 		displayName: "Bridget", | 		displayName: "Bridget", | ||||||
| 		assets: { | 		assets: { | ||||||
| 			default: "/assets/bridget.png", | 			default: "/assets/bridget.png", | ||||||
| 			fallback: "/assets/bridget.png", |  | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
| 	axelle: { | 	calvin: { | ||||||
| 		displayName: "Axelle", | 		displayName: "Calvin", | ||||||
| 		assets: { | 		assets: { | ||||||
| 			default: "/assets/bridget.png", | 			default: "/assets/calvin.png", | ||||||
| 			fallback: "/assets/bridget.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 | 
		Reference in New Issue
	
	Block a user
	 dylan
					dylan