Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(909)

Unified Diff: third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js

Issue 2292583002: DevTools: Create 2D slider for shadow-editor offset (Closed)
Patch Set: Move beginPath under if Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js b/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
index 74a23375f05e4e34776ea655363b76441b91a928..646927096b44fd4a166b64c0feaf6a20c511646c 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/CSSShadowEditor.js
@@ -21,20 +21,27 @@ WebInspector.CSSShadowEditor = function()
this._insetButton.textContent = WebInspector.UIString("Inset");
this._insetButton.addEventListener("click", this._onButtonClick.bind(this), false);
- var inputs;
- inputs = this._createSliderField(WebInspector.UIString("X offset"), true);
- this._xInput = inputs.textInput;
- this._xSlider = inputs.rangeInput;
- inputs = this._createSliderField(WebInspector.UIString("Y offset"), true);
- this._yInput = inputs.textInput;
- this._ySlider = inputs.rangeInput;
- inputs = this._createSliderField(WebInspector.UIString("Blur"), false);
- this._blurInput = inputs.textInput;
- this._blurSlider = inputs.rangeInput;
- inputs = this._createSliderField(WebInspector.UIString("Spread"), false);
- this._spreadInput = inputs.textInput;
- this._spreadSlider = inputs.rangeInput;
- this._spreadField = inputs.field;
+ var xField = this.contentElement.createChild("div", "shadow-editor-field");
+ this._xInput = this._createTextInput(xField, WebInspector.UIString("X offset"));
+ var yField = this.contentElement.createChild("div", "shadow-editor-field");
+ this._yInput = this._createTextInput(yField, WebInspector.UIString("Y offset"));
+ this._xySlider = xField.createChild("canvas", "shadow-editor-2D-slider");
+ this._xySlider.width = WebInspector.CSSShadowEditor.canvasSize;
+ this._xySlider.height = WebInspector.CSSShadowEditor.canvasSize;
+ this._xySlider.tabIndex = -1;
+ this._halfCanvasSize = WebInspector.CSSShadowEditor.canvasSize / 2;
+ this._innerCanvasSize = this._halfCanvasSize - WebInspector.CSSShadowEditor.sliderThumbRadius;
+ WebInspector.installDragHandle(this._xySlider, this._dragStart.bind(this), this._dragMove.bind(this), null, "default");
+ this._xySlider.addEventListener("keydown", this._onCanvasArrowKey.bind(this), false);
+ this._xySlider.addEventListener("blur", this._onCanvasBlur.bind(this), false);
+
+ var blurField = this.contentElement.createChild("div", "shadow-editor-blur-field");
+ this._blurInput = this._createTextInput(blurField, WebInspector.UIString("Blur"));
+ this._blurSlider = this._createSlider(blurField);
+
+ this._spreadField = this.contentElement.createChild("div", "shadow-editor-field");
+ this._spreadInput = this._createTextInput(this._spreadField, WebInspector.UIString("Spread"));
+ this._spreadSlider = this._createSlider(this._spreadField);
}
/** @enum {symbol} */
@@ -43,19 +50,22 @@ WebInspector.CSSShadowEditor.Events = {
}
/** @type {number} */
-WebInspector.CSSShadowEditor.maxRange = 40;
+WebInspector.CSSShadowEditor.maxRange = 20;
/** @type {string} */
WebInspector.CSSShadowEditor.defaultUnit = "px";
+/** @type {number} */
+WebInspector.CSSShadowEditor.sliderThumbRadius = 6;
+/** @type {number} */
+WebInspector.CSSShadowEditor.canvasSize = 88;
WebInspector.CSSShadowEditor.prototype = {
/**
+ * @param {!Element} field
* @param {string} propertyName
- * @param {boolean} negativeAllowed
- * @return {{textInput: !Element, rangeInput: !Element, field: !Element}}
+ * @return {!Element}
*/
- _createSliderField: function(propertyName, negativeAllowed)
+ _createTextInput: function(field, propertyName)
{
- var field = this.contentElement.createChild("div", "shadow-editor-field");
var label = field.createChild("label", "shadow-editor-label");
label.textContent = propertyName;
label.setAttribute("for", propertyName);
@@ -66,11 +76,19 @@ WebInspector.CSSShadowEditor.prototype = {
textInput.addEventListener("mousewheel", this._handleValueModification.bind(this), false);
textInput.addEventListener("input", this._onTextInput.bind(this), false);
textInput.addEventListener("blur", this._onTextBlur.bind(this), false);
- var halfRange = WebInspector.CSSShadowEditor.maxRange / 2;
- var slider = negativeAllowed ? createSliderLabel(-halfRange, halfRange) : createSliderLabel(0, WebInspector.CSSShadowEditor.maxRange);
+ return textInput;
+ },
+
+ /**
+ * @param {!Element} field
+ * @return {!Element}
+ */
+ _createSlider: function(field)
+ {
+ var slider = createSliderLabel(0, WebInspector.CSSShadowEditor.maxRange, -1);
slider.addEventListener("input", this._onSliderInput.bind(this), false);
field.appendChild(slider);
- return {field: field, textInput: textInput, rangeInput: slider};
+ return slider;
},
/**
@@ -99,10 +117,9 @@ WebInspector.CSSShadowEditor.prototype = {
this._yInput.value = this._model.offsetY().asCSSText();
this._blurInput.value = this._model.blurRadius().asCSSText();
this._spreadInput.value = this._model.spreadRadius().asCSSText();
- this._xSlider.value = this._model.offsetX().amount;
- this._ySlider.value = this._model.offsetY().amount;
this._blurSlider.value = this._model.blurRadius().amount;
this._spreadSlider.value = this._model.spreadRadius().amount;
+ this._updateCanvas(false);
},
_updateButtons: function()
@@ -112,6 +129,50 @@ WebInspector.CSSShadowEditor.prototype = {
},
/**
+ * @param {boolean} drawFocus
+ */
+ _updateCanvas: function(drawFocus)
+ {
+ var context = this._xySlider.getContext("2d");
+ context.clearRect(0, 0, this._xySlider.width, this._xySlider.height);
+
+ // Draw dashed axes.
+ context.save();
+ context.setLineDash([1, 1]);
+ context.strokeStyle = "rgba(0, 0, 0, 0.2)";
+ context.beginPath();
+ context.moveTo(this._halfCanvasSize, 0);
+ context.lineTo(this._halfCanvasSize, WebInspector.CSSShadowEditor.canvasSize);
+ context.moveTo(0, this._halfCanvasSize);
+ context.lineTo(WebInspector.CSSShadowEditor.canvasSize, this._halfCanvasSize);
+ context.stroke();
+ context.restore();
+
+ var thumbPoint = this._sliderThumbPosition();
+ // Draw 2D slider line.
+ context.save();
+ context.translate(this._halfCanvasSize, this._halfCanvasSize);
+ context.lineWidth = 2;
+ context.strokeStyle = "rgba(0, 0, 0, 0.3)";
+ context.beginPath();
+ context.moveTo(0, 0);
+ context.lineTo(thumbPoint.x, thumbPoint.y);
+ context.stroke();
+ // Draw 2D slider thumb.
+ if (drawFocus) {
+ context.beginPath();
+ context.fillStyle = "rgba(66, 133, 244, 0.4)";
+ context.arc(thumbPoint.x, thumbPoint.y, WebInspector.CSSShadowEditor.sliderThumbRadius + 2, 0, 2 * Math.PI);
+ context.fill();
+ }
+ context.beginPath()
+ context.fillStyle = "#4285F4";
+ context.arc(thumbPoint.x, thumbPoint.y, WebInspector.CSSShadowEditor.sliderThumbRadius, 0, 2 * Math.PI);
+ context.fill();
+ context.restore();
+ },
+
+ /**
* @param {!Event} event
*/
_onButtonClick: function(event)
@@ -163,16 +224,16 @@ WebInspector.CSSShadowEditor.prototype = {
_onTextInput: function(event)
{
this._changedElement = event.currentTarget;
- this._changedElement.classList.toggle("invalid", false);
+ this._changedElement.classList.remove("invalid");
var length = WebInspector.CSSLength.parse(event.currentTarget.value);
if (!length || event.currentTarget === this._blurInput && length.amount < 0)
return;
if (event.currentTarget === this._xInput) {
this._model.setOffsetX(length);
- this._xSlider.value = length.amount;
+ this._updateCanvas(false);
} else if (event.currentTarget === this._yInput) {
this._model.setOffsetY(length);
- this._ySlider.value = length.amount;
+ this._updateCanvas(false);
} else if (event.currentTarget === this._blurInput) {
this._model.setBlurRadius(length);
this._blurSlider.value = length.amount;
@@ -187,7 +248,7 @@ WebInspector.CSSShadowEditor.prototype = {
{
if (!this._changedElement)
return;
- var length = !this._changedElement.value ? WebInspector.CSSLength.zero() : WebInspector.CSSLength.parse(this._changedElement.value);
+ var length = !this._changedElement.value.trim() ? WebInspector.CSSLength.zero() : WebInspector.CSSLength.parse(this._changedElement.value);
if (!length)
length = WebInspector.CSSLength.parse(this._changedElement.value + WebInspector.CSSShadowEditor.defaultUnit);
if (!length) {
@@ -198,11 +259,11 @@ WebInspector.CSSShadowEditor.prototype = {
if (this._changedElement === this._xInput) {
this._model.setOffsetX(length);
this._xInput.value = length.asCSSText();
- this._xSlider.value = length.amount;
+ this._updateCanvas(false);
} else if (this._changedElement === this._yInput) {
this._model.setOffsetY(length);
this._yInput.value = length.asCSSText();
- this._ySlider.value = length.amount;
+ this._updateCanvas(false);
} else if (this._changedElement === this._blurInput) {
if (length.amount < 0)
length = WebInspector.CSSLength.zero();
@@ -223,25 +284,121 @@ WebInspector.CSSShadowEditor.prototype = {
*/
_onSliderInput: function(event)
{
- if (event.currentTarget === this._xSlider) {
- this._model.setOffsetX(new WebInspector.CSSLength(this._xSlider.value, this._model.offsetX().unit || WebInspector.CSSShadowEditor.defaultUnit));
- this._xInput.value = this._model.offsetX().asCSSText();
- this._xInput.classList.toggle("invalid", false);
- } else if (event.currentTarget === this._ySlider) {
- this._model.setOffsetY(new WebInspector.CSSLength(this._ySlider.value, this._model.offsetY().unit || WebInspector.CSSShadowEditor.defaultUnit));
- this._yInput.value = this._model.offsetY().asCSSText();
- this._yInput.classList.toggle("invalid", false);
- } else if (event.currentTarget === this._blurSlider) {
+ if (event.currentTarget === this._blurSlider) {
this._model.setBlurRadius(new WebInspector.CSSLength(this._blurSlider.value, this._model.blurRadius().unit || WebInspector.CSSShadowEditor.defaultUnit));
this._blurInput.value = this._model.blurRadius().asCSSText();
- this._blurInput.classList.toggle("invalid", false);
+ this._blurInput.classList.remove("invalid");
} else if (event.currentTarget === this._spreadSlider) {
this._model.setSpreadRadius(new WebInspector.CSSLength(this._spreadSlider.value, this._model.spreadRadius().unit || WebInspector.CSSShadowEditor.defaultUnit));
this._spreadInput.value = this._model.spreadRadius().asCSSText();
- this._spreadInput.classList.toggle("invalid", false);
+ this._spreadInput.classList.remove("invalid");
}
this.dispatchEventToListeners(WebInspector.CSSShadowEditor.Events.ShadowChanged, this._model);
},
+ /**
+ * @param {!Event} event
+ * @return {boolean}
+ */
+ _dragStart: function(event)
+ {
+ this._xySlider.focus();
+ this._updateCanvas(true);
+ this._canvasOrigin = new WebInspector.Geometry.Point(this._xySlider.totalOffsetLeft() + this._halfCanvasSize, this._xySlider.totalOffsetTop() + this._halfCanvasSize);
+ var clickedPoint = new WebInspector.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
+ var thumbPoint = this._sliderThumbPosition();
+ if (clickedPoint.distanceTo(thumbPoint) >= WebInspector.CSSShadowEditor.sliderThumbRadius)
+ this._dragMove(event);
+ return true;
+ },
+
+ /**
+ * @param {!Event} event
+ */
+ _dragMove: function(event)
+ {
+ var point = new WebInspector.Geometry.Point(event.x - this._canvasOrigin.x, event.y - this._canvasOrigin.y);
+ var constrainedPoint = this._constrainPoint(point, this._innerCanvasSize);
+ var newX = Math.round((constrainedPoint.x / this._innerCanvasSize) * WebInspector.CSSShadowEditor.maxRange);
+ var newY = Math.round((constrainedPoint.y / this._innerCanvasSize) * WebInspector.CSSShadowEditor.maxRange);
+ this._model.setOffsetX(new WebInspector.CSSLength(newX, this._model.offsetX().unit || WebInspector.CSSShadowEditor.defaultUnit));
+ this._model.setOffsetY(new WebInspector.CSSLength(newY, this._model.offsetY().unit || WebInspector.CSSShadowEditor.defaultUnit));
+ this._xInput.value = this._model.offsetX().asCSSText();
+ this._yInput.value = this._model.offsetY().asCSSText();
+ this._xInput.classList.remove("invalid");
+ this._yInput.classList.remove("invalid");
+ this._updateCanvas(true);
+ this.dispatchEventToListeners(WebInspector.CSSShadowEditor.Events.ShadowChanged, this._model);
+ },
+
+ _onCanvasBlur: function()
+ {
+ this._updateCanvas(false);
+ },
+
+ /**
+ * @param {!Event} event
+ */
+ _onCanvasArrowKey: function(event)
+ {
+ var shiftX = 0;
+ var shiftY = 0;
+ if (event.key === "ArrowRight")
+ shiftX = 1;
+ else if (event.key === "ArrowLeft")
+ shiftX = -1;
+ else if (event.key === "ArrowUp")
+ shiftY = -1;
+ else if (event.key === "ArrowDown")
+ shiftY = 1;
+
+ if (!shiftX && !shiftY)
+ return;
+ event.consume(true);
+
+ if (shiftX) {
+ var offsetX = this._model.offsetX();
+ var newAmount = Number.constrain(offsetX.amount + shiftX, -WebInspector.CSSShadowEditor.maxRange, WebInspector.CSSShadowEditor.maxRange);
+ if (newAmount === offsetX.amount)
+ return;
+ this._model.setOffsetX(new WebInspector.CSSLength(newAmount, offsetX.unit || WebInspector.CSSShadowEditor.defaultUnit));
+ this._xInput.value = this._model.offsetX().asCSSText();
+ this._xInput.classList.remove("invalid");
+ }
+ if (shiftY) {
+ var offsetY = this._model.offsetY();
+ var newAmount = Number.constrain(offsetY.amount + shiftY, -WebInspector.CSSShadowEditor.maxRange, WebInspector.CSSShadowEditor.maxRange);
+ if (newAmount === offsetY.amount)
+ return;
+ this._model.setOffsetY(new WebInspector.CSSLength(newAmount, offsetY.unit || WebInspector.CSSShadowEditor.defaultUnit));
+ this._yInput.value = this._model.offsetY().asCSSText();
+ this._yInput.classList.remove("invalid");
+ }
+ this._updateCanvas(true);
+ this.dispatchEventToListeners(WebInspector.CSSShadowEditor.Events.ShadowChanged, this._model);
+ },
+
+ /**
+ * @param {!WebInspector.Geometry.Point} point
+ * @param {number} max
+ * @return {!WebInspector.Geometry.Point}
+ */
+ _constrainPoint: function(point, max)
+ {
+ if (Math.abs(point.x) <= max && Math.abs(point.y) <= max)
+ return new WebInspector.Geometry.Point(point.x, point.y);
+ return point.scale(max / Math.max(Math.abs(point.x), Math.abs(point.y)));
+ },
+
+ /**
+ * @return {!WebInspector.Geometry.Point}
+ */
+ _sliderThumbPosition: function()
+ {
+ var x = (this._model.offsetX().amount / WebInspector.CSSShadowEditor.maxRange) * this._innerCanvasSize;
+ var y = (this._model.offsetY().amount / WebInspector.CSSShadowEditor.maxRange) * this._innerCanvasSize;
+ return this._constrainPoint(new WebInspector.Geometry.Point(x, y), this._innerCanvasSize);
+ },
+
__proto__: WebInspector.VBox.prototype
-}
+}

Powered by Google App Engine
This is Rietveld 408576698