Browse Source

Add new color picker to nme

David Catuhe 5 năm trước cách đây
mục cha
commit
75347fb77a

+ 15 - 1
.vscode/launch.json

@@ -13,7 +13,21 @@
             "runtimeArgs": [
                 "--enable-unsafe-es3-apis"
             ]
-        },        
+        },           
+        {
+            "name": "Launch Node Material Editor (Edge)",
+            "type": "edge",
+            "version": "dev",
+            "request": "launch",
+            "url": "http://localhost:1338/nodeEditor/public/index-local.html",
+            "webRoot": "${workspaceRoot}/",
+            "sourceMaps": true,
+            "preLaunchTask": "run",
+            "userDataDir": "${workspaceRoot}/.tempChromeProfileForDebug",
+            "runtimeArgs": [
+                "--enable-unsafe-es3-apis"
+            ]
+        },      
         {
             "name": "Launch Viewer (Chrome)",
             "type": "chrome",

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"thinEngineOnly":114605,"engineOnly":151234,"sceneOnly":508412,"minGridMaterial":640273,"minStandardMaterial":781344}
+{"thinEngineOnly":114605,"engineOnly":151234,"sceneOnly":508624,"minGridMaterial":640485,"minStandardMaterial":781556}

+ 28 - 1
nodeEditor/src/components/propertyTab/propertyTab.scss

@@ -208,6 +208,32 @@
         }
     }
 
