fix the bugs with skipping
This commit is contained in:
parent
f4e55a2257
commit
e2d1b006fe
@ -13,9 +13,11 @@ calvin (mathstruck) "Wow, did you know that $a^2+b^2=c^2$?"
|
|||||||
|
|
||||||
calvin (thinking) "Something else"
|
calvin (thinking) "Something else"
|
||||||
|
|
||||||
bridget (surprised) "Me again"
|
bridget (surprised) "Me again000000"
|
||||||
|
|
||||||
kit (smiling) "I'm Kit!"
|
kit (smiling) "I'm Kit 1!"
|
||||||
|
|
||||||
|
kit (smiling) "I'm Kit 2!"
|
||||||
|
|
||||||
board ""
|
board ""
|
||||||
|
|
||||||
|
@ -1,26 +1,51 @@
|
|||||||
import { useEffect, useLayoutEffect, useState } from "react";
|
import { ForwardedRef, forwardRef, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
|
||||||
import { MathText } from "./MathText";
|
import { MathText } from "./MathText";
|
||||||
|
|
||||||
export const DialogText = (props: {children: string, onFinish?: () => void}) => {
|
export type DialogTextImperatives = {
|
||||||
const {children: str, onFinish} = props;
|
skip(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DialogText = forwardRef((props: {children: string, speed?: number, onFinish?: () => void}, forwardedRef: ForwardedRef<DialogTextImperatives>) => {
|
||||||
|
const {children: str, onFinish, speed = 15} = props;
|
||||||
const [len, setLen] = useState(0);
|
const [len, setLen] = useState(0);
|
||||||
|
const interval = useRef<unknown>(null);
|
||||||
|
|
||||||
|
useImperativeHandle(forwardedRef, () => {
|
||||||
|
return {
|
||||||
|
skip() {
|
||||||
|
setLen(str.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [str, setLen]);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
setLen(0);
|
setLen(0);
|
||||||
}, [str]);
|
}, [str]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const interval = setInterval(() => {
|
interval.current = setInterval(() => {
|
||||||
setLen(l => Math.max(l+1, str.length));
|
setLen(l => {
|
||||||
}, 70);
|
return Math.min(l+1, str.length)
|
||||||
if (len === str.length) {
|
});
|
||||||
// clearInterval(interval);
|
}, 1000/speed);
|
||||||
onFinish && onFinish();
|
|
||||||
}
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(interval);
|
if (interval.current) {
|
||||||
|
clearInterval(interval.current as any);
|
||||||
|
interval.current = null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}, [str, setLen]);
|
}, [str, setLen]);
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
if (len === str.length) {
|
||||||
|
if (interval.current) {
|
||||||
|
clearInterval(interval.current as any);
|
||||||
|
interval.current = null;
|
||||||
|
}
|
||||||
|
console.log("onFinish");
|
||||||
|
onFinish && onFinish();
|
||||||
|
}
|
||||||
|
}, [len]);
|
||||||
|
|
||||||
return <MathText>{str.slice(0, len)}</MathText>
|
return <MathText>{str.slice(0, len)}</MathText>
|
||||||
}
|
});
|
@ -3,7 +3,7 @@ import { Mathuscript, parseMathuscript } from "./parse";
|
|||||||
import { useCallback, useMemo, useRef, useState } from "react";
|
import { useCallback, useMemo, useRef, useState } from "react";
|
||||||
import { MathText } from "./MathText";
|
import { MathText } from "./MathText";
|
||||||
import { characterData } from "./data";
|
import { characterData } from "./data";
|
||||||
import { DialogText } from "./DialogText";
|
import { DialogText, DialogTextImperatives } from "./DialogText";
|
||||||
|
|
||||||
type VisualState = {
|
type VisualState = {
|
||||||
turn: number,
|
turn: number,
|
||||||
@ -45,7 +45,6 @@ const afterStep = (state: VisualState, step: Mathuscript[number]): VisualState =
|
|||||||
dialog.emotion = char.emotion;
|
dialog.emotion = char.emotion;
|
||||||
dialog.text = step.text;
|
dialog.text = step.text;
|
||||||
}
|
}
|
||||||
console.log(newState);
|
|
||||||
return newState;
|
return newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,16 +64,18 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, emotion: "", text: ""}});
|
const [visualState, setVisualState] = useState<VisualState>({turn: 0, characters: [], board: {text: ""}, dialog: {name: null, emotion: "", text: ""}});
|
||||||
const dialogGoing = useRef(false);
|
const dialogGoing = useRef(false);
|
||||||
|
const dialogTextRef = useRef<DialogTextImperatives>(null);
|
||||||
|
|
||||||
const doStep = useCallback(() => {
|
const doStep = useCallback(() => {
|
||||||
|
goAgain.current = false;
|
||||||
if (dialogGoing.current) {
|
if (dialogGoing.current) {
|
||||||
console.log("dialog running");
|
if (dialogTextRef.current) {
|
||||||
|
dialogTextRef.current.skip();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
goAgain.current = false;
|
|
||||||
const step = parsedScript[index];
|
const step = parsedScript[index];
|
||||||
if (step) {
|
if (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") {
|
if (step.name === "board") {
|
||||||
@ -87,6 +88,10 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
}
|
}
|
||||||
}, [index, parsedScript, setIndex, setVisualState]);
|
}, [index, parsedScript, setIndex, setVisualState]);
|
||||||
|
|
||||||
|
const onDialogFinish = useCallback(() => {
|
||||||
|
dialogGoing.current = false;
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (goAgain.current) {
|
if (goAgain.current) {
|
||||||
doStep();
|
doStep();
|
||||||
}
|
}
|
||||||
@ -218,9 +223,7 @@ export const MathuscriptPlayer = (props: { script: string }) => {
|
|||||||
`}>
|
`}>
|
||||||
<strong>{speakingChar.displayName}</strong> {visualState.dialog.emotion && <em>({visualState.dialog.emotion})</em>}
|
<strong>{speakingChar.displayName}</strong> {visualState.dialog.emotion && <em>({visualState.dialog.emotion})</em>}
|
||||||
</div>
|
</div>
|
||||||
<DialogText onFinish={() => {
|
<DialogText onFinish={onDialogFinish} ref={dialogTextRef}>
|
||||||
dialogGoing.current = false;
|
|
||||||
}}>
|
|
||||||
{visualState.dialog.text}
|
{visualState.dialog.text}
|
||||||
</DialogText>
|
</DialogText>
|
||||||
</>
|
</>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es2017",
|
"target": "es2017",
|
||||||
"module": "es2022",
|
"module": "es2022",
|
||||||
|
"lib": ["DOM"],
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"jsx": "react-jsx",
|
"jsx": "react-jsx",
|
||||||
"allowImportingTsExtensions": true,
|
"allowImportingTsExtensions": true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user