mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Fix for #265
This commit is contained in:
parent
5d4b8b87a3
commit
0e817a88a7
@ -5,6 +5,7 @@
|
|||||||
var MAX_GIF_COLORS = 256;
|
var MAX_GIF_COLORS = 256;
|
||||||
var MAX_EXPORT_ZOOM = 20;
|
var MAX_EXPORT_ZOOM = 20;
|
||||||
var DEFAULT_EXPORT_ZOOM = 10;
|
var DEFAULT_EXPORT_ZOOM = 10;
|
||||||
|
var MAGIC_PINK = '#FF00FF';
|
||||||
|
|
||||||
ns.GifExportController = function (piskelController) {
|
ns.GifExportController = function (piskelController) {
|
||||||
this.piskelController = piskelController;
|
this.piskelController = piskelController;
|
||||||
@ -115,19 +116,24 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.GifExportController.prototype.renderAsImageDataAnimatedGIF = function(zoom, fps, cb) {
|
ns.GifExportController.prototype.renderAsImageDataAnimatedGIF = function(zoom, fps, cb) {
|
||||||
var colorCount = pskl.app.currentColorsService.getCurrentColors().length;
|
var currentColors = pskl.app.currentColorsService.computeCurrentColors();
|
||||||
var preserveColors = colorCount < MAX_GIF_COLORS;
|
|
||||||
|
var preserveColors = currentColors.length < MAX_GIF_COLORS;
|
||||||
|
var transparentColor = this.getTransparentColor(currentColors);
|
||||||
|
|
||||||
var gif = new window.GIF({
|
var gif = new window.GIF({
|
||||||
workers: 5,
|
workers: 5,
|
||||||
quality: 1,
|
quality: 1,
|
||||||
width: this.piskelController.getWidth() * zoom,
|
width: this.piskelController.getWidth() * zoom,
|
||||||
height: this.piskelController.getHeight() * zoom,
|
height: this.piskelController.getHeight() * zoom,
|
||||||
preserveColors : preserveColors
|
preserveColors : preserveColors,
|
||||||
|
transparent : parseInt(transparentColor, 16)
|
||||||
});
|
});
|
||||||
|
|
||||||
for (var i = 0; i < this.piskelController.getFrameCount(); i++) {
|
for (var i = 0; i < this.piskelController.getFrameCount(); i++) {
|
||||||
var frame = this.piskelController.getFrameAt(i);
|
var frame = this.piskelController.getFrameAt(i);
|
||||||
var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, zoom);
|
var canvasRenderer = new pskl.rendering.CanvasRenderer(frame, zoom);
|
||||||
|
canvasRenderer.drawTransparentAs(transparentColor);
|
||||||
var canvas = canvasRenderer.render();
|
var canvas = canvasRenderer.render();
|
||||||
gif.addFrame(canvas.getContext('2d'), {
|
gif.addFrame(canvas.getContext('2d'), {
|
||||||
delay: 1000 / fps
|
delay: 1000 / fps
|
||||||
@ -147,6 +153,17 @@
|
|||||||
gif.render();
|
gif.render();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.GifExportController.prototype.getTransparentColor = function(currentColors) {
|
||||||
|
var transparentColor = pskl.utils.ColorUtils.getUnusedColor(currentColors);
|
||||||
|
if (!transparentColor) {
|
||||||
|
console.error('Unable to find unused color to use as transparent color in the current sprite');
|
||||||
|
transparentColor = MAGIC_PINK;
|
||||||
|
} else {
|
||||||
|
transparentColor = window.tinycolor(transparentColor).toHexString();
|
||||||
|
}
|
||||||
|
return transparentColor;
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME : HORRIBLE COPY/PASTA
|
// FIXME : HORRIBLE COPY/PASTA
|
||||||
|
|
||||||
ns.GifExportController.prototype.updateStatus_ = function (imageUrl, error) {
|
ns.GifExportController.prototype.updateStatus_ = function (imageUrl, error) {
|
||||||
|
@ -32,6 +32,30 @@
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ns.CurrentColorsService.prototype.computeCurrentColors = function (max) {
|
||||||
|
var layers = this.piskelController.getLayers();
|
||||||
|
var frames = layers.map(function (l) {return l.getFrames();}).reduce(function (p, n) {return p.concat(n);});
|
||||||
|
var colors = {};
|
||||||
|
|
||||||
|
frames.forEach(function (f) {
|
||||||
|
var frameColors = this.cachedFrameProcessor.get(f);
|
||||||
|
Object.keys(frameColors).slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED).forEach(function (color) {
|
||||||
|
colors[color] = true;
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
// Remove transparent color from used colors
|
||||||
|
delete colors[Constants.TRANSPARENT_COLOR];
|
||||||
|
|
||||||
|
var colorsArray = Object.keys(colors);
|
||||||
|
// limit the array to the max colors to display
|
||||||
|
if (max) {
|
||||||
|
colorsArray = colorsArray.slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.colorSorter.sort(colorsArray);
|
||||||
|
};
|
||||||
|
|
||||||
ns.CurrentColorsService.prototype.isCurrentColorsPaletteSelected_ = function () {
|
ns.CurrentColorsService.prototype.isCurrentColorsPaletteSelected_ = function () {
|
||||||
var paletteId = pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE);
|
var paletteId = pskl.UserSettings.get(pskl.UserSettings.SELECTED_PALETTE);
|
||||||
var palette = this.paletteService.getPaletteById(paletteId);
|
var palette = this.paletteService.getPaletteById(paletteId);
|
||||||
@ -48,24 +72,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
ns.CurrentColorsService.prototype.updateCurrentColors_ = function () {
|
ns.CurrentColorsService.prototype.updateCurrentColors_ = function () {
|
||||||
var layers = this.piskelController.getLayers();
|
var currentColors = this.computeCurrentColors(Constants.MAX_CURRENT_COLORS_DISPLAYED);
|
||||||
var frames = layers.map(function (l) {return l.getFrames();}).reduce(function (p, n) {return p.concat(n);});
|
|
||||||
var colors = {};
|
|
||||||
|
|
||||||
frames.forEach(function (f) {
|
|
||||||
var frameColors = this.cachedFrameProcessor.get(f);
|
|
||||||
Object.keys(frameColors).slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED).forEach(function (color) {
|
|
||||||
colors[color] = true;
|
|
||||||
});
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
// Remove transparent color from used colors
|
|
||||||
delete colors[Constants.TRANSPARENT_COLOR];
|
|
||||||
|
|
||||||
// limit the array to the max colors to display
|
|
||||||
var colorsArray = Object.keys(colors).slice(0, Constants.MAX_CURRENT_COLORS_DISPLAYED);
|
|
||||||
var currentColors = this.colorSorter.sort(colorsArray);
|
|
||||||
|
|
||||||
this.setCurrentColors(currentColors);
|
this.setCurrentColors(currentColors);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
41
src/js/utils/ColorUtils.js
Normal file
41
src/js/utils/ColorUtils.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
(function () {
|
||||||
|
var ns = $.namespace('pskl.utils');
|
||||||
|
|
||||||
|
ns.ColorUtils = {
|
||||||
|
getUnusedColor : function (usedColors) {
|
||||||
|
// start with white
|
||||||
|
var color = {
|
||||||
|
r : 255,
|
||||||
|
g : 255,
|
||||||
|
b : 255
|
||||||
|
};
|
||||||
|
|
||||||
|
// create check map
|
||||||
|
var colorMap = {};
|
||||||
|
usedColors.forEach(function (color) {
|
||||||
|
colorMap[color.toUpperCase()] = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
var match = null;
|
||||||
|
while (true) {
|
||||||
|
var hex = tinycolor(color).toHexString().toUpperCase();
|
||||||
|
|
||||||
|
if (!colorMap[hex]) {
|
||||||
|
match = color;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// pick a non null component to decrease its value
|
||||||
|
var component = (color.r && 'r') || (color.g && 'g') || (color.b && 'b');
|
||||||
|
if (component) {
|
||||||
|
color[component] = color[component] - 1;
|
||||||
|
} else {
|
||||||
|
// no component available, no match found
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
@ -15,6 +15,7 @@
|
|||||||
"js/utils/Base64.js",
|
"js/utils/Base64.js",
|
||||||
"js/utils/BlobUtils.js",
|
"js/utils/BlobUtils.js",
|
||||||
"js/utils/CanvasUtils.js",
|
"js/utils/CanvasUtils.js",
|
||||||
|
"js/utils/ColorUtils.js",
|
||||||
"js/utils/DateUtils.js",
|
"js/utils/DateUtils.js",
|
||||||
"js/utils/Dom.js",
|
"js/utils/Dom.js",
|
||||||
"js/utils/Event.js",
|
"js/utils/Event.js",
|
||||||
|
Loading…
Reference in New Issue
Block a user