+    .color-picker {
+        height: calc(100% - 8px);
+        margin: 4px;
+        width: 100%;
+
+        .color-rect {
+            height: calc(100% - 4px);
+            border: 2px white solid;
+            cursor: pointer;
+            min-height: 18px;
+        }
+
+        .color-picker-cover {
+            position: fixed;
+            top: 0px;
+            right: 0px;
+            bottom: 0px;
+            left: 0px;
+        }
+
+        .color-picker-float {
+            z-index: 2;
+            position: absolute;  
+        }                
+    }
+
     .gradient-step {
         display: grid;
         grid-template-rows: 100%;
@@ -508,7 +534,8 @@
             }
 
             .color3 {
-                grid-column: 2;
+                grid-column: 2;                
+                width: 50px;
                 
                 display: flex;
                 align-items: center;            

+ 4 - 2
nodeEditor/src/sharedComponents/color3LineComponent.tsx

@@ -6,6 +6,7 @@ import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { GlobalState } from '../globalState';
+import { ColorPickerLineComponent } from './colorPickerComponent';
 
 const copyIcon: string = require("./copy.svg");
 
@@ -139,7 +140,6 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
     render() {
 
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
-        const colorAsColor3 = this.state.color.getClassName() === "Color3" ? this.state.color : new Color3(this.state.color.r, this.state.color.g, this.state.color.b);
 
         return (
             <div className="color3Line">
@@ -148,7 +148,9 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
                         {this.props.label}
                     </div>
                     <div className="color3">
-                        <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                        <ColorPickerLineComponent value={this.state.color} disableAlpha={true} onColorChanged={color => {
+                                this.onChange(color);
+                            }} />  
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                         <img src={copyIcon} alt=""/>

+ 6 - 4
nodeEditor/src/sharedComponents/color4LineComponent.tsx

@@ -6,6 +6,7 @@ import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { GlobalState } from '../globalState';
+import { ColorPickerLineComponent } from './colorPickerComponent';
 
 const copyIcon: string = require("./copy.svg");
 
@@ -42,7 +43,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
 
     onChange(newValue: string) {
         this._localChange = true;
-        const newColor = Color3.FromHexString(newValue);
+        const newColor = Color4.FromHexString(newValue);
 
         if (this.props.onPropertyChangedObservable) {
             this.props.onPropertyChangedObservable.notifyObservers({
@@ -53,7 +54,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
             });
         }
 
-        this.props.target[this.props.propertyName] = new Color4(newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
+        this.props.target[this.props.propertyName] = newColor;
 
         this.setState({ color: this.props.target[this.props.propertyName] });
 
@@ -150,7 +151,6 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
     render() {
 
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
-        const colorAsColor3 = new Color3(this.state.color.r, this.state.color.g, this.state.color.b);
 
         return (
             <div className="color3Line">
@@ -159,7 +159,9 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
                         {this.props.label}
                     </div>
                     <div className="color3">
-                        <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                        <ColorPickerLineComponent value={this.state.color} onColorChanged={color => {
+                                this.onChange(color);
+                            }} />  
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                         <img src={copyIcon} alt=""/>

+ 111 - 0
nodeEditor/src/sharedComponents/colorPickerComponent.tsx

@@ -0,0 +1,111 @@
+import * as React from "react";
+import { Color4, Color3 } from 'babylonjs/Maths/math.color';
+import { SketchPicker } from 'react-color';
+
+export interface IColorPickerComponentProps {
+    value: Color4 | Color3;
+    onColorChanged: (newOne: string) => void;
+    disableAlpha?: boolean;
+}
+
+interface IColorPickerComponentState {
+    pickerEnabled: boolean;
+    color: {
+        r: number,
+        g: number,
+        b: number,
+        a?: number
+    },
+    hex: string
+}
+
+export class ColorPickerLineComponent extends React.Component<IColorPickerComponentProps, IColorPickerComponentState> {
+    private _floatRef: React.RefObject<HTMLDivElement>
+    private _floatHostRef: React.RefObject<HTMLDivElement>
+
+    constructor(props: IColorPickerComponentProps) {
+        super(props);
+
+        this.state = {pickerEnabled: false, color: {
+            r: this.props.value.r * 255,
+            g: this.props.value.g * 255,
+            b: this.props.value.b * 255,
+            a: this.props.value instanceof Color4 ? this.props.value.a * 100 : 100,
+        }, hex: this.props.value.toHexString()};
+        
+        this._floatRef = React.createRef();
+        this._floatHostRef = React.createRef();
+    }
+
+    syncPositions() {
+        const div = this._floatRef.current as HTMLDivElement;
+        const host = this._floatHostRef.current as HTMLDivElement;
+
+        if (!div || !host) {
+            return;
+        }
+
+        let top = host.getBoundingClientRect().top;
+        let height = div.getBoundingClientRect().height;
+
+        if (top + height + 10 > window.innerHeight) {
+            top = window.innerHeight - height - 10;
+        }
+
+        div.style.top = top + "px";
+        div.style.left = host.getBoundingClientRect().left - div.getBoundingClientRect().width + "px";
+    }
+
+    shouldComponentUpdate(nextProps: IColorPickerComponentProps, nextState: IColorPickerComponentState) {
+        return nextProps.value.toHexString() !== this.props.value.toHexString() 
+            || nextProps.disableAlpha !== this.props.disableAlpha 
+            || nextState.hex !== this.state.hex
+            || nextState.pickerEnabled !== this.state.pickerEnabled;
+    }
+
+    componentDidUpdate() {
+        this.syncPositions();
+    }
+
+    componentDidMount() {
+        this.syncPositions();
+    }
+
+    render() {
+        var color = this.state.color;
+
+        return (
+            <div className="color-picker">
+                <div className="color-rect"  ref={this._floatHostRef} 
+                    style={{background: this.state.hex}} 
+                    onClick={() => this.setState({pickerEnabled: true})}>
+
+                </div>
+                {
+                    this.state.pickerEnabled &&
+                    <>
+                        <div className="color-picker-cover" onClick={() => this.setState({pickerEnabled: false})}></div>
+                        <div className="color-picker-float" ref={this._floatRef}>
+                            <SketchPicker color={color} 
+                                disableAlpha={this.props.disableAlpha}
+                                onChange={(color) => {
+                                    let hex: string;
+
+                                    if (this.props.disableAlpha) {
+                                        let newColor3 = Color3.FromInts(color.rgb.r, color.rgb.g, color.rgb.b);
+                                        hex = newColor3.toHexString();    
+                                    } else {
+                                        let newColor4 = Color4.FromInts(color.rgb.r, color.rgb.g, color.rgb.b, 255 * (color.rgb.a || 0));
+                                        hex = newColor4.toHexString();   
+                                    }
+                                    this.setState({hex: hex, color: color.rgb});
+                                    this.props.onColorChanged(hex);
+                                }}
+                            />
+                        </div>
+                    </>
+                }                
+            </div>
+        );
+    }
+}