diff options
author | bobzel <zzzman@gmail.com> | 2021-01-27 13:22:01 -0500 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2021-01-27 13:22:01 -0500 |
commit | f43f47662293ddb2cd4d2eb217bc4f01b6d22826 (patch) | |
tree | 490038f886cf644b088f0f7308103e17ad21c3a7 /src | |
parent | 31faf2b0683fc15c040d47425f931531c0d8a0f8 (diff) |
animated expansion of video box timeline.
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/DocumentDecorations.tsx | 2 | ||||
-rw-r--r-- | src/client/views/collections/CollectionStackedTimeline.tsx | 2 | ||||
-rw-r--r-- | src/client/views/nodes/VideoBox.tsx | 32 |
3 files changed, 27 insertions, 9 deletions
diff --git a/src/client/views/DocumentDecorations.tsx b/src/client/views/DocumentDecorations.tsx index 250b93188..54e0a7ac7 100644 --- a/src/client/views/DocumentDecorations.tsx +++ b/src/client/views/DocumentDecorations.tsx @@ -613,7 +613,7 @@ export class DocumentDecorations extends React.Component<{ boundsLeft: number, b }}> {closeIcon} {bounds.r - bounds.x < 100 ? null : titleArea} - {seldoc.props.hideDecorations ? (null) : + {seldoc.props.hideResizeHandles ? (null) : <> {SelectionManager.Views().length !== 1 || seldoc.Document.type === DocumentType.INK ? (null) : <Tooltip key="i" title={<div className="dash-tooltip">{`${seldoc.finalLayoutKey.includes("icon") ? "De" : ""}Iconify Document`}</div>} placement="top"> diff --git a/src/client/views/collections/CollectionStackedTimeline.tsx b/src/client/views/collections/CollectionStackedTimeline.tsx index 54cc86523..4b14c3508 100644 --- a/src/client/views/collections/CollectionStackedTimeline.tsx +++ b/src/client/views/collections/CollectionStackedTimeline.tsx @@ -292,7 +292,7 @@ export class CollectionStackedTimeline extends CollectionSubView<PanZoomDocument onClick={script} onDoubleClick={this.props.Document.autoPlay ? undefined : doublescript} ignoreAutoHeight={false} - hideDecorations={true} + hideResizeHandles={true} bringToFront={emptyFunction} scriptContext={this} /> }; diff --git a/src/client/views/nodes/VideoBox.tsx b/src/client/views/nodes/VideoBox.tsx index 6286b5e26..506ba8c49 100644 --- a/src/client/views/nodes/VideoBox.tsx +++ b/src/client/views/nodes/VideoBox.tsx @@ -55,16 +55,17 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD @observable _marqueeing: number[] | undefined; @observable _savedAnnotations: Dictionary<number, HTMLDivElement[]> = new Dictionary<number, HTMLDivElement[]>(); @observable _screenCapture = false; - @observable _visible: boolean = false; + @observable _clicking = false; @observable _forceCreateYouTubeIFrame = false; @observable _playTimer?: NodeJS.Timeout = undefined; @observable _fullScreen = false; @observable _playing = false; @computed get links() { return DocListCast(this.dataDoc.links); } - @computed get heightPercent() { return this.layoutDoc._timelineShow ? NumCast(this.layoutDoc._videoTimelineHeightPercent, VideoBox.heightPercent) : 100; } + @computed get heightPercent() { return NumCast(this.layoutDoc._timelineHeightPercent, 100); } @computed get duration() { return NumCast(this.dataDoc[this.fieldKey + "-duration"]); } @computed get anchorDocs() { return DocListCast(this.dataDoc[this.annotationKey + "-timeline"]).concat(DocListCast(this.dataDoc[this.annotationKey])); } + private get transition() { return this._clicking ? "left 0.5s, width 0.5s, height 0.5s" : ""; } public get player(): HTMLVideoElement | null { return this._videoRef; } constructor(props: Readonly<FieldViewProps>) { @@ -383,8 +384,8 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD <div className="videoBox-snapshot" key="snap" onClick={this.onSnapshot} > <FontAwesomeIcon icon="camera" size="lg" /> </div>, - <div className="videoBox-timelineButton" key="timeline" onClick={action(e => this.layoutDoc._timelineShow = !this.layoutDoc._timelineShow)}> - <FontAwesomeIcon icon={this.layoutDoc._timelineShow ? "eye-slash" : "eye"} size="lg" /> + <div className="videoBox-timelineButton" key="timeline" onPointerDown={this.onTimelineHdlDown} style={{ bottom: `${100 - this.heightPercent}%` }}> + <FontAwesomeIcon icon={"eye"} size="lg" /> </div>, VideoBox._showControls ? (null) : [ // <div className="control-background"> @@ -412,6 +413,23 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD e.preventDefault(); } + onTimelineHdlDown = action((e: React.PointerEvent) => { + this._clicking = true; + setupMoveUpEvents(this, e, + action((e: PointerEvent) => { + this._clicking = false; + if (this.active()) { + const local = this.props.ScreenToLocalTransform().transformPoint(e.clientX, e.clientY); + this.layoutDoc._timelineHeightPercent = Math.max(0, Math.min(100, local[1] / this.props.PanelHeight() * 100)); + } + return false; + }), emptyFunction, + () => { + this.layoutDoc._timelineHeightPercent = this.heightPercent !== 100 ? 100 : VideoBox.heightPercent; + setTimeout(action(() => this._clicking = false), 500); + }, this.active(), this.active()); + }); + onResetDown = (e: React.PointerEvent) => { setupMoveUpEvents(this, e, (e: PointerEvent) => { this.Seek(Math.max(0, (this.layoutDoc._currentTimecode || 0) + Math.sign(e.movementX) * 0.0333)); @@ -478,7 +496,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD // returns the timeline @computed get renderTimeline() { - return <div style={{ width: "100%", height: `${100 - this.heightPercent}%`, position: "absolute" }}> + return <div style={{ width: "100%", transition: this.transition, height: `${100 - this.heightPercent}%`, position: "absolute" }}> <CollectionStackedTimeline ref={this._stackedTimeline} Document={this.props.Document} fieldKey={this.annotationKey} @@ -519,7 +537,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD contentFunc = () => [this.youtubeVideoId ? this.youtubeContent : this.content]; @computed get annotationLayer() { - return <div className="imageBox-annotationLayer" style={{ height: `${this.heightPercent}%` }} ref={this._annotationLayer} />; + return <div className="imageBox-annotationLayer" style={{ transition: this.transition, height: `${this.heightPercent}%` }} ref={this._annotationLayer} />; } marqueeDown = action((e: React.PointerEvent) => { @@ -548,7 +566,7 @@ export class VideoBox extends ViewBoxAnnotatableComponent<FieldViewProps, VideoD borderRadius }} > <div className="videoBox-viewer" onPointerDown={this.marqueeDown} > - <div style={{ position: "absolute", width: this.panelWidth(), height: this.panelHeight(), top: 0, left: `${(100 - this.heightPercent) / 2}%` }}> + <div style={{ position: "absolute", transition: this.transition, width: this.panelWidth(), height: this.panelHeight(), top: 0, left: `${(100 - this.heightPercent) / 2}%` }}> <CollectionFreeFormView {...OmitKeys(this.props, ["NativeWidth", "NativeHeight", "setContentView"]).omit} fieldKey={this.annotationKey} isAnnotationOverlay={true} |