Feature #541 crop based on the current selection

This commit is contained in:
Julian Descottes 2017-05-23 23:13:12 +02:00
parent a9e22535d6
commit 799c9fbf5a
7 changed files with 555 additions and 14 deletions

View File

@ -142,6 +142,12 @@
recordEvent.type = 'instrumented-event';
recordEvent.methodName = methodName;
recordEvent.args = Array.prototype.slice.call(args, 0);
if (methodName === 'setPiskel' && args[1].noSnapshot) {
// Skip recording calls to setPiskel that don't trigger a save.
return;
}
this.events.push(recordEvent);
}
};

View File

@ -12,27 +12,47 @@
];
};
pskl.utils.inherit(ns.Crop, ns.AbstractTransformTool);
// This transform tool is the only one that adapts to the current selection and can't
// rely on the default AbstractTransformTool behavior.
pskl.utils.inherit(ns.Crop, pskl.tools.Tool);
ns.Crop.prototype.applyToolOnFrame_ = function (frame, altKey) {
var currentPiskel = pskl.app.piskelController.getPiskel();
var frames = currentPiskel.getLayers().map(function (l) {
return l.getFrames();
}).reduce(function (p, n) {
return p.concat(n);
});
ns.Crop.prototype.applyTransformation = function (evt) {
var frames = this.getFrames_();
var boundaries = pskl.tools.transform.TransformUtils.getBoundaries(frames);
if (boundaries.minx >= boundaries.maxx) {
return;
var boundaries;
if (pskl.app.selectionManager.currentSelection) {
// If we have a selection, we will compute the boundaries of the selection instead
// of looping on the frames.
boundaries = this.getBoundariesForSelection_();
} else {
boundaries = pskl.tools.transform.TransformUtils.getBoundaries(frames);
}
var applied = this.applyTool_(frames, boundaries);
if (applied) {
this.raiseSaveStateEvent({
boundaries : boundaries
});
}
};
ns.Crop.prototype.replay = function (frame, replayData) {
var frames = this.getFrames_();
this.applyTool_(frames, replayData.boundaries);
};
ns.Crop.prototype.applyTool_ = function (frames, boundaries) {
if (boundaries.minx >= boundaries.maxx) {
return false;
}
var currentPiskel = pskl.app.piskelController.getPiskel();
var width = 1 + boundaries.maxx - boundaries.minx;
var height = 1 + boundaries.maxy - boundaries.miny;
if (width === currentPiskel.getWidth() && height === currentPiskel.getHeight()) {
// Do not perform an unnecessary resize if it's a noop.
return;
return false;
}
frames.forEach(function (frame) {
@ -46,10 +66,62 @@
resizeContent: false
});
// Clear the current selection.
$.publish(Events.SELECTION_DISMISSED);
// Replace the current piskel with the resized version.
pskl.app.piskelController.setPiskel(piskel, {
preserveState: true,
// Saving is already handled by recording the transform tool action, no need for
// an expensive snapshot.
noSnapshot: true
});
return true;
};
/**
* Retrieve the list of frames for the current piskel in a single flat array.
*/
ns.Crop.prototype.getFrames_ = function () {
var currentPiskel = pskl.app.piskelController.getPiskel();
// Get all frames in a single array.
var frames = currentPiskel.getLayers().map(function (l) {
return l.getFrames();
}).reduce(function (p, n) {
return p.concat(n);
});
return frames;
};
/**
* Retrieve a boundaries object {minx, maxx, miny, maxy} for the current selection.
*/
ns.Crop.prototype.getBoundariesForSelection_ = function () {
var selectionManager = pskl.app.selectionManager;
var pixels = selectionManager.currentSelection.pixels;
// Fetch the first frame to perform out-of-bound checks.
var currentPiskel = pskl.app.piskelController.getPiskel();
var exampleFrame = currentPiskel.getLayerAt(0).getFrameAt(0);
// Anything different from Constants.TRANSPARENT_COLOR toInt().
var FAKE_COLOR = 1;
// Create a fake frame reimplementing the forEachPixel API.
var selectionFrame = {
forEachPixel : function (callback) {
for (var i = 0; i < pixels.length ; i++) {
var pixel = pixels[i];
// Selections might contain out of bound pixels, filter those out.
if (exampleFrame.containsPixel(pixel.col, pixel.row)) {
callback(FAKE_COLOR, pixel.col, pixel.row);
}
}
}
};
return pskl.tools.transform.TransformUtils.getBoundaries([selectionFrame]);
};
})();

