Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Render runinfo to a canvas #25

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/graphics/game-layout/16x9-1p.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
height: '176px',
}"
>
<run-info text-align="left" info-is-row />
<run-info-canvas :width="710" :height="176" text-align="left" info-is-row />
</div>

<!-- Media Box / Reader / Comms -->
Expand Down Expand Up @@ -96,18 +96,18 @@ import { Vue, Component } from 'vue-property-decorator';
import GameCapture from './components/GameCapture.vue';
import Player from './components/Player.vue';
import CommentatorsReader from './components/CommentatorsReader.vue';
import RunInfo from './components/RunInfo.vue';
import Timer from './components/Timer.vue';
import DonationBar from './components/DonationBar.vue';
import FlashingLightsWarning from './components/FlashingLightsWarning.vue';
import MediaBoxBox from './components/MediaBoxBox.vue';
import RunInfoCanvas from './components/RunInfoCanvas.vue';

@Component({
components: {
RunInfoCanvas,
GameCapture,
Player,
CommentatorsReader,
RunInfo,
Timer,
MediaBoxBox,
DonationBar,
Expand Down
19 changes: 10 additions & 9 deletions src/graphics/game-layout/4x3-1p-largecam.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,26 @@
id="GameCapture1"
class="BlockRed"
:style="{
left: '589px',
left: '591px',
top: '0px',
width: '1331px',
height: '998px',
width: '1329px',
height: '989px'
}"
/>

<!-- Camera Captures -->
<div
id="CameraCapture1"
class="Capture BlockBlue Relative"
class="Capture Relative Flex"
:style="{
left: '0px',
top: '346px',
width: '567px',
height: '426px',
}"
/>
>
<flashing-lights-warning class="Flex" style="align-self: flex-end" />
</div>

<!-- Player -->
<div
Expand All @@ -47,8 +49,7 @@
height: '281px',
}"
>
<run-info />
<flashing-lights-warning class="Flex" style="align-self: flex-end" />
<run-info-canvas :width="575" :height="281" line-right />
</div>

<!-- TIMER/media box -->
Expand Down Expand Up @@ -92,17 +93,17 @@ import MediaBoxBox from './components/MediaBoxBox.vue';
import GameCapture from './components/GameCapture.vue';
import Player from './components/Player.vue';
import CommentatorsReader from './components/CommentatorsReader.vue';
import RunInfo from './components/RunInfo.vue';
import Timer from './components/Timer.vue';
import DonationBar from './components/DonationBar.vue';
import FlashingLightsWarning from './components/FlashingLightsWarning.vue';
import RunInfoCanvas from './components/RunInfoCanvas.vue';

@Component({
components: {
RunInfoCanvas,
GameCapture,
Player,
CommentatorsReader,
RunInfo,
Timer,
MediaBoxBox,
DonationBar,
Expand Down
15 changes: 8 additions & 7 deletions src/graphics/game-layout/4x3-1p.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,23 @@
left: '591px',
top: '0px',
width: '1329px',
height: '988px'
height: '989px'
}"
/>

<!-- Camera Captures -->
<div
id="CameraCapture1"
class="Capture Relative"
class="Capture Relative Flex"
:style="{
left: '0px',
top: '344px',
width: '568px',
height: '332px'
}"
/>
>
<flashing-lights-warning class="Flex" style="align-self: flex-end" />
</div>

<!-- Run Game Info -->
<div
Expand All @@ -33,8 +35,7 @@
height: '281px',
}"
>
<run-info line-right />
<flashing-lights-warning class="Flex" style="align-self: flex-end" />
<run-info-canvas :width="575" :height="281" line-right />
</div>

<!-- Player -->
Expand Down Expand Up @@ -81,18 +82,18 @@ import { Vue, Component } from 'vue-property-decorator';
import MediaBoxBox from './components/MediaBoxBox.vue';
import GameCapture from './components/GameCapture.vue';
import Player from './components/Player.vue';
import RunInfo from './components/RunInfo.vue';
import DonationBar from './components/DonationBar.vue';
import CommentatorsReader from './components/CommentatorsReader.vue';
import FlashingLightsWarning from './components/FlashingLightsWarning.vue';
import Timer from './components/Timer.vue';
import RunInfoCanvas from './components/RunInfoCanvas.vue';

