animation wip

This commit is contained in:
Miodec 2026-01-08 17:22:16 +01:00
parent bca19b4933
commit 80d8c22c52
5 changed files with 80 additions and 27 deletions

View file

@ -1,4 +0,0 @@
import { createSignal } from "solid-js";
export const [getWpm, setWpm] = createSignal("0");
export const [getAcc, setAcc] = createSignal("100%");
export const [getBurst, setBurst] = createSignal("0");

View file

@ -1,11 +1,44 @@
import { Accessor, JSXElement } from "solid-js";
import { Accessor, createEffect, JSXElement } from "solid-js";
import { animate } from "animejs";
import { isFocused } from "./focus";
export function LiveCounter(props: {
value: Accessor<string>;
visible: Accessor<{
value: boolean;
withAnimation: boolean;
}>;
class?: string;
}): JSXElement {
let divRef: HTMLDivElement | undefined;
createEffect(() => {
if (divRef === undefined) return;
const visibleState = props.visible();
const focusState = isFocused();
if (visibleState.value && focusState) {
if (visibleState.withAnimation) {
animate(divRef, {
opacity: [0, 1],
duration: 125,
});
} else {
divRef.style.opacity = "1";
}
} else {
if (visibleState.withAnimation) {
animate(divRef, {
opacity: [1, 0],
duration: 125,
});
} else {
divRef.style.opacity = "0";
}
}
});
return (
<div class={`${props.class}`} classList={{ hidden: props.value() === "" }}>
<div ref={divRef} class={`${props.class}`}>
{props.value()}
</div>
);

View file

@ -1,35 +1,41 @@
import { createMemo } from "solid-js";
import { createMemo, createSignal } from "solid-js";
import { qsr } from "../utils/dom";
import { LiveCounter } from "./live-counter";
import { render } from "solid-js/web";
import { getAcc, getBurst, getWpm } from "../signals/live-states";
import {
getLiveAccStyle,
getLiveBurstStyle,
getLiveSpeedStyle,
} from "../signals/config";
import { isActive } from "./test-state";
import { isFocused } from "./focus";
const isTestRunning = createMemo(() => isActive() && isFocused());
const [getWpm, setLiveStatWpm] = createSignal("0");
const [getAcc, setLiveStatAcc] = createSignal("100%");
const [getBurst, setLiveStatBurst] = createSignal("0");
const [wpmVisible, setWpmVisible] = createSignal({
value: false,
withAnimation: true,
});
export { setLiveStatWpm, setLiveStatAcc, setLiveStatBurst, setWpmVisible };
const liveWpmText = createMemo(() =>
isTestRunning() && getLiveSpeedStyle() === "text" ? getWpm() : "",
getLiveSpeedStyle() === "text" ? getWpm() : "",
);
const liveWpmMini = createMemo(() =>
isTestRunning() && getLiveSpeedStyle() === "mini" ? getWpm() : "",
getLiveSpeedStyle() === "mini" ? getWpm() : "",
);
const liveAccText = createMemo(() =>
isTestRunning() && getLiveAccStyle() === "text" ? getAcc() : "",
getLiveAccStyle() === "text" ? getAcc() : "",
);
const liveAccMini = createMemo(() =>
isTestRunning() && getLiveAccStyle() === "mini" ? getAcc() : "",
getLiveAccStyle() === "mini" ? getAcc() : "",
);
const liveBurstText = createMemo(() =>
isTestRunning() && getLiveBurstStyle() === "text" ? getBurst() : "",
getLiveBurstStyle() === "text" ? getBurst() : "",
);
const liveBurstMini = createMemo(() =>
isTestRunning() && getLiveBurstStyle() === "mini" ? getBurst() : "",
getLiveBurstStyle() === "mini" ? getBurst() : "",
);
export function mountLiveCounters(): void {
@ -37,9 +43,9 @@ export function mountLiveCounters(): void {
render(
() => (
<div class="wrapper">
<LiveCounter class="liveSpeed" value={liveWpmText} />
{/* <LiveCounter class="liveSpeed" value={liveWpmText} />
<LiveCounter class="liveAcc" value={liveAccText} />
<LiveCounter class="liveBurst" value={liveBurstText} />
<LiveCounter class="liveBurst" value={liveBurstText} /> */}
</div>
),
textWrapper.native,
@ -49,9 +55,9 @@ export function mountLiveCounters(): void {
render(
() => (
<div>
<LiveCounter class="speed" value={liveWpmMini} />
<LiveCounter class="acc" value={liveAccMini} />
<LiveCounter class="burst" value={liveBurstMini} />
<LiveCounter class="speed" value={liveWpmMini} visible={wpmVisible} />
{/* <LiveCounter class="acc" value={liveAccMini} />
<LiveCounter class="burst" value={liveBurstMini} /> */}
</div>
),
miniWrapper.native,

View file

@ -20,8 +20,8 @@ import * as SoundController from "../controllers/sound-controller";
import { clearLowFpsMode, setLowFpsMode } from "../anim";
import { createTimer } from "animejs";
import { requestDebouncedAnimationFrame } from "../utils/debounced-animation-frame";
import { setWpm } from "../signals/live-states";
import Format from "../utils/format";
import { setLiveStatWpm } from "./live-states";
let lastLoop = 0;
const newTimer = createTimer({
@ -236,7 +236,7 @@ function timerStep(): void {
// already using raf
TimerProgress.update();
setWpm(
setLiveStatWpm(
Format.typingSpeed(Config.blindMode ? wpmAndRaw.raw : wpmAndRaw.wpm, {
showDecimalPlaces: false,
}),

View file

@ -55,7 +55,12 @@ import * as ModesNotice from "../elements/modes-notice";
import * as Last10Average from "../elements/last-10-average";
import * as MemoryFunboxTimer from "./funbox/memory-funbox-timer";
import { qsr } from "../utils/dom";
import { setAcc, setBurst } from "../signals/live-states";
import {
setLiveStatAcc,
setLiveStatBurst,
setLiveStatWpm,
setWpmVisible,
} from "./live-states";
export const updateHintsPositionDebounced = Misc.debounceUntilResolved(
updateHintsPosition,
@ -1679,7 +1684,7 @@ function afterAnyTestInput(
const acc: number = Numbers.roundTo2(TestStats.calculateAccuracy());
if (!isNaN(acc)) {
setAcc(Format.percentage(Config.blindMode ? 100 : acc));
setLiveStatAcc(Format.percentage(Config.blindMode ? 100 : acc));
}
if (Config.mode !== "time") {
@ -1784,7 +1789,9 @@ export async function afterTestWordChange(
const lastBurst = TestInput.burstHistory[TestInput.burstHistory.length - 1];
if (Numbers.isSafeNumber(lastBurst)) {
setBurst(Format.typingSpeed(lastBurst, { showDecimalPlaces: false }));
setLiveStatBurst(
Format.typingSpeed(lastBurst, { showDecimalPlaces: false }),
);
}
if (direction === "forward") {
//
@ -1814,6 +1821,10 @@ export function onTestStart(): void {
Monkey.show();
TimerProgress.show();
TimerProgress.update();
setWpmVisible({
value: true,
withAnimation: true,
});
}
export function onTestRestart(source: "testPage" | "resultPage"): void {
@ -1822,6 +1833,13 @@ export function onTestRestart(source: "testPage" | "resultPage"): void {
getInputElement().style.left = "0";
TestConfig.show();
Focus.set(false);
setWpmVisible({
value: false,
withAnimation: false,
});
setLiveStatWpm("0");
setLiveStatBurst("");
setLiveStatAcc("");
TimerProgress.instantHide();
TimerProgress.reset();
Monkey.instantHide();