mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Temp commit
This commit is contained in:
parent
b712a497e2
commit
0cecdc74eb
@ -32,6 +32,7 @@ var Events = {
|
||||
* Number of frames, content of frames, color used for the palette may have changed.
|
||||
*/
|
||||
PISKEL_RESET: "PISKEL_RESET",
|
||||
PISKEL_SAVE_STATE: "PISKEL_SAVE_STATE",
|
||||
|
||||
PISKEL_SAVED: "PISKEL_SAVED",
|
||||
|
||||
|
@ -175,6 +175,7 @@
|
||||
event
|
||||
);
|
||||
}
|
||||
$.publish(Events.CURSOR_MOVED, [coords.x, coords.y]);
|
||||
this.previousMousemoveTime = currentTime;
|
||||
}
|
||||
};
|
||||
|
@ -44,15 +44,15 @@
|
||||
this.piskelController.setCurrentLayerIndex(parseInt(index, 10));
|
||||
} else if (el.classList.contains('edit-icon')) {
|
||||
index = el.parentNode.dataset.layerIndex;
|
||||
var layer = this.piskelController.getLayerByIndex(parseInt(index, 10));
|
||||
this.renameLayer_(layer);
|
||||
this.renameLayerAt_(index);
|
||||
}
|
||||
};
|
||||
|
||||
ns.LayersListController.prototype.renameLayer_ = function (layer) {
|
||||
var newName = window.prompt("Please enter the layer name", layer.getName());
|
||||
if (newName) {
|
||||
layer.setName(newName);
|
||||
ns.LayersListController.prototype.renameLayerAt_ = function (index) {
|
||||
var layer = this.piskelController.getLayerAt(index);
|
||||
var name = window.prompt("Please enter the layer name", layer.getName());
|
||||
if (name) {
|
||||
this.piskelController.renameLayerAt(index, name);
|
||||
this.renderLayerList_();
|
||||
}
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
ns.PiskelController = function (piskel) {
|
||||
if (piskel) {
|
||||
this.setPiskel(piskel);
|
||||
this.silenced = false;
|
||||
} else {
|
||||
throw 'A piskel instance is mandatory for instanciating PiskelController';
|
||||
}
|
||||
@ -16,8 +17,13 @@
|
||||
|
||||
this.layerIdCounter = 1;
|
||||
|
||||
$.publish(Events.FRAME_SIZE_CHANGED);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.FRAME_SIZE_CHANGED);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'FULL'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.init = function () {
|
||||
@ -51,7 +57,11 @@
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getCurrentLayer = function () {
|
||||
return this.piskel.getLayerAt(this.currentLayerIndex);
|
||||
return this.getLayerAt(this.currentLayerIndex);
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getLayerAt = function (index) {
|
||||
return this.piskel.getLayerAt(index);
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getCurrentFrame = function () {
|
||||
@ -79,12 +89,18 @@
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.addFrameAt = function (index) {
|
||||
var layers = this.getLayers();
|
||||
layers.forEach(function (l) {
|
||||
this.getLayers().forEach(function (l) {
|
||||
l.addFrameAt(this.createEmptyFrame_(), index);
|
||||
}.bind(this));
|
||||
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'ADD_FRAME',
|
||||
index : index
|
||||
});
|
||||
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.createEmptyFrame_ = function () {
|
||||
@ -93,8 +109,7 @@
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.removeFrameAt = function (index) {
|
||||
var layers = this.getLayers();
|
||||
layers.forEach(function (l) {
|
||||
this.getLayers().forEach(function (l) {
|
||||
l.removeFrameAt(index);
|
||||
});
|
||||
// Current frame index is impacted if the removed frame was before the current frame
|
||||
@ -102,7 +117,13 @@
|
||||
this.setCurrentFrameIndex(this.currentFrameIndex - 1);
|
||||
}
|
||||
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'DELETE_FRAME',
|
||||
index : index
|
||||
});
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.duplicateCurrentFrame = function () {
|
||||
@ -110,19 +131,34 @@
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.duplicateFrameAt = function (index) {
|
||||
var layers = this.getLayers();
|
||||
layers.forEach(function (l) {
|
||||
this.getLayers().forEach(function (l) {
|
||||
l.duplicateFrameAt(index);
|
||||
});
|
||||
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'DUPLICATE_FRAME',
|
||||
index : index
|
||||
});
|
||||
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.moveFrame = function (fromIndex, toIndex) {
|
||||
var layers = this.getLayers();
|
||||
layers.forEach(function (l) {
|
||||
this.getLayers().forEach(function (l) {
|
||||
l.moveFrame(fromIndex, toIndex);
|
||||
});
|
||||
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'MOVE_FRAME',
|
||||
from : fromIndex,
|
||||
to : toIndex
|
||||
});
|
||||
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getFrameCount = function () {
|
||||
@ -132,7 +168,9 @@
|
||||
|
||||
ns.PiskelController.prototype.setCurrentFrameIndex = function (index) {
|
||||
this.currentFrameIndex = index;
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.selectNextFrame = function () {
|
||||
@ -151,7 +189,9 @@
|
||||
|
||||
ns.PiskelController.prototype.setCurrentLayerIndex = function (index) {
|
||||
this.currentLayerIndex = index;
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.selectLayer = function (layer) {
|
||||
@ -161,6 +201,20 @@
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.renameLayerAt = function (index, name) {
|
||||
var layer = this.getLayerByIndex(index);
|
||||
if (layer) {
|
||||
layer.setName(name);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'RENAME_LAYER',
|
||||
index : index,
|
||||
name : name
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getLayerByIndex = function (index) {
|
||||
var layers = this.getLayers();
|
||||
if (layers[index]) {
|
||||
@ -190,6 +244,13 @@
|
||||
}
|
||||
this.piskel.addLayer(layer);
|
||||
this.setCurrentLayerIndex(this.piskel.getLayers().length - 1);
|
||||
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'CREATE_LAYER',
|
||||
name : name
|
||||
});
|
||||
}
|
||||
} else {
|
||||
throw 'Layer name should be unique';
|
||||
}
|
||||
@ -203,12 +264,22 @@
|
||||
var layer = this.getCurrentLayer();
|
||||
this.piskel.moveLayerUp(layer);
|
||||
this.selectLayer(layer);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'LAYER_UP'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.moveLayerDown = function () {
|
||||
var layer = this.getCurrentLayer();
|
||||
this.piskel.moveLayerDown(layer);
|
||||
this.selectLayer(layer);
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'LAYER_DOWN'
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.removeCurrentLayer = function () {
|
||||
@ -216,14 +287,28 @@
|
||||
var layer = this.getCurrentLayer();
|
||||
this.piskel.removeLayer(layer);
|
||||
this.setCurrentLayerIndex(0);
|
||||
|
||||
if (!this.silenced) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'REMOVE_LAYER'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.serialize = function () {
|
||||
return pskl.utils.Serializer.serializePiskel(this.piskel);
|
||||
ns.PiskelController.prototype.serialize = function (compressed) {
|
||||
return pskl.utils.Serializer.serializePiskel(this.piskel, compressed);
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.load = function (data) {
|
||||
this.deserialize(JSON.stringify(data));
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.silence = function () {
|
||||
this.silenced = true;
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.voice = function () {
|
||||
this.silenced = false;
|
||||
};
|
||||
})();
|
@ -6,16 +6,17 @@
|
||||
(function() {
|
||||
var ns = $.namespace("pskl.drawingtools");
|
||||
|
||||
ns.BaseTool = function() {};
|
||||
ns.BaseTool = function() {
|
||||
this.toolId = "tool-base";
|
||||
};
|
||||
|
||||
ns.BaseTool.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {};
|
||||
|
||||
ns.BaseTool.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
};
|
||||
ns.BaseTool.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {};
|
||||
|
||||
ns.BaseTool.prototype.replay = Constants.ABSTRACT_FUNCTION;
|
||||
|
||||
ns.BaseTool.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
|
||||
if (overlay.containsPixel(col, row)) {
|
||||
if (!isNaN(this.highlightedPixelCol) &&
|
||||
@ -49,6 +50,14 @@
|
||||
}
|
||||
};
|
||||
|
||||
ns.BaseTool.prototype.raiseSaveStateEvent = function (args) {
|
||||
var toolInfo = {
|
||||
toolId : this.toolId,
|
||||
args : args
|
||||
};
|
||||
$.publish(Events.PISKEL_SAVE_STATE, toolInfo);
|
||||
};
|
||||
|
||||
|
||||
ns.BaseTool.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {};
|
||||
|
||||
|
@ -29,7 +29,6 @@
|
||||
};
|
||||
|
||||
ns.Move.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
var colDiff = col - this.startCol, rowDiff = row - this.startRow;
|
||||
this.shiftFrame(colDiff, rowDiff, frame, this.frameClone);
|
||||
};
|
||||
@ -53,5 +52,18 @@
|
||||
*/
|
||||
ns.Move.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
this.moveToolAt(col, row, color, frame, overlay);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
colDiff : col - this.startCol,
|
||||
rowDiff : row - this.startRow
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.Move.prototype.replay = function(frame, replayData) {
|
||||
this.shiftFrame(replayData.colDiff, replayData.rowDiff, frame, frame.clone());
|
||||
};
|
||||
})();
|
||||
|
@ -17,8 +17,21 @@
|
||||
* @override
|
||||
*/
|
||||
ns.PaintBucket.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {
|
||||
|
||||
pskl.PixelUtils.paintSimilarConnectedPixelsFromFrame(frame, col, row, color);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
col : col,
|
||||
row : row,
|
||||
color : color
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.PaintBucket.prototype.replay = function (frame, replayData) {
|
||||
pskl.PixelUtils.paintSimilarConnectedPixelsFromFrame(frame, replayData.col, replayData.row, replayData.color);
|
||||
};
|
||||
})();
|
||||
|
||||
|
@ -49,7 +49,29 @@
|
||||
}
|
||||
var coords = this.getCoordinates_(col, row, event);
|
||||
this.draw_(coords.col, coords.row, color, frame);
|
||||
|
||||
$.publish(Events.DRAG_END, [col, row]);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
col : col,
|
||||
row : row,
|
||||
startCol : this.startCol,
|
||||
startRow : this.startRow,
|
||||
color : color
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.ShapeTool.prototype.replay = function(frame, replayData) {
|
||||
this.startCol = replayData.startCol;
|
||||
this.startRow = replayData.startRow;
|
||||
this.draw_(replayData.col, replayData.row, replayData.color, frame);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -13,6 +13,7 @@
|
||||
this.previousCol = null;
|
||||
this.previousRow = null;
|
||||
|
||||
this.pixels = [];
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.SimplePen, ns.BaseTool);
|
||||
@ -21,18 +22,19 @@
|
||||
* @override
|
||||
*/
|
||||
ns.SimplePen.prototype.applyToolAt = function(col, row, color, frame, overlay, event) {
|
||||
if (frame.containsPixel(col, row)) {
|
||||
frame.setPixel(col, row, color);
|
||||
}
|
||||
frame.setPixel(col, row, color);
|
||||
this.previousCol = col;
|
||||
this.previousRow = row;
|
||||
this.pixels.push({
|
||||
col : col,
|
||||
row : row
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
ns.SimplePen.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
if((Math.abs(col - this.previousCol) > 1) || (Math.abs(row - this.previousRow) > 1)) {
|
||||
// The pen movement is too fast for the mousemove frequency, there is a gap between the
|
||||
// current point and the previously drawn one.
|
||||
@ -50,4 +52,24 @@
|
||||
this.previousCol = col;
|
||||
this.previousRow = row;
|
||||
};
|
||||
|
||||
|
||||
ns.SimplePen.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
pixels : this.pixels.slice(0),
|
||||
color : color
|
||||
}
|
||||
});
|
||||
this.pixels = [];
|
||||
};
|
||||
|
||||
ns.SimplePen.prototype.replay = function (frame, replayData) {
|
||||
var pixels = replayData.pixels;
|
||||
pixels.forEach(function (pixel) {
|
||||
frame.setPixel(pixel.col, pixel.row, replayData.color);
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
@ -37,8 +37,6 @@
|
||||
};
|
||||
|
||||
ns.Stroke.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
|
||||
overlay.clear();
|
||||
|
||||
// When the user moussemove (before releasing), we dynamically compute the
|
||||
@ -65,18 +63,29 @@
|
||||
* @override
|
||||
*/
|
||||
ns.Stroke.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
// If the stroke tool is released outside of the canvas, we cancel the stroke:
|
||||
// TODO: Mutualize this check in common method
|
||||
if(frame.containsPixel(col, row)) {
|
||||
// The user released the tool to draw a line. We will compute the pixel coordinate, impact
|
||||
// the model and draw them in the drawing canvas (not the fake overlay anymore)
|
||||
var strokePoints = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
||||
for(var i = 0; i< strokePoints.length; i++) {
|
||||
// Change model:
|
||||
frame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
||||
}
|
||||
// The user released the tool to draw a line. We will compute the pixel coordinate, impact
|
||||
// the model and draw them in the drawing canvas (not the fake overlay anymore)
|
||||
var strokePoints = this.getLinePixels_(this.startCol, col, this.startRow, row);
|
||||
for(var i = 0; i< strokePoints.length; i++) {
|
||||
// Change model:
|
||||
frame.setPixel(strokePoints[i].col, strokePoints[i].row, color);
|
||||
}
|
||||
// For now, we are done with the stroke tool and don't need an overlay anymore:
|
||||
overlay.clear();
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
pixels : strokePoints,
|
||||
color : color
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.Stroke.prototype.replay = function(frame, replayData) {
|
||||
replayData.pixels.forEach(function (pixel) {
|
||||
frame.setPixel(pixel.col, pixel.row, replayData.color);
|
||||
});
|
||||
};
|
||||
})();
|
||||
|
@ -2,12 +2,12 @@
|
||||
var ns = $.namespace("pskl.drawingtools");
|
||||
|
||||
ns.VerticalMirrorPen = function() {
|
||||
this.superclass.constructor.call(this);
|
||||
|
||||
this.toolId = "tool-vertical-mirror-pen";
|
||||
this.helpText = "vertical mirror pen tool";
|
||||
|
||||
this.swap = null;
|
||||
this.mirroredPreviousCol = null;
|
||||
this.mirroredPreviousRow = null;
|
||||
};
|
||||
|
||||
pskl.utils.inherit(ns.VerticalMirrorPen, ns.SimplePen);
|
||||
|
@ -48,7 +48,6 @@
|
||||
* @override
|
||||
*/
|
||||
ns.BaseSelect.prototype.moveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
if(this.mode == "select") {
|
||||
this.onSelect_(col, row, color, frame, overlay);
|
||||
}
|
||||
@ -75,7 +74,6 @@
|
||||
* @override
|
||||
*/
|
||||
ns.BaseSelect.prototype.moveUnactiveToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.CURSOR_MOVED, [col, row]);
|
||||
if (overlay.containsPixel(col, row)) {
|
||||
if(overlay.getPixel(col, row) != Constants.SELECTION_TRANSPARENT_COLOR) {
|
||||
// We're hovering the selection, show the move tool:
|
||||
|
@ -1,11 +1,12 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.model");
|
||||
|
||||
var __idCounter = 0;
|
||||
ns.Frame = function (width, height) {
|
||||
if (width && height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
this.id = __idCounter++;
|
||||
this.version = 0;
|
||||
this.pixels = ns.Frame.createEmptyPixelGrid_(width, height);
|
||||
this.previousStates = [this.getPixels()];
|
||||
this.stateIndex = 0;
|
||||
@ -59,6 +60,7 @@
|
||||
*/
|
||||
ns.Frame.prototype.setPixels = function (pixels) {
|
||||
this.pixels = this.clonePixels_(pixels);
|
||||
this.version++;
|
||||
};
|
||||
|
||||
ns.Frame.prototype.clear = function () {
|
||||
@ -78,13 +80,14 @@
|
||||
return clonedPixels;
|
||||
};
|
||||
|
||||
ns.Frame.prototype.serialize = function () {
|
||||
return JSON.stringify(this.pixels);
|
||||
ns.Frame.prototype.getHash = function () {
|
||||
return [this.id, this.version].join('-');
|
||||
};
|
||||
|
||||
ns.Frame.prototype.setPixel = function (col, row, color) {
|
||||
if (this.containsPixel(col, row)) {
|
||||
this.pixels[col][row] = color;
|
||||
this.version++;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
this.getGridWidth(),
|
||||
offset.x, offset.y,
|
||||
size.width, size.height,
|
||||
frame.serialize()
|
||||
frame.getHash()
|
||||
].join('-');
|
||||
if (this.serializedFrame != serializedFrame) {
|
||||
this.serializedFrame = serializedFrame;
|
||||
|
@ -23,12 +23,9 @@
|
||||
};
|
||||
|
||||
ns.BaseSelection.prototype.fillSelectionFromFrame = function (targetFrame) {
|
||||
var pixelWithCopiedColor;
|
||||
for(var i=0, l=this.pixels.length; i<l; i++) {
|
||||
pixelWithCopiedColor = this.pixels[i];
|
||||
pixelWithCopiedColor.copiedColor =
|
||||
targetFrame.getPixel(pixelWithCopiedColor.col, pixelWithCopiedColor.row);
|
||||
}
|
||||
this.pixels.forEach(function (pixel) {
|
||||
pixel.color = targetFrame.getPixel(pixel.col, pixel.row);
|
||||
});
|
||||
this.hasPastedContent = true;
|
||||
};
|
||||
})();
|
@ -51,12 +51,17 @@
|
||||
var pixels = this.currentSelection.pixels;
|
||||
var currentFrame = this.piskelController.getCurrentFrame();
|
||||
for(var i=0, l=pixels.length; i<l; i++) {
|
||||
try {
|
||||
currentFrame.setPixel(pixels[i].col, pixels[i].row, Constants.TRANSPARENT_COLOR);
|
||||
} catch(e) {
|
||||
// Catching out of frame's bound pixels without testing
|
||||
}
|
||||
currentFrame.setPixel(pixels[i].col, pixels[i].row, Constants.TRANSPARENT_COLOR);
|
||||
}
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
type : 'erase',
|
||||
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.cut = function() {
|
||||
@ -74,18 +79,30 @@
|
||||
if(this.currentSelection && this.currentSelection.hasPastedContent) {
|
||||
var pixels = this.currentSelection.pixels;
|
||||
var currentFrame = this.piskelController.getCurrentFrame();
|
||||
for(var i=0, l=pixels.length; i<l; i++) {
|
||||
try {
|
||||
currentFrame.setPixel(
|
||||
pixels[i].col, pixels[i].row,
|
||||
pixels[i].copiedColor);
|
||||
} catch(e) {
|
||||
// Catching out of frame's bound pixels without testing
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
type : 'paste',
|
||||
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
pixels.forEach(function (pixel) {
|
||||
currentFrame.setPixel(pixel.col,pixel.row,pixel.color);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.replay = function (frame, replayData) {
|
||||
var pixels = replayData.pixels;
|
||||
pixels.forEach(function (pixel) {
|
||||
var color = replayData.type === 'paste' ? pixel.color : Constants.TRANSPARENT_COLOR;
|
||||
frame.setPixel(pixel.col, pixel.row, color);
|
||||
});
|
||||
};
|
||||
|
||||
ns.SelectionManager.prototype.copy = function() {
|
||||
if(this.currentSelection && this.piskelController.getCurrentFrame()) {
|
||||
this.currentSelection.fillSelectionFromFrame(this.piskelController.getCurrentFrame());
|
||||
|
@ -1,35 +1,138 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.service");
|
||||
var ns = $.namespace('pskl.service');
|
||||
|
||||
var SNAPSHOT_PERIOD = 5000;
|
||||
|
||||
ns.HistoryService = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
this.stateQueue = [];
|
||||
this.currentIndex = -1;
|
||||
this.saveState__b = this.saveState.bind(this);
|
||||
|
||||
this.lastEvent = -1;
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.init = function () {
|
||||
|
||||
$.subscribe(Events.PISKEL_RESET, this.saveState__b);
|
||||
$.subscribe(Events.TOOL_RELEASED, this.saveState__b);
|
||||
$.subscribe(Events.PISKEL_SAVE_STATE, this.saveState__b);
|
||||
|
||||
pskl.app.shortcutService.addShortcut('ctrl+Z', this.undo.bind(this));
|
||||
pskl.app.shortcutService.addShortcut('ctrl+Y', this.redo.bind(this));
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.saveState = function () {
|
||||
this.piskelController.getCurrentFrame().saveState();
|
||||
ns.HistoryService.prototype.saveState = function (evt, actionInfo) {
|
||||
this.stateQueue = this.stateQueue.slice(0, this.currentIndex + 1);
|
||||
this.currentIndex = this.currentIndex + 1;
|
||||
|
||||
var state = {
|
||||
action : actionInfo,
|
||||
frameIndex : this.piskelController.currentFrameIndex,
|
||||
layerIndex : this.piskelController.currentLayerIndex
|
||||
};
|
||||
|
||||
if (actionInfo.type === 'FULL' || this.currentIndex % SNAPSHOT_PERIOD === 0) {
|
||||
state.piskel = this.piskelController.serialize(false);
|
||||
}
|
||||
|
||||
this.stateQueue.push(state);
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.undo = function () {
|
||||
this.piskelController.getCurrentFrame().loadPreviousState();
|
||||
$.unsubscribe(Events.PISKEL_RESET, this.saveState__b);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
$.subscribe(Events.PISKEL_RESET, this.saveState__b);
|
||||
var now = Date.now();
|
||||
if ((Date.now() - this.lastEvent) > 50 && this.currentIndex > 0) {
|
||||
this.currentIndex = this.currentIndex - 1;
|
||||
this.loadState(this.currentIndex);
|
||||
this.lastEvent = Date.now();
|
||||
}
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.redo = function () {
|
||||
this.piskelController.getCurrentFrame().loadNextState();
|
||||
$.unsubscribe(Events.PISKEL_RESET, this.saveState__b);
|
||||
var now = Date.now();
|
||||
if ((Date.now() - this.lastEvent) > 50 && this.currentIndex < this.stateQueue.length - 1) {
|
||||
this.currentIndex = this.currentIndex + 1;
|
||||
this.loadState(this.currentIndex);
|
||||
this.lastEvent = Date.now();
|
||||
}
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.loadState = function (index) {
|
||||
$.unsubscribe(Events.PISKEL_SAVE_STATE, this.saveState__b);
|
||||
this.piskelController.silence();
|
||||
|
||||
// get nearest snaphot index
|
||||
var snapshotIndex = -1;
|
||||
for (var i = index ; i >= 0 ; i--) {
|
||||
if (this.stateQueue[i].piskel) {
|
||||
snapshotIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshotIndex === -1) {
|
||||
throw 'Could not find previous SNAPSHOT saved in history stateQueue';
|
||||
}
|
||||
|
||||
var serializedPiskel = this.stateQueue[snapshotIndex].piskel;
|
||||
var targetState = this.stateQueue[index];
|
||||
|
||||
if (typeof serializedPiskel === "string") {
|
||||
this.stateQueue[snapshotIndex].piskel = JSON.parse(serializedPiskel);
|
||||
serializedPiskel = this.stateQueue[snapshotIndex].piskel;
|
||||
}
|
||||
|
||||
this.loadPiskel(serializedPiskel, this.onPiskelLoadedCallback.bind(this, index, snapshotIndex));
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.onPiskelLoadedCallback = function (index, snapshotIndex, piskel) {
|
||||
for (var i = snapshotIndex + 1 ; i <= index ; i++) {
|
||||
var state = this.stateQueue[i];
|
||||
this.piskelController.setCurrentFrameIndex(state.frameIndex);
|
||||
this.piskelController.setCurrentLayerIndex(state.layerIndex);
|
||||
this.replayState(state);
|
||||
}
|
||||
|
||||
this.piskelController.voice();
|
||||
$.subscribe(Events.PISKEL_SAVE_STATE, this.saveState__b);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
$.subscribe(Events.PISKEL_RESET, this.saveState__b);
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.loadPiskel = function (piskel, callback) {
|
||||
var descriptor = this.piskelController.piskel.getDescriptor();
|
||||
pskl.utils.serialization.Deserializer.deserialize(piskel, function (piskel) {
|
||||
piskel.setDescriptor(descriptor);
|
||||
pskl.app.piskelController.setPiskel(piskel);
|
||||
callback(piskel);
|
||||
});
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.replayState = function (state) {
|
||||
var type = state.action.type;
|
||||
if (type === 'DELETE_FRAME') {
|
||||
this.piskelController.removeFrameAt(state.action.index);
|
||||
} else if (type === 'ADD_FRAME') {
|
||||
this.piskelController.addFrameAt(state.action.index);
|
||||
} else if (type === 'DUPLICATE_FRAME') {
|
||||
this.piskelController.duplicateFrameAt(state.action.index);
|
||||
} else if (type === 'CREATE_LAYER') {
|
||||
this.piskelController.createLayer(state.action.name);
|
||||
} else if (type === 'REMOVE_LAYER') {
|
||||
this.piskelController.removeCurrentLayer();
|
||||
} else if (type === 'LAYER_UP') {
|
||||
this.piskelController.moveLayerUp();
|
||||
} else if (type === 'LAYER_DOWN') {
|
||||
this.piskelController.moveLayerUp();
|
||||
} else if (type === 'RENAME_LAYER') {
|
||||
this.piskelController.renameLayerAt(state.action.index, state.action.name);
|
||||
} else if (type === 'MOVE_FRAME') {
|
||||
this.piskelController.moveFrame(state.action.from, state.action.to);
|
||||
} else if (type === 'CREATE_LAYER') {
|
||||
this.piskelController.createLayer();
|
||||
} else if (type === 'TOOL') {
|
||||
var action = state.action;
|
||||
var layer = this.piskelController.getLayerAt(state.layerIndex);
|
||||
var frame = layer.getFrameAt(state.frameIndex);
|
||||
action.tool.replay(frame, action.replay);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
@ -31,37 +31,49 @@
|
||||
this.layersToLoad_ = piskelData.layers.length;
|
||||
|
||||
piskelData.layers.forEach(function (serializedLayer) {
|
||||
var layer = this.deserializeLayer(serializedLayer);
|
||||
this.piskel_.addLayer(layer);
|
||||
this.deserializeLayer(serializedLayer);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
ns.Deserializer.prototype.deserializeLayer = function (layerString) {
|
||||
var layerData = JSON.parse(layerString);
|
||||
var layerData = typeof layerString === "string" ? JSON.parse(layerString) : layerString;
|
||||
var layer = new pskl.model.Layer(layerData.name);
|
||||
|
||||
// 1 - create an image to load the base64PNG representing the layer
|
||||
var base64PNG = layerData.base64PNG;
|
||||
var image = new Image();
|
||||
var isCompressedLayer = !!layerData.base64PNG;
|
||||
|
||||
// 2 - attach the onload callback that will be triggered asynchronously
|
||||
image.onload = function () {
|
||||
// 5 - extract the frames from the loaded image
|
||||
var frames = pskl.utils.LayerUtils.createFromImage(image, layerData.frameCount);
|
||||
if (isCompressedLayer) {
|
||||
// 1 - create an image to load the base64PNG representing the layer
|
||||
var base64PNG = layerData.base64PNG;
|
||||
var image = new Image();
|
||||
|
||||
// 6 - add each image to the layer
|
||||
frames.forEach(layer.addFrame.bind(layer));
|
||||
// 2 - attach the onload callback that will be triggered asynchronously
|
||||
image.onload = function () {
|
||||
// 5 - extract the frames from the loaded image
|
||||
var frames = pskl.utils.LayerUtils.createFromImage(image, layerData.frameCount);
|
||||
// 6 - add each image to the layer
|
||||
this.addFramesToLayer(frames, layer);
|
||||
}.bind(this);
|
||||
|
||||
this.onLayerLoaded_();
|
||||
}.bind(this);
|
||||
|
||||
// 3 - set the source of the image
|
||||
image.src = base64PNG;
|
||||
// 3 - set the source of the image
|
||||
image.src = base64PNG;
|
||||
} else {
|
||||
var frames = layerData.grids.map(function (grid) {
|
||||
return pskl.model.Frame.fromPixelGrid(grid);
|
||||
});
|
||||
this.addFramesToLayer(frames, layer);
|
||||
}
|
||||
|
||||
// 4 - return a pointer to the new layer instance
|
||||
return layer;
|
||||
};
|
||||
|
||||
ns.Deserializer.prototype.addFramesToLayer = function (frames, layer) {
|
||||
frames.forEach(layer.addFrame.bind(layer));
|
||||
|
||||
this.piskel_.addLayer(layer);
|
||||
this.onLayerLoaded_();
|
||||
};
|
||||
|
||||
ns.Deserializer.prototype.onLayerLoaded_ = function () {
|
||||
this.layersToLoad_ = this.layersToLoad_ - 1;
|
||||
if (this.layersToLoad_ === 0) {
|
||||
|
@ -2,9 +2,9 @@
|
||||
var ns = $.namespace('pskl.utils');
|
||||
|
||||
ns.Serializer = {
|
||||
serializePiskel : function (piskel) {
|
||||
serializePiskel : function (piskel, compressed) {
|
||||
var serializedLayers = piskel.getLayers().map(function (l) {
|
||||
return pskl.utils.Serializer.serializeLayer(l);
|
||||
return pskl.utils.Serializer.serializeLayer(l, compressed);
|
||||
});
|
||||
return JSON.stringify({
|
||||
modelVersion : Constants.MODEL_VERSION,
|
||||
@ -16,16 +16,23 @@
|
||||
});
|
||||
},
|
||||
|
||||
serializeLayer : function (layer) {
|
||||
serializeLayer : function (layer, compressed) {
|
||||
if (compressed !== false) {
|
||||
compressed = true;
|
||||
}
|
||||
var frames = layer.getFrames();
|
||||
var renderer = new pskl.rendering.FramesheetRenderer(frames);
|
||||
var base64PNG = renderer.renderAsCanvas().toDataURL();
|
||||
|
||||
return JSON.stringify({
|
||||
var layerToSerialize = {
|
||||
name : layer.getName(),
|
||||
base64PNG : base64PNG,
|
||||
frameCount : frames.length
|
||||
});
|
||||
};
|
||||
if (compressed) {
|
||||
layerToSerialize.base64PNG = renderer.renderAsCanvas().toDataURL();
|
||||
return JSON.stringify(layerToSerialize);
|
||||
} else {
|
||||
layerToSerialize.grids = frames.map(function (f) {return f.pixels;});
|
||||
return layerToSerialize;
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
Loading…
Reference in New Issue
Block a user