Skip to content

Instantly share code, notes, and snippets.

@phaistonian
Last active August 29, 2015 14:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save phaistonian/b3737cf05c1b6a61dbb7 to your computer and use it in GitHub Desktop.
Save phaistonian/b3737cf05c1b6a61dbb7 to your computer and use it in GitHub Desktop.
Sketch: Select similar layers or groups based on a number of properties (and guesses)
// Select Similar (ctrl shift a)
// https://gist.githubusercontent.com/phaistonian/b3737cf05c1b6a61dbb7/raw/1f1ca90f1c72e395cb4d2abfc23315c47dc5c25d/Select%20Similar.sketchplugin
/* Based on initial work by Ale Muñoz */
(function(){
var sel = selection[0], all_layers = [[doc currentPage] children];
if (sel) {
var query = getIdForElement(sel), type = [sel className], found = 0;
if (query) {
for(var i=0; i < [all_layers count]; i++){
var item = all_layers[i];
// Make sure the type is the same so that we can avoid halts
if ([item className] != type) {
continue;
}
// Removing this will halt Sketch - duh!
log([[item className], type]);
uuid = getIdForElement(item);
if(uuid){
if(uuid.toString() == query.toString()){
found++;
[item select:true byExpandingSelection:true]
}
}
}
if (found) {
doc.displayMessage('Found (' + found + ') matches based on style, symbol.');
}
} else {
var type = [sel className],
props = getProps(sel),
layer = null,
layerProps = null;
if (!props) {
doc.displayMessage('Sorry, unable to get properties for selection');
}
for (var i=0; i < [all_layers count]; i++) {
layer = all_layers[i];
if (layer != sel && [layer className] == type) {
layerProps = getProps(layer);
if (layerProps.type == 'MSArtboardGroup') {
if (layerProps.name === props.name) {
[layer select:true byExpandingSelection:true];
found++;
}
} else if (layerProps
&& layerProps.fill == props.fill
&& layerProps.border == props.border
&& layerProps.borderThickness == props.borderThickness
&& layerProps.fontPostscriptName == props.fontPostscriptName
&& layerProps.fontSize == props.fontSize
&& layerProps.textColor == props.textColor
) {
[layer select:true byExpandingSelection:true];
found++;
}
}
}
if (found) {
doc.displayMessage('Found no style but found (' + found + ') matches based on border, fill and text and name');
}
}
} else {
[doc displayMessage:"You need to select one element"]
}
function getIdForElement (el){
var type = [el className], elementId, style_id, symbol_id;
if (type == "MSRectangleShape" || type == "MSSliceLayer" || type == "MSOvalShape" || type == "MSShapePathLayer" || type == "MSBitmapLayer" || type == "MSArtboardGroup" || type == "MSPage") {
return null
}
if(type == 'MSTextLayer') {
elementId = [[el style] sharedObjectID]
} else {
if (el.style) {
style_id = [[el style] sharedObjectID]
} else {
style_id = null
}
if (el.sharedObjectID) {
symbol_id = [el sharedObjectID]
} else {
symbol_id = null
}
elementId = style_id || symbol_id
}
return elementId;
}
function getProps (layer) {
var type = [layer className];
if (type == 'MSArtboardGroup') {
return {
'name': [layer name],
'type': [layer className]
}
}
if (!layer.style) {
return {
'fill': null,
'border': null,
'borderThickness' : null,
'fontPostscriptName': null,
'fontSize': null,
'textColor': null
};
}
var fill = layer.style().fills().firstObject(),
border = layer.style().borders().firstObject(),
isTextLayer = type == 'MSTextLayer';
return {
'name': [layer name],
'type': [layer className],
'fill': fill ? fill.color().hexValue().toString() : null,
'border': border ? border.color().hexValue().toString() : null,
'borderThickness': border ? border.thickness() : null,
'fontPostscriptName': isTextLayer ? [layer fontPostscriptName] : null,
'fontSize': isTextLayer ? [layer fontSize] : null,
'textColor': isTextLayer ? [layer textColor] : null
};
}
}())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment