├── Artboard-Tools.sketchplugin └── Contents │ ├── Resources │ └── artboard-tools.png │ └── Sketch │ ├── ArtboardTools.cocoascript │ ├── ArtboardTools.js │ └── manifest.json ├── README.md ├── appcast.xml └── contributions └── arkkimaagi.md /Artboard-Tools.sketchplugin/Contents/Resources/artboard-tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/frankko/Artboard-Tools/622fa69cd65491f36cc59d0a0984cc88f60c8716/Artboard-Tools.sketchplugin/Contents/Resources/artboard-tools.png -------------------------------------------------------------------------------- /Artboard-Tools.sketchplugin/Contents/Sketch/ArtboardTools.cocoascript: -------------------------------------------------------------------------------- 1 | @import "ArtboardTools.js" 2 | 3 | if (KOLOArtboardTools.util.checkForPrefOverrides()) { 4 | @import '~/.sketchplugin.artboard-tools.userprefs.js'; 5 | } 6 | 7 | var arrange_artboards = function (context) { 8 | KOLOArtboardTools.arrangeArtboards(context); 9 | }; 10 | var group_artboards = function (context) { 11 | KOLOArtboardTools.groupArtboards(context); 12 | }; 13 | var group_artboards_columns = function (context) { 14 | KOLOArtboardTools.groupArtboardsColumns(context); 15 | }; 16 | var fit_artboard = function (context) { 17 | KOLOArtboardTools.fitArtboard(context); 18 | }; 19 | var select_prev = function (context) { 20 | KOLOArtboardTools.selectPreviousArtboard(context); 21 | }; 22 | var select_next = function (context) { 23 | KOLOArtboardTools.selectNextArtboard(context); 24 | }; 25 | var reverse_artboards_order = function (context) { 26 | KOLOArtboardTools.reverseArtboardsOrder(context); 27 | }; 28 | -------------------------------------------------------------------------------- /Artboard-Tools.sketchplugin/Contents/Sketch/ArtboardTools.js: -------------------------------------------------------------------------------- 1 | var userPrefs = { 2 | "arrange_spacing_x": 128, 3 | "arrange_spacing_y": 256, 4 | "arrange_max_cols": 11, 5 | "group_spacing_x": 128, 6 | "group_spacing_y": 128, 7 | "sort_top_to_bottom": true, 8 | "use_slashes": false 9 | }; 10 | 11 | var KOLOArtboardTools = { 12 | "arrangeArtboards": function (context) { 13 | // User-adjustable: 14 | 15 | var group_related = false; 16 | var zoom_to_fit = true; 17 | 18 | var start_x = 0; 19 | var start_y = 0; 20 | 21 | var spacing_x = userPrefs.arrange_spacing_x; 22 | var spacing_y = userPrefs.arrange_spacing_y; 23 | var spacing_group = Math.round(spacing_x / 2); 24 | 25 | var max_cols = userPrefs.arrange_max_cols; 26 | 27 | // Main junk, don't tread on me 28 | 29 | var doc = context.document; 30 | var selection = context.selection; 31 | var page = [doc currentPage]; 32 | var view = [doc contentDrawView]; 33 | 34 | var sort_top_to_bottom = userPrefs.sort_top_to_bottom; 35 | 36 | var curr_x = start_x; 37 | var curr_y = start_y; 38 | var curr_cols = 0; 39 | 40 | var max_right = 0; 41 | var max_bottom = 0; 42 | 43 | var prev_group_item = null; 44 | var curr_row_height = 0; 45 | 46 | var sorted_artboards = KOLOArtboardTools.util.getAllArtboards(context); 47 | 48 | for (var i = 0; i < sorted_artboards.length; i++) { 49 | var new_x, new_y; 50 | var up_counts = true; 51 | 52 | var ab = sorted_artboards[i]; 53 | var artboard_name = [ab name]; 54 | 55 | var m = artboard_name.match(/^(.+)--([0-9]+)$/i); 56 | 57 | if ((m != null) && (group_related == true)) { 58 | var this_group = m[1]; 59 | 60 | if (prev_group_item == null) { 61 | new_x = curr_x; 62 | new_y = curr_y; 63 | } else { 64 | let pregGroupItemAbsoluteRect = KOLOArtboardTools.util.absoluteRectForLayer(prev_group_item); 65 | new_x = pregGroupItemAbsoluteRect.origin.x; 66 | new_y = pregGroupItemAbsoluteRect.origin.y + pregGroupItemAbsoluteRect.size.height + spacing_group; 67 | } 68 | 69 | prev_group_item = ab; 70 | 71 | if ((i + 1) < sorted_artboards.length) { 72 | artboard_next_name = sorted_artboards[i+1].name(); 73 | var m_next = artboard_next_name.match(/^(.+)--([0-9]+)$/i); 74 | if (m_next != null) { 75 | if (m_next[1] == this_group) { 76 | up_counts = false; 77 | } else { 78 | prev_group_item = null; 79 | } 80 | } else { 81 | prev_group_item = null; 82 | } 83 | } 84 | } else { 85 | prev_group_item = null; 86 | new_x = curr_x; 87 | new_y = curr_y; 88 | } 89 | 90 | [[ab frame] setX:new_x]; 91 | [[ab frame] setY:new_y]; 92 | 93 | let abRect = KOLOArtboardTools.util.absoluteRectForLayer(ab); 94 | var artboard_right = abRect.origin.x + abRect.size.width; 95 | var artboard_bottom = abRect.origin.y + abRect.size.height; 96 | 97 | max_right = (artboard_right > max_right) ? artboard_right : max_right; 98 | max_bottom = (artboard_bottom > max_bottom) ? artboard_bottom : max_bottom; 99 | curr_row_height = (artboard_bottom > curr_row_height) ? artboard_bottom : curr_row_height; 100 | 101 | if (up_counts == true) { 102 | curr_x += abRect.size.width + spacing_x; 103 | curr_cols++; 104 | 105 | if (curr_cols >= max_cols) { 106 | curr_x = start_x; 107 | curr_y = curr_row_height + spacing_y; 108 | curr_cols = 0; 109 | curr_row_height = 0; 110 | } 111 | } 112 | } 113 | 114 | if (zoom_to_fit == true) { 115 | [view centerLayersInCanvas]; 116 | } 117 | 118 | [doc showMessage:"Artboards arranged."]; 119 | }, 120 | "groupArtboards": function (context) { 121 | // User-adjustable: 122 | 123 | var zoom_to_fit = true; 124 | 125 | var start_x = 0; 126 | var start_y = 0; 127 | 128 | var spacing_x = userPrefs.group_spacing_x; 129 | var spacing_y = userPrefs.group_spacing_y; 130 | var spacing_group = Math.round(spacing_x / 2); 131 | 132 | // Main junk, don't tread on me 133 | 134 | var sort_top_to_bottom = userPrefs.sort_top_to_bottom; 135 | var use_slashes = userPrefs.use_slashes; 136 | 137 | if (use_slashes) { 138 | var regexp_patt = /^(.+)\/.+/i; 139 | } else { 140 | var regexp_patt = /^(.+)--.+/i; 141 | } 142 | 143 | var doc = context.document; 144 | var selection = context.selection; 145 | var page = [doc currentPage]; 146 | var view = [doc contentDrawView]; 147 | 148 | var curr_x = start_x; 149 | var curr_y = start_y; 150 | 151 | var max_right = 0; 152 | var max_bottom = 0; 153 | 154 | var prev_group_item = null; 155 | var curr_row_height = 0; 156 | var found_headers = false; 157 | 158 | var page_name = [page name]; 159 | if (page_name == "Symbols") { 160 | var regexp_patt = /^(.+)\/.+/i; 161 | } 162 | 163 | var sorted_artboards = KOLOArtboardTools.util.getAllArtboards(context); 164 | 165 | for (var j = 0; j < sorted_artboards.length; j++) { 166 | var ab = sorted_artboards[j]; 167 | var artboard_name = [ab name]; 168 | var m = artboard_name.match(regexp_patt); 169 | if (m != null) { 170 | found_headers = true; 171 | } 172 | } 173 | 174 | if (found_headers == true) { 175 | for (var i = 0; i < sorted_artboards.length; i++) { 176 | var new_x, new_y; 177 | 178 | var ab = sorted_artboards[i]; 179 | var artboard_name = [ab name]; 180 | 181 | // var m = artboard_name.match(/^(.+)--.+/i); 182 | var m = artboard_name.match(regexp_patt); 183 | 184 | if (m != null) { 185 | var this_group = m[1]; 186 | 187 | if (this_group != prev_group_item) { 188 | curr_x = start_x; 189 | curr_y = curr_row_height + spacing_y; 190 | curr_row_height = 0; 191 | } 192 | 193 | prev_group_item = m[1]; 194 | } else { 195 | curr_x = start_x; 196 | curr_y = curr_row_height + spacing_y; 197 | curr_row_height = 0; 198 | } 199 | 200 | if (i == 0) { 201 | curr_x = start_x; 202 | curr_y = start_y; 203 | } 204 | 205 | new_x = curr_x; 206 | new_y = curr_y; 207 | 208 | [[ab frame] setX:new_x]; 209 | [[ab frame] setY:new_y]; 210 | 211 | let abRect = KOLOArtboardTools.util.absoluteRectForLayer(ab); 212 | 213 | var artboard_right = abRect.origin.x + abRect.size.width; 214 | var artboard_bottom = abRect.origin.y + abRect.size.height; 215 | 216 | max_right = (artboard_right > max_right) ? artboard_right : max_right; 217 | max_bottom = (artboard_bottom > max_bottom) ? artboard_bottom : max_bottom; 218 | curr_row_height = (artboard_bottom > curr_row_height) ? artboard_bottom : curr_row_height; 219 | 220 | curr_x += abRect.size.width + spacing_x; 221 | } 222 | 223 | if (zoom_to_fit == true) { 224 | [view centerLayersInCanvas]; 225 | } 226 | [doc showMessage:"Artboards grouped."]; 227 | } else { 228 | var app = [NSApplication sharedApplication]; 229 | if (use_slashes) { 230 | [app displayDialog:"Canceling. No artboard names contain “/”" withTitle:"Group Artboards"]; 231 | } else { 232 | [app displayDialog:"Canceling. No artboard names contain “--”" withTitle:"Group Artboards"]; 233 | } 234 | } 235 | }, 236 | "groupArtboardsColumns": function (context) { 237 | // User-adjustable: 238 | 239 | var zoom_to_fit = true; 240 | 241 | var start_x = 0; 242 | var start_y = 0; 243 | 244 | var spacing_x = userPrefs.group_spacing_x; 245 | var spacing_y = userPrefs.group_spacing_y; 246 | var spacing_group = Math.round(spacing_x / 2); 247 | 248 | // Main junk, don't tread on me 249 | 250 | var sort_top_to_bottom = userPrefs.sort_top_to_bottom; 251 | var use_slashes = userPrefs.use_slashes; 252 | 253 | if (use_slashes) { 254 | var regexp_patt = /^(.+)\/.+/i; 255 | } else { 256 | var regexp_patt = /^(.+)--.+/i; 257 | } 258 | 259 | var doc = context.document; 260 | var selection = context.selection; 261 | var page = [doc currentPage]; 262 | var view = [doc contentDrawView]; 263 | 264 | var curr_x = start_x; 265 | var curr_y = start_y; 266 | 267 | var max_right = 0; 268 | var max_bottom = 0; 269 | 270 | var prev_group_item = null; 271 | var curr_row_width = 0; 272 | var found_headers = false; 273 | 274 | var page_name = [page name]; 275 | if (page_name == "Symbols") { 276 | var regexp_patt = /^(.+)\/.+/i; 277 | } 278 | 279 | var sorted_artboards = KOLOArtboardTools.util.getAllArtboards(context); 280 | 281 | for (var j = 0; j < sorted_artboards.length; j++) { 282 | var ab = sorted_artboards[j]; 283 | var artboard_name = [ab name]; 284 | var m = artboard_name.match(regexp_patt); 285 | if (m != null) { 286 | found_headers = true; 287 | } 288 | } 289 | 290 | if (found_headers == true) { 291 | for (var i = 0; i < sorted_artboards.length; i++) { 292 | var new_x, new_y; 293 | 294 | var ab = sorted_artboards[i]; 295 | var artboard_name = [ab name]; 296 | 297 | // var m = artboard_name.match(/^(.+)--.+/i); 298 | var m = artboard_name.match(regexp_patt); 299 | 300 | if (m != null) { 301 | var this_group = m[1]; 302 | 303 | if (this_group != prev_group_item) { 304 | curr_x = curr_row_width + spacing_x; 305 | curr_y = start_y; 306 | curr_row_width = 0; 307 | } 308 | 309 | prev_group_item = m[1]; 310 | } else { 311 | curr_x = curr_row_width + spacing_x; 312 | curr_y = start_y; 313 | curr_row_width = 0; 314 | } 315 | 316 | if (i == 0) { 317 | curr_x = start_x; 318 | curr_y = start_y; 319 | } 320 | 321 | new_x = curr_x; 322 | new_y = curr_y; 323 | 324 | [[ab frame] setX:new_x]; 325 | [[ab frame] setY:new_y]; 326 | 327 | let abRect = KOLOArtboardTools.util.absoluteRectForLayer(ab); 328 | var artboard_right = abRect.origin.x + abRect.size.width; 329 | var artboard_bottom = abRect.origin.y + abRect.size.height; 330 | 331 | max_right = (artboard_right > max_right) ? artboard_right : max_right; 332 | max_bottom = (artboard_bottom > max_bottom) ? artboard_bottom : max_bottom; 333 | curr_row_width = (artboard_right > curr_row_width) ? artboard_right : curr_row_width; 334 | 335 | curr_y += abRect.size.height + spacing_y; 336 | } 337 | 338 | if (zoom_to_fit == true) { 339 | [view centerLayersInCanvas]; 340 | } 341 | [doc showMessage:"Artboards grouped."]; 342 | } else { 343 | var app = [NSApplication sharedApplication]; 344 | if (use_slashes) { 345 | [app displayDialog:"Canceling. No artboard names contain “/”" withTitle:"Group Artboards"]; 346 | } else { 347 | [app displayDialog:"Canceling. No artboard names contain “--”" withTitle:"Group Artboards"]; 348 | } 349 | } 350 | }, 351 | "fitArtboard": function (context) { 352 | var doc = context.document; 353 | var selection = context.selection; 354 | var page = [doc currentPage]; 355 | var view = [doc contentDrawView]; 356 | 357 | var target_artboard; 358 | 359 | if ([selection count] > 0) { 360 | var selected_artboard = [selection objectAtIndex:0]; 361 | 362 | while ([selected_artboard parentGroup] != page) { 363 | selected_artboard = [selected_artboard parentGroup]; 364 | } 365 | 366 | [selected_artboard select:true byExpandingSelection:false]; 367 | doc.actionsController().actionForID("Sketch.MSZoomToSelectionAction").zoomToSelection(nil); 368 | // doc.actionsController().actionForID("MSZoomToActualSizeAction").actualSize(nil); 369 | // doc.actionsController().actionForID("MSCenterSelectionInVisibleAreaAction").centerSelectionInVisibleArea(nil); 370 | } 371 | }, 372 | "reverseArtboardsOrder": function (context) { 373 | var all_artboards = context.document.currentPage().artboards(); 374 | var sorted_artboards = []; 375 | 376 | for (var j = 0; j < [all_artboards count]; j++) { 377 | var ab = [all_artboards objectAtIndex:j]; 378 | sorted_artboards.push(ab); 379 | } 380 | 381 | for (var i = 0; i < sorted_artboards.length; i++) { 382 | var ab = sorted_artboards[i]; 383 | [MSLayerMovement moveToBack:[ab]]; 384 | } 385 | }, 386 | "selectPreviousArtboard": function (context) { 387 | var doc = context.document; 388 | var selection = context.selection; 389 | var page = [doc currentPage]; 390 | var view = [doc contentDrawView]; 391 | 392 | var current_zoom = [doc zoomValue]; 393 | 394 | var target_artboard; 395 | var sorted_artboards = KOLOArtboardTools.util.getAllArtboards(context); 396 | 397 | if ([selection count] > 0) { 398 | var selected_artboard = [selection objectAtIndex:0]; 399 | 400 | while ([selected_artboard parentGroup] != page) { 401 | selected_artboard = [selected_artboard parentGroup]; 402 | } 403 | 404 | var selected_artboard_name = [selected_artboard name]; 405 | 406 | var selected_index = -1; 407 | 408 | for (var i = 0; i < sorted_artboards.length; i++) { 409 | var ab = sorted_artboards[i]; 410 | 411 | if ([ab name] == selected_artboard_name) { 412 | selected_index = i; 413 | break; 414 | } 415 | } 416 | if (selected_index >= 0) { 417 | var prev_index = selected_index - 1; 418 | if (prev_index < 0) { 419 | prev_index = sorted_artboards.length - 1; 420 | } 421 | target_artboard = sorted_artboards[prev_index]; 422 | } else { 423 | target_artboard = false; 424 | } 425 | } else { 426 | target_artboard = sorted_artboards[sorted_artboards.length - 1]; 427 | } 428 | 429 | if (target_artboard != false) { 430 | [target_artboard select:true byExpandingSelection:false]; 431 | doc.actionsController().actionForID("Sketch.MSZoomToSelectionAction").zoomToSelection(nil); 432 | } 433 | }, 434 | "selectNextArtboard": function (context) { 435 | var doc = context.document; 436 | var selection = context.selection; 437 | var page = [doc currentPage]; 438 | var view = [doc contentDrawView]; 439 | 440 | var current_zoom = [doc zoomValue]; 441 | 442 | var target_artboard; 443 | var sorted_artboards = KOLOArtboardTools.util.getAllArtboards(context); 444 | 445 | if ([selection count] > 0) { 446 | var selected_artboard = [selection objectAtIndex:0]; 447 | 448 | while ([selected_artboard parentGroup] != page) { 449 | selected_artboard = [selected_artboard parentGroup]; 450 | } 451 | 452 | var selected_artboard_name = [selected_artboard name]; 453 | var selected_index = -1; 454 | 455 | for (var i = 0; i < sorted_artboards.length; i++) { 456 | var ab = sorted_artboards[i]; 457 | 458 | if ([ab name] == selected_artboard_name) { 459 | selected_index = i; 460 | break; 461 | } 462 | } 463 | if (selected_index >= 0) { 464 | var next_index = selected_index + 1; 465 | if (next_index >= sorted_artboards.length) { 466 | next_index = 0; 467 | } 468 | target_artboard = sorted_artboards[next_index]; 469 | } else { 470 | target_artboard = false; 471 | } 472 | } else { 473 | target_artboard = sorted_artboards[0]; 474 | } 475 | 476 | if (target_artboard != false) { 477 | [target_artboard select:true byExpandingSelection:false]; 478 | doc.actionsController().actionForID("Sketch.MSZoomToSelectionAction").zoomToSelection(nil); 479 | } 480 | }, 481 | "util": { 482 | "absoluteRectForLayer" : function(layer) { 483 | // thanks @rodionovd 484 | let parent = layer.parentObject(); 485 | let relativeRect = layer.frame().rect(); 486 | return parent.convertRect_toCoordinateSpace_(relativeRect,nil); 487 | }, 488 | "getAllArtboards": function(context) { 489 | var all_artboards = context.document.currentPage().artboards(); 490 | var sorted_artboards = []; 491 | 492 | if (userPrefs.sort_top_to_bottom) { 493 | var artboards_count = [all_artboards count]; 494 | for (var i = (artboards_count - 1); i >= 0; i--) { 495 | var ab = [all_artboards objectAtIndex:i]; 496 | sorted_artboards.push(ab); 497 | } 498 | } else { 499 | for (var i = 0; i < [all_artboards count]; i++) { 500 | var ab = [all_artboards objectAtIndex:i]; 501 | sorted_artboards.push(ab); 502 | } 503 | } 504 | return sorted_artboards; 505 | }, 506 | "checkForPrefOverrides": function() { 507 | var pathString = "~/.sketchplugin.artboard-tools.userprefs.js"; 508 | var path = NSString.alloc().initWithString_(pathString).stringByExpandingTildeInPath(); 509 | 510 | var isDir = MOPointer.alloc().initWithValue_(false); 511 | var fileExists = NSFileManager.defaultManager().fileExistsAtPath_isDirectory(path,isDir); 512 | 513 | if (fileExists) { 514 | return true; 515 | } 516 | return false; 517 | } 518 | } 519 | }; -------------------------------------------------------------------------------- /Artboard-Tools.sketchplugin/Contents/Sketch/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "appcast": "https://raw.githubusercontent.com/frankko/Artboard-Tools/master/appcast.xml", 3 | "author" : "Frank Kolodziej", 4 | "commands" : [ 5 | { 6 | "script" : "ArtboardTools.cocoascript", 7 | "handler": "arrange_artboards", 8 | "shortcut" : "control command 1", 9 | "name" : "Arrange Artboards", 10 | "identifier" : "101_arrange_artboards" 11 | }, 12 | { 13 | "script" : "ArtboardTools.cocoascript", 14 | "handler": "group_artboards", 15 | "shortcut" : "control option 1", 16 | "name" : "Group Artboards (Rows)", 17 | "identifier" : "201_group_artboards" 18 | }, 19 | { 20 | "script" : "ArtboardTools.cocoascript", 21 | "handler": "group_artboards_columns", 22 | "shortcut" : "control option 2", 23 | "name" : "Group Artboards (Columns)", 24 | "identifier" : "202_group_artboards_columns" 25 | }, 26 | { 27 | "script" : "ArtboardTools.cocoascript", 28 | "handler": "fit_artboard", 29 | "shortcut" : "command 4", 30 | "name" : "Zoom Artboard to Fit", 31 | "identifier" : "900_fit_artboard" 32 | }, 33 | { 34 | "script" : "ArtboardTools.cocoascript", 35 | "handler": "select_prev", 36 | "shortcut" : "control shift [", 37 | "name" : "Select Previous Artboard", 38 | "identifier" : "901_select_prev_artboard" 39 | }, 40 | { 41 | "script" : "ArtboardTools.cocoascript", 42 | "handler": "select_next", 43 | "shortcut" : "control shift ]", 44 | "name" : "Select Next Artboard", 45 | "identifier" : "902_select_next_artboard" 46 | }, 47 | { 48 | "script" : "ArtboardTools.cocoascript", 49 | "handler": "reverse_artboards_order", 50 | "shortcut" : "", 51 | "name" : "Reverse Artboards Order", 52 | "identifier" : "999_reverse_artboards_order" 53 | } 54 | ], 55 | "icon": "artboard-tools.png", 56 | "menu" : { 57 | "items" : [ 58 | "101_arrange_artboards", 59 | "201_group_artboards", 60 | "202_group_artboards_columns", 61 | "900_fit_artboard", 62 | "901_select_prev_artboard", 63 | "902_select_next_artboard", 64 | "999_reverse_artboards_order" 65 | ], 66 | "title" : "Artboard Tools" 67 | }, 68 | "homepage" : "https://github.com/frankko/Artboard-Tools", 69 | "identifier" : "io.kolo.sketch.artboard-tools", 70 | "compatibleVersion": "100", 71 | "version" : "3.100.0", 72 | "description" : "Plugins for arranging artboards and navigating between artboards.", 73 | "authorEmail" : "frank@kolo.io", 74 | "name" : "Artboard Tools" 75 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Artboard Tools (Sketch plugins) 2 | 3 | Contains seven items: 4 | 5 | ## Arrange Artboards ( cmd+ctrl+1 ) 6 | 7 | Selects all artboards and arranges them in a grid. Like so: 8 | 9 | ``` 10 | A B C D 11 | E F G H 12 | I J 13 | ``` 14 | 15 | ## Group Artboards (Rows) ( ctrl+opt+1 ) 16 | 17 | Similar to `Arrange Artboards`, but more complicated. Instead of a predefined number of artboards per row, the plugin searches for artboards whose names match a pattern and includes them all on one row, starting a new row when the pattern is broken. Like so: 18 | 19 | ``` 20 | A A 21 | B B B B B 22 | C C C 23 | ``` 24 | 25 | Useful if you’re designing a bunch of screens and you wanted each section to be its own row. 26 | 27 | The pattern searched for goes like this: ‘group name’ + ‘\-\-’ + ‘whatever’. For example, ‘headers\-\-version-A’, ‘headers\-\-version-B’, ‘sidebars\-\-version-A’, ‘footers\-\-version-A’, ‘footers\-\-version-B’. That would create three rows. 28 | 29 | ## Group Artboards (Columns) ( ctrl+opt+2 ) 30 | 31 | Just like `Group Artboards (Rows)` but goes vertically instead of horizontally, like so: 32 | 33 | ``` 34 | A B C 35 | A B C 36 | B C 37 | B 38 | B 39 | ``` 40 | 41 | ## Zoom Artboard to Fit ( cmd+4 ) 42 | 43 | The equivalent of selecting an artboard and doing “Zoom Selection” (cmd+2), but this plugin always zooms out and centers the current artboard, even if you’ve selected a layer within the artboard. 44 | 45 | ## Select Prev Artboard ( ctrl+shift+[ ), Select Next Artboard ( ctrl+shift+] ) 46 | 47 | Selects the previous artboard in the layer list or selects the next artboard in the layer list, depending on which you invoke, and zooms that artboard to fit the screen. (Think of it like next/previous tab in your browser.) 48 | 49 | If no artboard (or a layer within an artboard) is selected, Prev will select the last (top-most) artboard in the layer list, Next the first (bottom-most) artboard. 50 | 51 | **Note:** As of about Sketch 100, the old shortcuts, cmd+shift+[ and cmd+shift+], no longer work, so I changed them to ctrl+shift+[ and ctrl+shift+]. 52 | 53 | ## Reverse Artboards Order 54 | 55 | Reverses the artboards in the layer list. If your layer list looks like this: 56 | 57 | ``` 58 | frog 59 | pig 60 | chicken 61 | lizard 62 | ``` 63 | 64 | it will change to 65 | 66 | ``` 67 | lizard 68 | chicken 69 | pig 70 | frog 71 | ``` 72 | 73 | It doesn't sort the layers by name first. It doesn't move any artboard's position on the canvas. It just moves the top-most artboard to the bottom of the list, the bottom-most to the top, and so on. (Useful if you use a third-party service that sorts artboards the opposite way than you prefer.) 74 | 75 | * * * * * 76 | 77 | **Note that for all plugins, the artboard order is determined by the artboard’s position in the layer list _from top to bottom_. Current artboard position on the canvas is ignored.** 78 | 79 | * * * * * 80 | 81 | ### Installation 82 | 83 | Download the [plugin zip](https://github.com/frankko/Artboard-Tools/archive/master.zip); unzip the downloaded zip file; double-click the `Artboard-Tools.sketchplugin` file 84 | 85 | * * * * * 86 | 87 | ### User Prefs 88 | 89 | Persistent preference overrides for certain items are now available. See instructions in [this Gist](https://gist.github.com/frankko/5db4d671156815755fab89b4611afaba). 90 | 91 | * * * 92 | 93 | ### Who? 94 | 95 | I’m Frank Kolodziej, a Wichita, KS-based freelance designer & developer. I am [available for hire](http://kolo.io/). I’m on [BlueSky](https://bsky.app/profile/frankko.bsky.social) and [Mastodon](https://mastodon.social/@frankko). 96 | 97 | #### Other Plugins 98 | 99 | - [Place Linked Bitmap](https://github.com/frankko/Place-Linked-Bitmap): A plugin to place external bitmap files into Sketch and update Sketch layers after external bitmaps are updated 100 | - [★ Utility Belt](https://github.com/frankko/UtilityBelt): An always-expanding collection of simple, focused plugins for Sketch. 101 | -------------------------------------------------------------------------------- /appcast.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Artboard Tools 5 | https://raw.githubusercontent.com/frankko/Artboard-Tools/master/appcast.xml 6 | Plugins for arranging artboards and navigating between artboards. 7 | en 8 | 9 | Version 3.100.0 10 | 11 | 13 |
  • 2024-08-26: Updated for Sketch 100. Had to change some shortcut keys. Check the Readme.
  • 14 | 15 | ]]> 16 |
    17 | 18 |
    19 | 20 | Version 3.98.0 21 | 22 | 24 |
  • 2023-10-03: Updated for Sketch 98
  • 25 | 26 | ]]> 27 |
    28 | 29 |
    30 | 31 | Version 3.50.2 32 | 33 | 35 |
  • 2021-05-13: Updated for Sketch 72
  • 36 | 37 | ]]> 38 |
    39 | 40 |
    41 | 42 | Version 3.50.1 43 | 44 | 46 |
  • Allow for persistent user preferences
  • 47 | 48 | ]]> 49 |
    50 | 51 |
    52 | 53 | Version 3.50.0 54 | 55 | 57 |
  • Updates for Sketch 50
  • 58 | 59 | ]]> 60 |
    61 | 62 |
    63 | 64 | Version 3.48.0 65 | 66 | 68 |
  • New command: Group Artboards (Columns)
  • 69 | 70 | ]]> 71 |
    72 | 73 |
    74 | 75 | Version 2.48.1 76 | 77 | 79 |
  • Fixes for Sketch 48
  • 80 | 81 | ]]> 82 |
    83 | 84 |
    85 | 86 | Version 2.43.8 87 | 88 | 90 |
  • New command: Reverse Artboards Order. See README
  • 91 |
  • Grouped artboards now start at 0,0 (fixes #15)
  • 92 | 93 | ]]> 94 |
    95 | 96 |
    97 | 98 | Version 2.43.7 99 | 100 | 102 |
  • Bug fix relating to the new advanced option to arrange/group layers from top-to-bottom.
  • 103 |
  • Select Prev/Next Artboard commands now honor that new advanced option.
  • 104 | 105 | ]]> 106 |
    107 | 108 |
    109 | 110 | Version 2.43.6 111 | 112 | 114 |
  • Add advanced option to arrange/group layers from top-to-bottom. See README.
  • 115 | 116 | ]]> 117 |
    118 | 119 |
    120 | 121 | Version 2.43.5 122 | 123 | 125 |
  • Support for Sketch 45's plugin auto-updating.
  • 126 | 127 | ]]> 128 |
    129 | 130 |
    131 | 132 | Version 2.43.2 133 | 134 | 136 |
  • Bug fix for Sketch 45.
  • 137 | 138 | ]]> 139 |
    140 | 141 |
    142 |
    143 |
    -------------------------------------------------------------------------------- /contributions/arkkimaagi.md: -------------------------------------------------------------------------------- 1 | Artboard Tools’ “Zoom Artboard to Fit” uses bits from [ArtboardZoom](https://github.com/Arkkimaagi/ArtboardZoom): 2 | 3 | * * * * * * * * 4 | 5 | The MIT License (MIT) 6 | 7 | Copyright (c) 2014 Mikko Tapionlinna 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --------------------------------------------------------------------------------