Skip to content

Commit

Permalink
loading animation
Browse files Browse the repository at this point in the history
  • Loading branch information
alesmaye committed Aug 30, 2024
1 parent 1b46c83 commit f375aac
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/scss/skin-super-modern/_skin.scss
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
@import 'components/subtitlesettingspaneltogglebutton';
@import 'components/touch-control-overlay';
@import 'components/smallcenteredplaybacktogglebutton';
@import 'components/loadingicon';
@import 'skin-ads';
@import 'skin-cast-receiver';
@import 'skin-modern-smallscreen';
Expand Down
57 changes: 57 additions & 0 deletions src/scss/skin-super-modern/components/_loadingicon.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@import '../variables';
@import '../mixins';

@keyframes #{$prefix}-rotating {
from {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}

.#{$prefix}-ui-loading-icon {
@extend %ui-container;

cursor: default;
height: 2.5em;
outline: none;
overflow: hidden; // hide overflow from scale animation
width: 2.5em;
display: block;


background-position: center;
background-repeat: no-repeat;
background-size: 4em;
background: url('../../assets/skin-super-modern/images/loader.svg');

&.#{prefix}-show {
display: block;
}

.#{prefix}-container-wraper {
height: 100%;
}

* > &.#{prefix}-ui-loading-icon-image {
background-position: center;
background-repeat: no-repeat;
background-size: 4em;
height: 100%;
width: 100%;
background: url('../../assets/skin-super-modern/images/loader.svg');

&.#{$prefix}-loading {
animation: #{$prefix}-rotating 2s linear infinite;
}
}
}
105 changes: 105 additions & 0 deletions src/ts/components/loadingicon.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { PlayerAPI } from 'bitmovin-player';
import { UIInstanceManager } from '../uimanager';
import {Component, ComponentConfig} from './component';
import { Container, ContainerConfig } from './container';
import { Timeout } from '../timeout';
import { EventDispatcher, NoArgs } from '../eventdispatcher';

export interface LoadingIconConfig extends ContainerConfig {
/**
* Delay in milliseconds after which the buffering overlay will be displayed. Useful to bypass short stalls without
* displaying the overlay. Set to 0 to display the overlay instantly.
* Default: 1000ms (1 second)
*/
showDelayMs?: number;
}

export class LoadingIcon extends Container<LoadingIconConfig> {
private loader: Component<ComponentConfig>;
private isLoading: boolean = false;

private loadingEvents = {
loadingStartEvent: new EventDispatcher<LoadingIcon, NoArgs>(),
loadingEndEvent: new EventDispatcher<LoadingIcon, NoArgs>(),
}

constructor(config: LoadingIconConfig = {}) {
super(config);

this.loader = new Component<ComponentConfig>({ tag: 'div', cssClass: 'ui-loading-icon-image', role: 'img' });

this.config = this.mergeConfig(config, {
cssClass: 'ui-loading-icon',
role: 'icon',
components: [this.loader],
showDelayMs: 1000,
}, this.config);
}

configure(player: PlayerAPI, uimanager: UIInstanceManager): void {
super.configure(player, uimanager);

let config = this.getConfig();

let overlayShowTimeout = new Timeout(config.showDelayMs, () => {
this.startLoader();
});

let showOverlay = () => {
overlayShowTimeout.start();
};

let hideOverlay = () => {
overlayShowTimeout.clear();
this.stopLoader();
};

player.on(player.exports.PlayerEvent.StallStarted, showOverlay);
player.on(player.exports.PlayerEvent.StallEnded, hideOverlay);
player.on(player.exports.PlayerEvent.Play, showOverlay);
player.on(player.exports.PlayerEvent.Playing, hideOverlay);
player.on(player.exports.PlayerEvent.Paused, hideOverlay);
player.on(player.exports.PlayerEvent.Seek, showOverlay);
player.on(player.exports.PlayerEvent.Seeked, hideOverlay);
player.on(player.exports.PlayerEvent.TimeShift, showOverlay);
player.on(player.exports.PlayerEvent.TimeShifted, hideOverlay);
player.on(player.exports.PlayerEvent.SourceUnloaded, hideOverlay);

// Show overlay if player is already stalled at init
if (player.isStalled()) {
this.startLoader();
}
}

private startLoader(): void {
if (!this.isLoading) {
this.isLoading = true;
this.loader.getDomElement().addClass(this.prefixCss('loading'));
this.onLoadingStartEvent();
}
}

private stopLoader(): void {
if (this.isLoading) {
this.isLoading = false;
this.loader.getDomElement().removeClass(this.prefixCss('loading'));
this.onLoadingEndEvent();
}
}

public onLoadingStartEvent(): void {
this.loadingEvents.loadingStartEvent.dispatch(this);
}

public onLoadingEndEvent(): void {
this.loadingEvents.loadingEndEvent.dispatch(this);
}

get loadingStartEvent(): EventDispatcher<LoadingIcon, NoArgs> {
return this.loadingEvents.loadingStartEvent;
}

get loadingEndEvent(): EventDispatcher<LoadingIcon, NoArgs> {
return this.loadingEvents.loadingEndEvent;
}
}
6 changes: 5 additions & 1 deletion src/ts/components/touchcontroloverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Timeout } from '../timeout';
import { HTMLElementWithComponent } from '../dom';
import { Label, LabelConfig } from './label';
import { i18n } from '../localization/i18n';
import { LoadingIcon } from './loadingicon';

export interface TouchControlOverlayConfig extends ContainerConfig {
/**
Expand Down Expand Up @@ -59,6 +60,7 @@ export class TouchControlOverlay extends Container<TouchControlOverlayConfig> {
};

private playbackToggleButton: SmallCenteredPlaybackToggleButton;
private loadingIcon: LoadingIcon;
private seekForwardLabel: Label<LabelConfig>;
private seekBackwardLabel: Label<LabelConfig>;

Expand All @@ -75,6 +77,8 @@ export class TouchControlOverlay extends Container<TouchControlOverlayConfig> {
enterFullscreenOnInitialPlayback: Boolean(config.enterFullscreenOnInitialPlayback),
});

this.loadingIcon = new LoadingIcon();

this.seekForwardLabel = new Label({text: '', for: this.getConfig().id, cssClass: 'seek-forward-label', hidden: true});
this.seekBackwardLabel = new Label({text: '', for: this.getConfig().id, cssClass: 'seek-backward-label', hidden: true});

Expand All @@ -83,7 +87,7 @@ export class TouchControlOverlay extends Container<TouchControlOverlayConfig> {
acceptsTouchWithUiHidden: true,
seekTime: 10,
seekDoubleTapMargin: 15,
components: [this.playbackToggleButton, this.seekForwardLabel, this.seekBackwardLabel],
components: [this.loadingIcon, this.seekForwardLabel, this.seekBackwardLabel],
}, this.config);
}

Expand Down

0 comments on commit f375aac

Please sign in to comment.