Add own font for chyron
Alters Current Speakery Chyron, optionally shows the structure level in a new line (slightly smaler, faint) Font for user name in chyron can be configured Support way more font mime types Adds an own font for chyron (server, client) Extends loads-font service Cleanup countdown-time component from font loading
This commit is contained in:
parent
83efb19562
commit
74b32af293
@ -1,6 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
|
||||
import { ConfigService } from './config.service';
|
||||
import { FontConfigObject } from './media-manage.service';
|
||||
|
||||
/**
|
||||
* Enables the usage of the FontFace constructor
|
||||
@ -10,7 +11,7 @@ declare let FontFace: any;
|
||||
/**
|
||||
* The linter refuses to allow Document['fonts'].
|
||||
* Since Document.fonts is working draft since 2016, typescript
|
||||
* dies not yet support it natively (even though it exists in normal browsers)
|
||||
* does not yet support it natively (even though it exists in normal browsers)
|
||||
*/
|
||||
interface FontDocument extends Document {
|
||||
fonts: any;
|
||||
@ -40,23 +41,33 @@ export class LoadFontService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Observes and loads custom fonts for the projector.
|
||||
* Currently, normal and regular fonts can be considered, since
|
||||
* italic fonts can easily be calculated by the browser.
|
||||
* Observes and loads custom fonts.
|
||||
* Falls back to the normal OSFont when no custom font was set.
|
||||
*/
|
||||
private loadCustomFont(): void {
|
||||
this.configService.get<any>('font_regular').subscribe(regular => {
|
||||
this.configService.get<FontConfigObject>('font_regular').subscribe(regular => {
|
||||
if (regular) {
|
||||
this.setCustomProjectorFont(regular, 400);
|
||||
}
|
||||
});
|
||||
|
||||
this.configService.get<any>('font_bold').subscribe(bold => {
|
||||
this.configService.get<FontConfigObject>('font_bold').subscribe(bold => {
|
||||
if (bold) {
|
||||
this.setCustomProjectorFont(bold, 500);
|
||||
}
|
||||
});
|
||||
|
||||
this.configService.get<FontConfigObject>('font_monospace').subscribe(mono => {
|
||||
if (mono) {
|
||||
this.setNewFontFace('OSFont Monospace', mono.path || mono.default);
|
||||
}
|
||||
});
|
||||
|
||||
this.configService.get<FontConfigObject>('font_chyron_speaker_name').subscribe(chyronFont => {
|
||||
if (chyronFont) {
|
||||
this.setNewFontFace('OSFont ChyronName', chyronFont.path || chyronFont.default);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,20 +77,24 @@ export class LoadFontService {
|
||||
* @param font the font object from the config service
|
||||
* @param weight the desired weight of the font
|
||||
*/
|
||||
private setCustomProjectorFont(font: any, weight: number): void {
|
||||
const path = font.path ? font.path : font.default;
|
||||
private setCustomProjectorFont(font: FontConfigObject, weight: number): void {
|
||||
const path = font.path || font.default;
|
||||
if (!path) {
|
||||
return;
|
||||
}
|
||||
const url = font.path ? `${this.urlPrefix}${path}` : path;
|
||||
const fontFace = new FontFace('customProjectorFont', `url(${url})`, { weight: weight });
|
||||
fontFace
|
||||
const url: string = font.path ? `${this.urlPrefix}${path}` : path;
|
||||
this.setNewFontFace('customProjectorFont', url, weight);
|
||||
}
|
||||
|
||||
private setNewFontFace(fontName: string, fontPath: string, weight: number = 400): void {
|
||||
const customFont = new FontFace(fontName, `url(${fontPath})`, { weight: weight });
|
||||
customFont
|
||||
.load()
|
||||
.then(res => {
|
||||
(document as FontDocument).fonts.add(res);
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Component, Input, OnDestroy } from '@angular/core';
|
||||
|
||||
import { ServertimeService } from 'app/core/core-services/servertime.service';
|
||||
import { ConfigService } from 'app/core/ui-services/config.service';
|
||||
import { FontConfigObject } from 'app/core/ui-services/media-manage.service';
|
||||
|
||||
declare let FontFace: any;
|
||||
|
||||
export interface CountdownData {
|
||||
running: boolean;
|
||||
@ -19,7 +15,7 @@ export interface CountdownData {
|
||||
templateUrl: './countdown-time.component.html',
|
||||
styleUrls: ['./countdown-time.component.scss']
|
||||
})
|
||||
export class CountdownTimeComponent implements OnInit, OnDestroy {
|
||||
export class CountdownTimeComponent implements OnDestroy {
|
||||
/**
|
||||
* The time in seconds to make the countdown orange, is the countdown is below this value.
|
||||
*/
|
||||
@ -96,23 +92,7 @@ export class CountdownTimeComponent implements OnInit, OnDestroy {
|
||||
return this._countdown;
|
||||
}
|
||||
|
||||
public constructor(private servertimeService: ServertimeService, private configService: ConfigService) {}
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.configService.get<FontConfigObject>('font_monospace').subscribe(font => {
|
||||
if (font) {
|
||||
const customFont = new FontFace('OSFont Monospace', `url(${font.path || font.default})`);
|
||||
customFont
|
||||
.load()
|
||||
.then(res => {
|
||||
(document as any).fonts.add(res);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
public constructor(private servertimeService: ServertimeService) {}
|
||||
|
||||
/**
|
||||
* Updates the countdown time and string format it.
|
||||
|
@ -6,7 +6,33 @@ import { Searchable } from 'app/site/base/searchable';
|
||||
import { ViewGroup } from 'app/site/users/models/view-group';
|
||||
|
||||
export const IMAGE_MIMETYPES = ['image/png', 'image/jpeg', 'image/gif'];
|
||||
export const FONT_MIMETYPES = ['font/ttf', 'font/woff', 'application/font-woff', 'application/font-sfnt'];
|
||||
|
||||
export const FONT_MIMETYPES = [
|
||||
/**
|
||||
* Standard fonts by iana May 2021. See:
|
||||
* https://www.iana.org/assignments/media-types/media-types.xhtml#font
|
||||
*/
|
||||
'font/ttf',
|
||||
'font/sfnt',
|
||||
'font/otf',
|
||||
'font/woff',
|
||||
'font/woff2',
|
||||
/**
|
||||
* Non standard types
|
||||
*/
|
||||
/** (IANA: March 2013) (special non standard OTF fonts) */
|
||||
'font/opentype',
|
||||
'application/x-font-opentype',
|
||||
'application/vnd.oasis.opendocument.formula-template',
|
||||
/** (IANA: January 2013) */
|
||||
'application/font-woff',
|
||||
/** (W3C W./E.Draft: May 2014/March 2016) */
|
||||
'application/font-woff2',
|
||||
/** (IANA: March 2013) */
|
||||
'application/font-sfnt',
|
||||
'application/x-font-ttf',
|
||||
'application/x-font-truetype'
|
||||
];
|
||||
export const PDF_MIMETYPES = ['application/pdf'];
|
||||
export const VIDEO_MIMETYPES = [
|
||||
'video/quicktime',
|
||||
|
@ -1,5 +1,6 @@
|
||||
export interface CurrentSpeakerChyronSlideData {
|
||||
current_speaker?: string;
|
||||
current_speaker_name?: string;
|
||||
current_speaker_level?: string;
|
||||
background_color: string;
|
||||
font_color: string;
|
||||
}
|
||||
|
@ -1,8 +1,13 @@
|
||||
<div id="chyron" *ngIf="data" [ngStyle]="{
|
||||
<div
|
||||
id="chyron"
|
||||
*ngIf="data"
|
||||
[ngStyle]="{
|
||||
'background-color': data.data.background_color,
|
||||
color: data.data.font_color}">
|
||||
|
||||
color: data.data.font_color
|
||||
}"
|
||||
>
|
||||
<span id="inner">
|
||||
<b>{{ data.data.current_speaker }}</b>
|
||||
<div id="inner-name">{{ data.data.current_speaker_name }}</div>
|
||||
<div id="inner-level">{{ data.data.current_speaker_level }}</div>
|
||||
</span>
|
||||
</div>
|
||||
|
@ -1,19 +1,33 @@
|
||||
@import '~assets/styles/fonts.scss';
|
||||
|
||||
#chyron {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
left: 50px;
|
||||
bottom: 20px;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
height: 80px;
|
||||
font-size: 32px;
|
||||
text-align: center;
|
||||
line-height: 1.1;
|
||||
display: table;
|
||||
text-align: left;
|
||||
line-height: 1;
|
||||
opacity: 0.8;
|
||||
|
||||
#inner {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding-left: 20px;
|
||||
padding-left: 18px;
|
||||
padding-right: 20px;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
height: 60px;
|
||||
display: table-cell;
|
||||
|
||||
#inner-name {
|
||||
font-family: $font-chyronname;
|
||||
}
|
||||
|
||||
#inner-level {
|
||||
margin-top: 5px;
|
||||
font-size: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,3 +25,8 @@ $font-weight-condensed-regular: 400;
|
||||
$font-monospace: 'OSFont Monospace';
|
||||
$font-monospace-src: url('../fonts/roboto-condensed-bold.woff') format('woff');
|
||||
$font-weight-monospace: 400;
|
||||
|
||||
/** Special Chyron Name Font */
|
||||
$font-chyronname: 'OSFont ChyronName';
|
||||
$font-chyronname-src: url('../fonts/fira-sans-latin-400.woff') format('woff');
|
||||
$font-weight-chyronname: 400;
|
||||
|
@ -53,3 +53,12 @@
|
||||
font-weight: $font-weight-monospace;
|
||||
src: $font-monospace-src;
|
||||
}
|
||||
|
||||
/** Chyron Name */
|
||||
@font-face {
|
||||
font-family: $font-chyronname;
|
||||
font-style: normal;
|
||||
font-display: swap;
|
||||
font-weight: $font-weight-chyronname;
|
||||
src: $font-chyronname-src;
|
||||
}
|
||||
|
@ -478,6 +478,7 @@ def get_config_variables():
|
||||
"font_bold",
|
||||
"font_bold_italic",
|
||||
"font_monospace",
|
||||
"font_chyron_speaker_name",
|
||||
],
|
||||
weight=320,
|
||||
group="Font",
|
||||
@ -549,6 +550,19 @@ def get_config_variables():
|
||||
hidden=True,
|
||||
)
|
||||
|
||||
yield ConfigVariable(
|
||||
name="font_chyron_speaker_name",
|
||||
default_value={
|
||||
"display_name": "Font for speaker name (chyron)",
|
||||
"default": "assets/fonts/fira-sans-latin-400.woff",
|
||||
"path": "",
|
||||
},
|
||||
input_type="static",
|
||||
weight=321,
|
||||
group="Font",
|
||||
hidden=True,
|
||||
)
|
||||
|
||||
# Custom translations
|
||||
yield ConfigVariable(
|
||||
name="translations",
|
||||
|
Loading…
Reference in New Issue
Block a user