fix timeline not updating from outside seeks

This commit is contained in:
Robin Appelman 2024-12-02 23:53:31 +01:00
commit 8a651088ff

View file

@ -1,67 +1,70 @@
import {ParsedDemo, PlayerState, Header, WorldBoundaries, Team} from "../Data/Parser"; import {ParsedDemo, PlayerState, Header, WorldBoundaries, Team} from "../Data/Parser";
export interface TimelineProps { export interface TimelineProps {
parser: AsyncParser; parser: AsyncParser;
tick: number; tick: number;
onSetTick: (tick: number) => any; onSetTick: (tick: number) => any;
disabled?: boolean; disabled?: boolean;
} }
export const Timeline = ({parser, tick, onSetTick, disabled}) => { export const Timeline = (props: TimelineProps) => {
const background = <TimeLineBackground parser={parser}/>; const parser = props.parser;
return <div class="timeline"> const background = <TimeLineBackground parser={parser}/>;
<input max={parser.demo.tickCount} value={tick} class="timeline-progress" type="range" min={0} return <div class="timeline">
onChange={(event) => {onSetTick(parseInt(event.target.value, 10))}} <input max={parser.demo.tickCount} value={props.tick} class="timeline-progress" type="range" min={0}
disabled={disabled} onChange={(event) => {
/> props.onSetTick(parseInt(event.target.value, 10))
{background} }}
</div>; disabled={props.disabled}
/>
{background}
</div>;
} }
import {AsyncParser} from "../Data/AsyncParser"; import {AsyncParser} from "../Data/AsyncParser";
import {createSignal} from "solid-js"; import {createSignal} from "solid-js";
function TimeLineBackground({parser}:{parser: AsyncParser}) { function TimeLineBackground({parser}: { parser: AsyncParser }) {
const length = Math.floor(parser.demo.tickCount / 30); const length = Math.floor(parser.demo.tickCount / 30);
const blueHealth = new Uint16Array(length); const blueHealth = new Uint16Array(length);
const redHealth = new Uint16Array(length); const redHealth = new Uint16Array(length);
let index = 0; let index = 0;
let maxHealth = 0; let maxHealth = 0;
for (let tick = 0; tick < parser.demo.tickCount; tick += 30) { for (let tick = 0; tick < parser.demo.tickCount; tick += 30) {
index++; index++;
const players = parser.getPlayersAtTick(tick); const players = parser.getPlayersAtTick(tick);
for (const player of players) { for (const player of players) {
if (player.team === 2) { if (player.team === 2) {
redHealth[index] += player.health; redHealth[index] += player.health;
} else if (player.team === 3) { } else if (player.team === 3) {
blueHealth[index] += player.health; blueHealth[index] += player.health;
} }
} }
if (blueHealth[index] > 0 && redHealth[index] > 0) { if (blueHealth[index] > 0 && redHealth[index] > 0) {
maxHealth = Math.max(maxHealth, blueHealth[index], redHealth[index]); maxHealth = Math.max(maxHealth, blueHealth[index], redHealth[index]);
} }
} }
let darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches; let darkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
let redStroke = darkMode ? '#ff756bff' : '#ff000088'; let redStroke = darkMode ? '#ff756bff' : '#ff000088';
let blueStroke = darkMode ? '#7378ffff' : '#0000ff88'; let blueStroke = darkMode ? '#7378ffff' : '#0000ff88';
const redHealthPath = redHealth.reduce(pathReducer, 'M 0 0'); const redHealthPath = redHealth.reduce(pathReducer, 'M 0 0');
const blueHealthPath = blueHealth.reduce(pathReducer, 'M 0 0'); const blueHealthPath = blueHealth.reduce(pathReducer, 'M 0 0');
return ( return (
<svg class="timeline-background" <svg class="timeline-background"
viewBox={`0 0 ${length} ${maxHealth}`} viewBox={`0 0 ${length} ${maxHealth}`}
preserveAspectRatio="none"> preserveAspectRatio="none">
<path d={redHealthPath} stroke={redStroke} stroke-width={2} <path d={redHealthPath} stroke={redStroke} stroke-width={2}
fill="transparent" fill="transparent"
vector-effect="non-scaling-stroke"/> vector-effect="non-scaling-stroke"/>
<path d={blueHealthPath} stroke={blueStroke} stroke-width={2} <path d={blueHealthPath} stroke={blueStroke} stroke-width={2}
fill="transparent" fill="transparent"
vector-effect="non-scaling-stroke"/> vector-effect="non-scaling-stroke"/>
</svg>); </svg>);
} }
function pathReducer(path, y, x) { function pathReducer(path, y, x) {
return `${path} L ${x} ${y}` return `${path} L ${x} ${y}`
} }