aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client/views/nodes/Keyframe.tsx4
-rw-r--r--src/client/views/nodes/Timeline.scss1
-rw-r--r--src/client/views/nodes/Timeline.tsx167
-rw-r--r--src/client/views/nodes/Track.tsx9
4 files changed, 95 insertions, 86 deletions
diff --git a/src/client/views/nodes/Keyframe.tsx b/src/client/views/nodes/Keyframe.tsx
index c211766ed..dee226c64 100644
--- a/src/client/views/nodes/Keyframe.tsx
+++ b/src/client/views/nodes/Keyframe.tsx
@@ -13,6 +13,7 @@ import { FlyoutProps } from "./Timeline";
import { number } from "prop-types";
import { CollectionSchemaView, CollectionSchemaPreview } from "../collections/CollectionSchemaView";
import { faDiceOne, faFirstAid } from "@fortawesome/free-solid-svg-icons";
+import { Transform } from "../../util/Transform";
export namespace KeyframeFunc {
export enum KeyframeType {
@@ -70,6 +71,7 @@ interface IProps {
RegionData: Doc;
changeCurrentBarX: (x: number) => void;
setFlyout: (props: FlyoutProps) => any;
+ transform: Transform;
}
@observer
@@ -300,7 +302,7 @@ export class Keyframe extends React.Component<IProps> {
e.preventDefault();
e.stopPropagation();
let bar = this._bar.current!;
- let offset = e.clientX - bar.getBoundingClientRect().left;
+ let offset = Math.round((e.clientX - bar.getBoundingClientRect().left) * this.props.transform.Scale);
if (offset > this.regiondata.fadeIn && offset < this.regiondata.duration - this.regiondata.fadeOut) { //make sure keyframe is not created inbetween fades and ends
let position = NumCast(this.regiondata.position);
this.makeKeyData(Math.round(position + offset));
diff --git a/src/client/views/nodes/Timeline.scss b/src/client/views/nodes/Timeline.scss
index 6a95cd61b..47f448adb 100644
--- a/src/client/views/nodes/Timeline.scss
+++ b/src/client/views/nodes/Timeline.scss
@@ -79,7 +79,6 @@
height: calc(100% - 100px);
width: calc(100% - 140px);
overflow: hidden;
- padding:0px;
.scrubberbox{
position:absolute;
diff --git a/src/client/views/nodes/Timeline.tsx b/src/client/views/nodes/Timeline.tsx
index e2112a0f0..1f0fe8b77 100644
--- a/src/client/views/nodes/Timeline.tsx
+++ b/src/client/views/nodes/Timeline.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import "./Timeline.scss";
import { CollectionSubView } from "../collections/CollectionSubView";
-import { Document, listSpec} from "../../../new_fields/Schema";
+import { Document, listSpec } from "../../../new_fields/Schema";
import { observer } from "mobx-react";
import { Track } from "./Track";
import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, Reaction, IObservableObject, trace, autorun, runInAction } from "mobx";
@@ -16,6 +16,7 @@ import { DocumentManager } from "../../util/DocumentManager";
import { VideoBox } from "./VideoBox";
import { VideoField } from "../../../new_fields/URLField";
import { CollectionVideoView } from "../collections/CollectionVideoView";
+import { Transform } from "../../util/Transform";
export interface FlyoutProps {
@@ -33,19 +34,19 @@ export class Timeline extends CollectionSubView(Document) {
private readonly DEFAULT_TICK_SPACING: number = 50;
private readonly MIN_CONTAINER_HEIGHT: number = 205;
private readonly MAX_CONTAINER_HEIGHT: number = 800;
- private readonly DEFAULT_TICK_INCREMENT:number = 1000;
+ private readonly DEFAULT_TICK_INCREMENT: number = 1000;
@observable private _isMinimized = false;
@observable private _tickSpacing = this.DEFAULT_TICK_SPACING;
- @observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT;
+ @observable private _tickIncrement = this.DEFAULT_TICK_INCREMENT;
@observable private _scrubberbox = React.createRef<HTMLDivElement>();
@observable private _scrubber = React.createRef<HTMLDivElement>();
@observable private _trackbox = React.createRef<HTMLDivElement>();
@observable private _titleContainer = React.createRef<HTMLDivElement>();
@observable private _timelineContainer = React.createRef<HTMLDivElement>();
-
- @observable private _timelineWrapper = React.createRef<HTMLDivElement>();
+
+ @observable private _timelineWrapper = React.createRef<HTMLDivElement>();
@observable private _infoContainer = React.createRef<HTMLDivElement>();
@@ -57,62 +58,64 @@ export class Timeline extends CollectionSubView(Document) {
@observable private _containerHeight: number = this.DEFAULT_CONTAINER_HEIGHT;
@observable private _time = 100000; //DEFAULT
@observable private _ticks: number[] = [];
- @observable private flyoutInfo:FlyoutProps = {x: 0, y: 0, display: "none", regiondata: new Doc(), regions: new List<Doc>()};
+ @observable private flyoutInfo: FlyoutProps = { x: 0, y: 0, display: "none", regiondata: new Doc(), regions: new List<Doc>() };
@computed
- private get children():List<Doc>{
- let extendedDocument = ["image", "video", "pdf"].includes(StrCast(this.props.Document.type));
+ private get children(): List<Doc> {
+ let extendedDocument = ["image", "video", "pdf"].includes(StrCast(this.props.Document.type));
if (extendedDocument) {
if (this.props.Document.data_ext) {
- return Cast((Cast(this.props.Document.data_ext, Doc) as Doc).annotations, listSpec(Doc)) as List<Doc>;
+ return Cast((Cast(this.props.Document.data_ext, Doc) as Doc).annotations, listSpec(Doc)) as List<Doc>;
} else {
return new List<Doc>();
}
}
- return Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)) as List<Doc>;
+ return Cast(this.props.Document[this.props.fieldKey], listSpec(Doc)) as List<Doc>;
}
+ componentWillMount(){
+ }
componentDidMount() {
if (StrCast(this.props.Document.type) === "video") {
- console.log("ran");
- console.log(this.props.Document.duration);
- if (this.props.Document.duration){
- this._time = Math.round(NumCast(this.props.Document.duration)) * 1000;
+ console.log("ran");
+ console.log(this.props.Document.duration);
+ if (this.props.Document.duration) {
+ this._time = Math.round(NumCast(this.props.Document.duration)) * 1000;
reaction(() => {
- return NumCast(this.props.Document.curPage);
+ return NumCast(this.props.Document.curPage);
}, curPage => {
this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing)
- });
+ });
}
-
- }
+
+ }
runInAction(() => {
reaction(() => {
- return this._time;
- }, () =>{
- this._ticks = [];
+ return this._time;
+ }, () => {
+ this._ticks = [];
for (let i = 0; i < this._time;) {
- this._ticks.push(i);
- i += this._tickIncrement;
+ this._ticks.push(i);
+ i += this._tickIncrement;
}
let trackbox = this._trackbox.current!;
this._boxLength = this._tickIncrement / 1000 * this._tickSpacing * this._ticks.length;
trackbox.style.width = `${this._boxLength}`;
- }, {fireImmediately: true});
+ this._scrubberbox.current!.style.width = `${this._boxLength}`;
+ }, { fireImmediately: true });
});
}
componentDidUpdate() {
-
}
@action
changeCurrentBarX = (x: number) => {
this._currentBarX = x;
}
-
+
//for playing
@action
onPlay = async (e: React.MouseEvent) => {
@@ -166,7 +169,7 @@ export class Timeline extends CollectionSubView(Document) {
e.stopPropagation();
let scrubberbox = this._scrubberbox.current!;
let left = scrubberbox.getBoundingClientRect().left;
- let offsetX = Math.round(e.clientX - left);
+ let offsetX = Math.round(e.clientX - left) * this.props.ScreenToLocalTransform().Scale;
this._currentBarX = offsetX;
}
@@ -175,7 +178,7 @@ export class Timeline extends CollectionSubView(Document) {
e.preventDefault();
e.stopPropagation();
let scrubberbox = this._scrubberbox.current!;
- let offset = scrubberbox.scrollLeft + e.clientX - scrubberbox.getBoundingClientRect().left;
+ let offset = (e.clientX - scrubberbox.getBoundingClientRect().left) * this.props.ScreenToLocalTransform().Scale;
this._currentBarX = offset;
}
@@ -218,7 +221,7 @@ export class Timeline extends CollectionSubView(Document) {
onResizeMove = (e: PointerEvent) => {
e.preventDefault();
e.stopPropagation();
- let offset = e.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom;
+ let offset = e.clientY - this._timelineContainer.current!.getBoundingClientRect().bottom;
if (this._containerHeight + offset <= this.MIN_CONTAINER_HEIGHT) {
this._containerHeight = this.MIN_CONTAINER_HEIGHT;
} else if (this._containerHeight + offset >= this.MAX_CONTAINER_HEIGHT) {
@@ -231,10 +234,10 @@ export class Timeline extends CollectionSubView(Document) {
@action
onTimelineDown = (e: React.PointerEvent) => {
e.preventDefault();
- if (e.nativeEvent.which === 1 && !this._isFrozen){
+ if (e.nativeEvent.which === 1 && !this._isFrozen) {
document.addEventListener("pointermove", this.onTimelineMove);
- document.addEventListener("pointerup", () => { document.removeEventListener("pointermove", this.onTimelineMove);});
- }
+ document.addEventListener("pointerup", () => { document.removeEventListener("pointermove", this.onTimelineMove); });
+ }
}
@action
@@ -243,8 +246,8 @@ export class Timeline extends CollectionSubView(Document) {
e.stopPropagation();
let timelineContainer = this._timelineWrapper.current!;
let left = parseFloat(timelineContainer.style.left!);
- let top = parseFloat(timelineContainer.style.top!);
- timelineContainer.style.left = `${left + e.movementX}px`;
+ let top = parseFloat(timelineContainer.style.top!);
+ timelineContainer.style.left = `${left + e.movementX}px`;
timelineContainer.style.top = `${top + e.movementY}px`;
}
@@ -275,42 +278,46 @@ export class Timeline extends CollectionSubView(Document) {
}
- private _freezeText ="Freeze Timeline";
+ private _freezeText = "Freeze Timeline";
timelineContextMenu = (e: React.MouseEvent): void => {
let subitems: ContextMenuProps[] = [];
let timelineContainer = this._timelineWrapper.current!;
- subitems.push({ description: "Pin to Top", event: action(() => {
- if (!this._isFrozen){
- timelineContainer.style.transition = "top 1000ms ease-in, left 1000ms ease-in"; //?????
- timelineContainer.style.left = "0px";
- timelineContainer.style.top = "0px";
- timelineContainer.style.transition = "none";
- }
- }), icon: faArrowUp });
subitems.push({
- description: "Pin to Bottom", event: action(() => {
- console.log(this.props.Document.y);
+ description: "Pin to Top", event: action(() => {
+ if (!this._isFrozen) {
+ timelineContainer.style.transition = "top 1000ms ease-in, left 1000ms ease-in"; //?????
+ timelineContainer.style.left = "0px";
+ timelineContainer.style.top = "0px";
+ timelineContainer.style.transition = "none";
+ }
+ }), icon: faArrowUp
+ });
+ subitems.push({
+ description: "Pin to Bottom", event: action(() => {
+ console.log(this.props.Document.y);
- if (!this._isFrozen){
+ if (!this._isFrozen) {
timelineContainer.style.transform = `translate(0px, ${e.pageY - this._containerHeight}px)`;
}
- }), icon: faArrowDown});
+ }), icon: faArrowDown
+ });
subitems.push({
description: this._freezeText, event: action(() => {
- if (this._isFrozen){
- this._isFrozen = false;
- this._freezeText = "Freeze Timeline";
+ if (this._isFrozen) {
+ this._isFrozen = false;
+ this._freezeText = "Freeze Timeline";
} else {
- this._isFrozen = true;
- this._freezeText = "Unfreeze Timeline";
+ this._isFrozen = true;
+ this._freezeText = "Unfreeze Timeline";
}
- }), icon: "thumbtack" });
- ContextMenu.Instance.addItem({ description: "Timeline Funcs...", subitems: subitems, icon: faClock});
+ }), icon: "thumbtack"
+ });
+ ContextMenu.Instance.addItem({ description: "Timeline Funcs...", subitems: subitems, icon: faClock });
}
-
-
+
+
@action
getFlyout = (props: FlyoutProps) => {
for (const [k, v] of Object.entries(props)) {
@@ -320,15 +327,15 @@ export class Timeline extends CollectionSubView(Document) {
render() {
return (
- <div style={{left:"0px", top: "0px", position:"absolute", width:"100%", transform:"translate(0px, 0px)"}} ref = {this._timelineWrapper}>
+ <div style={{ left: "0px", top: "0px", position: "absolute", width: "100%", transform: "translate(0px, 0px)" }} ref={this._timelineWrapper}>
<button className="minimize" onClick={this.minimize}>Minimize</button>
- <div className="timeline-container" style={{ height: `${this._containerHeight}px`, left:"0px", top:"30px" }} ref={this._timelineContainer}onPointerDown={this.onTimelineDown} onContextMenu={this.timelineContextMenu}>
+ <div className="timeline-container" style={{ height: `${this._containerHeight}px`, left: "0px", top: "30px" }} ref={this._timelineContainer} onPointerDown={this.onTimelineDown} onContextMenu={this.timelineContextMenu}>
{/* <TimelineFlyout flyoutInfo={this.flyoutInfo} tickSpacing={this._tickSpacing}/> */}
<div className="toolbox">
<div onClick={this.windBackward}> <FontAwesomeIcon icon={faBackward} size="2x" /> </div>
<div onClick={this.onPlay}> <FontAwesomeIcon icon={faPlayCircle} size="2x" /> </div>
<div onClick={this.windForward}> <FontAwesomeIcon icon={faForward} size="2x" /> </div>
- <TimelineOverview currentBarX = {this._currentBarX}/>
+ {/* <TimelineOverview currentBarX = {this._currentBarX}/> */}
</div>
<div className="info-container" ref={this._infoContainer}>
<div className="scrubberbox" ref={this._scrubberbox} onClick={this.onScrubberClick}>
@@ -340,7 +347,7 @@ export class Timeline extends CollectionSubView(Document) {
<div className="scrubberhead"></div>
</div>
<div className="trackbox" ref={this._trackbox} onPointerDown={this.onPanDown}>
- {DocListCast(this.children).map(doc => <Track node={doc} currentBarX={this._currentBarX} changeCurrentBarX={this.changeCurrentBarX} setFlyout={this.getFlyout} />)}
+ {DocListCast(this.children).map(doc => <Track node={doc} currentBarX={this._currentBarX} changeCurrentBarX={this.changeCurrentBarX} setFlyout={this.getFlyout} transform={this.props.ScreenToLocalTransform()}/>)}
</div>
</div>
<div className="title-container" ref={this._titleContainer}>
@@ -358,21 +365,21 @@ export class Timeline extends CollectionSubView(Document) {
interface TimelineFlyoutProps {
- flyoutInfo:FlyoutProps;
- tickSpacing:number;
+ flyoutInfo: FlyoutProps;
+ tickSpacing: number;
}
interface TimelineOverviewProps {
- currentBarX : number;
+ currentBarX: number;
}
-class TimelineOverview extends React.Component<TimelineOverviewProps>{
+class TimelineOverview extends React.Component<TimelineOverviewProps>{
- componentWillMount(){
+ componentWillMount() {
}
-
+
render() {
return (
<div className="overview">
@@ -382,7 +389,7 @@ class TimelineOverview extends React.Component<TimelineOverviewProps>{
</div>
</div>
</div>
- );
+ );
}
}
@@ -391,21 +398,21 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{
@observable private _timeInput = React.createRef<HTMLInputElement>();
@observable private _durationInput = React.createRef<HTMLInputElement>();
@observable private _fadeInInput = React.createRef<HTMLInputElement>();
- @observable private _fadeOutInput = React.createRef<HTMLInputElement>();
-
+ @observable private _fadeOutInput = React.createRef<HTMLInputElement>();
+
private block = false;
componentDidMount() {
document.addEventListener("pointerdown", this.closeFlyout);
}
- componentWillUnmount(){
+ componentWillUnmount() {
document.removeEventListener("pointerdown", this.closeFlyout);
}
-
- componentDidUpdate(){
- console.log(this.props.flyoutInfo);
+
+ componentDidUpdate() {
+ console.log(this.props.flyoutInfo);
}
-
+
@action
changeTime = (e: React.KeyboardEvent) => {
@@ -469,7 +476,7 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{
}
}
- render(){
+ render() {
return (
<div>
<div className="flyout-container" style={{ left: `${this.props.flyoutInfo.x}px`, top: `${this.props.flyoutInfo.y}px`, display: `${this.props.flyoutInfo.display!}` }} onPointerDown={this.onFlyoutDown}>
@@ -489,19 +496,19 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{
<button onClick={action((e: React.MouseEvent) => { this.props.flyoutInfo.regions!.splice(this.props.flyoutInfo.regions!.indexOf(this.props.flyoutInfo.regiondata!), 1); this.props.flyoutInfo.display = "none"; })}>delete</button>
</div>
</div>
- );
+ );
}
}
-class TimelineZoom extends React.Component{
+class TimelineZoom extends React.Component {
componentDidMount() {
}
- render(){
+ render() {
return (
<div>
-
+
</div>
- );
+ );
}
} \ No newline at end of file
diff --git a/src/client/views/nodes/Track.tsx b/src/client/views/nodes/Track.tsx
index fe9034e8a..2fcb4f0e4 100644
--- a/src/client/views/nodes/Track.tsx
+++ b/src/client/views/nodes/Track.tsx
@@ -8,10 +8,13 @@ import { FieldValue, Cast, NumCast, BoolCast } from "../../../new_fields/Types";
import { List } from "../../../new_fields/List";
import { Keyframe, KeyframeFunc, RegionData } from "./Keyframe";
import { FlyoutProps } from "./Timeline";
+import { CollectionView } from "../collections/CollectionView";
+import { Transform } from "../../util/Transform";
interface IProps {
node: Doc;
currentBarX: number;
+ transform: Transform;
changeCurrentBarX: (x:number) => void;
setFlyout: (props:FlyoutProps) => any;
}
@@ -215,7 +218,6 @@ export class Track extends React.Component<IProps> {
let mainNode = new Doc();
const dif_time = NumCast(kf2.time) - NumCast(kf1.time);
const ratio = (this.props.currentBarX - NumCast(kf1.time)) / dif_time; //linear
-
let keys = [];
if (this.filterKeys(Doc.allKeys(node1)).length === Math.max(this.filterKeys(Doc.allKeys(node1)).length, this.filterKeys(Doc.allKeys(node2)).length )){
keys = this.filterKeys(Doc.allKeys(node1));
@@ -254,8 +256,7 @@ export class Track extends React.Component<IProps> {
@action
onInnerDoubleClick = (e: React.MouseEvent) => {
let inner = this._inner.current!;
- let left = inner.getBoundingClientRect().left;
- let offsetX = Math.round(e.clientX - left);
+ let offsetX = Math.round((e.clientX - inner.getBoundingClientRect().left) * this.props.transform.Scale);
let regiondata = KeyframeFunc.defaultKeyframe();
regiondata.position = offsetX;
let leftRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, regiondata, this.regions);
@@ -275,7 +276,7 @@ export class Track extends React.Component<IProps> {
<div className="track">
<div className="inner" ref={this._inner} onDoubleClick={this.onInnerDoubleClick}>
{DocListCast(this.regions).map((region) => {
- return <Keyframe node={this.props.node} RegionData={region} changeCurrentBarX={this.props.changeCurrentBarX} setFlyout={this.props.setFlyout}/>;
+ return <Keyframe node={this.props.node} RegionData={region} changeCurrentBarX={this.props.changeCurrentBarX} setFlyout={this.props.setFlyout} transform={this.props.transform}/>;
})}
</div>
</div>