diff --git a/src/img/icons/transform/tool-center.png b/src/img/icons/transform/tool-center.png new file mode 100644 index 00000000..f0b21bb4 Binary files /dev/null and b/src/img/icons/transform/tool-center.png differ diff --git a/src/js/controller/TransformationsController.js b/src/js/controller/TransformationsController.js index 79f922ac..de89f322 100644 --- a/src/js/controller/TransformationsController.js +++ b/src/js/controller/TransformationsController.js @@ -5,7 +5,8 @@ this.tools = [ new pskl.tools.transform.Flip(), new pskl.tools.transform.Rotate(), - new pskl.tools.transform.Clone() + new pskl.tools.transform.Clone(), + new pskl.tools.transform.Center() ]; this.toolIconBuilder = new pskl.tools.ToolIconBuilder(); diff --git a/src/js/tools/transform/Center.js b/src/js/tools/transform/Center.js new file mode 100644 index 00000000..7d08cb6f --- /dev/null +++ b/src/js/tools/transform/Center.js @@ -0,0 +1,19 @@ +(function () { + var ns = $.namespace('pskl.tools.transform'); + + ns.Center = function () { + this.toolId = 'tool-center'; + this.helpText = 'Align image to the center'; + this.tooltipDescriptors = [ + {key : 'ctrl', description : 'Apply to all layers'}, + {key : 'shift', description : 'Apply to all frames'} + ]; + }; + + pskl.utils.inherit(ns.Center, ns.AbstractTransformTool); + + ns.Center.prototype.applyToolOnFrame_ = function (frame) { + ns.TransformUtils.center(frame); + }; + +})(); diff --git a/src/js/tools/transform/TransformUtils.js b/src/js/tools/transform/TransformUtils.js index 03657f3e..042b58e0 100644 --- a/src/js/tools/transform/TransformUtils.js +++ b/src/js/tools/transform/TransformUtils.js @@ -62,6 +62,49 @@ }); frame.version++; return frame; + }, + + center : function(frame) { + // Figure out the boundary + var minx = frame.width; + var miny = frame.height; + var maxx = 0; + var maxy = 0; + frame.forEachPixel(function (color, x, y) { + if (color !== Constants.TRANSPARENT_COLOR) { + minx = Math.min(minx, x); + maxx = Math.max(maxx, x); + miny = Math.min(miny, y); + maxy = Math.max(maxy, y); + } + }); + + // Calculate how much to move the pixels + var bw = (maxx - minx + 1) / 2; + var bh = (maxy - miny + 1) / 2; + var fw = frame.width / 2; + var fh = frame.height / 2; + + var dx = Math.floor(fw - bw - minx); + var dy = Math.floor(fh - bh - miny); + + // Actually move the pixels + var clone = frame.clone(); + frame.forEachPixel(function(color, x, y) { + var _x = x; + var _y = y; + + x -= dx; + y -= dy; + + if (clone.containsPixel(x, y)) { + frame.pixels[_x][_y] = clone.getPixel(x, y); + } else { + frame.pixels[_x][_y] = Constants.TRANSPARENT_COLOR; + } + }); + frame.version++; + return frame; } }; })(); diff --git a/src/piskel-script-list.js b/src/piskel-script-list.js index a43b144d..ede3a844 100644 --- a/src/piskel-script-list.js +++ b/src/piskel-script-list.js @@ -201,6 +201,7 @@ "js/tools/drawing/ColorSwap.js", "js/tools/drawing/DitheringTool.js", "js/tools/transform/AbstractTransformTool.js", + "js/tools/transform/Center.js", "js/tools/transform/Clone.js", "js/tools/transform/Flip.js", "js/tools/transform/Rotate.js", diff --git a/test/js/tools/transform/TransformUtilsTest.js b/test/js/tools/transform/TransformUtilsTest.js index 0756548c..b0d4061a 100644 --- a/test/js/tools/transform/TransformUtilsTest.js +++ b/test/js/tools/transform/TransformUtilsTest.js @@ -230,4 +230,27 @@ describe("TransformUtils suite", function() { ]); }); -}); \ No newline at end of file + /*******************************/ + /*********** CENTER ************/ + /*******************************/ + + it("centers a frame", function () { + // create frame + var frame = pskl.model.Frame.fromPixelGrid(toFrameGrid([ + [A, B, O, O], + [B, A, O, O], + [O, O, O, O], + [O, O, O, O] + ])); + + // should be centered + pskl.tools.transform.TransformUtils.center(frame); + frameEqualsGrid(frame, [ + [O, O, O, O], + [O, A, B, O], + [O, B, A, O], + [O, O, O, O] + ]); + }); + +});