├── .gitignore ├── README.md ├── Resize Commands.sketchplugin └── Contents │ └── Sketch │ ├── manifest.json │ └── resize-commands.js └── demo-resize-commands.gif /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Resize Commands for Sketch 2 | A Sketch plugin that lets you resize and reposition objects by using simple arithmetic commands, like `b+20,lr+20`. Multiple objects are supported. 3 | 4 | ## Demo 5 | ![Using Resize Commands](demo-resize-commands.gif) 6 | 7 | ## How to use 8 | Press Ctrl + shift + q to open up a prompt in which you can enter your commands to resize your selection. 9 | 10 | ## Example usage 11 | * `l+20` // expand selection 20px from left side 12 | * `a-10` // contract 10px from all sides 13 | * `w/2` // divide width by 2 14 | * `x+100` // move selection 100px to the right 15 | * `h=200` // set height to 200px 16 | * `w25%` // make width 25% its size 17 | 18 | ### Multiple commands 19 | You can easily combine multiple commands by separating them with a , or use multiple directions followed by an operator, like so: 20 | * `lrb+20` // expand selection 20px from left, right & bottom side 21 | * `wh=100` // set width & height to 100px 22 | * `xy+100` // move 100px to the right and down 23 | * `b-20,w=200` // contract 20px from the bottom side, set width to 200px 24 | * `w20%,h/3` // set width to 20%, divide height by 3 25 | * `w*2,tb+50,y-100` // double the width, add 50px to top and bottom, move up by 100px 26 | 27 | ## Valid directions are: 28 | 29 | | Direction | | 30 | | :------- | :---- | 31 | | **t** | Top | 32 | | **b** | Bottom | 33 | | **r** | Right | 34 | | **l** | Left | 35 | | **a** | All directions | 36 | | **w** | Width | 37 | | **h** | Height | 38 | | **x** | X-axis | 39 | | **y** | Y-axis | 40 | 41 | | Operator | | 42 | | :------- | :---- | 43 | | **+** | Plus | 44 | | **-** | Minus | 45 | | **\*** | Multiply | 46 | | **=** | Set w or h | 47 | | **/** | Divide | 48 | | **%** | Percentage| 49 | 50 | ## Installation 51 | 1. [Download](https://github.com/ANGIstudio/Resize-Commands/archive/master.zip) the plugin. 52 | 2. Unzip & run ‘Resize Commands.sketchplugin’ to install 53 | 54 | ## Thanks to 55 | Matt Stow, who did the heavy lifting for this plugin. His Fireworks plugin [Math Resize](http://mattstow.com/math-resize.html) I have used for a long time! 56 | 57 | ## Feedback 58 | If you find any issues or have any suggestions, please create an issue. Pull requests are welcome also! 59 | 60 | ## Created by 61 | [Andre Jilderda](https://github.com/ajilderda) @ [Angi Studio](http://www.angistudio.com), The Hague (NL) 62 | -------------------------------------------------------------------------------- /Resize Commands.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "Resize Commands", 3 | "identifier" : "com.sketchapp.resizecommands", 4 | "version" : "1.1", 5 | "description" : "Resize and reposition objects by using simple arithmetic commands, like 'b+20,lr+20'. Multiple objects are supported.", 6 | "authorEmail" : "mail@andrejilderda.nl", 7 | "author" : "Andre Jilderda", 8 | "commands" : [ 9 | { 10 | "script" : "resize-commands.js", 11 | "handler" : "onResizeCommands", 12 | "shortcut" : "ctrl shift q", 13 | "name" : "Resize Commands", 14 | "identifier" : "onResizeCommands" 15 | } 16 | ], 17 | "menu": { 18 | "isRoot": true, 19 | "items": [ 20 | "onResizeCommands" 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Resize Commands.sketchplugin/Contents/Sketch/resize-commands.js: -------------------------------------------------------------------------------- 1 | var UI = require('sketch/ui'); 2 | 3 | var global_context; 4 | var resizeCommandDirections = /[lrtbwhaxy]/g; 5 | var escapedValue; 6 | var resizeCommandPrevValue = ""; 7 | 8 | function onResizeCommands(context) { 9 | global_context = context; 10 | doc = context.document; 11 | // check if there are no conflicting characters in the previous input string (else input prompt fails to open) 12 | try { 13 | escapedValue = rcSettingForKey("resizeCommandPromptValue"); 14 | resizeCommandPrevValue = escapedValue; 15 | if(escapedValue.indexOf('.') > -1) { // check if there are dots present 16 | resizeCommandPrevValue = escapedValue.replace(".",','); // reset . to , again 17 | } 18 | } 19 | catch (e) { // else reset history 20 | rcSetSettingForKey("resizeCommandPromptValue", ""); 21 | } 22 | 23 | // show inputprompt 24 | doc.showMessage("Valid directions: t b l r a(ll) w h x y. Valid operations: + - = * / %. "); 25 | UI.getInputFromUser( 26 | "Enter your Resize Commands. For example: lr-10,h=230", 27 | { 28 | initialValue: resizeCommandPrevValue, 29 | }, 30 | (err, resizeCommandPrompt) => { 31 | if (resizeCommandPrompt) { 32 | // store previous value for later use 33 | var escapedValue = resizeCommandPrompt.replace(",", "."); // workaround since comma's conflict with persistence.js 34 | rcSetSettingForKey("resizeCommandPromptValue", escapedValue); 35 | 36 | resizeCommandPrompt = resizeCommandPrompt.toString(); 37 | resizeCommandPrompt = resizeCommandPrompt.toLowerCase(); 38 | resizeCommandPrompt = resizeCommandPrompt.replace(/(px)/g, ""); 39 | resizeCommandPrompt = resizeCommandPrompt.replace(/ /g, ""); 40 | resizeCommandPrompt = resizeCommandPrompt.replace(/;/g, ","); 41 | 42 | var amount, operator, operation; 43 | var num = 1, 44 | operationArray = []; 45 | 46 | if (resizeCommandPrompt.indexOf(",") > 0) { 47 | num = resizeCommandPrompt.split(",").length; 48 | operationArray = resizeCommandPrompt.split(","); 49 | } 50 | else { 51 | operationArray[0] = resizeCommandPrompt; 52 | } 53 | 54 | // operationArray = array with all the operations that were put in, for example [0]=lr+20,[1]=h/2) 55 | // operation = one single operation, for example b-30 or lr+20 56 | 57 | for (var i = 0; i < operationArray.length; i++) { // loop through every operation in the array 58 | operation = operationArray[i]; 59 | 60 | if (operation.indexOf("*") >= 0) 61 | checkOperationNotation(operation, amount, "*"); 62 | else if (operation.indexOf("/") >= 0) 63 | checkOperationNotation(operation, amount, "/"); 64 | else if (operation.indexOf("%") >= 0) 65 | checkOperationNotation(operation, amount, "%"); 66 | else if (operation.indexOf("=") >= 0) 67 | checkOperationNotation(operation, amount, "="); 68 | else { 69 | amount = operation.replace(resizeCommandDirections, ""); 70 | 71 | if (operation.indexOf("-") >= 0) { 72 | operator = "-"; 73 | amount = amount.split(operator)[1]; 74 | ContractExpand(operation, operator, amount); 75 | } 76 | else { //if nothing is used, for example l20, then use expand 77 | operator = "+"; 78 | ContractExpand(operation, operator, amount); 79 | } 80 | } 81 | } 82 | } 83 | } 84 | ) 85 | } 86 | 87 | // A nicer/shorter way for saving settings than using persistence.js: http://developer.sketchapp.com/reference/api/file/api/Application.js.html 88 | // It seems like they are not part of the Sketch API yet, as long as that's not 89 | // the case I use 'rc' as a prefix to prevent conflicts in the future 90 | function rcSetSettingForKey(key, value) { 91 | NSUserDefaults.standardUserDefaults().setObject_forKey_(value, key) 92 | } 93 | function rcSettingForKey(key) { 94 | return NSUserDefaults.standardUserDefaults().objectForKey_(key); 95 | } 96 | 97 | function ContractExpand(operation, operator, amount) { 98 | var calcAmount = Math.round(amount); 99 | 100 | if(operator == "-") 101 | calcAmount *= -1; 102 | 103 | for (var i=0; i