Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (237604 => 237605)
--- trunk/Source/WebInspectorUI/ChangeLog 2018-10-30 22:10:56 UTC (rev 237604)
+++ trunk/Source/WebInspectorUI/ChangeLog 2018-10-30 22:15:16 UTC (rev 237605)
@@ -1,5 +1,52 @@
2018-10-30 Devin Rousso <[email protected]>
+ Web Inspector: change WI.ColorWheel to use conic-gradient()
+ https://bugs.webkit.org/show_bug.cgi?id=189485
+
+ Reviewed by Brian Burg.
+
+ Use the ("new") HSL `WI.ColorPicker` if `conic-gradient` is supported. Otherwise, use the
+ ("old") RGB `WI.LegacyColorPicker`.
+
+ * UserInterface/Views/ColorWheel.js:
+ (WI.ColorWheel):
+ (WI.ColorWheel.prototype.set dimension):
+ (WI.ColorWheel.prototype.set brightness):
+ (WI.ColorWheel.prototype.get tintedColor):
+ (WI.ColorWheel.prototype.set tintedColor):
+ (WI.ColorWheel.prototype.get rawColor):
+ (WI.ColorWheel.prototype.get _hue): Added.
+ (WI.ColorWheel.prototype.get _saturation): Added.
+ (WI.ColorWheel.prototype._updateColorForMouseEvent):
+ (WI.ColorWheel.prototype._setCrosshairPosition):
+ (WI.ColorWheel.prototype._updateGradient): Added.
+ (WI.ColorWheel.prototype._pointInCircleForEvent.distance): Deleted.
+ (WI.ColorWheel.prototype._pointInCircleForEvent.angleFromCenterToPoint): Deleted.
+ (WI.ColorWheel.prototype._pointInCircleForEvent.pointOnCircumference): Deleted.
+ (WI.ColorWheel.prototype._pointInCircleForEvent): Deleted.
+ (WI.ColorWheel.prototype._tintedColorToPointAndBrightness): Deleted.
+ (WI.ColorWheel.prototype._drawRawCanvas): Deleted.
+ (WI.ColorWheel.prototype._colorAtPointWithBrightness): Deleted.
+ (WI.ColorWheel.prototype._drawTintedCanvas): Deleted.
+ (WI.ColorWheel.prototype._draw): Deleted.
+ * UserInterface/Views/ColorWheel.css:
+ (.color-wheel > .gradient): Added.
+ (.color-wheel > .crosshair): Added.
+
+ * UserInterface/Views/LegacyColorWheel.js: Copied from Source/WebInspectorUI/UserInterface/Views/ColorWheel.js.
+
+ * UserInterface/Views/ColorPicker.js:
+ (WI.ColorPicker):
+ (WI.ColorPicker.supportsConicGradient): Added.
+ (WI.ColorPicker.prototype._updateSliders):
+
+ * UserInterface/Models/Geometry.js:
+ (WI.Point.prototype.distance):
+
+ * UserInterface/Main.html:
+
+2018-10-30 Devin Rousso <[email protected]>
+
Web Inspector: make the layers sidebar in the Elements tab always visible
https://bugs.webkit.org/show_bug.cgi?id=190158
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (237604 => 237605)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2018-10-30 22:10:56 UTC (rev 237604)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2018-10-30 22:15:16 UTC (rev 237605)
@@ -780,6 +780,8 @@
<script src=""
<script src=""
+ <script src=""
+
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Geometry.js (237604 => 237605)
--- trunk/Source/WebInspectorUI/UserInterface/Models/Geometry.js 2018-10-30 22:10:56 UTC (rev 237604)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Geometry.js 2018-10-30 22:15:16 UTC (rev 237605)
@@ -63,9 +63,9 @@
distance(anotherPoint)
{
- var dx = anotherPoint.x - this.x;
- var dy = anotherPoint.y - this.y;
- return Math.sqrt(dx * dx, dy * dy);
+ let dx = anotherPoint.x - this.x;
+ let dy = anotherPoint.y - this.y;
+ return Math.sqrt((dx * dx) + (dy * dy));
}
};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js (237604 => 237605)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js 2018-10-30 22:10:56 UTC (rev 237604)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorPicker.js 2018-10-30 22:15:16 UTC (rev 237605)
@@ -29,7 +29,7 @@
{
super();
- this._colorWheel = new WI.ColorWheel;
+ this._colorWheel = WI.ColorPicker.supportsConicGradient() ? new WI.ColorWheel : new WI.LegacyColorWheel;
this._colorWheel.delegate = this;
this._colorWheel.dimension = 200;
@@ -90,6 +90,24 @@
this._enableColorComponentInputs = true;
}
+ // Static
+
+ static supportsConicGradient()
+ {
+ if (WI.ColorPicker._supportsConicGradient === undefined) {
+ const property = "background-image";
+ const conicGradient = "conic-gradient(black, white)";
+
+ let element = document.body.appendChild(document.createElement("div"));
+ element.style.setProperty(property, conicGradient);
+
+ WI.ColorPicker._supportsConicGradient = window.getComputedStyle(element).getPropertyValue(property).includes(conicGradient);
+
+ element.remove();
+ }
+ return WI.ColorPicker._supportsConicGradient;
+ }
+
// Public
get element()
@@ -211,8 +229,14 @@
var opaque = new WI.Color(WI.Color.Format.RGBA, rgb.concat(1)).toString();
var transparent = new WI.Color(WI.Color.Format.RGBA, rgb.concat(0)).toString();
- this._opacitySlider.element.style.backgroundImage = "linear-gradient(90deg, " + transparent + ", " + opaque + "), " + this._opacityPattern;
- this._brightnessSlider.element.style.backgroundImage = "linear-gradient(90deg, black, " + rawColor + ")";
+ let brightnessGradient = "";
+ if (WI.ColorPicker.supportsConicGradient())
+ brightnessGradient = `linear-gradient(90deg, black, ${rawColor}, white)`;
+ else
+ brightnessGradient = `linear-gradient(90deg, black, ${rawColor})`;
+ this._brightnessSlider.element.style.setProperty("background-image", brightnessGradient);
+
+ this._opacitySlider.element.style.setProperty("background-image", "linear-gradient(90deg, " + transparent + ", " + opaque + "), " + this._opacityPattern);
}
_handleFormatChange()
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.css (237604 => 237605)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.css 2018-10-30 22:10:56 UTC (rev 237604)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.css 2018-10-30 22:15:16 UTC (rev 237605)
@@ -27,14 +27,22 @@
position: relative;
}
+.color-wheel > .gradient {
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+}
+
.color-wheel > .crosshair {
position: absolute;
- top: -4px;
- left: -3px;
- width: 5px;
- height: 5px;
+ top: calc(-1 * var(--crosshair-size) / 2);
+ left: calc(-1 * var(--crosshair-size) / 2);
+ width: var(--crosshair-size);
+ height: var(--crosshair-size);
+ background-color: white;
border: 1px solid black;
border-radius: 3px;
pointer-events: none;
- background-color: white;
+
+ --crosshair-size: 5px;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js (237604 => 237605)
--- trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js 2018-10-30 22:10:56 UTC (rev 237604)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js 2018-10-30 22:15:16 UTC (rev 237605)
@@ -29,46 +29,33 @@
{
super();
- this._rawCanvas = document.createElement("canvas");
- this._tintedCanvas = document.createElement("canvas");
- this._finalCanvas = document.createElement("canvas");
+ this._brightness = 0.5;
- this._crosshair = document.createElement("div");
- this._crosshair.className = "crosshair";
-
this._element = document.createElement("div");
this._element.className = "color-wheel";
- this._element.appendChild(this._finalCanvas);
- this._element.appendChild(this._crosshair);
+ this._gradientElement = this._element.appendChild(document.createElement("div"));
+ this._gradientElement.classList.add("gradient");
+ this._gradientElement.addEventListener("mousedown", this);
- this._finalCanvas.addEventListener("mousedown", this);
+ this._crosshairElement = this._element.appendChild(document.createElement("div"));
+ this._crosshairElement.className = "crosshair";
}
// Public
+ get element() { return this._element; }
+
set dimension(dimension)
{
- this._element.style.width = this.element.style.height = `${dimension}px`;
-
- this._finalCanvas.width = this._tintedCanvas.width = this._rawCanvas.width = dimension * window.devicePixelRatio;
- this._finalCanvas.height = this._tintedCanvas.height = this._rawCanvas.height = dimension * window.devicePixelRatio;
-
- this._finalCanvas.style.width = this._finalCanvas.style.height = dimension + "px";
-
this._dimension = dimension;
- // We shrink the radius a bit for better anti-aliasing.
- this._radius = dimension / 2 - 2;
- this._setCrosshairPosition(new WI.Point(dimension / 2, dimension / 2));
+ this._element.style.width = this.element.style.height = `${this._dimension}px`;
- this._drawRawCanvas();
- this._draw();
- }
+ let center = this._dimension / 2;
+ this._setCrosshairPosition(new WI.Point(center, center));
- get element()
- {
- return this._element;
+ this._updateGradient();
}
get brightness()
@@ -79,30 +66,35 @@
set brightness(brightness)
{
this._brightness = brightness;
- this._draw();
+ this._updateGradient();
}
get tintedColor()
{
if (this._crosshairPosition)
- return this._colorAtPointWithBrightness(this._crosshairPosition.x * window.devicePixelRatio, this._crosshairPosition.y * window.devicePixelRatio, this._brightness);
-
- return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
+ return new WI.Color(WI.Color.Format.HSL, [this._hue, this._saturation, this._brightness * 100]);
+ return new WI.Color(WI.Color.Format.HSLA, [0, 0, 0, 0]);
}
set tintedColor(tintedColor)
{
- var data = ""
- this._setCrosshairPosition(data.point);
- this.brightness = data.brightness;
+ let hsl = tintedColor.hsl;
+
+ let cosHue = Math.cos(hsl[0] * Math.PI / 180);
+ let sinHue = Math.sin(hsl[0] * Math.PI / 180);
+ let center = this._dimension / 2;
+ let x = center + (sinHue * hsl[1]);
+ let y = center - (cosHue * hsl[1]);
+ this._setCrosshairPosition(new WI.Point(x, y));
+
+ this.brightness = hsl[2] / 100;
}
get rawColor()
{
if (this._crosshairPosition)
- return this._colorAtPointWithBrightness(this._crosshairPosition.x * window.devicePixelRatio, this._crosshairPosition.y * window.devicePixelRatio, 1);
-
- return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
+ return new WI.Color(WI.Color.Format.HSL, [this._hue, this._saturation, 50]);
+ return new WI.Color(WI.Color.Format.HSLA, [0, 0, 0, 0]);
}
// Protected
@@ -124,6 +116,23 @@
// Private
+ get _hue()
+ {
+ let center = this._dimension / 2;
+ let hue = Math.atan2(this._crosshairPosition.x - center, center - this._crosshairPosition.y) * 180 / Math.PI;
+ if (hue < 0)
+ hue += 360;
+ return hue;
+ }
+
+ get _saturation()
+ {
+ let center = this._dimension / 2;
+ let xDis = (this._crosshairPosition.x - center) / center;
+ let yDis = (this._crosshairPosition.y - center) / center;
+ return Math.sqrt(Math.pow(xDis, 2) + Math.pow(yDis, 2)) * 100;
+ }
+
_handleMousedown(event)
{
window.addEventListener("mousemove", this, true);
@@ -143,36 +152,9 @@
window.removeEventListener("mouseup", this, true);
}
- _pointInCircleForEvent(event)
- {
- function distance(a, b)
- {
- return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
- }
-
- function angleFromCenterToPoint(center, point)
- {
- return Math.atan2(point.y - center.y, point.x - center.x);
- }
-
- function pointOnCircumference(c, r, a)
- {
- return new WI.Point(c.x + r * Math.cos(a), c.y + r * Math.sin(a));
- }
-
- var dimension = this._dimension;
- var point = window.webkitConvertPointFromPageToNode(this._finalCanvas, new WebKitPoint(event.pageX, event.pageY));
- var center = new WI.Point(dimension / 2, dimension / 2);
- if (distance(point, center) > this._radius) {
- var angle = angleFromCenterToPoint(center, point);
- point = pointOnCircumference(center, this._radius, angle);
- }
- return point;
- }
-
_updateColorForMouseEvent(event)
{
- var point = this._pointInCircleForEvent(event);
+ var point = window.webkitConvertPointFromPageToNode(this._gradientElement, new WebKitPoint(event.pageX, event.pageY));
this._setCrosshairPosition(point);
@@ -182,103 +164,25 @@
_setCrosshairPosition(point)
{
- this._crosshairPosition = point;
- this._crosshair.style.webkitTransform = "translate(" + Math.round(point.x) + "px, " + Math.round(point.y) + "px)";
- }
+ let radius = this._dimension / 2;
+ let center = new WI.Point(radius, radius);
- _tintedColorToPointAndBrightness(color)
- {
- var rgb = color.rgb;
- var hsv = WI.Color.rgb2hsv(rgb[0], rgb[1], rgb[2]);
- var cosHue = Math.cos(hsv[0] * Math.PI / 180);
- var sinHue = Math.sin(hsv[0] * Math.PI / 180);
- var center = this._dimension / 2;
- var x = center + (center * cosHue * hsv[1]);
- var y = center - (center * sinHue * hsv[1]);
- return {
- point: new WI.Point(x, y),
- brightness: hsv[2]
- };
- }
-
- _drawRawCanvas() {
- var ctx = this._rawCanvas.getContext("2d");
-
- var dimension = this._dimension * window.devicePixelRatio;
-
- ctx.fillStyle = "white";
- ctx.fillRect(0, 0, dimension, dimension);
-
- var imageData = ctx.getImageData(0, 0, dimension, dimension);
- var data = ""
- for (var j = 0; j < dimension; ++j) {
- for (var i = 0; i < dimension; ++i) {
- var color = this._colorAtPointWithBrightness(i, j, 1);
- if (!color)
- continue;
- var pos = (j * dimension + i) * 4;
- data[pos] = color.rgb[0];
- data[pos + 1] = color.rgb[1];
- data[pos + 2] = color.rgb[2];
- }
+ // Prevents the crosshair from being dragged outside the wheel.
+ if (center.distance(point) > radius) {
+ let angle = Math.atan2(point.y - center.y, point.x - center.x);
+ point = new WI.Point(center.x + radius * Math.cos(angle), center.y + radius * Math.sin(angle));
}
- ctx.putImageData(imageData, 0, 0);
- }
- _colorAtPointWithBrightness(x, y, brightness)
- {
- var center = this._dimension / 2 * window.devicePixelRatio;
- var xDis = x - center;
- var yDis = y - center;
- var distance = Math.sqrt(xDis * xDis + yDis * yDis);
-
- if (distance - center > 0.001)
- return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
-
- var h = Math.atan2(y - center, center - x) * 180 / Math.PI;
- h = (h + 180) % 360;
- var v = brightness;
- var s = Math.max(0, distance) / center;
-
- var rgb = WI.Color.hsv2rgb(h, s, v);
- return new WI.Color(WI.Color.Format.RGBA, [
- Math.round(rgb[0] * 255),
- Math.round(rgb[1] * 255),
- Math.round(rgb[2] * 255),
- 1
- ]);
+ this._crosshairPosition = point;
+ this._crosshairElement.style.setProperty("transform", "translate(" + Math.round(point.x) + "px, " + Math.round(point.y) + "px)");
}
- _drawTintedCanvas()
+ _updateGradient()
{
- var ctx = this._tintedCanvas.getContext("2d");
- var dimension = this._dimension * window.devicePixelRatio;
+ let stops = [];
+ for (let i = 0; i <= 360; i += 60)
+ stops.push(`hsl(${i}, 100%, ${this._brightness * 100}%)`);
- ctx.save();
- ctx.drawImage(this._rawCanvas, 0, 0, dimension, dimension);
- if (this._brightness !== 1) {
- ctx.globalAlpha = 1 - this._brightness;
- ctx.fillStyle = "black";
- ctx.fillRect(0, 0, dimension, dimension);
- }
- ctx.restore();
+ this._gradientElement.style.setProperty("background-image", `conic-gradient(${stops.join(",")})`);
}
-
- _draw()
- {
- this._drawTintedCanvas();
-
- var ctx = this._finalCanvas.getContext("2d");
- var dimension = this._dimension * window.devicePixelRatio;
- var radius = this._radius * window.devicePixelRatio;
-
- ctx.save();
- ctx.clearRect(0, 0, dimension, dimension);
- ctx.beginPath();
- ctx.arc(dimension / 2, dimension / 2, radius + 1, 0, Math.PI * 2, true);
- ctx.closePath();
- ctx.clip();
- ctx.drawImage(this._tintedCanvas, 0, 0, dimension, dimension);
- ctx.restore();
- }
};
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/LegacyColorWheel.js (from rev 237604, trunk/Source/WebInspectorUI/UserInterface/Views/ColorWheel.js) (0 => 237605)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LegacyColorWheel.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LegacyColorWheel.js 2018-10-30 22:15:16 UTC (rev 237605)
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.LegacyColorWheel = class LegacyColorWheel extends WI.Object
+{
+ constructor()
+ {
+ super();
+
+ this._rawCanvas = document.createElement("canvas");
+ this._tintedCanvas = document.createElement("canvas");
+ this._finalCanvas = document.createElement("canvas");
+
+ this._crosshair = document.createElement("div");
+ this._crosshair.className = "crosshair";
+
+ this._element = document.createElement("div");
+ this._element.className = "color-wheel";
+
+ this._element.appendChild(this._finalCanvas);
+ this._element.appendChild(this._crosshair);
+
+ this._finalCanvas.addEventListener("mousedown", this);
+ }
+
+ // Public
+
+ set dimension(dimension)
+ {
+ this._element.style.width = this.element.style.height = `${dimension}px`;
+
+ this._finalCanvas.width = this._tintedCanvas.width = this._rawCanvas.width = dimension * window.devicePixelRatio;
+ this._finalCanvas.height = this._tintedCanvas.height = this._rawCanvas.height = dimension * window.devicePixelRatio;
+
+ this._finalCanvas.style.width = this._finalCanvas.style.height = dimension + "px";
+
+ this._dimension = dimension;
+ // We shrink the radius a bit for better anti-aliasing.
+ this._radius = dimension / 2 - 2;
+
+ this._setCrosshairPosition(new WI.Point(dimension / 2, dimension / 2));
+
+ this._drawRawCanvas();
+ this._draw();
+ }
+
+ get element()
+ {
+ return this._element;
+ }
+
+ get brightness()
+ {
+ return this._brightness;
+ }
+
+ set brightness(brightness)
+ {
+ this._brightness = brightness;
+ this._draw();
+ }
+
+ get tintedColor()
+ {
+ if (this._crosshairPosition)
+ return this._colorAtPointWithBrightness(this._crosshairPosition.x * window.devicePixelRatio, this._crosshairPosition.y * window.devicePixelRatio, this._brightness);
+
+ return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
+ }
+
+ set tintedColor(tintedColor)
+ {
+ var data = ""
+ this._setCrosshairPosition(data.point);
+ this.brightness = data.brightness;
+ }
+
+ get rawColor()
+ {
+ if (this._crosshairPosition)
+ return this._colorAtPointWithBrightness(this._crosshairPosition.x * window.devicePixelRatio, this._crosshairPosition.y * window.devicePixelRatio, 1);
+
+ return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
+ }
+
+ // Protected
+
+ handleEvent(event)
+ {
+ switch (event.type) {
+ case "mousedown":
+ this._handleMousedown(event);
+ break;
+ case "mousemove":
+ this._handleMousemove(event);
+ break;
+ case "mouseup":
+ this._handleMouseup(event);
+ break;
+ }
+ }
+
+ // Private
+
+ _handleMousedown(event)
+ {
+ window.addEventListener("mousemove", this, true);
+ window.addEventListener("mouseup", this, true);
+
+ this._updateColorForMouseEvent(event);
+ }
+
+ _handleMousemove(event)
+ {
+ this._updateColorForMouseEvent(event);
+ }
+
+ _handleMouseup(event)
+ {
+ window.removeEventListener("mousemove", this, true);
+ window.removeEventListener("mouseup", this, true);
+ }
+
+ _pointInCircleForEvent(event)
+ {
+ function distance(a, b)
+ {
+ return Math.sqrt(Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2));
+ }
+
+ function angleFromCenterToPoint(center, point)
+ {
+ return Math.atan2(point.y - center.y, point.x - center.x);
+ }
+
+ function pointOnCircumference(c, r, a)
+ {
+ return new WI.Point(c.x + r * Math.cos(a), c.y + r * Math.sin(a));
+ }
+
+ var dimension = this._dimension;
+ var point = window.webkitConvertPointFromPageToNode(this._finalCanvas, new WebKitPoint(event.pageX, event.pageY));
+ var center = new WI.Point(dimension / 2, dimension / 2);
+ if (distance(point, center) > this._radius) {
+ var angle = angleFromCenterToPoint(center, point);
+ point = pointOnCircumference(center, this._radius, angle);
+ }
+ return point;
+ }
+
+ _updateColorForMouseEvent(event)
+ {
+ var point = this._pointInCircleForEvent(event);
+
+ this._setCrosshairPosition(point);
+
+ if (this.delegate && typeof this.delegate.colorWheelColorDidChange === "function")
+ this.delegate.colorWheelColorDidChange(this);
+ }
+
+ _setCrosshairPosition(point)
+ {
+ this._crosshairPosition = point;
+ this._crosshair.style.webkitTransform = "translate(" + Math.round(point.x) + "px, " + Math.round(point.y) + "px)";
+ }
+
+ _tintedColorToPointAndBrightness(color)
+ {
+ var rgb = color.rgb;
+ var hsv = WI.Color.rgb2hsv(rgb[0], rgb[1], rgb[2]);
+ var cosHue = Math.cos(hsv[0] * Math.PI / 180);
+ var sinHue = Math.sin(hsv[0] * Math.PI / 180);
+ var center = this._dimension / 2;
+ var x = center + (center * cosHue * hsv[1]);
+ var y = center - (center * sinHue * hsv[1]);
+ return {
+ point: new WI.Point(x, y),
+ brightness: hsv[2]
+ };
+ }
+
+ _drawRawCanvas() {
+ var ctx = this._rawCanvas.getContext("2d");
+
+ var dimension = this._dimension * window.devicePixelRatio;
+
+ ctx.fillStyle = "white";
+ ctx.fillRect(0, 0, dimension, dimension);
+
+ var imageData = ctx.getImageData(0, 0, dimension, dimension);
+ var data = ""
+ for (var j = 0; j < dimension; ++j) {
+ for (var i = 0; i < dimension; ++i) {
+ var color = this._colorAtPointWithBrightness(i, j, 1);
+ if (!color)
+ continue;
+ var pos = (j * dimension + i) * 4;
+ data[pos] = color.rgb[0];
+ data[pos + 1] = color.rgb[1];
+ data[pos + 2] = color.rgb[2];
+ }
+ }
+ ctx.putImageData(imageData, 0, 0);
+ }
+
+ _colorAtPointWithBrightness(x, y, brightness)
+ {
+ var center = this._dimension / 2 * window.devicePixelRatio;
+ var xDis = x - center;
+ var yDis = y - center;
+ var distance = Math.sqrt(xDis * xDis + yDis * yDis);
+
+ if (distance - center > 0.001)
+ return new WI.Color(WI.Color.Format.RGBA, [0, 0, 0, 0]);
+
+ var h = Math.atan2(y - center, center - x) * 180 / Math.PI;
+ h = (h + 180) % 360;
+ var v = brightness;
+ var s = Math.max(0, distance) / center;
+
+ var rgb = WI.Color.hsv2rgb(h, s, v);
+ return new WI.Color(WI.Color.Format.RGBA, [
+ Math.round(rgb[0] * 255),
+ Math.round(rgb[1] * 255),
+ Math.round(rgb[2] * 255),
+ 1
+ ]);
+ }
+
+ _drawTintedCanvas()
+ {
+ var ctx = this._tintedCanvas.getContext("2d");
+ var dimension = this._dimension * window.devicePixelRatio;
+
+ ctx.save();
+ ctx.drawImage(this._rawCanvas, 0, 0, dimension, dimension);
+ if (this._brightness !== 1) {
+ ctx.globalAlpha = 1 - this._brightness;
+ ctx.fillStyle = "black";
+ ctx.fillRect(0, 0, dimension, dimension);
+ }
+ ctx.restore();
+ }
+
+ _draw()
+ {
+ this._drawTintedCanvas();
+
+ var ctx = this._finalCanvas.getContext("2d");
+ var dimension = this._dimension * window.devicePixelRatio;
+ var radius = this._radius * window.devicePixelRatio;
+
+ ctx.save();
+ ctx.clearRect(0, 0, dimension, dimension);
+ ctx.beginPath();
+ ctx.arc(dimension / 2, dimension / 2, radius + 1, 0, Math.PI * 2, true);
+ ctx.closePath();
+ ctx.clip();
+ ctx.drawImage(this._tintedCanvas, 0, 0, dimension, dimension);
+ ctx.restore();
+ }
+};