Fix video loading

This commit is contained in:
schmelczerandras 2020-12-04 22:38:57 +01:00
parent a39c8c9350
commit 4b11edfbd9
9 changed files with 80 additions and 16 deletions

View file

@ -1,4 +1,5 @@
import adAstraPoster from '../static/media/ad_astra.jpg?format=jpg'; import adAstraWebP from '../static/media/ad_astra.jpg?format=webp';
import adAstraJpeg from '../static/media/ad_astra.jpg?format=jpg';
import adAstraMp4 from '../static/media/mp4/ad_astra.mp4'; import adAstraMp4 from '../static/media/mp4/ad_astra.mp4';
import adAstraWebM from '../static/media/webm/ad_astra.webm'; import adAstraWebM from '../static/media/webm/ad_astra.webm';
@ -9,7 +10,8 @@ export const adAstraTimelineElement = {
title: `Gaming on an ATtiny85`, title: `Gaming on an ATtiny85`,
date: `2020 Spring`, date: `2020 Spring`,
figure: new Video({ figure: new Video({
poster: adAstraPoster, posterWebP: adAstraWebP,
posterJpeg: adAstraJpeg,
mp4: adAstraMp4, mp4: adAstraMp4,
webm: adAstraWebM, webm: adAstraWebM,
}), }),

View file

@ -1,4 +1,5 @@
import citySimulationPoster from '../static/media/simulation.jpg?format=jpg'; import citySimulationPosterWebP from '../static/media/simulation.jpg?format=webp';
import citySimulationPosterJpeg from '../static/media/simulation.jpg?format=jpg';
import citySimulationMp4 from '../static/media/mp4/simulation.mp4'; import citySimulationMp4 from '../static/media/mp4/simulation.mp4';
import citySimulationWebM from '../static/media/webm/simulation.webm'; import citySimulationWebM from '../static/media/webm/simulation.webm';
@ -8,7 +9,8 @@ export const citySimulationTimelineElement = {
date: `2018 July - August`, date: `2018 July - August`,
title: `City simulation`, title: `City simulation`,
figure: new Video({ figure: new Video({
poster: citySimulationPoster, posterWebP: citySimulationPosterWebP,
posterJpeg: citySimulationPosterJpeg,
mp4: citySimulationMp4, mp4: citySimulationMp4,
webm: citySimulationWebM, webm: citySimulationWebM,
}), }),

View file

@ -1,6 +1,7 @@
import forexPosterWebP from '../static/media/forex.jpg?format=webp';
import forexPosterJpeg from '../static/media/forex.jpg?format=jpg';
import forexMp4 from '../static/media/mp4/forex.mp4'; import forexMp4 from '../static/media/mp4/forex.mp4';
import forexWebM from '../static/media/webm/forex.webm'; import forexWebM from '../static/media/webm/forex.webm';
import forexPoster from '../static/media/forex.jpg';
import { Video } from '../page/basics/video/video'; import { Video } from '../page/basics/video/video';
@ -8,7 +9,8 @@ export const forexTimelineElement = {
title: `Predicting foreign exchange rates`, title: `Predicting foreign exchange rates`,
date: `2019 Autumn`, date: `2019 Autumn`,
figure: new Video({ figure: new Video({
poster: forexPoster, posterWebP: forexPosterWebP,
posterJpeg: forexPosterJpeg,
mp4: forexMp4, mp4: forexMp4,
webm: forexWebM, webm: forexWebM,
invertButton: true, invertButton: true,

View file

@ -1,4 +1,5 @@
import ledPoster from '../static/media/led.jpg?format=jpg'; import ledPosterWebP from '../static/media/led.jpg?format=webp';
import ledPosterJpeg from '../static/media/led.jpg?format=jpg';
import ledMp4 from '../static/media/mp4/led.mp4'; import ledMp4 from '../static/media/mp4/led.mp4';
import ledWebM from '../static/media/webm/led.webm'; import ledWebM from '../static/media/webm/led.webm';
@ -8,7 +9,8 @@ export const ledsTimelineElement = {
date: `2016 spring`, date: `2016 spring`,
title: `Lights synchronised to music`, title: `Lights synchronised to music`,
figure: new Video({ figure: new Video({
poster: ledPoster, posterWebP: ledPosterWebP,
posterJpeg: ledPosterJpeg,
mp4: ledMp4, mp4: ledMp4,
webm: ledWebM, webm: ledWebM,
}), }),

View file

@ -1,4 +1,5 @@
import platformJpeg from '../static/media/platform.png?format=jpg'; import platformPosterWebP from '../static/media/platform.png?format=webp';
import platformPosterJpeg from '../static/media/platform.png?format=jpg';
import platformMp4 from '../static/media/mp4/platform.mp4'; import platformMp4 from '../static/media/mp4/platform.mp4';
import platformWebM from '../static/media/webm/platform.webm'; import platformWebM from '../static/media/webm/platform.webm';
@ -8,7 +9,8 @@ export const platformGameTimelineElement = {
date: `2017 autumn`, date: `2017 autumn`,
title: `Platform game`, title: `Platform game`,
figure: new Video({ figure: new Video({
poster: platformJpeg, posterWebP: platformPosterWebP,
posterJpeg: platformPosterJpeg,
mp4: platformMp4, mp4: platformMp4,
webm: platformWebM, webm: platformWebM,
}), }),

View file

@ -5,7 +5,7 @@ import { html } from '../../../types/html';
export const generate = ({ alt }: { alt: string }): html => ` export const generate = ({ alt }: { alt: string }): html => `
<div class="preview"> <div class="preview">
<img image-viewer-ignore class="poster" /> <img image-viewer-ignore class="poster"/>
<div class="overlay"> <div class="overlay">
<div class="loading">${loading}</div> <div class="loading">${loading}</div>
<iframe title="${alt}" allowfullscreen loading="lazy"></iframe> <iframe title="${alt}" allowfullscreen loading="lazy"></iframe>

View file

@ -1,14 +1,23 @@
import './video.scss'; import './video.scss';
import loading from '../../../static/icons/loading.svg';
import { html } from '../../../types/html'; import { html } from '../../../types/html';
import play from '../../../static/icons/play-button.svg'; import play from '../../../static/icons/play-button.svg';
import { VideoParameters } from './video'; import { VideoParameters } from './video';
import { last } from '../../../helper/last';
export const generate = ({ webm, mp4, poster, invertButton }: VideoParameters): html => ` export const generate = ({
<div class="figure-container" style="padding-top:${(poster.height / poster.width) * webm,
mp4,
posterJpeg,
invertButton,
}: VideoParameters): html => `
<div class="figure-container video-container" style="padding-top:${(posterJpeg.height /
posterJpeg.width) *
100}%"> 100}%">
<video playsinline preload="none" poster="${last(poster.images)!.path}"> <img image-viewer-ignore class="poster"/>
<div class="loading">${loading}</div>
<video playsinline preload="none">
<source src="${webm}" type="video/webm"/> <source src="${webm}" type="video/webm"/>
<source src="${mp4}" type="video/mp4"/> <source src="${mp4}" type="video/mp4"/>
</video> </video>

View file

@ -1 +1,35 @@
@use '../../../style/mixins' as *; @use '../../../style/mixins' as *;
.video-container {
& > *:not(.start-button) {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.loading {
@include square(var(--large-icon-size));
@include absolute-center;
visibility: hidden;
& > svg {
@include square(var(--large-icon-size));
@include absolute-center;
}
}
video {
z-index: 1;
visibility: hidden;
}
&.loaded .loading {
visibility: visible;
}
&.fully-loaded video {
visibility: visible;
}
}

View file

@ -1,13 +1,15 @@
import { PageElement } from '../../page-element'; import { PageElement } from '../../page-element';
import { createElement } from '../../../helper/create-element'; import { createElement } from '../../../helper/create-element';
import { generate } from './video.html'; import { generate } from './video.html';
import { Image } from '../image/image';
import { url } from '../../../types/url'; import { url } from '../../../types/url';
import { ResponsiveImage } from '../../../types/responsive-image'; import { ResponsiveImage } from '../../../types/responsive-image';
export interface VideoParameters { export interface VideoParameters {
mp4: url; mp4: url;
webm: url; webm: url;
poster: ResponsiveImage; posterWebP: ResponsiveImage;
posterJpeg: ResponsiveImage;
invertButton?: boolean; invertButton?: boolean;
} }
@ -16,8 +18,16 @@ export class Video extends PageElement {
public constructor(options: VideoParameters) { public constructor(options: VideoParameters) {
super(createElement(generate(options))); super(createElement(generate(options)));
this.attachElementByReplacing(
'.poster',
new Image(options.posterWebP, options.posterJpeg, `thumbnail for the video`, false)
);
this.video = this.query('video') as HTMLVideoElement; this.video = this.query('video') as HTMLVideoElement;
this.video.addEventListener('click', this.startVideo.bind(this)); this.video.addEventListener('click', this.startVideo.bind(this));
this.video.addEventListener('play', () =>
this.htmlRoot.classList.add('fully-loaded')
);
this.query('.start-button').addEventListener('click', this.startVideo.bind(this)); this.query('.start-button').addEventListener('click', this.startVideo.bind(this));
this.video.addEventListener('pause', this.stopVideo.bind(this)); this.video.addEventListener('pause', this.stopVideo.bind(this));
} }
@ -25,6 +35,7 @@ export class Video extends PageElement {
private startVideo(e: Event) { private startVideo(e: Event) {
if (this.video.paused) { if (this.video.paused) {
this.query('.start-button').style.visibility = 'hidden'; this.query('.start-button').style.visibility = 'hidden';
this.htmlRoot.classList.add('loaded');
this.video.play(); this.video.play();
this.video.controls = true; this.video.controls = true;
e.preventDefault(); e.preventDefault();