mirror of
https://codeberg.org/demostf/frontend.git
synced 2026-06-03 18:24:12 +02:00
fix timeline not updating from outside seeks
This commit is contained in:
parent
116b52c892
commit
8a651088ff
1 changed files with 53 additions and 50 deletions
|
|
@ -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}`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue