Alejandro Toledo 5 years ago
parent
commit
a675b605cb

+ 103 - 24
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx

@@ -20,6 +20,7 @@ import { LockObject } from '../lockObject';
 import { GlobalState } from '../../../../globalState';
 import { Nullable } from 'babylonjs/types';
 import { Observer } from 'babylonjs/Misc/observable';
+import { ScaleLabel } from './scale-label';
 
 require('./curveEditor.scss');
 
@@ -37,6 +38,14 @@ interface ICanvasAxis {
   label: number;
 }
 
+export enum CurveScale {
+  float,
+  radians,
+  degrees,
+  integers,
+  default,
+}
+
 export interface IActionableKeyFrame {
   frame?: number | string;
   value?: any;
@@ -79,6 +88,7 @@ export class AnimationCurveEditorComponent extends React.Component<
     panningX: number;
     repositionCanvas: boolean;
     actionableKeyframe: IActionableKeyFrame;
+    valueScale: CurveScale;
   }
 > {
   private _snippetUrl = 'https://snippet.babylonjs.com';
@@ -184,6 +194,7 @@ export class AnimationCurveEditorComponent extends React.Component<
       panningX: 0,
       repositionCanvas: false,
       actionableKeyframe: { frame: undefined, value: undefined },
+      valueScale: CurveScale.degrees,
     };
   }
 
@@ -225,7 +236,71 @@ export class AnimationCurveEditorComponent extends React.Component<
     return [...halfNegative, ...halfPositive];
   }
 
-  setValueLines() {
+  setValueLines(type: CurveScale) {
+    let scaleValues = { coeficient: 0, dividend: 0, factor: 0 };
+
+    switch (type) {
+      case CurveScale.default:
+        scaleValues.coeficient = 10;
+        scaleValues.dividend = 5;
+        scaleValues.factor = 2;
+        this._heightScale = 100;
+        break;
+      case CurveScale.float:
+        scaleValues.coeficient = 10;
+        scaleValues.dividend = 5;
+        scaleValues.factor = 2.5;
+        this._heightScale = 120;
+        break;
+      case CurveScale.degrees:
+        scaleValues.coeficient = 10;
+        scaleValues.dividend = 5;
+        scaleValues.factor = 50;
+        this._heightScale = 200;
+        break;
+      case CurveScale.integers:
+        scaleValues.coeficient = 10;
+        scaleValues.dividend = 5;
+        scaleValues.factor = 320;
+        break;
+      case CurveScale.radians:
+        scaleValues.coeficient = 10;
+        scaleValues.dividend = 5;
+        scaleValues.factor = 0.8;
+        break;
+    }
+
+    const initialValues = new Array(10).fill(0).map((_, i) => {
+      return {
+        value: i * 10,
+        label: (
+          scaleValues.factor *
+          ((scaleValues.coeficient - i) / scaleValues.coeficient)
+        ).toFixed(2),
+      };
+    });
+
+    initialValues.shift();
+
+    const valueHeight = Math.abs(Math.round(this.state.panningY / 10));
+    const sign = Math.sign(this.state.panningY);
+
+    const pannedValues = new Array(valueHeight).fill(0).map((s, i) => {
+      return sign === -1
+        ? {
+            value: -i * 10,
+            label: (i + 10) / (scaleValues.coeficient / scaleValues.factor),
+          }
+        : {
+            value: (i + 10) * 10,
+            label: (i * -1) / (scaleValues.coeficient / scaleValues.factor),
+          };
+    });
+
+    return [...initialValues, ...pannedValues];
+  }
+
+  setValueLinesOld() {
     const initialValues = new Array(10).fill(0).map((_, i) => {
       return { value: i * 10, label: 2 * ((10 - i) / 10) };
     });
@@ -704,7 +779,8 @@ export class AnimationCurveEditorComponent extends React.Component<
                   k.value
                 );
                 currentValue[coordinate] = this.state.actionableKeyframe.value;
-                k.value = currentValue;
+                k.value =
+                  currentValue.length === 1 ? currentValue[0] : currentValue;
               }
               return k;
             });
@@ -964,31 +1040,24 @@ export class AnimationCurveEditorComponent extends React.Component<
     valueType: number,
     value: number | Vector2 | Vector3 | Color3 | Color4 | Size | Quaternion
   ) {
-    let valueAsArray: number[] = [];
     switch (valueType) {
       case Animation.ANIMATIONTYPE_FLOAT:
-        valueAsArray = [value as number];
-        break;
+        return [value as number];
       case Animation.ANIMATIONTYPE_VECTOR3:
-        valueAsArray = (value as Vector3).asArray();
-        break;
+        return (value as Vector3).asArray();
       case Animation.ANIMATIONTYPE_VECTOR2:
-        valueAsArray = (value as Vector2).asArray();
-        break;
+        return (value as Vector2).asArray();
       case Animation.ANIMATIONTYPE_QUATERNION:
-        valueAsArray = (value as Quaternion).asArray();
-        break;
+        return (value as Quaternion).asArray();
       case Animation.ANIMATIONTYPE_COLOR3:
-        valueAsArray = (value as Color3).asArray();
-        break;
+        return (value as Color3).asArray();
       case Animation.ANIMATIONTYPE_COLOR4:
-        valueAsArray = (value as Color4).asArray();
-        break;
+        return (value as Color4).asArray();
       case Animation.ANIMATIONTYPE_SIZE:
-        valueAsArray = [(value as Size).width, (value as Size).height];
-        break;
+        return [(value as Size).width, (value as Size).height];
+      default:
+        return [];
     }
-    return valueAsArray;
   }
 
   setValueAsType(valueType: number, arrayValue: number[]) {
@@ -1623,7 +1692,7 @@ export class AnimationCurveEditorComponent extends React.Component<
         }
         let keys = this.state.selected.getKeys();
         let firstFrame = keys[0].frame;
-        let LastFrame = keys[keys.length - 1].frame;
+        let LastFrame = this.state.selected.getHighestFrame();
         if (direction === 1) {
           this._mainAnimatable = this.props.scene.beginAnimation(
             target,
@@ -1632,6 +1701,10 @@ export class AnimationCurveEditorComponent extends React.Component<
             this.state.isLooping,
             this.state.fps
           );
+          console.log(this._mainAnimatable);
+          console.log(
+            `${target}, ${firstFrame}, ${LastFrame}, ${this.state.isLooping}, ${this.state.fps}`
+          );
         }
         if (direction === -1) {
           this._mainAnimatable = this.props.scene.beginAnimation(
@@ -1745,6 +1818,7 @@ export class AnimationCurveEditorComponent extends React.Component<
               ref={this._graphCanvas}
               className='graph-chart'
               onWheel={(e) => this.zoom(e)}>
+              <ScaleLabel current={this.state.valueScale} />
               {this.state.svgKeyframes && (
                 <SvgDraggableArea
                   ref={this._svgCanvas}
@@ -1797,21 +1871,26 @@ export class AnimationCurveEditorComponent extends React.Component<
                       }}></path>
                   ))}
 
