diff options
| author | andrewdkim <adkim414@gmail.com> | 2019-07-24 15:54:16 -0400 | 
|---|---|---|
| committer | andrewdkim <adkim414@gmail.com> | 2019-07-24 15:54:16 -0400 | 
| commit | d2f6b3b2e4385dd17aca3f030fbc7cc8b070a56a (patch) | |
| tree | b21f6cf081d78a6c4fd3eab3bad937eec3667186 | |
| parent | 310f83002d715d50a32754fe78d48fc993edebe6 (diff) | |
interpolation fixed
| -rw-r--r-- | src/client/views/nodes/Keyframe.tsx | 47 | ||||
| -rw-r--r-- | src/client/views/nodes/Timeline.tsx | 33 | ||||
| -rw-r--r-- | src/client/views/nodes/Track.tsx | 219 | 
3 files changed, 133 insertions, 166 deletions
diff --git a/src/client/views/nodes/Keyframe.tsx b/src/client/views/nodes/Keyframe.tsx index e90c6e436..788108fa1 100644 --- a/src/client/views/nodes/Keyframe.tsx +++ b/src/client/views/nodes/Keyframe.tsx @@ -23,7 +23,7 @@ export namespace KeyframeFunc {      export const findAdjacentRegion = (dir: KeyframeFunc.Direction, currentRegion: Doc, regions: List<Doc>): (RegionData | undefined) => {          let leftMost: (RegionData | undefined) = undefined;          let rightMost: (RegionData | undefined) = undefined; -        regions.forEach(region => { +        DocListCast(regions).forEach(region => {              let neighbor = RegionData(region as Doc);              if (currentRegion.position! > neighbor.position) {                  if (!leftMost || neighbor.position > leftMost.position) { @@ -113,22 +113,14 @@ export class Keyframe extends React.Component<IProps> {      } -    componentWillMount() { +    async componentWillMount() {          if (!this.regiondata.keyframes) {              this.regiondata.keyframes = new List<Doc>();          } -    } - - -    @action -    componentDidMount() { -       -        console.log(toJS(this.props.node)); -        console.log("hi");       -        let fadeIn =  this.makeKeyData(this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade)!; -        let fadeOut =  this.makeKeyData(this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade)!; -        let start =  this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.fade)!; -        let finish =  this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!; +        let fadeIn =  await this.makeKeyData(this.regiondata.position + this.regiondata.fadeIn, KeyframeFunc.KeyframeType.fade)!; +        let fadeOut =  await this.makeKeyData(this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut, KeyframeFunc.KeyframeType.fade)!; +        let start =  await this.makeKeyData(this.regiondata.position, KeyframeFunc.KeyframeType.fade)!; +        let finish =  await this.makeKeyData(this.regiondata.position + this.regiondata.duration, KeyframeFunc.KeyframeType.fade)!;          (fadeIn.key! as Doc).opacity = 1;          (fadeOut.key! as Doc).opacity = 1;          (start.key! as Doc).opacity = 0.1; @@ -140,12 +132,10 @@ export class Keyframe extends React.Component<IProps> {                  fadeOut.time = this.regiondata.position + this.regiondata.duration - this.regiondata.fadeOut;                  start.time = this.regiondata.position;                  finish.time = this.regiondata.position + this.regiondata.duration; -                  let fadeInIndex = this.regiondata.keyframes!.indexOf(fadeIn);                  let fadeOutIndex = this.regiondata.keyframes!.indexOf(fadeOut);                  let startIndex = this.regiondata.keyframes!.indexOf(start);                  let finishIndex = this.regiondata.keyframes!.indexOf(finish); -                  this.regiondata.keyframes![fadeInIndex] = fadeIn;                  this.regiondata.keyframes![fadeOutIndex] = fadeOut;                  this.regiondata.keyframes![startIndex] = start; @@ -155,21 +145,17 @@ export class Keyframe extends React.Component<IProps> {          });      } -      @action -    makeKeyData = (kfpos: number, type: KeyframeFunc.KeyframeType = KeyframeFunc.KeyframeType.default) => { //Kfpos is mouse offsetX, representing time  -        let doclist =  DocListCast(this.regiondata.keyframes!); +    makeKeyData = async (kfpos: number, type: KeyframeFunc.KeyframeType = KeyframeFunc.KeyframeType.default) => { //Kfpos is mouse offsetX, representing time  +        let doclist =  await DocListCastAsync(this.regiondata.keyframes);          let existingkf: (Doc | undefined) = undefined;          if (doclist) { -            doclist.forEach(TK => { //TK is TimeAndKey -                if (TK.time === kfpos) { -                    existingkf = TK; -                } +            (doclist).forEach(TK => { +                TK = TK as Doc;  +                if (TK.time === kfpos) existingkf = TK;                });          } -        if (existingkf) { -            return existingkf; -        } +        if (existingkf) return existingkf;          let TK: Doc = new Doc();          TK.time = kfpos;          TK.key = Doc.MakeCopy(this.props.node, true); @@ -195,9 +181,6 @@ export class Keyframe extends React.Component<IProps> {          e.stopPropagation();          let left = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, this.regiondata, this.regions)!;          let right = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, this.regiondata, this.regions!); -        // let bar = this._bar.current!;  -        // let barX = bar.getBoundingClientRect().left; -        // let offset = e.clientX - barX;          let prevX = this.regiondata.position;          let futureX = this.regiondata.position + e.movementX;          if (futureX <= 0) { @@ -295,14 +278,14 @@ export class Keyframe extends React.Component<IProps> {      }      @action -    createKeyframe = (e: React.MouseEvent) => { +    createKeyframe = async (e: React.MouseEvent) => {          e.preventDefault();          e.stopPropagation();          let bar = this._bar.current!;          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)); +            await this.makeKeyData(Math.round(position + offset));              console.log(this.regiondata.keyframes!.length);               this.props.changeCurrentBarX(NumCast(Math.round(position + offset))); //first move the keyframe to the correct location and make a copy so the correct file gets coppied          } @@ -347,7 +330,7 @@ export class Keyframe extends React.Component<IProps> {                          e.stopPropagation();                          let offsetLeft = this._bar.current!.getBoundingClientRect().left - this._bar.current!.parentElement!.getBoundingClientRect().left;                          let offsetTop = this._bar.current!.getBoundingClientRect().top; //+ this._bar.current!.parentElement!.getBoundingClientRect().top;  -                        this.props.setFlyout({ x: offsetLeft, y: offsetTop, display: "block", regiondata: this.regiondata, regions: this.regions }); +                        this.props.setFlyout({ x: offsetLeft * this.props.transform.Scale, y: offsetTop * this.props.transform.Scale, display: "block", regiondata: this.regiondata, regions: this.regions });                      })}>                      <div className="leftResize" onPointerDown={this.onResizeLeft} ></div>                      <div className="rightResize" onPointerDown={this.onResizeRight}></div> diff --git a/src/client/views/nodes/Timeline.tsx b/src/client/views/nodes/Timeline.tsx index 1f0fe8b77..2d94bb15c 100644 --- a/src/client/views/nodes/Timeline.tsx +++ b/src/client/views/nodes/Timeline.tsx @@ -17,6 +17,7 @@ import { VideoBox } from "./VideoBox";  import { VideoField } from "../../../new_fields/URLField";  import { CollectionVideoView } from "../collections/CollectionVideoView";  import { Transform } from "../../util/Transform"; +import { faGrinTongueSquint } from "@fortawesome/free-regular-svg-icons";  export interface FlyoutProps { @@ -73,8 +74,7 @@ export class Timeline extends CollectionSubView(Document) {          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"); @@ -85,7 +85,7 @@ export class Timeline extends CollectionSubView(Document) {                  reaction(() => {                      return NumCast(this.props.Document.curPage);                  }, curPage => { -                    this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing) +                    this.changeCurrentBarX(curPage * this._tickIncrement / this._tickSpacing);                  });              } @@ -108,9 +108,6 @@ export class Timeline extends CollectionSubView(Document) {          });      } -    componentDidUpdate() { -    } -      @action      changeCurrentBarX = (x: number) => {          this._currentBarX = x; @@ -258,10 +255,10 @@ export class Timeline extends CollectionSubView(Document) {          let timelineContainer = this._timelineContainer.current!;          if (this._isMinimized) {              this._isMinimized = false; -            timelineContainer.style.transform = `translate(0px, 0px)`; +            timelineContainer.style.visibility = "visible";          } else {              this._isMinimized = true; -            timelineContainer.style.transform = `translate(0px, ${- this._containerHeight - 30}px)`; +            timelineContainer.style.visibility = "hidden";          }      } @@ -323,6 +320,7 @@ export class Timeline extends CollectionSubView(Document) {          for (const [k, v] of Object.entries(props)) {              (this.flyoutInfo as any)[k] = v;          } +        console.log(this.flyoutInfo);       }      render() { @@ -330,12 +328,11 @@ export class Timeline extends CollectionSubView(Document) {              <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}> -                    {/* <TimelineFlyout flyoutInfo={this.flyoutInfo} tickSpacing={this._tickSpacing}/> */} +                    <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}/> */}                      </div>                      <div className="info-container" ref={this._infoContainer}>                          <div className="scrubberbox" ref={this._scrubberbox} onClick={this.onScrubberClick}> @@ -399,21 +396,21 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{      @observable private _durationInput = React.createRef<HTMLInputElement>();      @observable private _fadeInInput = React.createRef<HTMLInputElement>();      @observable private _fadeOutInput = React.createRef<HTMLInputElement>(); +    @observable private  _data: FlyoutProps = { x: 0, y: 0, display: "none", regiondata: new Doc(), regions: new List<Doc>() };      private block = false;      componentDidMount() { +                  document.addEventListener("pointerdown", this.closeFlyout);      } + +      componentWillUnmount() {          document.removeEventListener("pointerdown", this.closeFlyout);      } -    componentDidUpdate() { -        console.log(this.props.flyoutInfo); -    } - - +         @action      changeTime = (e: React.KeyboardEvent) => {          let time = this._timeInput.current!; @@ -427,7 +424,7 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{      }      @action      onFlyoutDown = (e: React.PointerEvent) => { -        this.props.flyoutInfo.display = "block"; +        this._data.display = "block";          this.block = true;      } @@ -437,7 +434,7 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{              this.block = false;              return;          } -        this.props.flyoutInfo.display = "none"; +        this._data.display = "none";      }      @action @@ -479,7 +476,7 @@ class TimelineFlyout extends React.Component<TimelineFlyoutProps>{      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}> +                <div className="flyout-container" style={{ left: `${this._data.x}px`, top: `${this._data.y}px`, display: `${this._data.display!}` }} onPointerDown={this.onFlyoutDown}>                      <FontAwesomeIcon className="flyout" icon="comment-alt" color="grey" />                      <div className="text-container">                          <p>Time:</p> diff --git a/src/client/views/nodes/Track.tsx b/src/client/views/nodes/Track.tsx index ee8bee56f..92f66dad3 100644 --- a/src/client/views/nodes/Track.tsx +++ b/src/client/views/nodes/Track.tsx @@ -2,8 +2,8 @@ import * as React from "react";  import { observer } from "mobx-react";  import { observable, reaction, action, IReactionDisposer, observe, IObservableArray, computed, toJS, IObservableObject, runInAction } from "mobx";  import "./Track.scss"; -import { Doc, DocListCastAsync, DocListCast } from "../../../new_fields/Doc"; -import {listSpec} from "../../../new_fields/Schema"; +import { Doc, DocListCastAsync, DocListCast, Field } from "../../../new_fields/Doc"; +import { listSpec } from "../../../new_fields/Schema";  import { FieldValue, Cast, NumCast, BoolCast, StrCast } from "../../../new_fields/Types";  import { List } from "../../../new_fields/List";  import { Keyframe, KeyframeFunc, RegionData } from "./Keyframe"; @@ -14,17 +14,17 @@ import { AddComparisonParameters } from "../../northstar/model/idea/idea";  interface IProps {      node: Doc;      currentBarX: number; -    transform: Transform;  -    changeCurrentBarX: (x:number) => void; -    setFlyout: (props:FlyoutProps) => any;  +    transform: Transform; +    changeCurrentBarX: (x: number) => void; +    setFlyout: (props: FlyoutProps) => any;  }  @observer  export class Track extends React.Component<IProps> { -    @observable private _inner = React.createRef<HTMLDivElement>();    +    @observable private _inner = React.createRef<HTMLDivElement>();      @observable private _reactionDisposers: IReactionDisposer[] = []; -    @observable private _keyReaction:any; //reaction that is used to dispose when necessary  -    @observable private _currentBarXReaction:any;  +    @observable private _keyReaction: any; //reaction that is used to dispose when necessary  +    @observable private _currentBarXReaction: any;      @computed      private get regions() { @@ -32,80 +32,81 @@ export class Track extends React.Component<IProps> {      }      componentWillMount() { -        if (!this.props.node.regions){ +        if (!this.props.node.regions) {              this.props.node.regions = new List<Doc>();          } -        this.props.node.opacity = 1;          +        this.props.node.opacity = 1;      }      componentDidMount() {          runInAction(() => { -            this.createRegion(this.props.currentBarX);  -            this.props.node.hidden = false;   -            this._currentBarXReaction = this.currentBarXReaction();  -        });  +            this._currentBarXReaction = this.currentBarXReaction(); +            if (this.regions.length === 0 ) this.createRegion(this.props.currentBarX); +            this.props.node.hidden = false; +        });      }      componentWillUnmount() { -       runInAction(() => { -           if (this._keyReaction) this._keyReaction();  -           if (this._currentBarXReaction) this._currentBarXReaction();  -       });  +        runInAction(() => { +            if (this._keyReaction) this._keyReaction(); +            if (this._currentBarXReaction) this._currentBarXReaction(); +        });      } -    @action  +    @action      keyReaction = () => {          return reaction(() => { -            let keys = Doc.allKeys(this.props.node);  -            return keys.map(key => FieldValue(this.props.node[key]));      +            console.log("triggered keyReaction");  +            let keys = Doc.allKeys(this.props.node); +            return keys.map(key => FieldValue(this.props.node[key]));          }, data => { -            console.log("full reaction");  +            console.log("full reaction");              let regiondata = this.findRegion(this.props.currentBarX); -            if (regiondata){ +            if (regiondata) {                  DocListCast(regiondata.keyframes!).forEach((kf) => { -                    if (kf.type === KeyframeFunc.KeyframeType.default){ -                        kf.key = Doc.MakeCopy(this.props.node, true);  +                    if (kf.type === KeyframeFunc.KeyframeType.default && kf.time === this.props.currentBarX) { +                        console.log("data updated");  +                        kf.key = Doc.MakeCopy(this.props.node, true);                          let leftkf: (Doc | undefined) = this.calcMinLeft(regiondata!, kf); // lef keyframe, if it exists                          let rightkf: (Doc | undefined) = this.calcMinRight(regiondata!, kf); //right keyframe, if it exists -                        if (leftkf!.type === KeyframeFunc.KeyframeType.fade){ //replicating this keyframe to fades -                            let edge = this.calcMinLeft(regiondata!, leftkf!);  -                            edge!.key = Doc.MakeCopy(kf.key as Doc, true);  -                            leftkf!.key = Doc.MakeCopy(kf.key as Doc, true) ;  -                            (Cast(edge!.key, Doc)! as Doc).opacity = 0.1;  -                            (Cast(leftkf!.key, Doc)! as Doc).opacity = 1;  -                        }  -                        if (rightkf!.type === KeyframeFunc.KeyframeType.fade){ -                            let edge = this.calcMinRight(regiondata!, rightkf!);   -                            edge!.key = Doc.MakeCopy(kf.key as Doc, true);  -                            rightkf!.key = Doc.MakeCopy(kf.key as Doc, true);  -                            (Cast(edge!.key, Doc)! as Doc).opacity = 0.1;  -                            (Cast(rightkf!.key, Doc)! as Doc).opacity = 1;  +                        if (leftkf!.type === KeyframeFunc.KeyframeType.fade) { //replicating this keyframe to fades +                            let edge = this.calcMinLeft(regiondata!, leftkf!); +                            edge!.key = Doc.MakeCopy(kf.key as Doc, true); +                            leftkf!.key = Doc.MakeCopy(kf.key as Doc, true); +                            (Cast(edge!.key, Doc)! as Doc).opacity = 0.1; +                            (Cast(leftkf!.key, Doc)! as Doc).opacity = 1; +                        } +                        if (rightkf!.type === KeyframeFunc.KeyframeType.fade) { +                            let edge = this.calcMinRight(regiondata!, rightkf!); +                            edge!.key = Doc.MakeCopy(kf.key as Doc, true); +                            rightkf!.key = Doc.MakeCopy(kf.key as Doc, true); +                            (Cast(edge!.key, Doc)! as Doc).opacity = 0.1; +                            (Cast(rightkf!.key, Doc)! as Doc).opacity = 1;                          } -                    }  -                });  +                    } +                });              } -        });  +        });      } -    @action  +    @action      currentBarXReaction = () => { -        return reaction(() => this.props.currentBarX, () => {             -            console.log("currentbar changed");  +        return reaction(() =>  this.props.currentBarX, () => {              if (this._keyReaction) this._keyReaction(); //dispose previous reaction first              let regiondata: (Doc | undefined) = this.findRegion(this.props.currentBarX); -            if (regiondata) {                   -                this.props.node.hidden = false;                  -                this.timeChange(this.props.currentBarX);                         +            if (regiondata) { +                this.props.node.hidden = false;                 +                this.timeChange(this.props.currentBarX);                  DocListCast(regiondata.keyframes).forEach((kf) => { -                    if (kf.time === this.props.currentBarX && kf.type === KeyframeFunc.KeyframeType.default){ -                        console.log("HI!");  +                    if (kf.time === this.props.currentBarX && kf.type === KeyframeFunc.KeyframeType.default) { +                        this.applyKeys(kf);                           this._keyReaction = this.keyReaction(); //reactivates reaction.                       } -                });                  +                });                              } else {                  this.props.node.hidden = true;              } -        }); +        }, { fireImmediately: true });      } @@ -114,59 +115,54 @@ export class Track extends React.Component<IProps> {          let regiondata = this.findRegion(Math.round(time)); //finds a region that the scrubber is on          if (regiondata) {              let leftkf: (Doc | undefined) = this.calcMinLeft(regiondata!); // lef keyframe, if it exists -            let rightkf: (Doc | undefined) = this.calcMinRight(regiondata!); //right keyframe, if it exists -            if(leftkf && rightkf) { -                this.interpolate(leftkf, rightkf); -            }             +            let rightkf: (Doc | undefined) = this.calcMinRight(regiondata!); //right keyframe, if it exists                          let currentkf: (Doc | undefined) = this.calcCurrent(regiondata!); //if the scrubber is on top of the keyframe - -            if (currentkf){ -                console.log(toJS(currentkf));  -                this.applyKeys(Cast(currentkf.key, Doc) as Doc);   -            }  +            +            if (leftkf && rightkf) { +                this.interpolate(leftkf, rightkf); +            }            } -             } -    @action  +    @action      private applyKeys = (kf: Doc) => {          this.filterKeys(Doc.allKeys(kf)).forEach(key => {              if (key === "title" || key === "documentText") Doc.SetOnPrototype(this.props.node, key, StrCast(kf[key])); -            this.props.node[key] = kf[key];  -        });  +            this.props.node[key] = kf[key]; +        });      } -    @action  -    private filterKeys = (keys:string[]):string[] => { -        return keys.reduce((acc:string[], key:string) => { -            if ( key !== "regions" && key !== "data" && key !== "creationDate" && key !== "cursors" && key !== "hidden") acc.push(key);  -            return acc;  +    @action +    private filterKeys = (keys: string[]): string[] => { +        return keys.reduce((acc: string[], key: string) => { +            if (key !== "regions" && key !== "data" && key !== "creationDate" && key !== "cursors" && key !== "hidden" && key !== "nativeHeight" && key!== "nativeWidth") acc.push(key); +            return acc;          }, []) as string[];      } -    @action  -    calcCurrent = (region:Doc):(Doc|undefined) => { -        let currentkf:(Doc|undefined) = undefined;  +    @action +    calcCurrent = (region: Doc): (Doc | undefined) => { +        let currentkf: (Doc | undefined) = undefined;          DocListCast(region.keyframes!).forEach((kf) => { -            if (NumCast(kf.time) === Math.round(this.props.currentBarX)) currentkf = kf;  -        });  -        return currentkf;  +            if (NumCast(kf.time) === Math.round(this.props.currentBarX)) currentkf = kf; +        }); +        return currentkf;      }      @action -    calcMinLeft = (region: Doc, ref?:Doc): (Doc | undefined) => { //returns the time of the closet keyframe to the left -        let leftKf:(Doc| undefined) = undefined; -        let time:number = 0;  +    calcMinLeft = (region: Doc, ref?: Doc): (Doc | undefined) => { //returns the time of the closet keyframe to the left +        let leftKf: (Doc | undefined) = undefined; +        let time: number = 0;          DocListCast(region.keyframes!).forEach((kf) => { -            let compTime = this.props.currentBarX;  -            if (ref){ -                compTime = NumCast(ref.time);  -            }  +            let compTime = this.props.currentBarX; +            if (ref) { +                compTime = NumCast(ref.time); +            }              if (NumCast(kf.time) < compTime && NumCast(kf.time) >= time) {                  leftKf = kf; -                time = NumCast(kf.time);  +                time = NumCast(kf.time);              }          });          return leftKf; @@ -174,17 +170,17 @@ export class Track extends React.Component<IProps> {      @action -    calcMinRight = (region: Doc, ref?:Doc): (Doc | undefined) => { //returns the time of the closest keyframe to the right  -        let rightKf: (Doc|undefined) = undefined; -        let time:number = Infinity;  +    calcMinRight = (region: Doc, ref?: Doc): (Doc | undefined) => { //returns the time of the closest keyframe to the right  +        let rightKf: (Doc | undefined) = undefined; +        let time: number = Infinity;          DocListCast(region.keyframes!).forEach((kf) => { -            let compTime = this.props.currentBarX;  -            if (ref){ -                compTime = NumCast(ref.time);  +            let compTime = this.props.currentBarX; +            if (ref) { +                compTime = NumCast(ref.time);              }              if (NumCast(kf.time) > compTime && NumCast(kf.time) <= NumCast(time)) {                  rightKf = kf; -                time = NumCast(kf.time);  +                time = NumCast(kf.time);              }          });          return rightKf; @@ -192,37 +188,28 @@ export class Track extends React.Component<IProps> {      @action      interpolate = (left: Doc, right: Doc) => { -        console.log("interpolating");  +        console.log("interpolating");          let leftNode = left.key as Doc;          let rightNode = right.key as Doc; - -        console.log(toJS(leftNode));  -        console.log(toJS(rightNode));  -          const dif_time = NumCast(right.time) - NumCast(left.time);          const ratio = (this.props.currentBarX - NumCast(left.time)) / dif_time; //linear  - -          this.filterKeys(Doc.allKeys(leftNode)).forEach(key => { -            console.log(key);  -            if (leftNode[key] && rightNode[key] && typeof(leftNode[key]) === "number" && typeof(rightNode[key]) === "number"){ //if it is number, interpolate +            if (leftNode[key] && rightNode[key] && typeof (leftNode[key]) === "number" && typeof (rightNode[key]) === "number") { //if it is number, interpolate                  const diff = NumCast(rightNode[key]) - NumCast(leftNode[key]);                  const adjusted = diff * ratio; -                this.props.node[key] = NumCast(leftNode[key]) + adjusted; +                this.props.node[key] = NumCast(leftNode[key]) + adjusted;                              } else if (key === "title" || key === "documentText") {                  Doc.SetOnPrototype(this.props.node, key, StrCast(leftNode[key])); -                this.props.node[key] = leftNode[key];  +                this.props.node[key] = leftNode[key];              } -            console.log(this.props.node[key]);           }); -        console.log("done");       }      @action -    findRegion(time: number): (Doc | undefined) { +    findRegion(time: number): (RegionData | undefined) {          let foundRegion = undefined; -        this.regions.map(region => { -            region = region as Doc;  +        DocListCast(this.regions).map(region => { +            region = region as RegionData;               if (time >= NumCast(region.position) && time <= (NumCast(region.position) + NumCast(region.duration))) {                  foundRegion = region;              } @@ -234,21 +221,21 @@ export class Track extends React.Component<IProps> {      onInnerDoubleClick = (e: React.MouseEvent) => {          let inner = this._inner.current!;          let offsetX = Math.round((e.clientX - inner.getBoundingClientRect().left) * this.props.transform.Scale); -        this.createRegion(offsetX);  +        this.createRegion(offsetX);      }      createRegion = (position: number) => {          let regiondata = KeyframeFunc.defaultKeyframe(); -        regiondata.position = position;  -        let leftRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, regiondata, this.regions);  -        let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions);  -        if ((rightRegion && leftRegion && rightRegion.position - (leftRegion.position + leftRegion.duration) < NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut)) || (rightRegion && rightRegion.position - regiondata.position < NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut))){ -            return;  -        } else if (rightRegion && rightRegion.position - regiondata.position >= NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut)){ -            regiondata.duration = rightRegion.position - regiondata.position;  +        regiondata.position = position; +        let leftRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.left, regiondata, this.regions); +        let rightRegion = KeyframeFunc.findAdjacentRegion(KeyframeFunc.Direction.right, regiondata, this.regions); +        if ((rightRegion && leftRegion && rightRegion.position - (leftRegion.position + leftRegion.duration) < NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut)) || (rightRegion && rightRegion.position - regiondata.position < NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut))) { +            return; +        } else if (rightRegion && rightRegion.position - regiondata.position >= NumCast(regiondata.fadeIn) + NumCast(regiondata.fadeOut)) { +            regiondata.duration = rightRegion.position - regiondata.position;          }          this.regions.push(regiondata); -        return regiondata;  +        return regiondata;      } @@ -258,7 +245,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} transform={this.props.transform}/>; +                            return <Keyframe node={this.props.node} RegionData={region} changeCurrentBarX={this.props.changeCurrentBarX} setFlyout={this.props.setFlyout} transform={this.props.transform} />;                          })}                      </div>                  </div>  | 
