diff --git a/src/css/color-picker-slider.css b/src/css/color-picker-slider.css index 8c3cdda..f3a52dd 100644 --- a/src/css/color-picker-slider.css +++ b/src/css/color-picker-slider.css @@ -66,7 +66,8 @@ display: none; } -.color-picker-slider { +.color-picker-slider, +.color-picker-input { padding: 0 10px; height : 25px; overflow: hidden; @@ -91,6 +92,14 @@ margin-left: 5px; } +.color-picker-input { + margin-bottom: 10px; +} + +.color-picker-input .textfield{ + width:100%; +} + .color-picker-slider input[type="range"][data-dimension="h"] { background-image:linear-gradient(to right, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%); } \ No newline at end of file diff --git a/src/css/dialogs-create-palette.css b/src/css/dialogs-create-palette.css index 6988b98..2ebfc9d 100644 --- a/src/css/dialogs-create-palette.css +++ b/src/css/dialogs-create-palette.css @@ -60,7 +60,7 @@ .color-preview { width: 170px; - height: 76px; + height: 70px; margin: 11px; } diff --git a/src/css/style.css b/src/css/style.css index 37b0da2..924667e 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -46,3 +46,7 @@ body { .pull-left { left:0; } + +.uppercase { + text-transform: uppercase; +} diff --git a/src/js/utils/core.js b/src/js/utils/core.js index af71c3d..01d7e84 100644 --- a/src/js/utils/core.js +++ b/src/js/utils/core.js @@ -101,6 +101,10 @@ if (!Function.prototype.bind) { return hash; }; + ns.copy = function (object) { + return JSON.parse(JSON.stringify(object)); + }; + var entityMap = { "&": "&", "<": "<", diff --git a/src/js/widgets/HslRgbColorPicker.js b/src/js/widgets/HslRgbColorPicker.js index 744eb7f..86b3480 100644 --- a/src/js/widgets/HslRgbColorPicker.js +++ b/src/js/widgets/HslRgbColorPicker.js @@ -4,6 +4,11 @@ ns.HslRgbColorPicker = function (container, colorUpdatedCallback) { this.container = container; this.colorUpdatedCallback = colorUpdatedCallback; + + this.tinyColor = null; + this.hsvColor = null; + this.rgbColor = null; + this.lastInputTimestamp_ = 0; }; @@ -12,16 +17,15 @@ var changeEvent = isChromeOrFirefox ? 'input' : 'change'; this.container.addEventListener(changeEvent, this.onPickerChange_.bind(this)); this.container.addEventListener('keydown', this.onKeydown_.bind(this)); + this.container.addEventListener('focusout', this.onBlur_.bind(this)); this.spectrumEl = this.container.querySelector('.color-picker-spectrum'); $(this.spectrumEl).spectrum({ flat: true, - showInput: true, showButtons: false, move : this.setColor.bind(this), - change : this.setColor.bind(this), - preferredFormat: 'hex' + change : this.setColor.bind(this) }); this.setColor("#000000"); @@ -34,49 +38,72 @@ ns.HslRgbColorPicker.prototype.onPickerChange_ = function (evt) { var target = evt.target; + if (target.dataset.dimension) { + var model = target.dataset.model; + var dimension = target.dataset.dimension; + var value = target.value; - var model = target.dataset.model; - var dimension = target.dataset.dimension; - - var value = parseInt(target.value, 10); - if (dimension === 'v' || dimension === 's') { - value = value/100; + this.updateColor_(value, model, dimension); } - - var color; - if (model === 'rgb') { - color = this.tinyColor.toRgb(); - } else if (model === 'hsv') { - color = this.hsvColor; - } - - if (isNaN(value)) { - value = color[dimension]; - } else { - color[dimension] = value; - } - - this.setColor(color); }; ns.HslRgbColorPicker.prototype.onKeydown_ = function (evt) { var target = evt.target; - if (target.getAttribute('type').toLowerCase() === 'text') { - var value = parseInt(target.value, 10); - var dimension = target.dataset.dimension; + var isInputText = target.getAttribute('type').toLowerCase() === 'text'; + if (isInputText && target.dataset.dimension) { + var model = target.dataset.model; - var key = pskl.service.keyboard.KeycodeTranslator.toChar(evt.keyCode); - if (key === 'up') { - value = value + 1; - } else if (key === 'down') { - value = value - 1; + if (model === 'rgb' || model === 'hsv') { + var increment = this.getIncrement_(evt); + if (increment) { + var dimension = target.dataset.dimension; + var value = parseInt(target.value, 10); + this.updateColor_(value + increment, model, dimension); + } } + } + }; - value = this.normalizeDimension_(value, dimension); + ns.HslRgbColorPicker.prototype.getIncrement_ = function (evt) { + var increment = 0; + var key = pskl.service.keyboard.KeycodeTranslator.toChar(evt.keyCode); + if (key === 'up') { + increment = 1; + } else if (key === 'down') { + increment = -1; + } - target.value = value; - this.onPickerChange_(evt); + if (evt.shiftKey) { + increment = increment * 5; + } + + return increment; + }; + + ns.HslRgbColorPicker.prototype.updateColor_ = function (inputValue, model, dimension) { + var value = this.toModelValue_(inputValue, model, dimension); + if (model === 'hsv' || model === 'rgb') { + if (!isNaN(value)) { + var color = this.getColor_(model); + color[dimension] = this.normalizeDimension_(value, dimension); + this.setColor(color); + } + } else if (model === 'hex') { + if (/^#([a-f0-9]{3}){1,2}$/i.test(value)) { + this.setColor(value); + } + } + }; + + ns.HslRgbColorPicker.prototype.onBlur_ = function (evt) { + var target = evt.target; + + var isInputText = target.getAttribute('type').toLowerCase() === 'text'; + if (isInputText && target.dataset.dimension) { + var model = target.dataset.model; + var dimension = target.dataset.dimension; + target.value = this.toInputValue_(model, dimension); } }; @@ -86,6 +113,7 @@ this.hsvColor = this.toHsvColor_(inputColor); this.tinyColor = this.toTinyColor_(inputColor); + this.rgbColor = this.tinyColor.toRgb(); this.updateInputs(); $(".color-picker-spectrum").spectrum("set", this.tinyColor); @@ -98,30 +126,85 @@ ns.HslRgbColorPicker.prototype.updateInputs = function () { var inputs = this.container.querySelectorAll('input'); - var rgb = this.tinyColor.toRgb(); - for (var i = 0 ; i < inputs.length ; i++) { var input = inputs[i]; var dimension = input.dataset.dimension; var model = input.dataset.model; - if (model === 'rgb') { - input.value = rgb[dimension]; - } else if (model === 'hsv') { - var value = this.hsvColor[dimension]; - if (dimension === 'v' || dimension === 's') { - value = 100 * value; - } - input.value = Math.round(value); + var value = this.toInputValue_(model, dimension); + if (input.value != value) { + input.value = value; } - if (input.getAttribute('type') === 'range') { this.updateSliderBackground(input); } } }; + ns.HslRgbColorPicker.prototype.toInputValue_ = function (model, dimension) { + var value; + + if (model === 'rgb' || model === 'hsv') { + var color = this.getColor_(model); + value = color[dimension]; + + if (dimension === 'v' || dimension === 's') { + value = 100 * value; + } + value = Math.round(value); + } else if (model === 'hex') { + value = this.tinyColor.toHexString(true); + } + + return value; + }; + + ns.HslRgbColorPicker.prototype.toModelValue_ = function (value, model, dimension) { + var modelValue; + + if (model === 'rgb' || model === 'hsv') { + modelValue = parseInt(value, 10); + if (dimension === 'v' || dimension === 's') { + modelValue = modelValue/100; + } + } else if (model === 'hex') { + modelValue = value; + } + + return modelValue; + }; + + ns.HslRgbColorPicker.prototype.toTinyColor_ = function (color) { + var isTinyColor = typeof color == 'object' && color.hasOwnProperty('_tc_id'); + if (isTinyColor) { + return color; + } else { + return window.tinycolor(pskl.utils.copy(color)); + } + }; + + ns.HslRgbColorPicker.prototype.toHsvColor_ = function (color) { + var isHsvColor = ['h','s','v'].every(color.hasOwnProperty.bind(color)); + if (isHsvColor) { + return { + h : this.normalizeDimension_(color.h, 'h'), + s : this.normalizeDimension_(color.s, 's'), + v : this.normalizeDimension_(color.v, 'v') + }; + } else { + return this.toTinyColor_(color).toHsv(); + } + }; + + ns.HslRgbColorPicker.prototype.normalizeDimension_ = function (value, dimension) { + var range = this.getDimensionRange_(dimension); + return Math.max(range[0], Math.min(range[1], value)); + }; + + /** + * Update background colors for range inputs + */ ns.HslRgbColorPicker.prototype.updateSliderBackground = function (slider) { var dimension = slider.dataset.dimension; var model = slider.dataset.model; @@ -135,20 +218,13 @@ }; ns.HslRgbColorPicker.prototype.getSliderBackgroundColors_ = function (model, dimension) { - var start, end; - if (model === 'hsv') { - start = JSON.parse(JSON.stringify(this.hsvColor)); - start[dimension] = 0; + var color = this.getColor_(model); + var start = pskl.utils.copy(color); + var end = pskl.utils.copy(color); - end = JSON.parse(JSON.stringify(this.hsvColor)); - end[dimension] = 1; - } else { - start = this.tinyColor.toRgb(); - start[dimension] = 0; - - end = this.tinyColor.toRgb(); - end[dimension] = 255; - } + var range = this.getDimensionRange_(dimension); + start[dimension] = range[0]; + end[dimension] = range[1]; return { start : window.tinycolor(start).toRgbString(), @@ -156,39 +232,24 @@ }; }; - ns.HslRgbColorPicker.prototype.toTinyColor_ = function (color) { - if (typeof color == "object" && color.hasOwnProperty("_tc_id")) { - return color; - } else { - return window.tinycolor(JSON.parse(JSON.stringify(color))); + ns.HslRgbColorPicker.prototype.getDimensionRange_ = function (d) { + if (d === 'h') { + return [0, 359]; + } else if (d === 's' || d === 'v') { + return [0, 1]; + } else if (d === 'r' || d === 'g' || d === 'b') { + return [0, 255]; } }; - ns.HslRgbColorPicker.prototype.toHsvColor_ = function (color) { - var isHsvColor = ['h','s','v'].every(color.hasOwnProperty.bind(color)); - if (isHsvColor) { - return { - h : Math.max(0, Math.min(359, color.h)), - s : Math.max(0, Math.min(1, color.s)), - v : Math.max(0, Math.min(1, color.v)) - }; - } else { - return this.toTinyColor_(color).toHsv(); + ns.HslRgbColorPicker.prototype.getColor_ = function (model) { + var color; + if (model === 'hsv') { + color = this.hsvColor; + } else if (model === 'rgb'){ + color = this.rgbColor; } + return color; }; - ns.HslRgbColorPicker.prototype.normalizeDimension_ = function (value, dimension) { - var ranges = { - 'h' : [0, 359], - 's' : [0, 100], - 'v' : [0, 100], - 'r' : [0, 255], - 'g' : [0, 255], - 'b' : [0, 255] - }; - var range = ranges[dimension]; - return Math.max(range[0], Math.min(range[1], value)); - } ; - - })(); \ No newline at end of file diff --git a/src/templates/dialogs/create-palette.html b/src/templates/dialogs/create-palette.html index eb8c26e..1df6f59 100644 --- a/src/templates/dialogs/create-palette.html +++ b/src/templates/dialogs/create-palette.html @@ -25,6 +25,9 @@