library-ts/browser/dom/page-features/components/MediaGallerySelector.ts

234 lines
6.1 KiB
TypeScript

import { Vector2 } from "../../../geometry/Vector2";
import { MathX } from "../../../math/MathX";
import { ClassFlag } from "../../ClassFlag";
import { DOMHitTest } from "../../DOMHitTest";
import { DOMOrientation } from "../../DOMOrientation";
import { ElementAttribute } from "../../ElementAttribute";
import { ElementType } from "../../ElementType";
import { OnClick, OnDrag } from "../../EventListeners";
import { MediaGallery } from "./MediaGallery";
export class OffsetElement extends HTMLElement
{
_position:Vector2;
static applyOffset( e:OffsetElement )
{
e.style.transform = `translate(${e._position.x}px, ${e._position.y}px)`;
}
}
export class MediaGallerySelector
{
static type = new ElementType( "media-gallery-selector" );
static target = new ElementAttribute( "target" );
static leftArrow = new ElementAttribute( "left-arrow" );
static rightArrow = new ElementAttribute( "right-arrow" );
static state = new ElementAttribute( "state" );
static active = new ClassFlag( "active" );
static index = new ElementAttribute( "index" );
static applyOnDocument()
{
MediaGallerySelector.type.forEachInDoc( e => this.applyOnElement( e ) );
}
static applyOnElement( e:Element )
{
let target = MediaGallerySelector.target.queryValueInDoc( e );
let items = MediaGallery.itemIndex.queryAll( target );
items.sort(
( a:any, b:any )=>
{
let indexA = MediaGallery.itemIndex.asNumberFrom( a );
let indexB = MediaGallery.itemIndex.asNumberFrom( b );
return indexB - indexA ;
}
);
let offsetElement = target as OffsetElement;
offsetElement._position = new Vector2();
let startPosition = new Vector2();
let direction = 0;
OnDrag.add( offsetElement,
( ev )=>
{
if ( DOMOrientation.isLandscape )
{
return;
}
let position = DOMHitTest.getPointerPosition( ev);
if ( /start|down/.test( ev.type ) )
{
startPosition = position.clone();
direction = 0;
}
else if ( /end|up/.test( ev.type ) )
{
if ( direction == 1 )
{
let index = MediaGallerySelector.index.asNumberFrom( e );
let indexOffset = ( offsetElement._position.x > 0 ? -1 : 1 );
console.log( "offset:", offsetElement._position.x, "index offset:", indexOffset );
index += indexOffset;
let videos = MediaGallery.mediaVideo.queryAll( target );
let images = MediaGallery.mediaImage.queryAll( target );
let num = videos.length + images.length;
index = MathX.clamp( index, 0, num - 1 );
MediaGallerySelector.index.to( e, index + "" );
MediaGallerySelector.redraw( e );
}
offsetElement._position.set( 0, 0 );
OffsetElement.applyOffset( offsetElement );
}
else
{
let diff = position.clone().sub( startPosition );
if ( direction == 0 && diff.length > 5 )
{
direction = Math.abs( diff.x ) > Math.abs( diff.y ) ? 1 : -1;
}
if ( direction == -1 )
{
offsetElement._position.set( 0, 0 );
OffsetElement.applyOffset( offsetElement );
return;
}
diff.multiply( 0.2 );
offsetElement._position.set( diff.x, diff.y );
offsetElement._position.clampPolar( window.innerWidth / 10, 0 );
OffsetElement.applyOffset( offsetElement );
}
if ( direction > 0 )
{
ev.stopImmediatePropagation();
ev.stopPropagation();
ev.preventDefault();
}
}
);
MediaGallerySelector.leftArrow.forAll( e,
l =>
{
OnClick.add( l as HTMLElement,
()=>
{
console.log( "WHI L" );
let index = MediaGallerySelector.index.asNumberFrom( e );
if ( index == 0 )
{
return;
}
index --;
MediaGallerySelector.index.to( e, index + "" );
MediaGallerySelector.redraw( e );
}
);
}
);
MediaGallerySelector.rightArrow.forAll( e,
r =>
{
OnClick.add( r as HTMLElement,
()=>
{
console.log( "WHI R" );
let index = MediaGallerySelector.index.asNumberFrom( e );
if ( index == ( items.length - 1 ) )
{
return;
}
index ++;
MediaGallerySelector.index.to( e, index + "" );
MediaGallerySelector.redraw( e );
}
);
}
);
MediaGallerySelector.state.forAll( e,
s =>
{
OnClick.add( s as HTMLElement,
()=>
{
let stateIndex = MediaGallerySelector.index.asNumberFrom( s );
console.log( "WHI INDEX", stateIndex );
MediaGallerySelector.index.to( e, stateIndex + "" );
MediaGallerySelector.redraw( e );
}
);
}
);
MediaGallerySelector.redraw( e );
}
static redraw( e:Element )
{
let index = MediaGallerySelector.index.asNumberFrom( e );
let target = MediaGallerySelector.target.queryValueInDoc( e );
let container = MediaGallery.container.query( target ) as HTMLElement;
let offset = index * -103;
let value = `translate3d(${offset}vw,0vw,0vw)`;
container.style.transform = value;
console.log( "current-index", index );
let numElements = 3;
MediaGallerySelector.leftArrow.forAll( e,
l => MediaGallerySelector.active.setAs( l, index > 0 )
);
MediaGallerySelector.rightArrow.forAll( e,
r => MediaGallerySelector.active.setAs( r, index < ( numElements - 1 ))
);
MediaGallerySelector.state.forAll( e,
s =>
{
let stateIndex = MediaGallerySelector.index.asNumberFrom( s );
MediaGallerySelector.active.setAs( s, index == stateIndex );
}
);
}
}