mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Mutualize HTML generation for drawing tools and transform
This commit is contained in:
145
src/js/widgets/ColorsList.js
Normal file
145
src/js/widgets/ColorsList.js
Normal file
@@ -0,0 +1,145 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.widgets');
|
||||
|
||||
var DEFAULT_COLOR = '#000000';
|
||||
|
||||
ns.ColorsList = function (container) {
|
||||
this.selectedIndex = -1;
|
||||
this.palette = new pskl.model.Palette('tmp', 'tmp', []);
|
||||
this.container = container;
|
||||
|
||||
this.colorsList = this.container.querySelector('.colors-list');
|
||||
this.colorPreviewEl = this.container.querySelector('.color-preview');
|
||||
|
||||
$(container).sortable({
|
||||
placeholder: 'colors-list-drop-proxy',
|
||||
update: this.onColorDrop_.bind(this),
|
||||
items: '.create-palette-color'
|
||||
});
|
||||
|
||||
this.colorsList.addEventListener('click', this.onColorContainerClick_.bind(this));
|
||||
|
||||
var colorPickerContainer = container.querySelector('.color-picker-container');
|
||||
this.hslRgbColorPicker = new pskl.widgets.HslRgbColorPicker(colorPickerContainer, this.onColorUpdated_.bind(this));
|
||||
this.hslRgbColorPicker.init();
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.setColors = function (colors) {
|
||||
if (colors.length === 0) {
|
||||
colors.push(DEFAULT_COLOR);
|
||||
}
|
||||
|
||||
this.palette.setColors(colors);
|
||||
|
||||
this.selectColor_(0);
|
||||
this.refresh_();
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.getColors = function () {
|
||||
return this.palette.getColors();
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.destroy = function () {
|
||||
this.hslRgbColorPicker.destroy();
|
||||
this.container = null;
|
||||
this.colorsList = null;
|
||||
this.colorPreviewEl = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Lightweight refresh only changing the color of one element of the palette color list
|
||||
*/
|
||||
ns.ColorsList.prototype.refreshColorElement_ = function (index) {
|
||||
var color = this.palette.get(this.selectedIndex);
|
||||
var element = document.querySelector('[data-palette-index="'+index+'"]');
|
||||
if (element) {
|
||||
element.style.background = color;
|
||||
element.classList.toggle('light-color', this.isLight_(color));
|
||||
}
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.onColorContainerClick_ = function (evt) {
|
||||
var target = evt.target;
|
||||
if (target.classList.contains('create-palette-color')) {
|
||||
this.onPaletteColorClick_(evt, target);
|
||||
} else if (target.classList.contains('create-palette-new-color')) {
|
||||
this.onNewColorClick_(evt, target);
|
||||
} else if (target.classList.contains('create-palette-remove-color')) {
|
||||
this.onRemoveColorClick_(evt, target);
|
||||
}
|
||||
this.refresh_();
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.onColorUpdated_ = function (color) {
|
||||
var rgbColor = color.toRgbString();
|
||||
this.colorPreviewEl.style.background = rgbColor;
|
||||
if (this.palette) {
|
||||
this.palette.set(this.selectedIndex, rgbColor);
|
||||
this.refreshColorElement_(this.selectedIndex);
|
||||
}
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.onPaletteColorClick_ = function (evt, target) {
|
||||
var index = parseInt(target.dataset.paletteIndex,10);
|
||||
this.selectColor_(index);
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.onRemoveColorClick_ = function (evt, target) {
|
||||
var colorElement = target.parentNode;
|
||||
var index = parseInt(colorElement.dataset.paletteIndex,10);
|
||||
this.removeColor_(index);
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.onNewColorClick_ = function (evt, target) {
|
||||
var newColor = this.palette.get(this.selectedIndex) || '#000000';
|
||||
this.palette.add(newColor);
|
||||
this.selectColor_(this.palette.size()-1);
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.refresh_ = function () {
|
||||
var html = "";
|
||||
var tpl = pskl.utils.Template.get('create-palette-color-template');
|
||||
var colors = this.palette.getColors();
|
||||
|
||||
colors.forEach(function (color, index) {
|
||||
var isSelected = (index === this.selectedIndex);
|
||||
|
||||
html += pskl.utils.Template.replace(tpl, {
|
||||
'color':color, index:index,
|
||||
':selected':isSelected,
|
||||
':light-color':this.isLight_(color)
|
||||
});
|
||||
}.bind(this));
|
||||
|
||||
html += '<li class="create-palette-new-color">+</li>';
|
||||
|
||||
this.colorsList.innerHTML = html;
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.selectColor_ = function (index) {
|
||||
this.selectedIndex = index;
|
||||
this.hslRgbColorPicker.setColor(this.palette.get(index));
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.removeColor_ = function (index) {
|
||||
this.palette.removeAt(index);
|
||||
this.refresh_();
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.isLight_ = function (color) {
|
||||
var rgb = window.tinycolor(color).toRgb();
|
||||
return rgb.r+rgb.b+rgb.g > 128*3;
|
||||
};
|
||||
|
||||
ns.ColorsList.prototype.onColorDrop_ = function (evt, drop) {
|
||||
var colorElement = drop.item.get(0);
|
||||
|
||||
var oldIndex = parseInt(colorElement.dataset.paletteIndex, 10);
|
||||
var newIndex = $('.create-palette-color').index(drop.item);
|
||||
this.palette.move(oldIndex, newIndex);
|
||||
|
||||
this.selectedIndex = newIndex;
|
||||
|
||||
this.refresh_();
|
||||
};
|
||||
})();
|
||||
194
src/js/widgets/HslRgbColorPicker.js
Normal file
194
src/js/widgets/HslRgbColorPicker.js
Normal file
@@ -0,0 +1,194 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.widgets');
|
||||
|
||||
ns.HslRgbColorPicker = function (container, colorUpdatedCallback) {
|
||||
this.container = container;
|
||||
this.colorUpdatedCallback = colorUpdatedCallback;
|
||||
this.lastInputTimestamp_ = 0;
|
||||
};
|
||||
|
||||
ns.HslRgbColorPicker.prototype.init = function () {
|
||||
var isChromeOrFirefox = pskl.utils.UserAgent.isChrome || pskl.utils.UserAgent.isFirefox;
|
||||
var changeEvent = isChromeOrFirefox ? 'input' : 'change';
|
||||
this.container.addEventListener(changeEvent, this.onPickerChange_.bind(this));
|
||||
this.container.addEventListener('keydown', this.onKeydown_.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'
|
||||
});
|
||||
|
||||
this.setColor("#000000");
|
||||
};
|
||||
|
||||
ns.HslRgbColorPicker.prototype.destroy = function () {
|
||||
this.container = null;
|
||||
this.spectrumEl = null;
|
||||
};
|
||||
|
||||
ns.HslRgbColorPicker.prototype.onPickerChange_ = function (evt) {
|
||||
var target = evt.target;
|
||||
|
||||
var model = target.dataset.model;
|
||||
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) {
|
||||
var target = evt.target;
|
||||
|
||||
if (target.getAttribute('type').toLowerCase() === 'text') {
|
||||
var value = parseInt(target.value, 10);
|
||||
var dimension = target.dataset.dimension;
|
||||
|
||||
var key = pskl.service.keyboard.KeycodeTranslator.toChar(evt.keyCode);
|
||||
if (key === 'up') {
|
||||
value = value + 1;
|
||||
} else if (key === 'down') {
|
||||
value = value - 1;
|
||||
}
|
||||
|
||||
value = this.normalizeDimension_(value, dimension);
|
||||
|
||||
target.value = value;
|
||||
this.onPickerChange_(evt);
|
||||
}
|
||||
};
|
||||
|
||||
ns.HslRgbColorPicker.prototype.setColor = function (inputColor) {
|
||||
if (!this.unplugged) {
|
||||
this.unplugged = true;
|
||||
|
||||
this.hsvColor = this.toHsvColor_(inputColor);
|
||||
this.tinyColor = this.toTinyColor_(inputColor);
|
||||
|
||||
this.updateInputs();
|
||||
$(".color-picker-spectrum").spectrum("set", this.tinyColor);
|
||||
|
||||
this.colorUpdatedCallback(this.tinyColor);
|
||||
|
||||
this.unplugged = false;
|
||||
}
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (input.getAttribute('type') === 'range') {
|
||||
this.updateSliderBackground(input);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.HslRgbColorPicker.prototype.updateSliderBackground = function (slider) {
|
||||
var dimension = slider.dataset.dimension;
|
||||
var model = slider.dataset.model;
|
||||
|
||||
var start, end;
|
||||
var isHueSlider = dimension === 'h';
|
||||
if (!isHueSlider) {
|
||||
var colors = this.getSliderBackgroundColors_(model, dimension);
|
||||
slider.style.backgroundImage = "linear-gradient(to right, " + colors.start + " 0, " + colors.end + " 100%)";
|
||||
}
|
||||
};
|
||||
|
||||
ns.HslRgbColorPicker.prototype.getSliderBackgroundColors_ = function (model, dimension) {
|
||||
var start, end;
|
||||
if (model === 'hsv') {
|
||||
start = JSON.parse(JSON.stringify(this.hsvColor));
|
||||
start[dimension] = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return {
|
||||
start : window.tinycolor(start).toRgbString(),
|
||||
end : window.tinycolor(end).toRgbString()
|
||||
};
|
||||
};
|
||||
|
||||
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.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.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));
|
||||
} ;
|
||||
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user