mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Simplified SAVE STATE events, added wrap method to easily build decorators
This commit is contained in:
parent
8335c07519
commit
c2a3ccc8d0
@ -56,6 +56,19 @@
|
||||
return layer.getFrameAt(this.currentFrameIndex);
|
||||
};
|
||||
|
||||
|
||||
ns.PiskelController.prototype.getCurrentLayerIndex = function () {
|
||||
return this.currentLayerIndex;
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getCurrentFrameIndex = function () {
|
||||
return this.currentFrameIndex;
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getPiskel = function () {
|
||||
return this.piskel;
|
||||
};
|
||||
|
||||
ns.PiskelController.prototype.getFrameAt = function (index) {
|
||||
var frames = this.getLayers().map(function (l) {
|
||||
return l.getFrameAt(index);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
ns.PublicPiskelController = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
pskl.utils.wrap(this, this.piskelController);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.init = function () {
|
||||
@ -32,22 +33,13 @@
|
||||
|
||||
ns.PublicPiskelController.prototype.addFrameAt = function (index) {
|
||||
this.piskelController.addFrameAt(index);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'ADD_FRAME',
|
||||
index : index
|
||||
});
|
||||
|
||||
this.raiseSaveStateEvent_(this.piskelController.addFrameAt, [index]);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.removeFrameAt = function (index) {
|
||||
this.piskelController.removeFrameAt(index);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'DELETE_FRAME',
|
||||
index : index
|
||||
});
|
||||
this.raiseSaveStateEvent_(this.piskelController.removeFrameAt, [index]);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
@ -55,32 +47,33 @@
|
||||
this.piskelController.duplicateFrameAt(this.getCurrentFrameIndex());
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.raiseSaveStateEvent_ = function (fn, args) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'REPLAY',
|
||||
scope : this,
|
||||
replay : {
|
||||
fn : fn,
|
||||
args : args
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.replay = function (frame, replayData) {
|
||||
replayData.fn.apply(this.piskelController, replayData.args);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.duplicateFrameAt = function (index) {
|
||||
this.piskelController.duplicateFrameAt(index);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'DUPLICATE_FRAME',
|
||||
index : index
|
||||
});
|
||||
|
||||
this.raiseSaveStateEvent_(this.piskelController.duplicateFrameAt, [index]);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.moveFrame = function (fromIndex, toIndex) {
|
||||
this.piskelController.moveFrame(fromIndex, toIndex);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'MOVE_FRAME',
|
||||
from : fromIndex,
|
||||
to : toIndex
|
||||
});
|
||||
this.raiseSaveStateEvent_(this.piskelController.moveFrame, [fromIndex, toIndex]);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getFrameCount = function () {
|
||||
return this.piskelController.getFrameCount();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.setCurrentFrameIndex = function (index) {
|
||||
this.piskelController.setCurrentFrameIndex(index);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
@ -108,86 +101,37 @@
|
||||
|
||||
ns.PublicPiskelController.prototype.renameLayerAt = function (index, name) {
|
||||
this.piskelController.renameLayerAt(index, name);
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'RENAME_LAYER',
|
||||
index : index,
|
||||
name : name
|
||||
});
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getLayerByIndex = function (index) {
|
||||
return this.piskelController.getLayerByIndex(index);
|
||||
this.raiseSaveStateEvent_(this.piskelController.renameLayerAt, [index, name]);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.createLayer = function (name) {
|
||||
this.piskelController.createLayer(name);
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'CREATE_LAYER',
|
||||
name : name
|
||||
});
|
||||
this.raiseSaveStateEvent_(this.piskelController.createLayer, [name]);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.moveLayerUp = function () {
|
||||
this.piskelController.moveLayerUp();
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'LAYER_UP'
|
||||
});
|
||||
this.raiseSaveStateEvent_(this.piskelController.moveLayerUp, []);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.moveLayerDown = function () {
|
||||
this.piskelController.moveLayerDown();
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'LAYER_DOWN'
|
||||
});
|
||||
this.raiseSaveStateEvent_(this.piskelController.moveLayerDown, []);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.removeCurrentLayer = function () {
|
||||
this.piskelController.removeCurrentLayer();
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'REMOVE_LAYER'
|
||||
});
|
||||
this.raiseSaveStateEvent_(this.piskelController.removeCurrentLayer, []);
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.serialize = function (compressed) {
|
||||
return this.piskelController.serialize(compressed);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getHeight = function () {
|
||||
return this.piskelController.getHeight();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getWidth = function () {
|
||||
return this.piskelController.getWidth();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getFPS = function () {
|
||||
return this.piskelController.getFPS();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getLayers = function () {
|
||||
return this.piskelController.getLayers();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getCurrentLayer = function () {
|
||||
return this.piskelController.getCurrentLayer();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getCurrentLayerIndex = function () {
|
||||
return this.piskelController.currentLayerIndex;
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getLayerAt = function (index) {
|
||||
return this.piskelController.getLayerAt(index);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getCurrentFrame = function () {
|
||||
return this.piskelController.getCurrentFrame();
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getCurrentFrameIndex = function () {
|
||||
return this.piskelController.currentFrameIndex;
|
||||
};
|
||||
@ -196,12 +140,4 @@
|
||||
return this.piskelController.piskel;
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.getFrameAt = function (index) {
|
||||
return this.piskelController.getFrameAt(index);
|
||||
};
|
||||
|
||||
ns.PublicPiskelController.prototype.hasFrameAt = function (index) {
|
||||
return this.piskelController.hasFrameAt(index);
|
||||
};
|
||||
|
||||
})();
|
@ -50,12 +50,12 @@
|
||||
}
|
||||
};
|
||||
|
||||
ns.BaseTool.prototype.raiseSaveStateEvent = function (args) {
|
||||
var toolInfo = {
|
||||
toolId : this.toolId,
|
||||
args : args
|
||||
};
|
||||
$.publish(Events.PISKEL_SAVE_STATE, toolInfo);
|
||||
ns.BaseTool.prototype.raiseSaveStateEvent = function (replayData) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'REPLAY',
|
||||
scope : this,
|
||||
replay : replayData
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
@ -53,13 +53,9 @@
|
||||
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 : {
|
||||
this.raiseSaveStateEvent({
|
||||
colDiff : col - this.startCol,
|
||||
rowDiff : row - this.startRow
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -19,14 +19,10 @@
|
||||
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 : {
|
||||
this.raiseSaveStateEvent({
|
||||
col : col,
|
||||
row : row,
|
||||
color : color
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -51,17 +51,12 @@
|
||||
this.draw_(coords.col, coords.row, color, frame);
|
||||
|
||||
$.publish(Events.DRAG_END, [col, row]);
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
this.raiseSaveStateEvent({
|
||||
col : col,
|
||||
row : row,
|
||||
startCol : this.startCol,
|
||||
startRow : this.startRow,
|
||||
color : color
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -55,13 +55,9 @@
|
||||
|
||||
|
||||
ns.SimplePen.prototype.releaseToolAt = function(col, row, color, frame, overlay, event) {
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
replay : {
|
||||
this.raiseSaveStateEvent({
|
||||
pixels : this.pixels.slice(0),
|
||||
color : color
|
||||
}
|
||||
});
|
||||
this.pixels = [];
|
||||
};
|
||||
|
@ -73,13 +73,9 @@
|
||||
// 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 : {
|
||||
this.raiseSaveStateEvent({
|
||||
pixels : strokePoints,
|
||||
color : color
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
(function () {
|
||||
var ns = $.namespace("pskl.selection");
|
||||
|
||||
var SELECTION_REPLAY = {
|
||||
PASTE : 'REPLAY_PASTE',
|
||||
ERASE : 'REPLAY_ERASE'
|
||||
};
|
||||
|
||||
ns.SelectionManager = function (piskelController) {
|
||||
|
||||
this.piskelController = piskelController;
|
||||
@ -55,10 +60,10 @@
|
||||
}
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
type : 'REPLAY',
|
||||
scope : this,
|
||||
replay : {
|
||||
type : 'erase',
|
||||
type : SELECTION_REPLAY.ERASE,
|
||||
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
|
||||
}
|
||||
});
|
||||
@ -81,10 +86,10 @@
|
||||
var currentFrame = this.piskelController.getCurrentFrame();
|
||||
|
||||
$.publish(Events.PISKEL_SAVE_STATE, {
|
||||
type : 'TOOL',
|
||||
tool : this,
|
||||
type : 'REPLAY',
|
||||
scope : this,
|
||||
replay : {
|
||||
type : 'paste',
|
||||
type : SELECTION_REPLAY.PASTE,
|
||||
pixels : JSON.parse(JSON.stringify(pixels.slice(0)))
|
||||
}
|
||||
});
|
||||
@ -98,7 +103,7 @@
|
||||
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;
|
||||
var color = replayData.type === SELECTION_REPLAY.PASTE ? pixel.color : Constants.TRANSPARENT_COLOR;
|
||||
frame.setPixel(pixel.col, pixel.row, color);
|
||||
});
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
var ns = $.namespace('pskl.service');
|
||||
|
||||
var SNAPSHOT_PERIOD = 50;
|
||||
var LOAD_STATE_INTERVAL = 50;
|
||||
|
||||
ns.HistoryService = function (piskelController) {
|
||||
this.piskelController = piskelController;
|
||||
@ -9,7 +10,7 @@
|
||||
this.currentIndex = -1;
|
||||
this.saveState__b = this.saveState.bind(this);
|
||||
|
||||
this.lastEvent = -1;
|
||||
this.lastLoadState = -1;
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.init = function () {
|
||||
@ -38,39 +39,23 @@
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.undo = function () {
|
||||
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();
|
||||
}
|
||||
this.loadState(this.currentIndex - 1);
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.redo = function () {
|
||||
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();
|
||||
}
|
||||
this.loadState(this.currentIndex + 1);
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.loadState = function (index) {
|
||||
// get nearest snaphot index
|
||||
var snapshotIndex = -1;
|
||||
for (var i = index ; i >= 0 ; i--) {
|
||||
if (this.stateQueue[i].piskel) {
|
||||
snapshotIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this.isLoadStateAllowed_(index)) {
|
||||
this.lastLoadState = Date.now();
|
||||
|
||||
if (snapshotIndex === -1) {
|
||||
var snapshotIndex = this.getPreviousSnapshotIndex_(index);
|
||||
if (snapshotIndex < 0) {
|
||||
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);
|
||||
@ -78,6 +63,20 @@
|
||||
}
|
||||
|
||||
this.loadPiskel(serializedPiskel, this.onPiskelLoadedCallback.bind(this, index, snapshotIndex));
|
||||
}
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.isLoadStateAllowed_ = function (index) {
|
||||
var timeOk = (Date.now() - this.lastLoadState) > LOAD_STATE_INTERVAL;
|
||||
var indexInRange = index >= 0 && index < this.stateQueue.length;
|
||||
return timeOk && indexInRange;
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.getPreviousSnapshotIndex_ = function (index) {
|
||||
while (this.stateQueue[index] && !this.stateQueue[index].piskel) {
|
||||
index = index - 1;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
ns.HistoryService.prototype.onPiskelLoadedCallback = function (index, snapshotIndex, piskel) {
|
||||
@ -89,7 +88,7 @@
|
||||
|
||||
var lastState = this.stateQueue[index];
|
||||
this.setupState(lastState);
|
||||
|
||||
this.currentIndex = index;
|
||||
$.publish(Events.PISKEL_RESET);
|
||||
};
|
||||
|
||||
@ -108,33 +107,11 @@
|
||||
};
|
||||
|
||||
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 type = action.type;
|
||||
var layer = this.piskelController.getLayerAt(state.layerIndex);
|
||||
var frame = layer.getFrameAt(state.frameIndex);
|
||||
action.tool.replay(frame, action.replay);
|
||||
}
|
||||
action.scope.replay(frame, action.replay);
|
||||
};
|
||||
|
||||
})();
|
@ -47,5 +47,13 @@ if (typeof Function.prototype.bind !== "function") {
|
||||
extendedObject.prototype.superclass = inheritFrom.prototype;
|
||||
};
|
||||
|
||||
ns.wrap = function (wrapper, wrappedObject) {
|
||||
for (var prop in wrappedObject) {
|
||||
if (typeof wrappedObject[prop] === 'function') {
|
||||
wrapper[prop] = wrappedObject[prop].bind(wrappedObject);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user