258 lines
6.9 KiB
TypeScript
258 lines
6.9 KiB
TypeScript
![]() |
import { TimePin } from "../../../animation/TimePin";
|
||
|
import { LinearGradient } from "../../../colors/Gradient";
|
||
|
import { HSLColor } from "../../../colors/HSLColor";
|
||
|
import { DateHelper } from "../../../date/DateHelper";
|
||
|
import { DateMath } from "../../../date/DateMath";
|
||
|
import { TimestampMessage } from "../../../messages/TimestampMessage";
|
||
|
import { RegExpUtility } from "../../../text/RegExpUtitlity";
|
||
|
import { ClassFlag } from "../../ClassFlag";
|
||
|
import { DOMHitTest } from "../../DOMHitTest";
|
||
|
import { DOMOrientation } from "../../DOMOrientation";
|
||
|
import { ElementAttribute } from "../../ElementAttribute";
|
||
|
import { ElementType } from "../../ElementType";
|
||
|
import { OnClick, OnMouseEnter, OnMouseMove, OnPause, OnPlay, OnTimeUpdate, OnTouchDrag, OnTouchEnd, OnTouchStart } from "../../EventListeners";
|
||
|
import { Fullscreen } from "../../Fullscreen";
|
||
|
import { Insight } from "../../Insight";
|
||
|
|
||
|
export class MediaGallery
|
||
|
{
|
||
|
static videoElements:HTMLElement[];
|
||
|
static activeVideoElement:HTMLElement;
|
||
|
static attachedGlobalListeners = false;
|
||
|
static insight:Insight;
|
||
|
|
||
|
static readonly mediaVideo = new ElementType( "media-video" );
|
||
|
static readonly mediaImage = new ElementType( "media-image" );
|
||
|
static readonly activeFlag = new ClassFlag( "active-video" );
|
||
|
static readonly itemIndex = new ElementAttribute( "item-index" );
|
||
|
static readonly container = new ElementType ( "media-container" );
|
||
|
static readonly showPlayButton = new ClassFlag( "show-play-button" );
|
||
|
|
||
|
static readonly fullScreenButton = new ElementType( "fullscreen-button" );
|
||
|
static readonly progressIndicator = new ElementType( "progress-indicator" );
|
||
|
|
||
|
static applyOnDocument( insight:Insight )
|
||
|
{
|
||
|
this.insight = insight;
|
||
|
this.attachGlobalListener();
|
||
|
|
||
|
MediaGallery.videoElements = MediaGallery.mediaVideo.queryAll( document.body ) as HTMLElement[];
|
||
|
|
||
|
MediaGallery.videoElements.forEach( v => this.applyOnVideoElement( v ) );
|
||
|
}
|
||
|
|
||
|
static attachGlobalListener()
|
||
|
{
|
||
|
if ( MediaGallery.attachedGlobalListeners )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
MediaGallery.attachedGlobalListeners = true;
|
||
|
|
||
|
// OnMouseMove.add(
|
||
|
// document.body,
|
||
|
// ( e )=>
|
||
|
// {
|
||
|
|
||
|
// if ( DOMOrientation.isPortrait )
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// if ( ! MediaGallery.activeVideoElement )
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// let isOver = DOMHitTest.isPointerOver( e, MediaGallery.activeVideoElement );
|
||
|
|
||
|
// if ( isOver )
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// MediaGallery.updateActiveVideo( null );
|
||
|
|
||
|
// }
|
||
|
// )
|
||
|
}
|
||
|
|
||
|
static applyOnVideoElement( element:Element )
|
||
|
{
|
||
|
let videoElement = ElementType.video.query( element );
|
||
|
let fs = MediaGallery.fullScreenButton.query( element );
|
||
|
let pi = MediaGallery.progressIndicator.query( element ) as HTMLElement;
|
||
|
|
||
|
OnClick.add( pi,
|
||
|
( e )=>
|
||
|
{
|
||
|
let relative = DOMHitTest.getNormalizedPointerPosition( e, pi );
|
||
|
let position = Math.round( videoElement.duration * relative.x );
|
||
|
videoElement.currentTime = position;
|
||
|
|
||
|
e.preventDefault();
|
||
|
e.stopImmediatePropagation();
|
||
|
e.stopPropagation();
|
||
|
}
|
||
|
);
|
||
|
|
||
|
let updateVideoTimeCode = ( text:string = null )=>
|
||
|
{
|
||
|
let textValue = text != null ? text : ( DateMath.formatToMinutesAndSeconds( videoElement.currentTime ) + " / " +
|
||
|
DateMath.formatToMinutesAndSeconds( videoElement.duration ) );
|
||
|
|
||
|
pi.innerHTML = `<span class="label">${textValue}</span>`;
|
||
|
let percent = text != null ? 0 : (videoElement.currentTime / videoElement.duration) * 100;
|
||
|
let leftColor = new HSLColor( 0, 0, 100, 0.3 );
|
||
|
let rightColor = new HSLColor( 0, 0, 100, 0.1 );
|
||
|
|
||
|
let linearBG = LinearGradient.createHorizontal( leftColor, rightColor, percent, 1 );
|
||
|
|
||
|
pi.style.background = linearBG + ", hsl(0,0%,0%,0.3)";
|
||
|
};
|
||
|
|
||
|
OnTimeUpdate.add( videoElement, () => { updateVideoTimeCode(); } );
|
||
|
|
||
|
|
||
|
OnClick.add( fs as HTMLElement,
|
||
|
()=>
|
||
|
{
|
||
|
|
||
|
Fullscreen.toggleFullscreen( element as HTMLElement, "auto" );
|
||
|
|
||
|
}
|
||
|
);
|
||
|
|
||
|
updateVideoTimeCode( "--:--" );
|
||
|
|
||
|
// OnMouseEnter.add( element as HTMLElement,
|
||
|
// ()=>
|
||
|
// {
|
||
|
// if ( DOMOrientation.isPortrait )
|
||
|
// {
|
||
|
// return;
|
||
|
// }
|
||
|
|
||
|
// MediaGallery.updateActiveVideo( element );
|
||
|
// }
|
||
|
// );
|
||
|
|
||
|
MediaGallery.showPlayButton.setAs( element, true );
|
||
|
|
||
|
OnClick.add( element as HTMLElement,
|
||
|
( me ) =>
|
||
|
{
|
||
|
if ( DOMOrientation.isPortrait )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( videoElement.paused )
|
||
|
{
|
||
|
this.updateActiveVideo( element );
|
||
|
MediaGallery.showPlayButton.setAs( element, false );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
videoElement.pause();
|
||
|
MediaGallery.showPlayButton.setAs( element, true );
|
||
|
}
|
||
|
}
|
||
|
);
|
||
|
|
||
|
OnTouchStart.add( element as HTMLElement,
|
||
|
( touchStartEvent )=>
|
||
|
{
|
||
|
if ( touchStartEvent.target == pi || DOMOrientation.isLandscape )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
console.log( touchStartEvent );
|
||
|
let startPosition = DOMHitTest.getRelativeWindowPosition( touchStartEvent );
|
||
|
let moved = false;
|
||
|
let treshold = 0.1;
|
||
|
|
||
|
let onDrag = ( dragEvent:TouchEvent )=>
|
||
|
{
|
||
|
if ( moved )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let dragPosition = DOMHitTest.getRelativeWindowPosition( dragEvent );
|
||
|
moved = dragPosition.sub( startPosition ).length > treshold;
|
||
|
}
|
||
|
|
||
|
let onEnd = ()=>
|
||
|
{
|
||
|
|
||
|
OnTouchEnd.remove( element as HTMLElement, onEnd );
|
||
|
OnTouchDrag.remove( element as HTMLElement, onDrag );
|
||
|
|
||
|
if ( moved )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
let videoElement = ElementType.video.query( element );
|
||
|
|
||
|
if ( videoElement.paused )
|
||
|
{
|
||
|
this.updateActiveVideo( element );
|
||
|
MediaGallery.showPlayButton.setAs( element, false );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
videoElement.pause();
|
||
|
MediaGallery.showPlayButton.setAs( element, true );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
OnTouchEnd.add( element as HTMLElement, onEnd );
|
||
|
OnTouchDrag.add( element as HTMLElement, onDrag );
|
||
|
}
|
||
|
)
|
||
|
|
||
|
}
|
||
|
|
||
|
static updateActiveVideo( e:Element )
|
||
|
{
|
||
|
MediaGallery.activeVideoElement = e as HTMLElement;
|
||
|
|
||
|
this.videoElements.forEach(
|
||
|
( v )=>
|
||
|
{
|
||
|
let isActive = MediaGallery.activeVideoElement === v;
|
||
|
this.activeFlag.setAs( v, isActive );
|
||
|
|
||
|
let video = ElementType.video.query( v );
|
||
|
|
||
|
if ( ! video )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( video.paused === ! isActive )
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ( isActive )
|
||
|
{
|
||
|
// video.currentTime = 0;
|
||
|
video.play();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
video.pause();
|
||
|
MediaGallery.showPlayButton.setAs( v, true );
|
||
|
}
|
||
|
|
||
|
}
|
||
|
)
|
||
|
}
|
||
|
}
|