-                  {this.setValueLines().map((line, i) => {
+                  {this.setValueLines(this.state.valueScale).map((line, i) => {
                     return (
                       <text
                         key={`value_inline_${i}`}
                         x={this.state.panningX - 5}
                         y={line.value}
-                        dx='0'
-                        dy='1'
-                        style={{ fontSize: `${0.2 * this.state.scale}em` }}>
+                        dx='2'
+                        textAnchor='middle'
+                        dy='-1'
+                        style={{
+                          fontSize: `${0.18 * this.state.scale}em`,
+                          fontWeight: 'bold',
+                          textAlign: 'center',
+                        }}>
                         {line.label}
                       </text>
                     );
                   })}
 
-                  {this.setValueLines().map((line, i) => {
+                  {this.setValueLines(this.state.valueScale).map((line, i) => {
                     return (
                       <line
                         key={i}

+ 15 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss

@@ -1120,6 +1120,21 @@
       height: 364px;
       width: 782px;
 
+      .switch-button {
+        background-color: black;
+        width: 38px;
+        height: 38px;
+        position: absolute;
+        z-index: 100;
+        bottom: 103px;
+        align-items: center;
+        justify-content: center;
+        display: flex;
+        font-size: 12px;
+        font-weight: bold;
+        color: white;
+      }
+
       .linear {
         overflow: visible;
         border: 0px solid white;

+ 27 - 20
inspector/src/components/actionTabs/tabs/propertyGrids/animations/notification.tsx

@@ -1,25 +1,32 @@
-
-import * as React from "react";
+import * as React from 'react';
 
 interface IPlayheadProps {
-    message: string;
-    open: boolean;
-    close: () => void
+  message: string;
+  open: boolean;
+  close: () => void;
 }
 
-export class Notification extends React.Component<IPlayheadProps>{
-    constructor(props: IPlayheadProps) {
-        super(props);
-    }
+export class Notification extends React.Component<IPlayheadProps> {
+  constructor(props: IPlayheadProps) {
+    super(props);
+  }
 
-    render() {
-        return (
-            <div className="notification-area" style={{ display: this.props.open ? 'block' : 'none' }}>
-                <div className="alert alert-error" >
-                    <button type="button" className="close" data-dismiss="alert" onClick={this.props.close}>&times;</button>
-                    {this.props.message}
-                </div>
-            </div>
-        )
-    }
-} 
+  render() {
+    return (
+      <div
+        className='notification-area'
+        style={{ display: this.props.open ? 'block' : 'none' }}>
+        <div className='alert alert-error'>
+          <button
+            type='button'
+            className='close'
+            data-dismiss='alert'
+            onClick={this.props.close}>
+            &times;
+          </button>
+          {this.props.message}
+        </div>
+      </div>
+    );
+  }
+}

+ 44 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/animations/scale-label.tsx

@@ -0,0 +1,44 @@
+import * as React from 'react';
+import { CurveScale } from './animationCurveEditorComponent';
+
+interface ISwitchButtonProps {
+  current: CurveScale;
+  action?: (event: CurveScale) => void;
+}
+
+export class ScaleLabel extends React.Component<
+  ISwitchButtonProps,
+  { current: CurveScale }
+> {
+  constructor(props: ISwitchButtonProps) {
+    super(props);
+    this.state = { current: this.props.current };
+  }
+
+  renderLabel(scale: CurveScale) {
+    switch (scale) {
+      case CurveScale.default:
+        return '';
+      case CurveScale.degrees:
+        return 'DEG';
+      case CurveScale.float:
+        return 'FLT';
+      case CurveScale.integers:
+        return 'INT';
+      case CurveScale.radians:
+        return 'RAD';
+    }
+  }
+
+  render() {
+    return (
+      <div
+        className='switch-button'
+        onClick={() =>
+          this.props.action && this.props.action(this.state.current)
+        }>
+        <p>{this.renderLabel(this.state.current)}</p>
+      </div>
+    );
+  }
+}

+ 4 - 6
inspector/src/components/actionTabs/tabs/propertyGrids/animations/svgDraggableArea.tsx

@@ -276,14 +276,13 @@ export class SvgDraggableArea extends React.Component<
       <>
         <svg
           style={{
-            width: 30,
+            width: 38,
             height: 364,
             position: 'absolute',
             zIndex: 1,
             pointerEvents: 'none',
-          }}
-        >
-          <rect x='0' y='0' width='30px' height='100%' fill='#ffffff1c'></rect>
+          }}>
+          <rect x='0' y='0' width='38px' height='100%' fill='#ffffff1c'></rect>
         </svg>
         <svg
           className='linear pannable'
@@ -299,8 +298,7 @@ export class SvgDraggableArea extends React.Component<
           onClick={(e) => this.focus(e)}
           viewBox={`${this.state.panX} ${this.state.panY} ${Math.round(
             this.props.scale * 200
-          )} ${Math.round(this.props.scale * 100)}`}
-        >
+          )} ${Math.round(this.props.scale * 100)}`}>
           {this.props.children}
 
           {this.props.keyframeSvgPoints.map((keyframe, i) => (