mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Enhancement : Palette color creator
- Added import button on create palette dialog - implemented import from images - missing limitation on color count when importing !! - should remove button when editing existing palette
This commit is contained in:
parent
8643f4402a
commit
e457209c8f
@ -17,6 +17,10 @@
|
|||||||
top: 50px;
|
top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.create-palette-import-section {
|
||||||
|
display : inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
.colors-container {
|
.colors-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
|
@ -38,8 +38,8 @@
|
|||||||
this.piskelController = new pskl.controller.piskel.PublicPiskelController(this.corePiskelController);
|
this.piskelController = new pskl.controller.piskel.PublicPiskelController(this.corePiskelController);
|
||||||
this.piskelController.init();
|
this.piskelController.init();
|
||||||
|
|
||||||
|
this.paletteImportService = new pskl.service.palette.PaletteImportService();
|
||||||
this.paletteService = new pskl.service.palette.PaletteService();
|
this.paletteService = new pskl.service.palette.PaletteService();
|
||||||
this.paletteService.init();
|
|
||||||
|
|
||||||
this.paletteController = new pskl.controller.PaletteController();
|
this.paletteController = new pskl.controller.PaletteController();
|
||||||
this.paletteController.init();
|
this.paletteController.init();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
ns.CreatePaletteController = function (piskelController) {
|
ns.CreatePaletteController = function (piskelController) {
|
||||||
this.paletteService = pskl.app.paletteService;
|
this.paletteService = pskl.app.paletteService;
|
||||||
|
this.paletteImportService = pskl.app.paletteImportService;
|
||||||
this.selectedIndex = -1;
|
this.selectedIndex = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -11,32 +12,41 @@
|
|||||||
ns.CreatePaletteController.prototype.init = function (paletteId) {
|
ns.CreatePaletteController.prototype.init = function (paletteId) {
|
||||||
this.superclass.init.call(this);
|
this.superclass.init.call(this);
|
||||||
|
|
||||||
if (paletteId) {
|
|
||||||
var palette = this.paletteService.getPaletteById(paletteId);
|
|
||||||
this.palette = pskl.model.Palette.fromObject(palette);
|
|
||||||
} else {
|
|
||||||
paletteId = pskl.utils.Uuid.generate();
|
|
||||||
this.palette = new pskl.model.Palette(paletteId, 'New palette', []);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.colorsList = document.querySelector('.colors-list');
|
this.colorsList = document.querySelector('.colors-list');
|
||||||
this.colorPreviewEl = document.querySelector('.color-preview');
|
this.colorPreviewEl = document.querySelector('.color-preview');
|
||||||
|
this.hiddenFileInput = document.querySelector('.create-palette-import-input');
|
||||||
this.nameInput = document.querySelector('input[name="palette-name"]');
|
this.nameInput = document.querySelector('input[name="palette-name"]');
|
||||||
this.nameInput.value = pskl.utils.unescapeHtml(this.palette.name);
|
|
||||||
|
|
||||||
var submitButton = document.querySelector('.create-palette-submit');
|
var submitButton = document.querySelector('.create-palette-submit');
|
||||||
var cancelButton = document.querySelector('.create-palette-cancel');
|
var cancelButton = document.querySelector('.create-palette-cancel');
|
||||||
|
var importFileButton = document.querySelector('.create-palette-import-button');
|
||||||
|
|
||||||
this.colorsList.addEventListener('click', this.onColorContainerClick_.bind(this));
|
this.colorsList.addEventListener('click', this.onColorContainerClick_.bind(this));
|
||||||
this.nameInput.addEventListener('input', this.onNameInputChange_.bind(this));
|
this.nameInput.addEventListener('input', this.onNameInputChange_.bind(this));
|
||||||
|
this.hiddenFileInput.addEventListener('change', this.onFileInputChange_.bind(this));
|
||||||
|
|
||||||
submitButton.addEventListener('click', this.onSubmitButtonClick_.bind(this));
|
submitButton.addEventListener('click', this.onSubmitButtonClick_.bind(this));
|
||||||
cancelButton.addEventListener('click', this.closeDialog.bind(this));
|
cancelButton.addEventListener('click', this.closeDialog.bind(this));
|
||||||
|
importFileButton.addEventListener('click', this.onImportFileButtonClick_.bind(this));
|
||||||
|
|
||||||
var colorPickerContainer = document.querySelector('.color-picker-container');
|
var colorPickerContainer = document.querySelector('.color-picker-container');
|
||||||
this.hslRgbColorPicker = new pskl.controller.widgets.HslRgbColorPicker(colorPickerContainer, this.onColorUpdated_.bind(this));
|
this.hslRgbColorPicker = new pskl.controller.widgets.HslRgbColorPicker(colorPickerContainer, this.onColorUpdated_.bind(this));
|
||||||
this.hslRgbColorPicker.init();
|
this.hslRgbColorPicker.init();
|
||||||
|
|
||||||
|
var palette;
|
||||||
|
if (paletteId) {
|
||||||
|
var paletteObject = this.paletteService.getPaletteById(paletteId);
|
||||||
|
palette = pskl.model.Palette.fromObject(paletteObject);
|
||||||
|
} else {
|
||||||
|
palette = new pskl.model.Palette(pskl.utils.Uuid.generate(), 'New palette', []);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPalette_(palette);
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.CreatePaletteController.prototype.setPalette_ = function (palette) {
|
||||||
|
this.palette = palette;
|
||||||
|
this.nameInput.value = pskl.utils.unescapeHtml(this.palette.name);
|
||||||
this.refresh_();
|
this.refresh_();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,9 +59,10 @@
|
|||||||
ns.CreatePaletteController.prototype.onColorUpdated_ = function (color) {
|
ns.CreatePaletteController.prototype.onColorUpdated_ = function (color) {
|
||||||
var rgbColor = color.toRgbString();
|
var rgbColor = color.toRgbString();
|
||||||
this.colorPreviewEl.style.background = rgbColor;
|
this.colorPreviewEl.style.background = rgbColor;
|
||||||
|
if (this.palette) {
|
||||||
this.palette.set(this.selectedIndex, rgbColor);
|
this.palette.set(this.selectedIndex, rgbColor);
|
||||||
|
|
||||||
this.refreshColorElement_(this.selectedIndex);
|
this.refreshColorElement_(this.selectedIndex);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -100,6 +111,17 @@
|
|||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.CreatePaletteController.prototype.onImportFileButtonClick_ = function () {
|
||||||
|
this.hiddenFileInput.click();
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.CreatePaletteController.prototype.onFileInputChange_ = function (evt) {
|
||||||
|
var files = this.hiddenFileInput.files;
|
||||||
|
if (files.length == 1) {
|
||||||
|
this.paletteImportService.read(files[0], this.setPalette_.bind(this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
ns.CreatePaletteController.prototype.onNameInputChange_ = function (evt) {
|
ns.CreatePaletteController.prototype.onNameInputChange_ = function (evt) {
|
||||||
this.palette.name = pskl.utils.escapeHtml(this.nameInput.value);
|
this.palette.name = pskl.utils.escapeHtml(this.nameInput.value);
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
this.importImageForm = $('[name=import-image-form]');
|
this.importImageForm = $('[name=import-image-form]');
|
||||||
this.importImageForm.submit(this.onImportFormSubmit_.bind(this));
|
this.importImageForm.submit(this.onImportFormSubmit_.bind(this));
|
||||||
|
|
||||||
pskl.utils.FileUtils.readFile(this.file_, this.processImageSource_.bind(this));
|
pskl.utils.FileUtils.readImageFile(this.file_, this.onImageLoaded_.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.ImportImageController.prototype.onImportFormSubmit_ = function (evt) {
|
ns.ImportImageController.prototype.onImportFormSubmit_ = function (evt) {
|
||||||
@ -55,18 +55,9 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
ns.ImportImageController.prototype.onImageLoaded_ = function (image) {
|
||||||
* Create an image from the given source (url or data-url), and onload forward to onImageLoaded
|
this.importedImage_ = image;
|
||||||
* TODO : should be a generic utility method, should take a callback
|
|
||||||
* @param {String} imageSource url or data-url, will be used as src for the image
|
|
||||||
*/
|
|
||||||
ns.ImportImageController.prototype.processImageSource_ = function (imageSource) {
|
|
||||||
this.importedImage_ = new Image();
|
|
||||||
this.importedImage_.onload = this.onImageLoaded_.bind(this);
|
|
||||||
this.importedImage_.src = imageSource;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.ImportImageController.prototype.onImageLoaded_ = function (evt) {
|
|
||||||
var w = this.importedImage_.width,
|
var w = this.importedImage_.width,
|
||||||
h = this.importedImage_.height;
|
h = this.importedImage_.height;
|
||||||
|
|
||||||
|
@ -1,61 +0,0 @@
|
|||||||
(function () {
|
|
||||||
var ns = $.namespace('pskl.service');
|
|
||||||
ns.PaletteService = function () {
|
|
||||||
this.palettes = [];
|
|
||||||
this.localStorageService = window.localStorage;
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.init = function () {};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.getPalettes = function () {
|
|
||||||
var palettesString = this.localStorageService.getItem('piskel.palettes');
|
|
||||||
return JSON.parse(palettesString) || [];
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.getPaletteById = function (paletteId) {
|
|
||||||
var palettes = this.getPalettes();
|
|
||||||
return this.findPaletteInArray_(paletteId, palettes);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.savePalette = function (palette) {
|
|
||||||
var palettes = this.getPalettes();
|
|
||||||
var existingPalette = this.findPaletteInArray_(palette.id, palettes);
|
|
||||||
if (existingPalette) {
|
|
||||||
var currentIndex = palettes.indexOf(existingPalette);
|
|
||||||
palettes.splice(currentIndex, 1, palette);
|
|
||||||
} else {
|
|
||||||
palettes.push(palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.savePalettes_(palettes);
|
|
||||||
|
|
||||||
$.publish(Events.SHOW_NOTIFICATION, [{"content": "Palette " + palette.name + " successfully saved !"}]);
|
|
||||||
window.setTimeout($.publish.bind($, Events.HIDE_NOTIFICATION), 2000);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.deletePaletteById = function (id) {
|
|
||||||
var palettes = this.getPalettes();
|
|
||||||
var filteredPalettes = palettes.filter(function (palette) {
|
|
||||||
return palette.id !== id;
|
|
||||||
});
|
|
||||||
|
|
||||||
this.savePalettes_(filteredPalettes);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.savePalettes_ = function (palettes) {
|
|
||||||
this.localStorageService.setItem('piskel.palettes', JSON.stringify(palettes));
|
|
||||||
$.publish(Events.PALETTE_LIST_UPDATED);
|
|
||||||
};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.findPaletteInArray_ = function (paletteId, palettes) {
|
|
||||||
var match = null;
|
|
||||||
|
|
||||||
palettes.forEach(function (palette) {
|
|
||||||
if (palette.id === paletteId) {
|
|
||||||
match = palette;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return match;
|
|
||||||
};
|
|
||||||
})();
|
|
29
src/js/service/palette/PaletteImageReader.js
Normal file
29
src/js/service/palette/PaletteImageReader.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace('pskl.service.palette');
|
||||||
|
|
||||||
|
ns.PaletteImageReader = function (file, onSuccess, onError) {
|
||||||
|
this.file = file;
|
||||||
|
this.onSuccess = onSuccess;
|
||||||
|
this.onError = onError;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PaletteImageReader.prototype.read = function () {
|
||||||
|
pskl.utils.FileUtils.readImageFile(this.file, this.onImageLoaded_.bind(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PaletteImageReader.prototype.onImageLoaded_ = function (image) {
|
||||||
|
var frame = pskl.utils.FrameUtils.createFromImage(image);
|
||||||
|
var colorsMap = {};
|
||||||
|
frame.forEachPixel(function (color, x, y) {
|
||||||
|
colorsMap[color] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
delete colorsMap[Constants.TRANSPARENT_COLOR];
|
||||||
|
|
||||||
|
var colors = Object.keys(colorsMap);
|
||||||
|
var uuid = pskl.utils.Uuid.generate();
|
||||||
|
var palette = new pskl.model.Palette(uuid, this.file.name + ' palette', colors);
|
||||||
|
|
||||||
|
this.onSuccess(palette);
|
||||||
|
};
|
||||||
|
})();
|
26
src/js/service/palette/PaletteImportService.js
Normal file
26
src/js/service/palette/PaletteImportService.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace('pskl.service.palette');
|
||||||
|
|
||||||
|
ns.PaletteImportService = function () {};
|
||||||
|
|
||||||
|
ns.PaletteImportService.prototype.read = function (file, onSuccess, onError) {
|
||||||
|
if (this.isImage_(file)){
|
||||||
|
var reader = new ns.PaletteImageReader(file, onSuccess, onError);
|
||||||
|
reader.read();
|
||||||
|
} else if (this.isSupportedFormat_(file)) {
|
||||||
|
this.importFile(file);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PaletteImportService.prototype.importFile = function (file) {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PaletteImportService.prototype.isImage_ = function (file) {
|
||||||
|
return file.type.indexOf('image') === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
ns.PaletteImportService.prototype.isSupportedFormat_ = function (file) {
|
||||||
|
return (/\.piskel$/).test(file.name);
|
||||||
|
};
|
||||||
|
})();
|
@ -1,12 +1,11 @@
|
|||||||
(function () {
|
(function () {
|
||||||
var ns = $.namespace('pskl.service.palette');
|
var ns = $.namespace('pskl.service.palette');
|
||||||
|
|
||||||
ns.PaletteService = function () {
|
ns.PaletteService = function () {
|
||||||
this.palettes = [];
|
this.palettes = [];
|
||||||
this.localStorageService = window.localStorage;
|
this.localStorageService = window.localStorage;
|
||||||
};
|
};
|
||||||
|
|
||||||
ns.PaletteService.prototype.init = function () {};
|
|
||||||
|
|
||||||
ns.PaletteService.prototype.getPalettes = function () {
|
ns.PaletteService.prototype.getPalettes = function () {
|
||||||
var palettesString = this.localStorageService.getItem('piskel.palettes');
|
var palettesString = this.localStorageService.getItem('piskel.palettes');
|
||||||
return JSON.parse(palettesString) || [];
|
return JSON.parse(palettesString) || [];
|
||||||
|
@ -14,6 +14,14 @@
|
|||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
readImageFile : function (file, callback) {
|
||||||
|
ns.FileUtils.readFile(file, function (content) {
|
||||||
|
var image = new Image();
|
||||||
|
image.onload = callback.bind(null, image);
|
||||||
|
image.src = content;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
downloadAsFile : function (content, filename) {
|
downloadAsFile : function (content, filename) {
|
||||||
var saveAs = window.saveAs || (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator));
|
var saveAs = window.saveAs || (navigator.msSaveBlob && navigator.msSaveBlob.bind(navigator));
|
||||||
if (saveAs) {
|
if (saveAs) {
|
||||||
|
@ -120,6 +120,8 @@
|
|||||||
"js/service/BeforeUnloadService.js",
|
"js/service/BeforeUnloadService.js",
|
||||||
"js/service/HistoryService.js",
|
"js/service/HistoryService.js",
|
||||||
"js/service/palette/PaletteService.js",
|
"js/service/palette/PaletteService.js",
|
||||||
|
"js/service/palette/PaletteImportService.js",
|
||||||
|
"js/service/palette/PaletteImageReader.js",
|
||||||
"js/service/SavedStatusService.js",
|
"js/service/SavedStatusService.js",
|
||||||
"js/service/keyboard/ShortcutService.js",
|
"js/service/keyboard/ShortcutService.js",
|
||||||
"js/service/keyboard/KeycodeTranslator.js",
|
"js/service/keyboard/KeycodeTranslator.js",
|
||||||
|
@ -5,7 +5,14 @@
|
|||||||
</h3>
|
</h3>
|
||||||
<div class="dialog-create-palette" style="font-size:1.3em">
|
<div class="dialog-create-palette" style="font-size:1.3em">
|
||||||
<div class="create-palette-section form-section">
|
<div class="create-palette-section form-section">
|
||||||
<span class="dialog-create-palette-name">Name :</span><input type="text" class="textfield" name="palette-name" placeholder="palette name ..."/>
|
<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>
|
||||||
|
<input style="display:none"
|
||||||
|
class="create-palette-import-input"
|
||||||
|
type="file" value="file" accept="*"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colors-container">
|
<div class="colors-container">
|
||||||
<ul class="colors-list"></ul>
|
<ul class="colors-list"></ul>
|
||||||
|
@ -37,7 +37,7 @@ describe("Palette Service", function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
paletteService = new pskl.service.PaletteService();
|
paletteService = new pskl.service.palette.PaletteService();
|
||||||
paletteService.localStorageService = localStorageService;
|
paletteService.localStorageService = localStorageService;
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user