publish select similar elements script

This commit is contained in:
zsviczian
2023-08-05 23:33:59 +02:00
parent d89d35e420
commit fa918e1c76
4 changed files with 213 additions and 1 deletions

View File

@@ -0,0 +1,204 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-select-similar-elements.png)
This script allows users to streamline their Obsidian-Excalidraw workflows by enabling the selection of elements based on similar properties. Users can precisely define which attributes such as stroke color, fill style, font family, and more, should match for selection. It's perfect for large canvases where manual selection would be cumbersome. Users can either run the script to find and select matching elements across the entire scene, or define a specific group of elements to apply the selection criteria within a defined timeframe. This script enhances control and efficiency in your Excalidraw experience.
```js */
let config = window.ExcalidrawSelectConfig;
config = config && (Date.now() - config.timestamp < 60000) ? config : null;
let elements = ea.getViewSelectedElements();
if(!config && (elements.length !==1)) {
new Notice("Select a single element");
return;
} else {
if(elements.length === 0) {
elements = ea.getViewElements();
}
}
const {angle, backgroundColor, fillStyle, fontFamily, fontSize, height, width, opacity, roughness, roundness, strokeColor, strokeStyle, strokeWidth, type, startArrowhead, endArrowhead} = ea.getViewSelectedElement();
const fragWithHTML = (html) => createFragment((frag) => (frag.createDiv().innerHTML = html));
//--------------------------
// RUN
//--------------------------
const run = () => {
selectedElements = ea.getViewElements().filter(el=>
((typeof config.angle === "undefined") || (el.angle === config.angle)) &&
((typeof config.backgroundColor === "undefined") || (el.backgroundColor === config.backgroundColor)) &&
((typeof config.fillStyle === "undefined") || (el.fillStyle === config.fillStyle)) &&
((typeof config.fontFamily === "undefined") || (el.fontFamily === config.fontFamily)) &&
((typeof config.fontSize === "undefined") || (el.fontSize === config.fontSize)) &&
((typeof config.height === "undefined") || Math.abs(el.height - config.height) < 0.01) &&
((typeof config.width === "undefined") || Math.abs(el.width - config.width) < 0.01) &&
((typeof config.opacity === "undefined") || (el.opacity === config.opacity)) &&
((typeof config.roughness === "undefined") || (el.roughness === config.roughness)) &&
((typeof config.roundness === "undefined") || (el.roundness === config.roundness)) &&
((typeof config.strokeColor === "undefined") || (el.strokeColor === config.strokeColor)) &&
((typeof config.strokeStyle === "undefined") || (el.strokeStyle === config.strokeStyle)) &&
((typeof config.strokeWidth === "undefined") || (el.strokeWidth === config.strokeWidth)) &&
((typeof config.type === "undefined") || (el.type === config.type)) &&
((typeof config.startArrowhead === "undefined") || (el.startArrowhead === config.startArrowhead)) &&
((typeof config.endArrowhead === "undefined") || (el.endArrowhead === config.endArrowhead))
)
ea.selectElementsInView(selectedElements);
delete window.ExcalidrawSelectConfig;
}
//--------------------------
// Modal
//--------------------------
const showInstructions = () => {
const instructionsModal = new ea.obsidian.Modal(app);
instructionsModal.onOpen = () => {
instructionsModal.contentEl.createEl("h2", {text: "Instructions"});
instructionsModal.contentEl.createEl("p", {text: "Step 1: Choose the attributes that you want the selected elements to match."});
instructionsModal.contentEl.createEl("p", {text: "Step 2: Select an action:"});
instructionsModal.contentEl.createEl("ul", {}, el => {
el.createEl("li", {text: "Click 'RUN' to find matching elements throughout the entire scene."});
el.createEl("li", {text: "Click 'SELECT' to first choose a specific group of elements. Then run the 'Select Similar Elements' script once more on that group within 1 minute."});
});
instructionsModal.contentEl.createEl("p", {text: "Note: If you choose 'SELECT', make sure to click the 'Select Similar Elements' script again within 1 minute to apply your selection criteria to the group of elements you chose."});
};
instructionsModal.open();
};
const selectAttributesToCopy = () => {
const configModal = new ea.obsidian.Modal(app);
configModal.onOpen = () => {
config = {};
configModal.contentEl.createEl("h1", {text: "Select Similar Elements"});
new ea.obsidian.Setting(configModal.contentEl)
.setDesc("Choose the attributes you want the selected elements to match, then select an action.")
.addButton(button => button
.setButtonText("Instructions")
.onClick(showInstructions)
);
// Add Toggles for the rest of the attributes
let attributes = [
{name: "Element type", key: "type"},
{name: "Stroke color", key: "strokeColor"},
{name: "Background color", key: "backgroundColor"},
{name: "Opacity", key: "opacity"},
{name: "Fill style", key: "fillStyle"},
{name: "Stroke style", key: "strokeStyle"},
{name: "Stroke width", key: "strokeWidth"},
{name: "Roughness", key: "roughness"},
{name: "Roundness", key: "roundness"},
{name: "Font family", key: "fontFamily"},
{name: "Font size", key: "fontSize"},
{name: "Start arrowhead", key: "startArrowhead"},
{name: "End arrowhead", key: "endArrowhead"},
{name: "Height", key: "height"},
{name: "Width", key: "width"},
];
attributes.forEach(attr => {
const attrValue = elements[0][attr.key];
if(attrValue || (attr.key === "startArrowhead" && elements[0].type === "arrow") || (attr.key === "endArrowhead" && elements[0].type === "arrow")) {
let description = '';
switch(attr.key) {
case 'backgroundColor':
case 'strokeColor':
description = `<div style='background-color:${attrValue};'>${attrValue}</div>`;
break;
case 'roundness':
description = attrValue === null ? 'Sharp' : 'Round';
break;
case 'roughness':
description = attrValue === 0 ? 'Architect' : attrValue === 1 ? 'Artist' : 'Cartoonist';
break;
case 'strokeWidth':
description = attrValue <= 0.5 ? 'Extra thin' :
attrValue <= 1 ? 'Thin' :
attrValue <= 2 ? 'Bold' :
'Extra bold';
break;
case 'opacity':
description = `${attrValue}%`;
break;
case 'width':
case 'height':
description = `${attrValue.toFixed(2)}`;
break;
case 'startArrowhead':
case 'endArrowhead':
description = attrValue === null ? 'None' : `${attrValue.charAt(0).toUpperCase() + attrValue.slice(1)}`;
break;
case 'fontFamily':
description = attrValue === 1 ? 'Hand-drawn' :
attrValue === 2 ? 'Normal' :
attrValue === 3 ? 'Code' :
'Custom 4th font';
break;
case 'fontSize':
description = `${attrValue}`;
break;
default:
console.log(attr.key);
console.log(attrValue);
description = `${attrValue.charAt(0).toUpperCase() + attrValue.slice(1)}`;
break;
}
new ea.obsidian.Setting(configModal.contentEl)
.setName(`${attr.name}`)
.setDesc(fragWithHTML(`${description}`))
.addToggle(toggle => toggle
.setValue(false)
.onChange(value => {
if(value) {
config[attr.key] = attrValue;
} else {
delete config[attr.key];
}
})
)
}
});
//Add Toggle for the rest of the attirbutes. Organize attributes into a logical sequence or groups by adding
//configModal.contentEl.createEl("h") or similar to the code
new ea.obsidian.Setting(configModal.contentEl)
.addButton(button => button
.setButtonText("SELECT")
.onClick(()=>{
config.timestamp = Date.now();
window.ExcalidrawSelectConfig = config;
configModal.close();
})
)
.addButton(button => button
.setButtonText("RUN")
.setCta(true)
.onClick(()=>{
elements = ea.getViewElements();
run();
configModal.close();
})
)
}
configModal.onClose = () => {
setTimeout(()=>delete configModal);
}
configModal.open();
}
if(config) {
run();
} else {
selectAttributesToCopy();
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-filter"><polygon fill="none" stroke-width="2" points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></svg>

After

Width:  |  Height:  |  Size: 285 B

File diff suppressed because one or more lines are too long

View File

@@ -75,6 +75,7 @@ I would love to include your contribution in the script library. If you have a s
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Reverse%20arrows.svg"/></div>|[[#Reverse arrows]]|
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Scribble%20Helper.svg"/></div>|[[#Scribble Helper]]|
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Select%20Elements%20of%20Type.svg"/></div>|[[#Select Elements of Type]]|
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Select%20Similar%20Elements.svg"/></div>|[[#Select Similar Elements]]|
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Set%20background%20color%20of%20unclosed%20line%20object%20by%20adding%20a%20shadow%20clone.svg"/></div>|[[#Set background color of unclosed line object by adding a shadow clone]]|
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Set%20Dimensions.svg"/></div>|[[#Set Dimensions]]|
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Set%20Font%20Family.svg"/></div>|[[#Set Font Family]]|
@@ -378,6 +379,12 @@ https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea
```
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/zsviczian'>@zsviczian</a></td></tr><tr valign='top'><td class="label">Source</td><td class="data"><a href='https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/master/ea-scripts/Select%20Elements%20of%20Type.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">Prompts you with a list of the different element types in the active image. Only elements of the selected type will be selected on the canvas. If nothing is selected when running the script, then the script will process all the elements on the canvas. If some elements are selected when the script is executed, then the script will only process the selected elements.<br>The script is useful when, for example, you want to bring to front all the arrows, or want to change the color of all the text elements, etc.<br><img src='https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-select-element-of-type.jpg'></td></tr></table>
## Select Similar Elements
```excalidraw-script-install
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Select%20Similar%20Elements.md
```
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/zsviczian'>@zsviczian</a></td></tr><tr valign='top'><td class="label">Source</td><td class="data"><a href='https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/master/ea-scripts/Select%20Similar%20Elements.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">This script allows you to streamline your Obsidian-Excalidraw workflows by enabling the selection of elements based on similar properties. you can precisely define which attributes such as stroke color, fill style, font family, and more, should match for selection. It's perfect for large canvases where manual selection would be cumbersome. You can either run the script to find and select matching elements across the entire scene, or define a specific group of elements to apply the selection criteria within a defined timeframe. This script enhances control and efficiency in your Excalidraw experience.<br><img src='https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-select-similar-elements.png'></td></tr></table>
## Set background color of unclosed line object by adding a shadow clone
```excalidraw-script-install
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Set%20background%20color%20of%20unclosed%20line%20object%20by%20adding%20a%20shadow%20clone.md