View File

@ -65,8 +65,8 @@
},
getBoundaries : function(frames) {
var minx = frames[0].width;
var miny = frames[0].height;
var minx = +Infinity;
var miny = +Infinity;
var maxx = 0;
var maxy = 0;

View File

@ -21,6 +21,8 @@
"transform.center.json",
"transform.clone.once.json",
"transform.clone.twice.undo.once.json",
"transform.crop.json",
"transform.crop.selection.json",
"transform.rotate.once.alt.json",
"transform.rotate.twice.undo.once.json",
"transform.rotate.alt.twice.undo.once.json",

View File

@ -19,6 +19,8 @@
"transform.center.json",
"transform.clone.once.json",
"transform.clone.twice.undo.once.json",
"transform.crop.json",
"transform.crop.selection.json",
"transform.rotate.once.alt.json",
"transform.rotate.twice.undo.once.json",
"transform.rotate.alt.twice.undo.once.json",

View File

@ -0,0 +1,185 @@
{
"events": [
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 1
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 1
},
"type": "mouse-event"
},
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 3,
"y": 1
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 3,
"y": 1
},
"type": "mouse-event"
},
{
"type": "transformtool-event",
"toolId": "tool-crop",
"event": {
"shiftKey": false,
"altKey": false,
"ctrlKey": false
}
},
{
"event": {
"type": "mousedown",
"button": 2,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 0
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 2,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 0
},
"type": "mouse-event"
},
{
"type": "transformtool-event",
"toolId": "tool-crop",
"event": {
"shiftKey": false,
"altKey": false,
"ctrlKey": false
}
},
{
"type": "keyboard-event",
"event": {
"which": 90,
"shiftKey": false,
"altKey": false,
"ctrlKey": true,
"target": {
"nodeName": "BODY"
}
}
}
],
"initialState": {
"size": {
"width": 4,
"height": 4
},
"primaryColor": "#000000",
"secondaryColor": "rgba(0, 0, 0, 0)",
"selectedTool": "tool-pen",
"penSize": 1
},
"png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAAG0lEQVQYV2NkYGD4z8DAwMgAI0AMGAckA2YDACxpAgQTZnIjAAAAAElFTkSuQmCC"
}

View File

@ -0,0 +1,274 @@
{
"events": [
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 0,
"y": 0
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 0,
"y": 0
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 1
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 2
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 3,
"y": 2
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 3,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 3,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 0,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 0,
"y": 3
},
"type": "mouse-event"
},
{
"type": "tool-event",
"toolId": "tool-lasso-select"
},
{
"type": "keyboard-event",
"event": {
"which": 72,
"shiftKey": false,
"altKey": false,
"ctrlKey": false,
"target": {
"nodeName": "BODY"
}
}
},
{
"event": {
"type": "mousedown",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 1
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 1
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 1,
"y": 2
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 2
},
"type": "mouse-event"
},
{
"event": {
"type": "mousemove",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 3
},
"type": "mouse-event"
},
{
"event": {
"type": "mouseup",
"button": 0,
"shiftKey": false,
"altKey": false,
"ctrlKey": false
},
"coords": {
"x": 2,
"y": 3
},
"type": "mouse-event"
},
{
"type": "transformtool-event",
"toolId": "tool-crop",
"event": {
"shiftKey": false,
"altKey": false,
"ctrlKey": false
}
},
{
"type": "keyboard-event",
"event": {
"which": 90,
"shiftKey": false,
"altKey": false,
"ctrlKey": true,
"target": {
"nodeName": "BODY"
}
}
},
{
"type": "keyboard-event",
"event": {
"which": 89,
"shiftKey": false,
"altKey": false,
"ctrlKey": true,
"target": {
"nodeName": "BODY"
}
}
}
],
"initialState": {
"size": {
"width": 4,
"height": 4
},
"primaryColor": "#000000",
"secondaryColor": "rgba(0, 0, 0, 0)",
"selectedTool": "tool-pen",
"penSize": 1
},
"png": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAADCAYAAAC56t6BAAAAGElEQVQYV2NkYGD4z8DAwMjIAAH/YQwGACFDAgOWGgpZAAAAAElFTkSuQmCC"
}