Speed slider

This commit is contained in:
nise.moe 2024-03-03 17:26:45 +01:00
parent 3ddddc168b
commit 923848a156
8 changed files with 126 additions and 82 deletions

View File

@ -37,6 +37,7 @@
"sonner": "^1.3.1",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
"ts-md5": "^1.3.1",
"zustand": "^4.4.1"
},
"devDependencies": {
@ -3645,6 +3646,14 @@
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="
},
"node_modules/ts-md5": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/ts-md5/-/ts-md5-1.3.1.tgz",
"integrity": "sha512-DiwiXfwvcTeZ5wCE0z+2A9EseZsztaiZtGrtSaY5JOD7ekPnR/GoIVD5gXZAlK9Na9Kvpo9Waz5rW64WKAWApg==",
"engines": {
"node": ">=12"
}
},
"node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",

View File

@ -46,6 +46,7 @@
"sonner": "^1.3.1",
"tailwind-merge": "^2.0.0",
"tailwindcss-animate": "^1.0.7",
"ts-md5": "^1.3.1",
"zustand": "^4.4.1"
}
}

View File

@ -6,7 +6,7 @@ import { Button } from "../components/ui/button";
import { ArrowLeft, ArrowRight, PauseIcon, PlayIcon } from "lucide-react";
export function SongSlider() {
const { beatmap, replay, playing, time } = state();
const { beatmap, replay, playing, time, speed } = state();
if (!beatmap || !replay) {
return;
}
@ -45,7 +45,6 @@ export function SongSlider() {
</div>
<Slider
step={10}
min={0}
@ -55,6 +54,23 @@ export function SongSlider() {
OsuRenderer.setTime(value[0]);
}}
/>
<div className="flex flex-col items-start w-full ">
<p className="text-sm opacity-50">Current speed</p>
<p>{speed}x</p>
</div>
<Slider
step={0.1}
min={0.1}
max={2}
value={[speed]}
onValueChange={(value: any) => {
OsuRenderer.setSpeed(value[0]);
}}
/>
</Card>
);
}

View File

@ -1,9 +1,12 @@
import { Vector2 } from "osu-classes";
import p5 from "p5";
import { loadImageAsync } from "@/utils";
import { Md5 } from "ts-md5";
export class Drawer {
private static imageCache: Record<string, p5.Graphics> = {};
static images = {
cursor: undefined as any as p5.Image,
cursortrail: undefined as any as p5.Image,
@ -128,6 +131,8 @@ export class Drawer {
static drawSliderBody(origin: Vector2, path: Vector2[], radius: number) {
Drawer.p.push();
const cacheKey = Md5.hashStr(JSON.stringify(origin) + JSON.stringify(path) + JSON.stringify(radius));
if (!this.imageCache[cacheKey]) {
const g = Drawer.p.createGraphics(512 * 4, 384 * 4);
g.scale(2);
g.translate(512 - 256, 384 - 192);
@ -167,12 +172,15 @@ export class Drawer {
g.endShape();
}
this.imageCache[cacheKey] = g;
}
Drawer.p.imageMode(Drawer.p.CORNER);
Drawer.p.image(g, -256, -192, 512 * 2, 384 * 2);
Drawer.p.image(this.imageCache[cacheKey], -256, -192, 512 * 2, 384 * 2);
Drawer.p.pop();
}
static drawCursorPath(
path: {
position: Vector2;

View File

@ -20,6 +20,7 @@ export enum OsuRendererEvents {
LOAD = "LOAD",
PLAY = "PLAY",
TIME = "TIME",
SPEED = "SPEED",
}
export class OsuRendererBridge extends EventEmitter {
@ -37,6 +38,7 @@ export class OsuRenderer {
static event = new OsuRendererBridge();
static speedMultiplier = 0.5;
static time: number = 0;
static beatmap: StandardBeatmap;
static og_beatmap: StandardBeatmap;
@ -64,7 +66,7 @@ export class OsuRenderer {
}
if (this.playing) {
this.setTime(this.time + (Date.now() - this.lastRender));
this.setTime(this.time + ((Date.now() - this.lastRender) * this.speedMultiplier));
}
this.lastRender = Date.now();
@ -189,6 +191,11 @@ export class OsuRenderer {
this.event.emit(OsuRendererEvents.TIME);
}
static setSpeed(speed: number) {
this.speedMultiplier = speed;
this.event.emit(OsuRendererEvents.SPEED);
}
private static renderObject(hitObject: StandardHitObject) {
if (hitObject instanceof Circle) {
this.renderCircle(hitObject);
@ -318,15 +325,6 @@ export class OsuRenderer {
Drawer.drawSliderFollowPoint(sliderPos, hitObject.radius);
}
// if (GameplayAnalyzer.renderJudgements[hitObject.startTime]) {
// Drawer.setDrawingOpacity(opacity / 2);
// Drawer.drawCircleJudgement(
// hitObject.stackedStartPosition,
// hitObject.radius,
// GameplayAnalyzer.renderJudgements[hitObject.startTime]
// );
// }
Drawer.endDrawing();
return arScale;
}

View File

@ -52,5 +52,10 @@ export class Renderer {
time: OsuRenderer.time,
});
});
OsuRenderer.event.on(OsuRendererEvents.SPEED, () => {
state.setState({
speed: OsuRenderer.speedMultiplier,
});
});
}
}

View File

@ -55,6 +55,7 @@ export const state = create<{
mods: IMod[] | null;
playing: boolean;
time: number;
speed: number;
}>(() => ({
metadataEditorDialog: false,
openDialog: false,
@ -69,6 +70,7 @@ export const state = create<{
mods: null,
playing: false,
time: 0,
speed: 1
}));
state.subscribe((newState) => {

View File

@ -1899,6 +1899,11 @@ ts-interface-checker@^0.1.9:
resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz"
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
ts-md5@^1.3.1:
version "1.3.1"
resolved "https://registry.npmjs.org/ts-md5/-/ts-md5-1.3.1.tgz"
integrity sha512-DiwiXfwvcTeZ5wCE0z+2A9EseZsztaiZtGrtSaY5JOD7ekPnR/GoIVD5gXZAlK9Na9Kvpo9Waz5rW64WKAWApg==
tslib@^2.0.0, tslib@^2.1.0, tslib@^2.4.0:
version "2.6.2"
resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz"