Selaa lähdekoodia

Small fixes for colorpicker

David Catuhe 8 vuotta sitten
vanhempi
commit
70f3c14b5d

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5011 - 5011
dist/preview release/babylon.d.ts


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 5011 - 5011
dist/preview release/babylon.module.d.ts


+ 36 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -506,3 +506,39 @@ declare module BABYLON.GUI {
         static CreateSimpleButton(name: string, text: string): Button;
     }
 }
+
+
+declare var DOMImage: new (width?: number, height?: number) => HTMLImageElement;
+declare module BABYLON.GUI {
+    class ColorPicker extends Control {
+        name: string;
+        private static _ColorWheelCanvas;
+        private _value;
+        private _tmpColor;
+        private _pointerStartedOnSquare;
+        private _pointerStartedOnWheel;
+        private _squareLeft;
+        private _squareTop;
+        private _squareSize;
+        private _h;
+        private _s;
+        private _v;
+        onValueChangedObservable: Observable<Color3>;
+        value: Color3;
+        constructor(name?: string);
+        private _updateSquareProps();
+        private _drawGradientSquare(hueValue, left, top, width, height, context);
+        private _drawCircle(centerX, centerY, radius, context);
+        private _createColorWheelImage(context, radius, thickness);
+        private _RGBtoHSV(color, result);
+        private _HSVtoRGB(hue, saturation, value, result);
+        _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+        private _pointerIsDown;
+        private _updateValueFromPointer(x, y);
+        private _isPointOnSquare(coordinates);
+        private _isPointOnWheel(coordinates);
+        protected _onPointerDown(coordinates: Vector2): boolean;
+        protected _onPointerMove(coordinates: Vector2): void;
+        protected _onPointerUp(coordinates: Vector2): void;
+    }
+}

+ 298 - 0
dist/preview release/gui/babylon.gui.js

@@ -3023,3 +3023,301 @@ var BABYLON;
 })(BABYLON || (BABYLON = {}));
 
 //# sourceMappingURL=button.js.map
