mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
fix : keyboard accessibility for colorpicker inpus
This commit is contained in:
@@ -66,7 +66,8 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-picker-slider {
|
.color-picker-slider,
|
||||||
|
.color-picker-input {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
height : 25px;
|
height : 25px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -91,6 +92,14 @@
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.color-picker-input {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-picker-input .textfield{
|
||||||
|
width:100%;
|
||||||
|
}
|
||||||
|
|
||||||
.color-picker-slider input[type="range"][data-dimension="h"] {
|
.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%);
|
background-image:linear-gradient(to right, #ff0000 0%, #ffff00 17%, #00ff00 33%, #00ffff 50%, #0000ff 67%, #ff00ff 83%, #ff0000 100%);
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@
|
|||||||
|
|
||||||
.color-preview {
|
.color-preview {
|
||||||
width: 170px;
|
width: 170px;
|
||||||
height: 76px;
|
height: 70px;
|
||||||
margin: 11px;
|
margin: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,3 +46,7 @@ body {
|
|||||||
.pull-left {
|
.pull-left {
|
||||||
left:0;
|
left:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.uppercase {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ if (!Function.prototype.bind) {
|
|||||||
return hash;
|
return hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.copy = function (object) {
|
||||||
|
return JSON.parse(JSON.stringify(object));
|
||||||
|
};
|
||||||
|
|
||||||
var entityMap = {
|
var entityMap = {
|
||||||
"&": "&",
|
"&": "&",
|
||||||
"<": "<",
|
"<": "<",
|
||||||
|
|||||||
@@ -4,6 +4,11 @@
|
|||||||
ns.HslRgbColorPicker = function (container, colorUpdatedCallback) {
|
ns.HslRgbColorPicker = function (container, colorUpdatedCallback) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.colorUpdatedCallback = colorUpdatedCallback;
|
this.colorUpdatedCallback = colorUpdatedCallback;
|
||||||
|
|
||||||
|
this.tinyColor = null;
|
||||||
|
this.hsvColor = null;
|
||||||
|
this.rgbColor = null;
|
||||||
|
|
||||||
this.lastInputTimestamp_ = 0;
|
this.lastInputTimestamp_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -12,16 +17,15 @@
|
|||||||
var changeEvent = isChromeOrFirefox ? 'input' : 'change';
|
var changeEvent = isChromeOrFirefox ? 'input' : 'change';
|
||||||
this.container.addEventListener(changeEvent, this.onPickerChange_.bind(this));
|
this.container.addEventListener(changeEvent, this.onPickerChange_.bind(this));
|
||||||
this.container.addEventListener('keydown', this.onKeydown_.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 = this.container.querySelector('.color-picker-spectrum');
|
||||||
|
|
||||||
$(this.spectrumEl).spectrum({
|
$(this.spectrumEl).spectrum({
|
||||||
flat: true,
|
flat: true,
|
||||||
showInput: true,
|
|
||||||
showButtons: false,
|
showButtons: false,
|
||||||
move : this.setColor.bind(this),
|
move : this.setColor.bind(this),
|
||||||
change : this.setColor.bind(this),
|
change : this.setColor.bind(this)
|
||||||
preferredFormat: 'hex'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.setColor("#000000");
|
this.setColor("#000000");
|
||||||
@@ -34,49 +38,72 @@
|
|||||||
|
|
||||||
ns.HslRgbColorPicker.prototype.onPickerChange_ = function (evt) {
|
ns.HslRgbColorPicker.prototype.onPickerChange_ = function (evt) {
|
||||||
var target = evt.target;
|
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;
|
this.updateColor_(value, model, dimension);
|
||||||
var dimension = target.dataset.dimension;
|
|
||||||
|
|
||||||
var value = parseInt(target.value, 10);
|
|
||||||
if (dimension === 'v' || dimension === 's') {
|
|
||||||
value = value/100;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
ns.HslRgbColorPicker.prototype.onKeydown_ = function (evt) {
|
||||||
var target = evt.target;
|
var target = evt.target;
|
||||||
|
|
||||||
if (target.getAttribute('type').toLowerCase() === 'text') {
|
var isInputText = target.getAttribute('type').toLowerCase() === 'text';
|
||||||
var value = parseInt(target.value, 10);
|
if (isInputText && target.dataset.dimension) {
|
||||||
var dimension = target.dataset.dimension;
|
var model = target.dataset.model;
|
||||||
|
|
||||||
var key = pskl.service.keyboard.KeycodeTranslator.toChar(evt.keyCode);
|
if (model === 'rgb' || model === 'hsv') {
|
||||||
if (key === 'up') {
|
var increment = this.getIncrement_(evt);
|
||||||
value = value + 1;
|
if (increment) {
|
||||||
} else if (key === 'down') {
|
var dimension = target.dataset.dimension;
|
||||||
value = value - 1;
|
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;
|
if (evt.shiftKey) {
|
||||||
this.onPickerChange_(evt);
|
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.hsvColor = this.toHsvColor_(inputColor);
|
||||||
this.tinyColor = this.toTinyColor_(inputColor);
|
this.tinyColor = this.toTinyColor_(inputColor);
|
||||||
|
this.rgbColor = this.tinyColor.toRgb();
|
||||||
|
|
||||||
this.updateInputs();
|
this.updateInputs();
|
||||||
$(".color-picker-spectrum").spectrum("set", this.tinyColor);
|
$(".color-picker-spectrum").spectrum("set", this.tinyColor);
|
||||||
@@ -98,30 +126,85 @@
|
|||||||
|
|
||||||
ns.HslRgbColorPicker.prototype.updateInputs = function () {
|
ns.HslRgbColorPicker.prototype.updateInputs = function () {
|
||||||
var inputs = this.container.querySelectorAll('input');
|
var inputs = this.container.querySelectorAll('input');
|
||||||
var rgb = this.tinyColor.toRgb();
|
|
||||||
|
|
||||||
|
|
||||||
for (var i = 0 ; i < inputs.length ; i++) {
|
for (var i = 0 ; i < inputs.length ; i++) {
|
||||||
var input = inputs[i];
|
var input = inputs[i];
|
||||||
var dimension = input.dataset.dimension;
|
var dimension = input.dataset.dimension;
|
||||||
var model = input.dataset.model;
|
var model = input.dataset.model;
|
||||||
|
|
||||||
if (model === 'rgb') {
|
var value = this.toInputValue_(model, dimension);
|
||||||
input.value = rgb[dimension];
|
if (input.value != value) {
|
||||||
} else if (model === 'hsv') {
|
input.value = value;
|
||||||
var value = this.hsvColor[dimension];
|
|
||||||
if (dimension === 'v' || dimension === 's') {
|
|
||||||
value = 100 * value;
|
|
||||||
}
|
|
||||||
input.value = Math.round(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input.getAttribute('type') === 'range') {
|
if (input.getAttribute('type') === 'range') {
|
||||||
this.updateSliderBackground(input);
|
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) {
|
ns.HslRgbColorPicker.prototype.updateSliderBackground = function (slider) {
|
||||||
var dimension = slider.dataset.dimension;
|
var dimension = slider.dataset.dimension;
|
||||||
var model = slider.dataset.model;
|
var model = slider.dataset.model;
|
||||||
@@ -135,20 +218,13 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.HslRgbColorPicker.prototype.getSliderBackgroundColors_ = function (model, dimension) {
|
ns.HslRgbColorPicker.prototype.getSliderBackgroundColors_ = function (model, dimension) {
|
||||||
var start, end;
|
var color = this.getColor_(model);
|
||||||
if (model === 'hsv') {
|
var start = pskl.utils.copy(color);
|
||||||
start = JSON.parse(JSON.stringify(this.hsvColor));
|
var end = pskl.utils.copy(color);
|
||||||
start[dimension] = 0;
|
|
||||||
|
|
||||||
end = JSON.parse(JSON.stringify(this.hsvColor));
|
var range = this.getDimensionRange_(dimension);
|
||||||
end[dimension] = 1;
|
start[dimension] = range[0];
|
||||||
} else {
|
end[dimension] = range[1];
|
||||||
start = this.tinyColor.toRgb();
|
|
||||||
start[dimension] = 0;
|
|
||||||
|
|
||||||
end = this.tinyColor.toRgb();
|
|
||||||
end[dimension] = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
start : window.tinycolor(start).toRgbString(),
|
start : window.tinycolor(start).toRgbString(),
|
||||||
@@ -156,39 +232,24 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HslRgbColorPicker.prototype.toTinyColor_ = function (color) {
|
ns.HslRgbColorPicker.prototype.getDimensionRange_ = function (d) {
|
||||||
if (typeof color == "object" && color.hasOwnProperty("_tc_id")) {
|
if (d === 'h') {
|
||||||
return color;
|
return [0, 359];
|
||||||
} else {
|
} else if (d === 's' || d === 'v') {
|
||||||
return window.tinycolor(JSON.parse(JSON.stringify(color)));
|
return [0, 1];
|
||||||
|
} else if (d === 'r' || d === 'g' || d === 'b') {
|
||||||
|
return [0, 255];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.HslRgbColorPicker.prototype.toHsvColor_ = function (color) {
|
ns.HslRgbColorPicker.prototype.getColor_ = function (model) {
|
||||||
var isHsvColor = ['h','s','v'].every(color.hasOwnProperty.bind(color));
|
var color;
|
||||||
if (isHsvColor) {
|
if (model === 'hsv') {
|
||||||
return {
|
color = this.hsvColor;
|
||||||
h : Math.max(0, Math.min(359, color.h)),
|
} else if (model === 'rgb'){
|
||||||
s : Math.max(0, Math.min(1, color.s)),
|
color = this.rgbColor;
|
||||||
v : Math.max(0, Math.min(1, color.v))
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return this.toTinyColor_(color).toHsv();
|
|
||||||
}
|
}
|
||||||
|
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));
|
|
||||||
} ;
|
|
||||||
|
|
||||||
|
|
||||||
})();
|
})();
|
||||||
@@ -25,6 +25,9 @@
|
|||||||
<ul class="colors-list"></ul>
|
<ul class="colors-list"></ul>
|
||||||
<div class="color-picker-container">
|
<div class="color-picker-container">
|
||||||
<div class="color-picker-spectrum"></div>
|
<div class="color-picker-spectrum"></div>
|
||||||
|
<div class="color-picker-input">
|
||||||
|
<input type="text" data-model="hex" data-dimension="*" class="textfield uppercase" value="#000000" />
|
||||||
|
</div>
|
||||||
<div class="color-picker-slider">
|
<div class="color-picker-slider">
|
||||||
<span>H</span>
|
<span>H</span>
|
||||||
<input type="range" data-model="hsv" data-dimension="h" value="0" min="0" max="359" tabindex="-1"/>
|
<input type="range" data-model="hsv" data-dimension="h" value="0" min="0" max="359" tabindex="-1"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user