some basic viewer

This commit is contained in:
Robin Appelman 2023-04-29 14:54:53 +02:00
commit 5910b2f35a
45 changed files with 1089 additions and 1436 deletions

View file

@ -1,4 +1,5 @@
import {BuildingState, WorldBoundaries, BuildingType, Team} from "@demostf/parser-worker";
import {BuildingState, WorldBoundaries, BuildingType, Team} from "../Data/Parser";
import {Show} from "solid-js";
export interface BuildingProp {
building: BuildingState;
@ -54,17 +55,15 @@ export function Building({building, mapBoundary, targetSize, scale}: BuildingPro
const alpha = building.health / maxHealth;
try {
const image = getIcon(building);
const angle = (building.angle) ?
<polygon points="-6,14 0, 16 6,14 0,24" fill="white"
transform={`rotate(${270 - building.angle})`}/> : '';
return <g transform={`translate(${scaledX} ${scaledY}) scale(${1 / scale})`}
opacity={alpha}>
{angle}
<image href={image} class={"player-icon"} height={32}
width={32}
transform={`translate(-16 -16)`}/>
<image href={image} className={"player-icon"} height={32}
width={32}
transform={`translate(-16 -16)`}/>
<Show when={building.angle}>
<polygon points="-6,14 0, 16 6,14 0,24" fill="white"
transform={`rotate(${270 - building.angle})`}/>
</Show>
</g>
} catch (e) {
console.log(e);

View file

@ -1,45 +0,0 @@
.killfeed {
position: absolute;
top: 0;
right: 0;
padding: 15px;
user-select: none;
.kill {
.red {
color: #a75d50;
}
.blue {
color: #5b818f;
}
&.active-player {
background-color: #ddcfb2;
}
display: inline-block;
margin: 3px;
white-space: nowrap;
background-color: #2d2727cc;
border-radius: 5px;
padding: 5px 15px;
width: auto;
text-align: right;
color: var(--primary-color);
font-weight: bold;
float: right;
clear: both;
.player {
padding: 0 5px;
}
}
}
.kill-icon {
display: inline-block;
height: 22px;
width: auto;
vertical-align: middle;
filter: brightness(600%);
}

View file

@ -1,4 +1,4 @@
import {Kill, PlayerState} from "@demostf/parser-worker";
import {Kill, PlayerState} from "../Data/Parser";
import {killAlias} from "./killAlias";
export interface KillFeedProps {

View file

@ -1,4 +0,0 @@
.player-icon {
mask-size: cover;
mask-repeat: no-repeat;
}

View file

@ -1,4 +1,4 @@
import {PlayerState, WorldBoundaries, Team} from "@demostf/parser-worker";
import {PlayerState, WorldBoundaries, Team} from "../Data/Parser";
export interface PlayerProp {
player: PlayerState;

View file

@ -1,218 +0,0 @@
.blueSpecHolder {
position: absolute;
left: 0;
top: 50%;
transform: translate(0, -50%);
}
.redSpecHolder {
position: absolute;
right: 0;
top: 50%;
transform: translate(0, -50%);
}
.playerspec {
background-color: black;
color: white;
height: 42px;
width: 200px;
position: relative;
font-family: sans-serif;
margin-bottom: 2px;
user-select: none;
&.uber {
height: 28px;
}
.class-icon, .steam-avatar {
width: 42px;
height: 42px;
display: inline-block;
position: absolute;
top: 0;
left: 0;
background-position: top left;
background-size: 100% 100%;
&.uber {
height: 28px;
background-size: 28px 28px;
background-repeat: no-repeat;
background-position: 50% 50%;
}
}
.player-name {
display: inline-block;
position: relative;
padding: 0 5px;
white-space: nowrap;
width: 120px;
overflow: hidden;
text-overflow: ellipsis;
}
.health-container {
display: inline-block;
position: absolute;
left: 42px;
top: 0;
height: 28px;
width: calc(100% - 42px);
line-height: 28px;
font-weight: bold;
.health {
position: relative;
float: right;
padding: 0 5px;
}
.healthbar {
position: absolute;
top: 0;
left: 0;
height: 28px;
}
}
&.red {
.health-container {
background-color: #a75d50aa;
}
.healthbar {
background-color: #a75d50;
}
.class-icon.scout {
background-image: url('../../images/class_portraits/Icon_scout.jpg');
}
.class-icon.soldier {
background-image: url('../../images/class_portraits/Icon_soldier.jpg');
}
.class-icon.pyro {
background-image: url('../../images/class_portraits/Icon_pyro.jpg');
}
.class-icon.demoman {
background-image: url('../../images/class_portraits/Icon_demoman.jpg');
}
.class-icon.engineer {
background-image: url('../../images/class_portraits/Icon_engineer.jpg');
}
.class-icon.heavy {
background-image: url('../../images/class_portraits/Icon_heavy.jpg');
}
.class-icon.medic {
background-image: url('../../images/class_portraits/Icon_medic.jpg');
}
.class-icon.sniper {
background-image: url('../../images/class_portraits/Icon_sniper.jpg');
}
.class-icon.spy{
background-image: url('../../images/class_portraits/Icon_spy.jpg');
}
.class-icon.uber {
background-image: url('../../images/charge_red.svg');
}
.class-icon, .steam-avatar {
right: 0;
left: auto;
}
.health-container {
right: 42px;
left: auto;
}
.health {
float: left;
}
.player-name {
float: right;
direction: ltr;
text-align: right;
}
}
&.blue {
.health-container {
background-color: #5b818faa;
}
.healthbar {
background-color: #5b818f;
}
.class-icon.scout {
background-image: url('../../images/class_portraits/Icon_scout_blue.jpg');
}
.class-icon.soldier {
background-image: url('../../images/class_portraits/Icon_soldier_blue.jpg');
}
.class-icon.pyro {
background-image: url('../../images/class_portraits/Icon_pyro_blue.jpg');
}
.class-icon.demoman {
background-image: url('../../images/class_portraits/Icon_demoman_blue.jpg');
}
.class-icon.engineer {
background-image: url('../../images/class_portraits/Icon_engineer_blue.jpg');
}
.class-icon.heavy {
background-image: url('../../images/class_portraits/Icon_heavy_blue.jpg');
}
.class-icon.medic {
background-image: url('../../images/class_portraits/Icon_medic_blue.jpg');
}
.class-icon.sniper {
background-image: url('../../images/class_portraits/Icon_sniper_blue.jpg');
}
.class-icon.spy {
background-image: url('../../images/class_portraits/Icon_spy_blue.jpg');
}
.class-icon.uber {
background-image: url('../../images/charge_blue.svg');
}
}
&.overhealed {
.health {
color: #79d297;
}
.health:after {
position: absolute;
top: 21px;
right: 0;
padding: 0 5px;
font-size: 10px;
font-weight: bold;
content: 'OVERHEALED'
}
&.red .health:after {
position: absolute;
top: 21px;
left: 0;
right: auto;
}
}
&.dead {
.healthbar, .health {
display: none;
}
.health-container {
background-color: transparent;
}
.class-icon {
opacity: 0.5;
}
}
}

View file

@ -1,4 +1,4 @@
import {PlayerState} from "@demostf/parser-worker";
import {PlayerState} from "../Data/Parser";
export interface PlayerSpecProps {
player: PlayerState;

View file

@ -1,7 +1,7 @@
import {PlayersSpec} from './PlayerSpec';
import {KillFeed} from './KillFeed';
import {AsyncParser} from "../Data/AsyncParser";
import {PlayerState, Kill} from "@demostf/parser-worker";
import {PlayerState, Kill} from "../Data/Parser";
export interface SpecHUDProps {
tick: number;

View file

@ -1,23 +0,0 @@
.timeline {
width: 100%;
height: 100px;
/*bottom: 0;*/
/*position: relative;*/
}
.timeline-progress {
position: absolute;
bottom: -60px;
left: 0;
width: 100%;
height: 160px;
}
.timeline-background {
position: absolute;
bottom: 22px;
left: 0;
width: 100%;
height: 78px;
transform: scale(1, -1);
}

View file

@ -1,4 +1,4 @@
import {ParsedDemo, PlayerState, Header, WorldBoundaries, Team} from "@demostf/parser-worker";
import {ParsedDemo, PlayerState, Header, WorldBoundaries, Team} from "../Data/Parser";
export interface TimelineProps {
parser: AsyncParser;
@ -8,16 +8,13 @@ export interface TimelineProps {
}
export const Timeline = ({parser, tick, onSetTick, disabled}) => {
const background = <TimeLineBackground parser={parser}/>;
return (<div class="timeline">
{background}
<input class="timeline-progress" type="range" min={0}
max={parser.demo.tickCount} value={tick}
disabled={disabled}
return <div class="timeline">
<input max={parser.demo.tickCount} value={tick} class="timeline-progress" type="range" min={0}
onChange={(event) => {onSetTick(parseInt(event.target.value, 10))}}
disabled={disabled}
/>
</div>);
<TimeLineBackground parser={parser}/>
</div>;
}
import {AsyncParser} from "../Data/AsyncParser";