+
+/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var DOMImage = Image;
+var BABYLON;
+(function (BABYLON) {
+    var GUI;
+    (function (GUI) {
+        var ColorPicker = (function (_super) {
+            __extends(ColorPicker, _super);
+            function ColorPicker(name) {
+                var _this = _super.call(this, name) || this;
+                _this.name = name;
+                _this._value = BABYLON.Color3.White();
+                _this._tmpColor = new BABYLON.Color3();
+                _this._pointerStartedOnSquare = false;
+                _this._pointerStartedOnWheel = false;
+                _this._squareLeft = 0;
+                _this._squareTop = 0;
+                _this._squareSize = 0;
+                _this._h = 360;
+                _this._s = 1;
+                _this._v = 1;
+                _this.onValueChangedObservable = new BABYLON.Observable();
+                // Events
+                _this._pointerIsDown = false;
+                _this.isPointerBlocker = true;
+                return _this;
+            }
+            Object.defineProperty(ColorPicker.prototype, "value", {
+                get: function () {
+                    return this._value;
+                },
+                set: function (value) {
+                    if (this._value.equals(value)) {
+                        return;
+                    }
+                    this._value.copyFrom(value);
+                    this._RGBtoHSV(this._value, this._tmpColor);
+                    this._h = this._tmpColor.r;
+                    this._s = this._tmpColor.g;
+                    this._v = this._tmpColor.b;
+                    this._markAsDirty();
+                    this.onValueChangedObservable.notifyObservers(this._value);
+                },
+                enumerable: true,
+                configurable: true
+            });
+            ColorPicker.prototype._updateSquareProps = function () {
+                var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+                var wheelThickness = radius * .2;
+                var innerDiameter = (radius - wheelThickness) * 2;
+                var squareSize = innerDiameter / (Math.sqrt(2));
+                var offset = radius - squareSize * .5;
+                this._squareLeft = this._currentMeasure.left + offset;
+                this._squareTop = this._currentMeasure.top + offset;
+                this._squareSize = squareSize;
+            };
+            ColorPicker.prototype._drawGradientSquare = function (hueValue, left, top, width, height, context) {
+                var lgh = context.createLinearGradient(left, top, width + left, top);
+                lgh.addColorStop(0, '#fff');
+                lgh.addColorStop(1, 'hsl(' + hueValue + ', 100%, 50%)');
+                context.fillStyle = lgh;
+                context.fillRect(left, top, width, height);
+                var lgv = context.createLinearGradient(left, top, left, height + top);
+                lgv.addColorStop(0, 'rgba(0,0,0,0)');
+                lgv.addColorStop(1, '#000');
+                context.fillStyle = lgv;
+                context.fillRect(left, top, width, height);
+            };
+            ColorPicker.prototype._drawCircle = function (centerX, centerY, radius, context) {
+                context.beginPath();
+                context.arc(centerX, centerY, radius + 1, 0, 2 * Math.PI, false);
+                context.lineWidth = 3;
+                context.strokeStyle = '#333333';
+                context.stroke();
+                context.beginPath();
+                context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
+                context.lineWidth = 3;
+                context.strokeStyle = '#ffffff';
+                context.stroke();
+            };
+            ColorPicker.prototype._createColorWheelImage = function (context, radius, thickness) {
+                ColorPicker._ColorWheelCanvas = document.createElement("canvas");
+                ColorPicker._ColorWheelCanvas.width = radius * 2;
+                ColorPicker._ColorWheelCanvas.height = radius * 2;
+                var context = ColorPicker._ColorWheelCanvas.getContext("2d");
+                var image = context.getImageData(0, 0, radius * 2, radius * 2);
+                var data = image.data;
+                var color = this._tmpColor;
+                var maxDistSq = radius * radius;
+                var innerRadius = radius - thickness;
+                var minDistSq = innerRadius * innerRadius;
+                for (var x = -radius; x < radius; x++) {
+                    for (var y = -radius; y < radius; y++) {
+                        var distSq = x * x + y * y;
+                        if (distSq > maxDistSq || distSq < minDistSq) {
+                            continue;
+                        }
+                        var dist = Math.sqrt(distSq);
+                        var ang = Math.atan2(y, x);
+                        this._HSVtoRGB(ang * 180 / Math.PI + 180, dist / radius, 1, color);
+                        var index = ((x + radius) + ((y + radius) * 2 * radius)) * 4;
+                        data[index] = color.r * 255;
+                        data[index + 1] = color.g * 255;
+                        data[index + 2] = color.b * 255;
+                        var alphaRatio = (distSq - minDistSq) / (maxDistSq - minDistSq);
+                        if (alphaRatio < 0.2) {
+                            data[index + 3] = 255 * (alphaRatio / 0.2);
+                        }
+                        else if (alphaRatio > 0.8) {
+                            data[index + 3] = 255 * (1.0 - ((alphaRatio - 0.8) / 0.2));
+                        }
+                        else {
+                            data[index + 3] = 255;
+                        }
+                    }
+                }
+                context.putImageData(image, 0, 0);
+            };
+            ColorPicker.prototype._RGBtoHSV = function (color, result) {
+                var r = color.r;
+                var g = color.g;
+                var b = color.b;
+                var max = Math.max(r, g, b);
+                var min = Math.min(r, g, b);
+                var h = 0;
+                var s = 0;
+                var v = max;
+                var dm = max - min;
+                if (max !== 0) {
+                    s = dm / max;
+                }
+                if (max != min) {
+                    if (max == r) {
+                        h = (g - b) / dm;
+                        if (g < b) {
+                            h += 6;
+                        }
+                    }
+                    else if (max == g) {
+                        h = (b - r) / dm + 2;
+                    }
+                    else if (max == b) {
+                        h = (r - g) / dm + 4;
+                    }
+                    h *= 60;
+                }
+                result.r = h;
+                result.g = s;
+                result.b = v;
+            };
+            ColorPicker.prototype._HSVtoRGB = function (hue, saturation, value, result) {
+                var chroma = value * saturation;
+                var h = hue / 60;
+                var x = chroma * (1 - Math.abs((h % 2) - 1));
+                var r = 0;
+                var g = 0;
+                var b = 0;
+                if (h >= 0 && h <= 1) {
+                    r = chroma;
+                    g = x;
+                }
+                else if (h >= 1 && h <= 2) {
+                    r = x;
+                    g = chroma;
+                }
+                else if (h >= 2 && h <= 3) {
+                    g = chroma;
+                    b = x;
+                }
+                else if (h >= 3 && h <= 4) {
+                    g = x;
+                    b = chroma;
+                }
+                else if (h >= 4 && h <= 5) {
+                    r = x;
+                    b = chroma;
+                }
+                else if (h >= 5 && h <= 6) {
+                    r = chroma;
+                    b = x;
+                }
+                var m = value - chroma;
+                result.set((r + m), (g + m), (b + m));
+            };
+            ColorPicker.prototype._draw = function (parentMeasure, context) {
+                context.save();
+                this._applyStates(context);
+                if (this._processMeasures(parentMeasure, context)) {
+                    var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+                    var wheelThickness = radius * .2;
+                    var left = this._currentMeasure.left;
+                    var top = this._currentMeasure.top;
+                    if (!ColorPicker._ColorWheelCanvas) {
+                        this._createColorWheelImage(context, radius, wheelThickness);
+                    }
+                    context.drawImage(ColorPicker._ColorWheelCanvas, left, top);
+                    this._updateSquareProps();
+                    this._drawGradientSquare(this._h, this._squareLeft, this._squareTop, this._squareSize, this._squareSize, context);
+                    var cx = this._squareLeft + this._squareSize * this._s;
+                    var cy = this._squareTop + this._squareSize * (1 - this._v);
+                    this._drawCircle(cx, cy, radius * .04, context);
+                    var dist = radius - wheelThickness * .5;
+                    cx = left + radius + Math.cos((this._h - 180) * Math.PI / 180) * dist;
+                    cy = top + radius + Math.sin((this._h - 180) * Math.PI / 180) * dist;
+                    this._drawCircle(cx, cy, wheelThickness * .35, context);
+                }
+                context.restore();
+            };
+            ColorPicker.prototype._updateValueFromPointer = function (x, y) {
+                if (this._pointerStartedOnWheel) {
+                    var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+                    var centerX = radius + this._currentMeasure.left;
+                    var centerY = radius + this._currentMeasure.top;
+                    this._h = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI + 180;
+                }
+                else if (this._pointerStartedOnSquare) {
+                    this._updateSquareProps();
+                    this._s = (x - this._squareLeft) / this._squareSize;
+                    this._v = 1 - (y - this._squareTop) / this._squareSize;
+                    this._s = Math.min(this._s, 1);
+                    this._s = Math.max(this._s, 0.00001);
+                    this._v = Math.min(this._v, 1);
+                    this._v = Math.max(this._v, 0.00001);
+                }
+                this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
+                this.value = this._tmpColor;
+            };
+            ColorPicker.prototype._isPointOnSquare = function (coordinates) {
+                this._updateSquareProps();
+                var left = this._squareLeft;
+                var top = this._squareTop;
+                var size = this._squareSize;
+                if (coordinates.x >= left && coordinates.x <= left + size &&
+                    coordinates.y >= top && coordinates.y <= top + size) {
+                    return true;
+                }
+                return false;
+            };
+            ColorPicker.prototype._isPointOnWheel = function (coordinates) {
+                var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+                var centerX = radius + this._currentMeasure.left;
+                var centerY = radius + this._currentMeasure.top;
+                var wheelThickness = radius * .2;
+                var innerRadius = radius - wheelThickness;
+                var radiusSq = radius * radius;
+                var innerRadiusSq = innerRadius * innerRadius;
+                var dx = coordinates.x - centerX;
+                var dy = coordinates.y - centerY;
+                var distSq = dx * dx + dy * dy;
+                if (distSq <= radiusSq && distSq >= innerRadiusSq) {
+                    return true;
+                }
+                return false;
+            };
+            ColorPicker.prototype._onPointerDown = function (coordinates) {
+                if (!_super.prototype._onPointerDown.call(this, coordinates)) {
+                    return false;
+                }
+                this._pointerIsDown = true;
+                this._pointerStartedOnSquare = false;
+                this._pointerStartedOnWheel = false;
+                if (this._isPointOnSquare(coordinates)) {
+                    this._pointerStartedOnSquare = true;
+                }
+                else if (this._isPointOnWheel(coordinates)) {
+                    this._pointerStartedOnWheel = true;
+                }
+                this._updateValueFromPointer(coordinates.x, coordinates.y);
+                this._host._capturingControl = this;
+                return true;
+            };
+            ColorPicker.prototype._onPointerMove = function (coordinates) {
+                if (this._pointerIsDown) {
+                    this._updateValueFromPointer(coordinates.x, coordinates.y);
+                }
+                _super.prototype._onPointerMove.call(this, coordinates);
+            };
+            ColorPicker.prototype._onPointerUp = function (coordinates) {
+                this._pointerIsDown = false;
+                this._host._capturingControl = null;
+                _super.prototype._onPointerUp.call(this, coordinates);
+            };
+            return ColorPicker;
+        }(GUI.Control));
+        GUI.ColorPicker = ColorPicker;
+    })(GUI = BABYLON.GUI || (BABYLON.GUI = {}));
+})(BABYLON || (BABYLON = {}));

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


+ 36 - 37
gui/src/controls/colorpicker.ts

@@ -4,9 +4,9 @@ var DOMImage = Image;
 
 module BABYLON.GUI {
     export class ColorPicker extends Control {
+        private static _ColorWheelCanvas: HTMLCanvasElement;
         
         private _value:Color3 = Color3.White();
-        private _colorWheelImage:ImageData;
         private _tmpColor = new Color3();
 
         private _pointerStartedOnSquare = false;
@@ -50,8 +50,7 @@ module BABYLON.GUI {
             this.isPointerBlocker = true;
         }
 
-        private _updateSquareProps():void{
-
+        private _updateSquareProps():void {
             var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
             var wheelThickness = radius*.2;
             var innerDiameter = (radius-wheelThickness)*2;
@@ -61,11 +60,9 @@ module BABYLON.GUI {
             this._squareLeft = this._currentMeasure.left + offset;
             this._squareTop = this._currentMeasure.top + offset;
             this._squareSize = squareSize;
-
         }
 
-        private _drawGradientSquare(hueValue:number, left:number, top:number, width:number, height:number, context: CanvasRenderingContext2D){
-
+        private _drawGradientSquare(hueValue:number, left:number, top:number, width:number, height:number, context: CanvasRenderingContext2D) {
             var lgh = context.createLinearGradient(left, top, width+left, top);
             lgh.addColorStop(0, '#fff');
             lgh.addColorStop(1,  'hsl(' + hueValue + ', 100%, 50%)');
@@ -79,11 +76,9 @@ module BABYLON.GUI {
 
             context.fillStyle = lgv;
             context.fillRect(left, top, width, height);
-
         }
 
-        private _drawCircle(centerX:number, centerY:number, radius:number, context: CanvasRenderingContext2D){
-
+        private _drawCircle(centerX:number, centerY:number, radius:number, context: CanvasRenderingContext2D) {
             context.beginPath();
             context.arc(centerX, centerY, radius+1, 0, 2 * Math.PI, false);
             context.lineWidth = 3;
@@ -94,12 +89,14 @@ module BABYLON.GUI {
             context.lineWidth = 3;
             context.strokeStyle = '#ffffff';
             context.stroke();
-
         }
 
-        private _createColorWheelImage(context: CanvasRenderingContext2D, radius:number, thickness:number):ImageData{
-
-            var image = context.createImageData(radius*2, radius*2);
+        private _createColorWheelImage(context: CanvasRenderingContext2D, radius:number, thickness:number): void {
+            ColorPicker._ColorWheelCanvas = document.createElement("canvas");
+            ColorPicker._ColorWheelCanvas.width = radius * 2;
+            ColorPicker._ColorWheelCanvas.height = radius * 2;
+            var context = ColorPicker._ColorWheelCanvas.getContext("2d");
+            var image = context.getImageData(0, 0, radius * 2, radius * 2);
             var data = image.data;
             
             var color = this._tmpColor;
@@ -124,19 +121,24 @@ module BABYLON.GUI {
                     var index = ((x + radius) + ((y + radius)*2*radius)) * 4;
                     
                     data[index] = color.r*255;
-                    data[index+1] = color.g*255;
-                    data[index+2] = color.b*255;
-                    data[index+3] = 255;
-
+                    data[index + 1] = color.g*255;
+                    data[index + 2] = color.b*255;      
+                    var alphaRatio = (distSq - minDistSq) / (maxDistSq - minDistSq);
+
+                    if (alphaRatio < 0.2) {
+                        data[index + 3] = 255 * (alphaRatio / 0.2);
+                    } else if (alphaRatio > 0.8) {
+                        data[index + 3] = 255 * (1.0 - ((alphaRatio - 0.8) / 0.2));
+                    } else {
+                        data[index + 3] = 255;
+                    }
                 }
             }
 
-            return image;
-
+            context.putImageData(image, 0, 0);
         }
 
         private _RGBtoHSV(color:Color3, result:Color3){
-
             var r = color.r;
             var g = color.g;
             var b = color.b;
@@ -170,11 +172,9 @@ module BABYLON.GUI {
             result.r = h;
             result.g = s;
             result.b = v;
-
         }
 
         private _HSVtoRGB(hue:number, saturation:number, value:number, result:Color3) {
-
             var chroma = value * saturation;
             var h = hue / 60;
             var x = chroma * (1- Math.abs((h % 2) - 1));
@@ -203,8 +203,7 @@ module BABYLON.GUI {
             }
             
             var m = value - chroma;
-            result.set((r+m), (g+m), (b+m));
-            
+            result.set((r+m), (g+m), (b+m));            
         }
 
         public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
@@ -218,11 +217,11 @@ module BABYLON.GUI {
                 var left = this._currentMeasure.left;
                 var top = this._currentMeasure.top;
 
-                if(!this._colorWheelImage){
-                    this._colorWheelImage = this._createColorWheelImage(context, radius, wheelThickness);
+                if(!ColorPicker._ColorWheelCanvas){
+                    this._createColorWheelImage(context, radius, wheelThickness);
                 }
 
-                context.putImageData(this._colorWheelImage, left, top);
+                context.drawImage(ColorPicker._ColorWheelCanvas, left, top);
 
                 this._updateSquareProps();
 
@@ -251,7 +250,6 @@ module BABYLON.GUI {
         private _pointerIsDown = false;
 
         private _updateValueFromPointer(x: number, y:number): void {
-
             if(this._pointerStartedOnWheel)
             {
                 var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
@@ -273,11 +271,9 @@ module BABYLON.GUI {
             this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
 
             this.value = this._tmpColor;
-
         }
 
-        private _isPointOnSquare(coordinates: Vector2):boolean{
-
+        private _isPointOnSquare(coordinates: Vector2):boolean {
             this._updateSquareProps();
 
             var left = this._squareLeft;
@@ -290,11 +286,9 @@ module BABYLON.GUI {
             }
 
             return false;
-
         }
 
-        private _isPointOnWheel(coordinates: Vector2):boolean{
-
+        private _isPointOnWheel(coordinates: Vector2):boolean {
             var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
             var centerX = radius + this._currentMeasure.left;
             var centerY = radius + this._currentMeasure.top;
@@ -313,10 +307,13 @@ module BABYLON.GUI {
             }
 
             return false;
-
         }
 
-        protected _onPointerDown(coordinates: Vector2): void {
+        protected _onPointerDown(coordinates: Vector2): boolean {
+            if (!super._onPointerDown(coordinates)) {
+                return false;
+            }            
+
             this._pointerIsDown = true;
 
             this._pointerStartedOnSquare = false;
@@ -334,13 +331,15 @@ module BABYLON.GUI {
             this._updateValueFromPointer(coordinates.x, coordinates.y);
             this._host._capturingControl = this;
 
-            super._onPointerDown(coordinates);
+            return true;
         }
 
         protected _onPointerMove(coordinates: Vector2): void {
             if (this._pointerIsDown) {
                 this._updateValueFromPointer(coordinates.x, coordinates.y);
             }
+
+            super._onPointerMove(coordinates);
         }
 
         protected _onPointerUp (coordinates: Vector2): void {