mirror of
https://github.com/piskelapp/piskel.git
synced 2023-08-10 21:12:52 +03:00
Feature #541 crop based on the current selection
This commit is contained in:
parent
a9e22535d6
commit
799c9fbf5a
@ -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);
|
||||
}
|
||||
};
|
||||
|
@ -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]);
|
||||
};
|
||||
})();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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",
|
||||
|
@ -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",
|
||||
|
185
test/drawing/tests/transform.crop.json
Normal file
185
test/drawing/tests/transform.crop.json
Normal 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"
|
||||
}
|
274
test/drawing/tests/transform.crop.selection.json
Normal file
274
test/drawing/tests/transform.crop.selection.json
Normal 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"
|
||||
}
|
Loading…
Reference in New Issue
Block a user