Merge pull request #6063 from tsiegleauq/cryon-font
Add own font for chyron
This commit is contained in:
commit
2eda8fea22
@ -1,6 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
import { ConfigService } from './config.service';
|
import { ConfigService } from './config.service';
|
||||||
|
import { FontConfigObject } from './media-manage.service';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables the usage of the FontFace constructor
|
* Enables the usage of the FontFace constructor
|
||||||
@ -10,7 +11,7 @@ declare let FontFace: any;
|
|||||||
/**
|
/**
|
||||||
* The linter refuses to allow Document['fonts'].
|
* The linter refuses to allow Document['fonts'].
|
||||||
* Since Document.fonts is working draft since 2016, typescript
|
* 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 {
|
interface FontDocument extends Document {
|
||||||
fonts: any;
|
fonts: any;
|
||||||
@ -40,23 +41,33 @@ export class LoadFontService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Observes and loads custom fonts for the projector.
|
* Observes and loads custom fonts.
|
||||||
* Currently, normal and regular fonts can be considered, since
|
|
||||||
* italic fonts can easily be calculated by the browser.
|
|
||||||
* Falls back to the normal OSFont when no custom font was set.
|
* Falls back to the normal OSFont when no custom font was set.
|
||||||
*/
|
*/
|
||||||
private loadCustomFont(): void {
|
private loadCustomFont(): void {
|
||||||
this.configService.get<any>('font_regular').subscribe(regular => {
|
this.configService.get<FontConfigObject>('font_regular').subscribe(regular => {
|
||||||
if (regular) {
|
if (regular) {
|
||||||
this.setCustomProjectorFont(regular, 400);
|
this.setCustomProjectorFont(regular, 400);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.configService.get<any>('font_bold').subscribe(bold => {
|
this.configService.get<FontConfigObject>('font_bold').subscribe(bold => {
|
||||||
if (bold) {
|
if (bold) {
|
||||||
this.setCustomProjectorFont(bold, 500);
|
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 font the font object from the config service
|
||||||
* @param weight the desired weight of the font
|
* @param weight the desired weight of the font
|
||||||
*/
|
*/
|
||||||
private setCustomProjectorFont(font: any, weight: number): void {
|
private setCustomProjectorFont(font: FontConfigObject, weight: number): void {
|
||||||
const path = font.path ? font.path : font.default;
|
const path = font.path || font.default;
|
||||||
if (!path) {
|
if (!path) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const url = font.path ? `${this.urlPrefix}${path}` : path;
|
const url: string = font.path ? `${this.urlPrefix}${path}` : path;
|
||||||
const fontFace = new FontFace('customProjectorFont', `url(${url})`, { weight: weight });
|
this.setNewFontFace('customProjectorFont', url, weight);
|
||||||
fontFace
|
}
|
||||||
|
|
||||||
|
private setNewFontFace(fontName: string, fontPath: string, weight: number = 400): void {
|
||||||
|
const customFont = new FontFace(fontName, `url(${fontPath})`, { weight: weight });
|
||||||
|
customFont
|
||||||
.load()
|
.load()
|
||||||
.then(res => {
|
.then(res => {
|
||||||
(document as FontDocument).fonts.add(res);
|
(document as FontDocument).fonts.add(res);
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.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 { 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 {
|
export interface CountdownData {
|
||||||
running: boolean;
|
running: boolean;
|
||||||
@ -19,7 +15,7 @@ export interface CountdownData {
|
|||||||
templateUrl: './countdown-time.component.html',
|
templateUrl: './countdown-time.component.html',
|
||||||
styleUrls: ['./countdown-time.component.scss']
|
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.
|
* 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;
|
return this._countdown;
|
||||||
}
|
}
|
||||||
|
|
||||||
public constructor(private servertimeService: ServertimeService, private configService: ConfigService) {}
|
public constructor(private servertimeService: ServertimeService) {}
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the countdown time and string format it.
|
* 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';
|
import { ViewGroup } from 'app/site/users/models/view-group';
|
||||||
|
|
||||||
export const IMAGE_MIMETYPES = ['image/png', 'image/jpeg', 'image/gif'];
|
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 PDF_MIMETYPES = ['application/pdf'];
|
||||||
export const VIDEO_MIMETYPES = [
|
export const VIDEO_MIMETYPES = [
|
||||||
'video/quicktime',
|
'video/quicktime',
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
export interface CurrentSpeakerChyronSlideData {
|
export interface CurrentSpeakerChyronSlideData {
|
||||||
current_speaker?: string;
|
current_speaker_name?: string;
|
||||||
|
current_speaker_level?: string;
|
||||||
background_color: string;
|
background_color: string;
|
||||||
font_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,
|
'background-color': data.data.background_color,
|
||||||
color: data.data.font_color}">
|
color: data.data.font_color
|
||||||
|
}"
|
||||||
|
>
|
||||||
<span id="inner">
|
<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>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,19 +1,33 @@
|
|||||||
|
@import '~assets/styles/fonts.scss';
|
||||||
|
|
||||||
#chyron {
|
#chyron {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 50px;
|
||||||
bottom: 0;
|
bottom: 20px;
|
||||||
|
right: 0;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
width: 100%;
|
height: 80px;
|
||||||
height: 100px;
|
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
text-align: center;
|
text-align: left;
|
||||||
line-height: 1.1;
|
line-height: 1;
|
||||||
display: table;
|
opacity: 0.8;
|
||||||
|
|
||||||
#inner {
|
#inner {
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
padding-left: 20px;
|
padding-left: 18px;
|
||||||
padding-right: 20px;
|
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: 'OSFont Monospace';
|
||||||
$font-monospace-src: url('../fonts/roboto-condensed-bold.woff') format('woff');
|
$font-monospace-src: url('../fonts/roboto-condensed-bold.woff') format('woff');
|
||||||
$font-weight-monospace: 400;
|
$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;
|
font-weight: $font-weight-monospace;
|
||||||
src: $font-monospace-src;
|
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",
|
||||||
"font_bold_italic",
|
"font_bold_italic",
|
||||||
"font_monospace",
|
"font_monospace",
|
||||||
|
"font_chyron_speaker_name",
|
||||||
],
|
],
|
||||||
weight=320,
|
weight=320,
|
||||||
group="Font",
|
group="Font",
|
||||||
@ -549,6 +550,19 @@ def get_config_variables():
|
|||||||
hidden=True,
|
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
|
# Custom translations
|
||||||
yield ConfigVariable(
|
yield ConfigVariable(
|
||||||
name="translations",
|
name="translations",
|
||||||
|
Loading…
Reference in New Issue
Block a user