mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Enhancement : Color palettes
- Added clone feature when editing existing palette - Added arrow up/down to increase decrease input values - Paint.net palettes are supported
This commit is contained in:
parent
125e332b7c
commit
90845b3a62
2
src/css/bootstrap/bootstrap.css
vendored
2
src/css/bootstrap/bootstrap.css
vendored
@ -36,7 +36,7 @@
|
||||
}
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
z-index: 1030;
|
||||
z-index: 30000;
|
||||
display: block;
|
||||
visibility: visible;
|
||||
padding: 5px;
|
||||
|
@ -112,7 +112,7 @@
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 2px 4px;
|
||||
padding: 2px 4px 0 0;
|
||||
opacity : 0.2;
|
||||
|
||||
font-weight: bold;
|
||||
|
@ -1,10 +1,16 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.controller.dialogs');
|
||||
|
||||
var MODE = {
|
||||
CREATE : 'CREATE',
|
||||
EDIT : 'EDIT'
|
||||
};
|
||||
|
||||
ns.CreatePaletteController = function (piskelController) {
|
||||
this.paletteService = pskl.app.paletteService;
|
||||
this.paletteImportService = pskl.app.paletteImportService;
|
||||
this.selectedIndex = -1;
|
||||
this.mode = null;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.CreatePaletteController, ns.AbstractDialogController);
|
||||
@ -18,6 +24,7 @@
|
||||
this.nameInput = document.querySelector('input[name="palette-name"]');
|
||||
|
||||
var submitButton = document.querySelector('.create-palette-submit');
|
||||
var cloneButton = document.querySelector('.create-palette-clone');
|
||||
var cancelButton = document.querySelector('.create-palette-cancel');
|
||||
var importFileButton = document.querySelector('.create-palette-import-button');
|
||||
|
||||
@ -26,6 +33,7 @@
|
||||
this.hiddenFileInput.addEventListener('change', this.onFileInputChange_.bind(this));
|
||||
|
||||
submitButton.addEventListener('click', this.onSubmitButtonClick_.bind(this));
|
||||
cloneButton.addEventListener('click', this.onCloneButtonClick_.bind(this));
|
||||
cancelButton.addEventListener('click', this.closeDialog.bind(this));
|
||||
importFileButton.addEventListener('click', this.onImportFileButtonClick_.bind(this));
|
||||
|
||||
@ -37,8 +45,12 @@
|
||||
if (paletteId) {
|
||||
var paletteObject = this.paletteService.getPaletteById(paletteId);
|
||||
palette = pskl.model.Palette.fromObject(paletteObject);
|
||||
importFileButton.style.display = 'none';
|
||||
this.mode = MODE.EDIT;
|
||||
} else {
|
||||
palette = new pskl.model.Palette(pskl.utils.Uuid.generate(), 'New palette', []);
|
||||
palette = new pskl.model.Palette(pskl.utils.Uuid.generate(), 'New palette', ['#000000']);
|
||||
cloneButton.style.display = 'none';
|
||||
this.mode = MODE.CREATE;
|
||||
}
|
||||
|
||||
this.setPalette_(palette);
|
||||
@ -47,6 +59,7 @@
|
||||
ns.CreatePaletteController.prototype.setPalette_ = function (palette) {
|
||||
this.palette = palette;
|
||||
this.nameInput.value = pskl.utils.unescapeHtml(this.palette.name);
|
||||
this.selectColor_(0);
|
||||
this.refresh_();
|
||||
};
|
||||
|
||||
@ -111,6 +124,12 @@
|
||||
this.closeDialog();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onCloneButtonClick_ = function (evt) {
|
||||
var palette = new pskl.model.Palette(pskl.utils.Uuid.generate(), this.palette.name, this.palette.colors);
|
||||
this.paletteService.savePalette(palette);
|
||||
this.closeDialog();
|
||||
};
|
||||
|
||||
ns.CreatePaletteController.prototype.onImportFileButtonClick_ = function () {
|
||||
this.hiddenFileInput.click();
|
||||
};
|
||||
|
@ -11,6 +11,7 @@
|
||||
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');
|
||||
|
||||
@ -25,7 +26,6 @@
|
||||
this.setColor("#000000");
|
||||
};
|
||||
|
||||
|
||||
ns.HslRgbColorPicker.prototype.onPickerChange_ = function (evt) {
|
||||
var target = evt.target;
|
||||
|
||||
@ -53,6 +53,27 @@
|
||||
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;
|
||||
@ -150,5 +171,18 @@
|
||||
}
|
||||
};
|
||||
|
||||
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));
|
||||
} ;
|
||||
|
||||
|
||||
})();
|
@ -504,8 +504,10 @@
|
||||
|
||||
$(doc).bind("mousedown.spectrum", onMousedown);
|
||||
|
||||
// Piskel-specific : change the color as soon as the user does a mouseup
|
||||
$(doc).bind("mouseup.spectrum", updateColor);
|
||||
if (!flat) {
|
||||
// Piskel-specific : change the color as soon as the user does a mouseup
|
||||
$(doc).bind("mouseup.spectrum", updateColor);
|
||||
}
|
||||
|
||||
$(window).bind("resize.spectrum", resize);
|
||||
replacer.addClass("sp-active");
|
||||
|
@ -1,18 +1,15 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette');
|
||||
|
||||
var supportedFileFormats = ['gpl'];
|
||||
var fileReaders = {
|
||||
'gpl' : ns.PaletteGplReader,
|
||||
'txt' : ns.PaletteTxtReader
|
||||
};
|
||||
|
||||
ns.PaletteImportService = function () {};
|
||||
|
||||
ns.PaletteImportService.prototype.read = function (file, onSuccess, onError) {
|
||||
var reader;
|
||||
if (this.isImage_(file)){
|
||||
reader = new ns.PaletteImageReader(file, onSuccess, onError);
|
||||
} else if (this.isSupportedFormat_(file)) {
|
||||
reader = this.getFileReader_(file, onSuccess, onError);
|
||||
}
|
||||
|
||||
var reader = this.getFileReader_(file, onSuccess, onError);
|
||||
if (reader) {
|
||||
reader.read();
|
||||
} else {
|
||||
@ -25,19 +22,24 @@
|
||||
};
|
||||
|
||||
ns.PaletteImportService.prototype.getFileReader_ = function (file, onSuccess, onError) {
|
||||
var extension = this.getExtension_(file);
|
||||
if (extension === 'gpl') {
|
||||
return new ns.PaletteGplReader(file, onSuccess, onError);
|
||||
var readerClass = this.getReaderClass_(file);
|
||||
|
||||
var reader = null;
|
||||
if (readerClass) {
|
||||
reader = new readerClass(file, onSuccess, onError);
|
||||
}
|
||||
|
||||
return reader;
|
||||
};
|
||||
|
||||
ns.PaletteImportService.prototype.isSupportedFormat_ = function (file) {
|
||||
ns.PaletteImportService.prototype.getReaderClass_ = function (file) {
|
||||
var extension = this.getExtension_(file);
|
||||
return supportedFileFormats.indexOf(extension) != -1;
|
||||
return fileReaders[extension];
|
||||
};
|
||||
|
||||
ns.PaletteImportService.prototype.getExtension_ = function (file) {
|
||||
var parts = file.name.split('.');
|
||||
return parts[parts.length-1];
|
||||
var extension = parts[parts.length-1];
|
||||
return extension.toLowerCase();
|
||||
};
|
||||
})();
|
38
src/js/service/palette/PaletteTxtReader.js
Normal file
38
src/js/service/palette/PaletteTxtReader.js
Normal file
@ -0,0 +1,38 @@
|
||||
(function () {
|
||||
var ns = $.namespace('pskl.service.palette');
|
||||
|
||||
var RE_COLOR_LINE = /^[A-F0-9]{2}([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/;
|
||||
|
||||
ns.PaletteTxtReader = function (file, onSuccess, onError) {
|
||||
this.file = file;
|
||||
this.onSuccess = onSuccess;
|
||||
this.onError = onError;
|
||||
};
|
||||
|
||||
ns.PaletteTxtReader.prototype.read = function () {
|
||||
pskl.utils.FileUtils.readFile(this.file, this.onFileLoaded_.bind(this));
|
||||
};
|
||||
|
||||
ns.PaletteTxtReader.prototype.onFileLoaded_ = function (content) {
|
||||
var text = pskl.utils.Base64.toText(content);
|
||||
var lines = text.match(/[^\r\n]+/g);
|
||||
|
||||
var colorLines = lines.filter(function (l) {
|
||||
return RE_COLOR_LINE.test(l);
|
||||
});
|
||||
|
||||
var colors = colorLines.map(function (l) {
|
||||
var matches = l.match(RE_COLOR_LINE);
|
||||
var color = "#" + matches[1] + matches[2] + matches[3];
|
||||
return color;
|
||||
});
|
||||
|
||||
if (colors.length) {
|
||||
var uuid = pskl.utils.Uuid.generate();
|
||||
var palette = new pskl.model.Palette(uuid, 'Imported palette', colors);
|
||||
this.onSuccess(palette);
|
||||
} else {
|
||||
this.onError();
|
||||
}
|
||||
};
|
||||
})();
|
@ -120,9 +120,10 @@
|
||||
"js/service/BeforeUnloadService.js",
|
||||
"js/service/HistoryService.js",
|
||||
"js/service/palette/PaletteService.js",
|
||||
"js/service/palette/PaletteImportService.js",
|
||||
"js/service/palette/PaletteTxtReader.js",
|
||||
"js/service/palette/PaletteGplReader.js",
|
||||
"js/service/palette/PaletteImageReader.js",
|
||||
"js/service/palette/PaletteImportService.js",
|
||||
"js/service/SavedStatusService.js",
|
||||
"js/service/keyboard/ShortcutService.js",
|
||||
"js/service/keyboard/KeycodeTranslator.js",
|
||||
|
@ -8,7 +8,10 @@
|
||||
<span class="create-palette-name-label">Name</span>
|
||||
<input type="text" class="textfield create-palette-name-input" name="palette-name" placeholder="palette name ..."/>
|
||||
<div class="create-palette-import-section">
|
||||
<button type="button" class="button button-primary create-palette-import-button">Import from file</button>
|
||||
<button
|
||||
type="button"
|
||||
rel="tooltip" data-placement="right" title="Import palette from an existing Image or from a palette file"
|
||||
class="button button-primary create-palette-import-button">Import from file</button>
|
||||
<input style="display:none"
|
||||
class="create-palette-import-input"
|
||||
type="file" value="file" accept="*"/>
|
||||
@ -20,40 +23,41 @@
|
||||
<div class="color-picker-spectrum"></div>
|
||||
<div class="color-picker-slider">
|
||||
<span>H</span>
|
||||
<input type="range" data-model="hsv" data-dimension="h" value="0" min="0" max="359"/>
|
||||
<input type="text" data-model="hsv" data-dimension="h" class="textfield" value="0"/>
|
||||
<input type="range" data-model="hsv" data-dimension="h" value="0" min="0" max="359" tabindex="-1"/>
|
||||
<input type="text" data-model="hsv" data-dimension="h" class="textfield" value="0" tabindex="101"/>
|
||||
</div>
|
||||
<div class="color-picker-slider">
|
||||
<span>S</span>
|
||||
<input type="range" data-model="hsv" data-dimension="s" value="0" min="0" max="100"/>
|
||||
<input type="text" data-model="hsv" data-dimension="s" class="textfield" value="0"/>
|
||||
<input type="range" data-model="hsv" data-dimension="s" value="0" min="0" max="100" tabindex="-1"/>
|
||||
<input type="text" data-model="hsv" data-dimension="s" class="textfield" value="0" tabindex="102"/>
|
||||
</div>
|
||||
<div class="color-picker-slider">
|
||||
<span>V</span>
|
||||
<input type="range" data-model="hsv" data-dimension="v" value="0" min="0" max="100"/>
|
||||
<input type="text" data-model="hsv" data-dimension="v" class="textfield" value="0"/>
|
||||
<input type="range" data-model="hsv" data-dimension="v" value="0" min="0" max="100" tabindex="-1"/>
|
||||
<input type="text" data-model="hsv" data-dimension="v" class="textfield" value="0" tabindex="103"/>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="color-picker-slider">
|
||||
<span>R</span>
|
||||
<input type="range" data-model="rgb" data-dimension="r" value="0" min="0" max="255"/>
|
||||
<input type="text" data-model="rgb" data-dimension="r" class="textfield" value="0"/>
|
||||
<input type="range" data-model="rgb" data-dimension="r" value="0" min="0" max="255" tabindex="-1"/>
|
||||
<input type="text" data-model="rgb" data-dimension="r" class="textfield" value="0" tabindex="104"/>
|
||||
</div>
|
||||
<div class="color-picker-slider">
|
||||
<span>G</span>
|
||||
<input type="range" data-model="rgb" data-dimension="g" value="0" min="0" max="255"/>
|
||||
<input type="text" data-model="rgb" data-dimension="g" class="textfield" value="0"/>
|
||||
<input type="range" data-model="rgb" data-dimension="g" value="0" min="0" max="255" tabindex="-1"/>
|
||||
<input type="text" data-model="rgb" data-dimension="g" class="textfield" value="0" tabindex="105"/>
|
||||
</div>
|
||||
<div class="color-picker-slider">
|
||||
<span>B</span>
|
||||
<input type="range" data-model="rgb" data-dimension="b" value="0" min="0" max="255"/>
|
||||
<input type="text" data-model="rgb" data-dimension="b" class="textfield" value="0"/>
|
||||
<input type="range" data-model="rgb" data-dimension="b" value="0" min="0" max="255" tabindex="-1"/>
|
||||
<input type="text" data-model="rgb" data-dimension="b" class="textfield" value="0" tabindex="106"/>
|
||||
</div>
|
||||
<div class="color-preview"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="create-palette-actions">
|
||||
<button type="button" name="create-palette-cancel" class="button button-primary create-palette-cancel">Cancel</button>
|
||||
<button type="button" name="create-palette-cancel" class="button create-palette-cancel">Cancel</button>
|
||||
<button type="button" name="create-palette-clone" class="button button-primary create-palette-clone">Save as new</button>
|
||||
<button type="button" name="create-palette-submit" class="button button-primary create-palette-submit">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user