Skip to content

Commit

Permalink
Merge pull request #14 from pberrecloth/v1.3
Browse files Browse the repository at this point in the history
V1.3
  • Loading branch information
DWilliames authored Aug 23, 2017
2 parents a9bea6d + 6f13be9 commit 10485a5
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 49 deletions.
69 changes: 43 additions & 26 deletions .appcast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,48 @@
<link>https://raw.githubusercontent.com/pberrecloth/butter-sketch-plugin/master/.appcast.xml</link>
<description>Butts layers together</description>
<language>en</language>
<item>
<title>Version 1.2</title>
<description>
<![CDATA[
<ul>
<li>Remove keyboard shortcuts</li>
</ul>
]]>
</description>
<enclosure url="https://github.com/pberrecloth/butter-sketch-plugin/releases/download/v1.2/Butter.sketchplugin.zip" sparkle:version="1.2" />
</item>
<item>
<title>Version 1.1</title>
<description>
<![CDATA[
<ul>
<li>Rewritten from the ground up</li>
<li>Fixed support for latest versions of Sketch</li>
<li>Added support for Sketch Runner</li>
<li>Most recently used spacing value is the default next time</li>
<li>Reorders selected layers in the layer list in the same order they are butted together</li>
</ul>
]]>
</description>
<enclosure url="https://github.com/pberrecloth/butter-sketch-plugin/releases/download/v1.1/Butter.sketchplugin.zip" sparkle:version="1.1" />
</item>
<item>
<title>Version 1.3</title>
<description>
<![CDATA[
<ul>
<li>Fixed: layers with transformation (e.g. rotation) now work as expected</li>
</ul>
Added some new behaviour for when less than 2 layers are selected:
<ul>
<li>If 1 layer is selected — it will select all its sublayers (even ones that are locked). Great for selecting a single artboard or group to butt everything within it.</li>
<li>If no layers are selected and there are no artboards on the current page — it will select all top level layers (even locked ones)</li>
<li>If no layers are selected and there is a current artboard — it will select all the top-level layers within the artboard.</li>
</ul>
]]>
</description>
<enclosure url="https://github.com/pberrecloth/butter-sketch-plugin/releases/download/v1.3/Butter.sketchplugin.zip" sparkle:version="1.3" />
</item>
<item>
<title>Version 1.2</title>
<description>
<![CDATA[
<ul>
<li>Remove keyboard shortcuts</li>
</ul>
]]>
</description>
<enclosure url="https://github.com/pberrecloth/butter-sketch-plugin/releases/download/v1.2/Butter.sketchplugin.zip" sparkle:version="1.2" />
</item>
<item>
<title>Version 1.1</title>
<description>
<![CDATA[
<ul>
<li>Rewritten from the ground up</li>
<li>Fixed support for latest versions of Sketch</li>
<li>Added support for Sketch Runner</li>
<li>Most recently used spacing value is the default next time</li>
<li>Reorders selected layers in the layer list in the same order they are butted together</li>
</ul>
]]>
</description>
<enclosure url="https://github.com/pberrecloth/butter-sketch-plugin/releases/download/v1.1/Butter.sketchplugin.zip" sparkle:version="1.1" />
</item>
</channel>
</rss>
86 changes: 65 additions & 21 deletions butter.sketchplugin/Contents/Sketch/butter.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,54 +66,81 @@ function buttSelectionRightAddingMargin() {
// Butt all selected elements in a specified direction
// direction: The direction to butt from
function buttSelection(direction, askUser) {

var layersToButt = selection

// If nothing is selected — use the current artboard, otherwise use the page's layers
if (layersToButt.count() == 0) {
var page = doc.currentPage()
var artboard = page.currentArtboard()
layersToButt = artboard ? artboard.layers() : page.layers()
}
else if (layersToButt.count() == 1) {
// If exactly one thing is selected, use it's layers
layersToButt = layersToButt.firstObject().layers()
}

// Will only work if the user has selected more than one layer
if (count <= 1) {
doc.showMessage("Select at least two layers to butt together")
if (layersToButt.count() <= 1) {
doc.showMessage("Select at least two layers to butt together. Or one layer with multiple sublayers.")
return
}

// Will only work if all the layers have the same parent
if (!layersHaveSameParent(selection)) {
if (!layersHaveSameParent(layersToButt)) {
doc.showMessage("Please select multiple layers in one group")
return
}

// Get the margin for butting — asking the user if necessary
var margin = getMargin(askUser)
// If the user cancelled their margin input, finish running the script
if (margin === null)
if (margin === null) {
return
}

// Deselect all layers — in case we are not butting the current selection
selection.forEach(function(layer) {
layer.select_byExtendingSelection(false, false)
})

// Convert the selection array from an NSArray into a Javascript array
// This makes it easier to sort and use 'shift' etc.
var selectedLayers = []
selection.forEach(function(layer) {
selectedLayers.push(layer)
var layersArray = []
layersToButt.forEach(function(layer) {
layersArray.push(layer)
// Select all the layers we are butting — in case we are not butting the original selection
layer.select_byExtendingSelection(true, true)
})

// Sort the layers based on the direction
var layers = sortLayersForDirection(selectedLayers, direction)
var layers = sortLayersForDirection(layersArray, direction)

// Apart from the first layer, shift each layer based on previous layer's position
var previous = layers.shift()
layers.forEach(function(layer) {
// The amount to offset the layer
var x = 0
var y = 0

// Shift the position based on the direction we are 'butting'
switch(direction) {
case directions.LEFT:
layer.frame().setX(previous.frame().maxX() + margin)
x = margin - rectForLayer(layer).minX() + rectForLayer(previous).maxX()
break;
case directions.RIGHT:
layer.frame().setX(previous.frame().minX() - margin - layer.frame().width())
x = rectForLayer(previous).minX() - rectForLayer(layer).maxX() - margin
break;
case directions.UP:
layer.frame().setY(previous.frame().maxY() + margin)
y = margin - rectForLayer(layer).minY() + rectForLayer(previous).maxY()
break;
case directions.DOWN:
layer.frame().setY(previous.frame().minY() - margin - layer.frame().height())
y = rectForLayer(previous).minY() - rectForLayer(layer).maxY() - margin
break;
}

offsetLayer(layer, x, y)

// Reorder the layer list — if that's the preference
if (defaults.reorderLayerList > 0) {
// Reorder the layer in the layer list by removing it, then placing after the previous layer
Expand All @@ -125,7 +152,7 @@ function buttSelection(direction, askUser) {
})

// Display a message for what just occured
var message = "Butted " + count + " layers"
var message = "Butted " + layersToButt.count() + " layers"
if (margin != 0)
message += " with a spacing of " + margin

Expand Down Expand Up @@ -160,15 +187,18 @@ function getMargin(shouldAskUser) {
// direction: The direction to order them in reference to
function sortLayersForDirection(layers, direction) {
return layers.sort(function(a, b) {
var aFrame = rectForLayer(a)
var bFrame = rectForLayer(b)

switch(direction) {
case directions.LEFT:
return a.frame().minX() <= b.frame().minX() ? -1 : 1
return aFrame.minX() <= bFrame.minX() ? -1 : 1
case directions.RIGHT:
return a.frame().maxX() >= b.frame().maxX() ? -1 : 1
return aFrame.maxX() >= bFrame.maxX() ? -1 : 1
case directions.UP:
return a.frame().minY() <= b.frame().minY() ? -1 : 1
return aFrame.minY() <= bFrame.minY() ? -1 : 1
case directions.DOWN:
return a.frame().maxY() >= b.frame().maxY() ? -1 : 1
return aFrame.maxY() >= bFrame.maxY() ? -1 : 1
}
})
}
Expand All @@ -184,6 +214,17 @@ function layersHaveSameParent(layers) {
})
}

// Returns an MSRect for the layer, taking into account transforms (e.g. rotation)
function rectForLayer(layer) {
return MSRect.alloc().initWithRect(layer.frameForTransforms())
}

// Offset a layer's position by x and y
function offsetLayer(layer, x, y) {
layer.frame().setX(layer.frame().x() + x)
layer.frame().setY(layer.frame().y() + y)
}


// CURRENTLY UNUSED HELPER FUNCTIONS

Expand All @@ -207,14 +248,17 @@ function areLayersButted(layers, diretion) {

// Returns the space between two layers in a specific direction
function spaceBetweenLayers(a, b, direction) {
var aFrame = rectForLayer(a)
var bFrame = rectForLayer(b)

switch(direction) {
case directions.LEFT:
return b.frame().minX() - a.frame().maxX()
return bFrame.minX() - aFrame.maxX()
case directions.RIGHT:
return a.frame().minX() - b.frame().maxX()
return aFrame.minX() - bFrame.maxX()
case directions.UP:
return b.frame().minY() - a.frame().maxY()
return bFrame.minY() - aFrame.maxY()
case directions.DOWN:
return a.frame().minY() - b.frame().maxY()
return aFrame.minY() - bFrame.maxY()
}
}
4 changes: 2 additions & 2 deletions butter.sketchplugin/Contents/Sketch/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Butts layers together",
"author": "Peter Berrecloth & David Williames",
"homepage": "https://github.com/pberrecloth/butter-sketch-plugin",
"version": "1.2",
"version": "1.3",
"identifier": "com.butter.sketchplugin",
"appcast": "https://raw.githubusercontent.com/pberrecloth/butter-sketch-plugin/master/.appcast.xml",
"compatibleVersion": "39.1",
Expand Down Expand Up @@ -80,7 +80,7 @@
"script": "butter.js",
"handler": "buttSelectionRightAddingMargin",
"shortcut": ""
},
}
],
"menu": {
"isRoot": true,
Expand Down

0 comments on commit 10485a5

Please sign in to comment.