@Component({
components: {
RunInfoCanvas,
GameCapture,
Player,
CommentatorsReader,
RunInfo,
Timer,
MediaBox,
MediaBoxBox,
Expand Down
19 changes: 7 additions & 12 deletions src/graphics/game-layout/4x3-2p.vue
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,7 @@
height: '220px',
}"
>
<run-info text-align="left" :info-is-row="infoIsRow" line-right/>
<flashing-lights-warning
class="Flex"
@flashing-lights-updated="flashingLightsUpdated"
style="align-self: flex-end"/>
<run-info-canvas :width="710" :height="220" text-align="left" line-right/>
</div>

<!-- Media box / commentator / donation reader -->
Expand All @@ -100,6 +96,9 @@
height: '221px',
}"
>
<flashing-lights-warning
class="Flex"
style="align-self: flex-end"/>
<media-box-box
line-left
:style="{
Expand All @@ -119,7 +118,7 @@ import MediaBox from '@esa-layouts/graphics/_misc/components/mediabox';
import CommentatorsReader from './components/CommentatorsReader.vue';
import GameCapture from './components/GameCapture.vue';
import Player from './components/Player.vue';
import RunInfo from './components/RunInfo.vue';
import RunInfoCanvas from './components/RunInfoCanvas.vue';
import Timer from './components/Timer.vue';
import DonationBar from './components/DonationBar.vue';
import FlashingLightsWarning from './components/FlashingLightsWarning.vue';
Expand All @@ -130,7 +129,7 @@ import MediaBoxBox from './components/MediaBoxBox.vue';
GameCapture,
Player,
CommentatorsReader,
RunInfo,
RunInfoCanvas,
Timer,
MediaBox,
MediaBoxBox,
Expand All @@ -139,10 +138,6 @@ import MediaBoxBox from './components/MediaBoxBox.vue';
},
})
export default class extends Vue {
infoIsRow = false;

flashingLightsUpdated(newVal: boolean): void {
this.infoIsRow = newVal;
}
//
}
</script>
176 changes: 176 additions & 0 deletions src/graphics/game-layout/components/RunInfoCanvas.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
<template>
<div class="Flex runInfoRoot">
<div
v-show="runData"
class="FlexColumn runDataContainer has-side-lines"
:style="{
'border-right': lineRight ? '5px solid var(--slide-color)' : '5px solid rgba(0,0,0,0)',
'border-left': lineLeft ? '5px solid var(--slide-color)' : '5px solid rgba(0,0,0,0)',
}"
>
<canvas :width="canvasWidth" :height="canvasHeight" ref="runInfo"/>
</div>
</div>
</template>

<script lang="ts">
import { Vue, Component, Prop, Watch, Ref } from 'vue-property-decorator'; // eslint-disable-line object-curly-newline, max-len
import { State } from 'vuex-class';
import { RunDataActiveRun } from 'speedcontrol-util/types';

import './tester/jsTifierExtensionFunctions';
import './tester/jsTifier';

type VAlign = 'top' | 'center' | 'bottom';
type HAlign = 'left' | 'center' | 'right' | 'justify';

interface JSTifierContextExtension {
/* eslint-disable max-len */
mlFillTextBsg: (text: string, x: number, y: number, w: number, h: number, vAlign: VAlign, hAlign: HAlign, lineHeight: number) => void;
mlFillText: (text: string, x: number, y: number, w: number, h: number, vAlign: VAlign, hAlign: HAlign, lineHeight: number) => void;
/* enable-disable max-len */
}

type CustomCanvasContext = CanvasRenderingContext2D & JSTifierContextExtension;

// TODO: https://stackoverflow.com/questions/4712242/wait-for-fonts-to-load-before-rendering-web-page
// useHead to insert the pre-load for the fonts.
@Component
export default class extends Vue {
@State('runDataActiveRun') runData!: RunDataActiveRun;
@Prop({ type: Number }) readonly width!: number;
@Prop({ type: Number }) readonly height!: number;
@Prop({ type: String, default: 'center' }) readonly textAlign!: HAlign;
@Prop({ type: Boolean, default: false }) lineLeft!: string;
@Prop({ type: Boolean, default: false }) lineRight!: string;
@Ref('runInfo') canvas!: HTMLCanvasElement;
context!: CustomCanvasContext;

get canvasWidth(): number {
return this.width - 14;
}

get canvasHeight(): number {
return this.height - 14;
}

setupMainFont() {
this.context.fillStyle = 'white';
this.context.font = '23px Goodlight';
this.context.textAlign = 'left';
this.context.textBaseline = 'ideographic';
}

drawConsole(system: string): void {
// reset shadow
this.context.shadowBlur = 0;
this.context.shadowOffsetX = 0;
this.context.shadowOffsetY = 0;

this.context.fillStyle = 'white';
this.context.font = '15pt Corbel-Bold';

this.context.mlFillText(
system,
0,
(this.canvas.height / 2),
this.canvas.width,
50,
'top',
this.textAlign,
35,
);
}

drawCategoryEstimate(category: string, estimate: string): void {
// reset shadow
this.context.shadowBlur = 0;
this.context.shadowOffsetX = 0;
this.context.shadowOffsetY = 0;

this.context.fillStyle = '#cf773b';
this.context.font = '15pt Goodlight';

const textItem = `${category} | ${estimate}`;

this.context.mlFillText(
textItem,
0,
this.canvas.height - 45,
this.canvas.width,
45,
'top',
this.textAlign,
35,
);
}

fit(): void {
this.context.fillStyle = '#404040';
this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);

const gameName = this.runData?.game;

if (gameName) {
this.context.mlFillTextBsg(
gameName.trim().toUpperCase(),
0,
5,
this.canvas.width,
this.canvas.height / 2,
'top',
this.textAlign,
35,
);
}

const system = this.runData?.system;

if (system) {
this.drawConsole(system.toUpperCase());
}

const category = this.runData?.category;
const estimate = this.runData?.estimate;

if (category && estimate) {
this.drawCategoryEstimate(category.toUpperCase(), estimate.toUpperCase());
}
}

async mounted(): Promise<void> {
this.context = this.canvas.getContext('2d') as CustomCanvasContext;
this.setupMainFont();
await Vue.nextTick();
this.fit();
}

destroyed(): void {
//
}

@Watch('runData', { deep: true })
async onRunDataChange(): Promise<void> {
await Vue.nextTick();
this.fit();
}
}
</script>

<style scoped lang="scss">
.runInfoRoot {
height: 100%;
width: 100%;
justify-content: center;
// Ensure the font is loaded
font-weight: 300;
font-family: Goodlight;
}

.runDataContainer {
box-sizing: border-box;
//padding: 5px 20px;
//padding: 8px;
justify-content: flex-start;
}
</style>
Loading