diff --git a/ea-scripts/Deconstruct selected elements into new drawing.md b/ea-scripts/Deconstruct selected elements into new drawing.md
index 4653e66..0cf4f38 100644
--- a/ea-scripts/Deconstruct selected elements into new drawing.md
+++ b/ea-scripts/Deconstruct selected elements into new drawing.md
@@ -9,7 +9,7 @@ Select some elements in the scene. The script will take these elements and move
```javascript
*/
-if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("2.0.25")) {
+if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("2.7.3")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
@@ -81,6 +81,7 @@ ea.getElements().filter(el=>el.type==="image").forEach(el=>{
const path = (img?.linkParts?.original)??(img?.file?.path);
const hyperlink = img?.hyperlink;
if(img && (path || hyperlink)) {
+ const colorMap = ea.getColorMapForImageElement(el);
ea.imagesDict[el.fileId] = {
mimeType: img.mimeType,
id: el.fileId,
@@ -90,6 +91,7 @@ ea.getElements().filter(el=>el.type==="image").forEach(el=>{
hyperlink,
hasSVGwithBitmap: img.isSVGwithBitmap,
latex: null,
+ colorMap,
};
return;
}
diff --git a/ea-scripts/Shade Master.md b/ea-scripts/Shade Master.md
index 6513dbf..291029d 100644
--- a/ea-scripts/Shade Master.md
+++ b/ea-scripts/Shade Master.md
@@ -10,17 +10,25 @@ If you select only a single SVG or nested Excalidraw element, then the script of
```js*/
const HELP_TEXT = `
-- Select SVG images, nested Excalidraw drawings and/or regular Excalidraw elements
-- For a single selected image, you can map colors individually in the color mapping section
-- For Excalidraw elements: stroke and background colors are modified permanently
-- For SVG/nested drawings: original files stay unchanged, color mapping is stored under \`## Embedded Files\`
-- Using color maps helps maintain links between drawings while allowing different color themes
-- Sliders work on relative scale - the amount of change is applied to current values
-- Unlike Excalidraw's opacity setting which affects the whole element:
- - Shade Master can set different opacity for stroke vs background
- - Note: SVG/nested drawing colors are mapped at color name level, thus "black" is different from "#000000"
- - Additionally if the same color is used as fill and stroke the color can only be changed once
-- This is an experimental script - contributions welcome on GitHub via PRs
+
+
Select SVG images, nested Excalidraw drawings and/or regular Excalidraw elements
+
For a single selected image, you can map colors individually in the color mapping section
+
For Excalidraw elements: stroke and background colors are modified permanently
+
For SVG/nested drawings: original files stay unchanged, color mapping is stored under ## Embedded Files
+
Using color maps helps maintain links between drawings while allowing different color themes
+
Sliders work on relative scale - the amount of change is applied to current values
+
Unlike Excalidraw's opacity setting which affects the whole element:
+
+
Shade Master can set different opacity for stroke vs background
+
Note: SVG/nested drawing colors are mapped at color name level, thus "black" is different from "#000000"
+
Additionally if the same color is used as fill and stroke the color can only be mapped once
+
+
+
This is an experimental script - contributions welcome on GitHub via PRs
+
+
+
+
`;
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("2.7.3")) {
@@ -46,6 +54,7 @@ interface ColorMap {
// Main script execution
const allElements = ea.getViewSelectedElements();
const svgImageElements = allElements.filter(el => {
+ if(el.type !== "image") return false;
const file = ea.getViewFileForImageElement(el);
if(!file) return false;
return el.type === "image" && (
@@ -60,6 +69,7 @@ if(allElements.length === 0) {
}
const originalColors = new Map();
+const currentColors = new Map();
const colorInputs = new Map();
const sliderResetters = [];
let terminate = false;
@@ -67,6 +77,10 @@ const FORMAT = "Color Format";
const STROKE = "Modify Stroke Color";
const BACKGROUND = "Modify Background Color"
const ACTIONS = ["Hue", "Lightness", "Saturation", "Transparency"];
+const precision = [1,2,2,3];
+const minLigtness = 1/Math.pow(10,precision[2]);
+const maxLightness = 100 - minLigtness;
+const minSaturation = 1/Math.pow(10,precision[2]);
let settings = ea.getScriptSettings();
//set default values on first run
@@ -126,11 +140,23 @@ async function storeOriginalColors() {
for (const [color, info] of colorInfo.entries()) {
svgColors.set(color, {...info});
}
- const svgColorData = {
- type: "svg",
- colors: svgColors
- };
- originalColors.set(el.id, svgColorData);
+
+ originalColors.set(el.id, {type: "svg",colors: svgColors});
+ }
+ copyOriginalsToCurrent();
+}
+
+function copyOriginalsToCurrent() {
+ for (const [key, value] of originalColors.entries()) {
+ if(value.type === "regular") {
+ currentColors.set(key, {...value});
+ } else {
+ const newColorMap = new Map();
+ for (const [color, info] of value.colors.entries()) {
+ newColorMap.set(color, {...info});
+ }
+ currentColors.set(key, {type: "svg", colors: newColorMap});
+ }
}
}
@@ -142,45 +168,36 @@ function clearSVGMapping() {
if (svgImageElements.length === 1) {
const el = svgImageElements[0];
const original = originalColors.get(el.id);
+ const current = currentColors.get(el.id);
if (original && original.type === "svg") {
for (const color of original.colors.keys()) {
- // Update UI components
- const inputs = colorInputs.get(color);
- if (inputs) {
- if(color === "fill") {
- //stroke is a special value in case the SVG has no fill color defined (i.e black)
- inputs.textInput.setValue("black");
- inputs.colorPicker.setValue("#000000");
- } else {
- const cm = ea.getCM(color);
- inputs.textInput.setValue(color);
- inputs.colorPicker.setValue(cm.stringHEX({alpha: false}).toLowerCase());
- }
- }
+ current.colors.get(color).mappedTo = color;
}
- updatedImageElementColorMaps.set(el, {});
}
} else {
for (const el of svgImageElements) {
- updatedImageElementColorMaps.set(el, {});
+ const original = originalColors.get(el.id);
+ const current = currentColors.get(el.id);
+ if (original && original.type === "svg") {
+ for (const color of original.colors.keys()) {
+ current.colors.get(color).mappedTo = color;
+ }
+ }
}
}
- updateViewImageColors();
+ run("clear");
}
-// Function to reset colors
-async function resetColors() {
- for (const resetter of sliderResetters) {
- resetter();
- }
-
+// Set colors
+async function setColors(colors) {
+ debounceColorPicker = true;
const regularElements = getRegularElements();
if (regularElements.length > 0) {
ea.copyViewElementsToEAforEditing(regularElements);
for (const el of ea.getElements()) {
- const original = originalColors.get(el.id);
+ const original = colors.get(el.id);
if (original && original.type === "regular") {
if (original.strokeColor) el.strokeColor = original.strokeColor;
if (original.backgroundColor) el.backgroundColor = original.backgroundColor;
@@ -192,7 +209,7 @@ async function resetColors() {
// Reset SVG elements
if (svgImageElements.length === 1) {
const el = svgImageElements[0];
- const original = originalColors.get(el.id);
+ const original = colors.get(el.id);
if (original && original.type === "svg") {
const newColorMap = {};
@@ -201,16 +218,23 @@ async function resetColors() {
// Update UI components
const inputs = colorInputs.get(color);
if (inputs) {
- const cm = ea.getCM(info.mappedTo);
- inputs.textInput.setValue(info.mappedTo);
- inputs.colorPicker.setValue(cm.stringHEX({alpha: false}).toLowerCase());
+ if(info.mappedTo === "fill") {
+ info.mappedTo = "black";
+ //"fill" is a special value in case the SVG has no fill color defined (i.e black)
+ inputs.textInput.setValue("black");
+ inputs.colorPicker.setValue("#000000");
+ } else {
+ const cm = ea.getCM(info.mappedTo);
+ inputs.textInput.setValue(info.mappedTo);
+ inputs.colorPicker.setValue(cm.stringHEX({alpha: false}).toLowerCase());
+ }
}
}
updatedImageElementColorMaps.set(el, newColorMap);
}
} else {
for (const el of svgImageElements) {
- const original = originalColors.get(el.id);
+ const original = colors.get(el.id);
if (original && original.type === "svg") {
const newColorMap = {};
@@ -231,10 +255,20 @@ function modifyColor(color, isDecrease, step, action) {
if (!cm) return color;
let modified = cm;
+ if (modified.lightness === 0) modified = modified.lightnessTo(minLigtness);
+ if (modified.lightness === 100) modified = modified.lightnessTo(maxLightness);
+ if (modified.saturation === 0) modified = modified.saturationTo(minSaturation);
switch(action) {
case "Lightness":
- modified = isDecrease ? modified.darkerBy(step) : modified.lighterBy(step);
+ // handles edge cases where lightness is 0 or 100 would convert saturation and hue to 0
+ let lightness = cm.lightness;
+ const shouldRoundLight = (lightness === minLigtness || lightness === maxLightness);
+ if (shouldRoundLight) lightness = Math.round(lightness);
+ lightness += isDecrease ? -step : step;
+ if (lightness <= 0) lightness = minLigtness;
+ if (lightness >= 100) lightness = maxLightness;
+ modified = modified.lightnessTo(lightness);
break;
case "Hue":
modified = isDecrease ? modified.hueBy(-step) : modified.hueBy(step);
@@ -243,11 +277,16 @@ function modifyColor(color, isDecrease, step, action) {
modified = isDecrease ? modified.alphaBy(-step) : modified.alphaBy(step);
break;
default:
- modified = isDecrease ? modified.desaturateBy(step) : modified.saturateBy(step);
+ let saturation = cm.saturation;
+ const shouldRoundSat = saturation === minSaturation;
+ if (shouldRoundSat) saturation = Math.round(saturation);
+ saturation += isDecrease ? -step : step;
+ if (saturation <= 0) saturation = minSaturation;
+ modified = modified.saturationTo(saturation);
}
const hasAlpha = modified.alpha < 1;
- const opts = { alpha: hasAlpha, precision: [1,2,2,3] };
+ const opts = { alpha: hasAlpha, precision };
const format = settings[FORMAT].value;
switch(format) {
@@ -274,7 +313,7 @@ function slider(contentEl, action, min, max, step, invert) {
const step = Math.abs(value-prevValue);
prevValue = value;
if(step>0) {
- run(isDecrease, step, action);
+ run(action, isDecrease, step);
}
});
}
@@ -300,12 +339,12 @@ function showModal() {
const helpDiv = contentEl.createEl("details", {
attr: { style: "margin-bottom: 1em;background: var(--background-secondary); padding: 1em; border-radius: 4px;" }});
helpDiv.createEl("summary", { text: "Help & Usage Guide", attr: { style: "cursor: pointer; color: var(--text-accent);" } });
- helpDiv.createEl("div", {
- text: HELP_TEXT,
- attr: { style: "margin-top: 0.5em; white-space: pre-wrap;" }
+ const helpDetailsDiv = helpDiv.createEl("div", {
+ attr: { style: "margin-top: 0em; " }
});
+ helpDetailsDiv.innerHTML = HELP_TEXT;
- new ea.obsidian.Setting(contentEl)
+ const component = new ea.obsidian.Setting(contentEl)
.setName(FORMAT)
.setDesc("Output color format")
.addDropdown(dropdown => dropdown
@@ -317,6 +356,7 @@ function showModal() {
.setValue(settings[FORMAT].value)
.onChange(value => {
settings[FORMAT].value = value;
+ run();
dirty = true;
})
);
@@ -341,9 +381,17 @@ function showModal() {
})
);
- sliderResetters.push(slider(contentEl, "Hue", 0, 400, 1, false));
+ // lightness and saturation are on a scale of 0%-100%
+ // Hue is in degrees, 360 for the full circle
+ // transparency is on a range between 0 and 1 (equivalent to 0%-100%)
+ // The range for lightness, saturation and transparency are double since
+ // the input could be at either end of the scale
+ // The range for Hue is 360 since regarless of the position on the circle moving
+ // the slider to the two extremes will travel the entire circle
+ // To modify blacks and whites, lightness first needs to be changed to value between 1% and 99%
+ sliderResetters.push(slider(contentEl, "Hue", 0, 360, 1, false));
sliderResetters.push(slider(contentEl, "Saturation", 0, 200, 1, false));
- sliderResetters.push(slider(contentEl, "Lightness", 0, 100, 1, false));
+ sliderResetters.push(slider(contentEl, "Lightness", 0, 200, 1, false));
sliderResetters.push(slider(contentEl, "Transparency", 0, 2, 0.05, true));
// Add color pickers if a single SVG image is selected
@@ -358,10 +406,12 @@ function showModal() {
const row = new ea.obsidian.Setting(colorSection)
.setName(color === "fill" ? "SVG default" : color)
.setDesc(`${info.fill ? "Fill" : ""}${info.fill && info.stroke ? " & " : ""}${info.stroke ? "Stroke" : ""}`);
-
+ row.descEl.style.width = "100px";
+ row.nameEl.style.width = "100px";
+
// Create color preview div
const previewDiv = row.controlEl.createDiv();
- previewDiv.style.width = "30px";
+ previewDiv.style.width = "50px";
previewDiv.style.height = "20px";
previewDiv.style.border = "1px solid var(--background-modifier-border)";
if (color === "transparent") {
@@ -378,22 +428,13 @@ function showModal() {
.setClass("reset-color-button")
.onClick(async () => {
const original = originalColors.get(svgElement.id);
+ const current = currentColors.get(svgElement.id);
if (original?.type === "svg") {
const originalInfo = original.colors.get(color);
+ const currentInfo = current.colors.get(color);
if (originalInfo) {
- const newColorMap = await ea.getColorMapForImageElement(svgElement);
- delete newColorMap[color];
- updatedImageElementColorMaps.set(svgElement, newColorMap);
- updateViewImageColors();
-
- // Update UI components
- debounceColorPicker = true;
- textInput.setValue(color === "fill" ? "black" : color);
- colorPicker.setValue(color === "fill"
- ? "#000000"
- : ea.getCM(color).stringHEX({alpha: false}).toLowerCase()
- );
- updateViewImageColors();
+ currentInfo.mappedTo = color;
+ run("reset single color");
}
}
}))
@@ -404,7 +445,7 @@ function showModal() {
const textInput = new ea.obsidian.TextComponent(row.controlEl)
.setValue(info.mappedTo)
.setPlaceholder("Color value");
- textInput.inputEl.style.width = "120px";
+ textInput.inputEl.style.width = "100%";
textInput.onChange(value => {
const lower = value.toLowerCase();
if (lower === color) return;
@@ -427,19 +468,15 @@ function showModal() {
const format = settings[FORMAT].value;
const alpha = cm.alpha < 1 ? true : false;
const newColor = format === "RGB"
- ? cm.stringRGB({alpha , precision: [1,2,2,3]}).toLowerCase()
+ ? cm.stringRGB({alpha , precision }).toLowerCase()
: format === "HEX"
? cm.stringHEX({alpha}).toLowerCase()
- : cm.stringHSL({alpha, precision: [1,2,2,3]}).toLowerCase();
-
- const newColorMap = await ea.getColorMapForImageElement(svgElement);
- if(color === newColor) {
- delete newColorMap[color];
- } else {
- newColorMap[color] = newColor;
- }
- updatedImageElementColorMaps.set(svgElement, newColorMap);
- updateViewImageColors();
+ : cm.stringHSL({alpha, precision }).toLowerCase();
+
+ textInput.setValue(newColor);
+ const colorInfo = currentColors.get(svgElement.id).colors;
+ colorInfo.get(color).mappedTo = newColor;
+ run("no action");
debounceColorPicker = true;
colorPicker.setValue(cm.stringHEX({alpha: false}).toLowerCase());
}
@@ -476,10 +513,10 @@ function showModal() {
const alpha = originalAlpha < 1 ? true : false;
const format = settings[FORMAT].value;
const newColor = format === "RGB"
- ? cm.stringRGB({alpha, precision: [1,2,2,3]}).toLowerCase()
+ ? cm.stringRGB({alpha, precision }).toLowerCase()
: format === "HEX"
? cm.stringHEX({alpha}).toLowerCase()
- : cm.stringHSL({alpha, precision: [1,2,2,3]}).toLowerCase();
+ : cm.stringHSL({alpha, precision }).toLowerCase();
// Update text input
textInput.setValue(newColor);
@@ -518,8 +555,11 @@ function showModal() {
.addButton(button => button
.setButtonText("Reset")
.onClick(() => {
- debounceColorPicker = true;
- resetColors();
+ for (const resetter of sliderResetters) {
+ resetter();
+ }
+ copyOriginalsToCurrent();
+ setColors(originalColors);
}))
.addButton(button => button
.setButtonText("Close")
@@ -596,101 +636,86 @@ function makeModalDraggable(modalEl) {
});
}
-async function executeChange(isDecrease, step, action) {
- try {
- isRunning = true;
- const modifyStroke = settings[STROKE].value;
- const modifyBackground = settings[BACKGROUND].value;
- const regularElements = getRegularElements();
+function executeChange(isDecrease, step, action) {
+ const modifyStroke = settings[STROKE].value;
+ const modifyBackground = settings[BACKGROUND].value;
+ const regularElements = getRegularElements();
- // Process regular elements
- if (regularElements.length > 0) {
- ea.copyViewElementsToEAforEditing(regularElements);
- for (const el of ea.getElements()) {
- if (modifyStroke && el.strokeColor) {
- el.strokeColor = modifyColor(el.strokeColor, isDecrease, step, action);
- }
-
- if (modifyBackground && el.backgroundColor) {
- el.backgroundColor = modifyColor(el.backgroundColor, isDecrease, step, action);
- }
+ // Process regular elements
+ if (regularElements.length > 0) {
+ for (const el of regularElements) {
+ const currentColor = currentColors.get(el.id);
+
+ if (modifyStroke && currentColor.strokeColor) {
+ currentColor.strokeColor = modifyColor(el.strokeColor, isDecrease, step, action);
}
- await ea.addElementsToView(false, false);
- }
-
- // Process SVG image elements
- if (svgImageElements.length === 1) { // Only update UI for single SVG
- const el = svgImageElements[0];
- const colorInfo = await ea.getSVGColorInfoForImgElement(el);
- const newColorMap = {};
-
- // Process each color in the SVG
- for (const [color, info] of colorInfo.entries()) {
- let shouldModify = (modifyBackground && info.fill) || (modifyStroke && info.stroke);
-
- if (shouldModify) {
- const modifiedColor = modifyColor(info.mappedTo, isDecrease, step, action);
- if (modifiedColor !== color) {
- newColorMap[color] = modifiedColor;
- }
- // Update UI components if they exist
- const inputs = colorInputs.get(color);
- if (inputs) {
- const cm = ea.getCM(modifiedColor);
- inputs.textInput.setValue(modifiedColor);
- inputs.colorPicker.setValue(cm.stringHEX({alpha: false}).toLowerCase());
- }
- }
- }
- updatedImageElementColorMaps.set(el, newColorMap);
- } else {
- if (svgImageElements.length > 0) {
- for (const el of svgImageElements) {
- const colorInfo = await ea.getSVGColorInfoForImgElement(el);
- const newColorMap = {};
- // Process each color in the SVG
- for (const [color, info] of colorInfo.entries()) {
- let shouldModify = (modifyBackground && info.fill) || (modifyStroke && info.stroke);
-
- if (shouldModify) {
- const modifiedColor = modifyColor(info.mappedTo, isDecrease, step, action);
- if (modifiedColor !== color) {
- newColorMap[color] = modifiedColor;
- }
- }
- }
- updatedImageElementColorMaps.set(el, newColorMap);
+ if (modifyBackground && currentColor.backgroundColor) {
+ currentColor.backgroundColor = modifyColor(el.backgroundColor, isDecrease, step, action);
+ }
+ }
+ }
+
+ // Process SVG image elements
+ if (svgImageElements.length === 1) { // Only update UI for single SVG
+ const el = svgImageElements[0];
+ colorInfo = currentColors.get(el.id).colors;
+
+ // Process each color in the SVG
+ for (const [color, info] of colorInfo.entries()) {
+ let shouldModify = (modifyBackground && info.fill) || (modifyStroke && info.stroke);
+
+ if (shouldModify) {
+ const modifiedColor = modifyColor(info.mappedTo, isDecrease, step, action);
+ colorInfo.get(color).mappedTo = modifiedColor;
+ // Update UI components if they exist
+ const inputs = colorInputs.get(color);
+ if (inputs) {
+ const cm = ea.getCM(modifiedColor);
+ inputs.textInput.setValue(modifiedColor);
+ inputs.colorPicker.setValue(cm.stringHEX({alpha: false}).toLowerCase());
+ }
+ }
+ }
+ } else {
+ if (svgImageElements.length > 0) {
+ for (const el of svgImageElements) {
+ const colorInfo = currentColors.get(el.id).colors;
+
+ // Process each color in the SVG
+ for (const [color, info] of colorInfo.entries()) {
+ let shouldModify = (modifyBackground && info.fill) || (modifyStroke && info.stroke);
+
+ if (shouldModify) {
+ const modifiedColor = modifyColor(info.mappedTo, isDecrease, step, action);
+ colorInfo.get(color).mappedTo = modifiedColor;
+ }
}
}
}
- } catch (e) {
- new Notice("Error in executeChange. See developer console for details");
- console.error("Error in executeChange:", e);
- } finally {
- isRunning = false;
}
}
-isRunning = false;
-const queue = [];
+let isRunning = false;
+let queue = false;
function processQueue() {
- if (!terminate && !isRunning && queue.length > 0) {
- const [isDecrease, step, action] = queue.shift();
- executeChange(isDecrease, step, action).then(() => {
- updateViewImageColors()
- if (queue.length > 0) processQueue();
+ if (!terminate && !isRunning && queue) {
+ queue = false;
+ isRunning = true;
+ setColors(currentColors).then(() => {
+ isRunning = false;
+ if (queue) processQueue();
});
}
}
-const MAX_QUEUE_SIZE = 100;
-function run(isDecrease, step, action) {
- if (queue.length >= MAX_QUEUE_SIZE) {
- new Notice ("Queue overflow. Dropping task.");
- return;
+function run(action="Hue", isDecrease=true, step=0) {
+ // passing invalid action (such as "clear") will bypass rewriting of colors using CM
+ // this is useful when resetting colors to original values
+ if(ACTIONS.includes(action)) {
+ executeChange(isDecrease, step, action);
}
- queue.push([isDecrease, step, action]);
+ queue = true;
if (!isRunning) processQueue();
}
diff --git a/ea-scripts/directory-info.json b/ea-scripts/directory-info.json
index 917da7b..a52d6d4 100644
--- a/ea-scripts/directory-info.json
+++ b/ea-scripts/directory-info.json
@@ -1 +1 @@
-[{"fname":"Mindmap connector.md","mtime":1658686599427},{"fname":"Mindmap connector.svg","mtime":1658686599427},{"fname":"Add Connector Point.md","mtime":1645305706000},{"fname":"Add Connector Point.svg","mtime":1645944722000},{"fname":"Add Link to Existing File and Open.md","mtime":1647807918345},{"fname":"Add Link to Existing File and Open.svg","mtime":1645964261000},{"fname":"Add Link to New Page and Open.md","mtime":1654168862138},{"fname":"Add Link to New Page and Open.svg","mtime":1645960639000},{"fname":"Add Next Step in Process.md","mtime":1688304760357},{"fname":"Add Next Step in Process.svg","mtime":1645960639000},{"fname":"Box Each Selected Groups.md","mtime":1645305706000},{"fname":"Box Each Selected Groups.svg","mtime":1645967510000},{"fname":"Box Selected Elements.md","mtime":1645305706000},{"fname":"Box Selected Elements.svg","mtime":1645960639000},{"fname":"Change shape of selected elements.md","mtime":1652701169236},{"fname":"Change shape of selected elements.svg","mtime":1645960775000},{"fname":"Connect elements.md","mtime":1645305706000},{"fname":"Connect elements.svg","mtime":1645960639000},{"fname":"Convert freedraw to line.md","mtime":1645305706000},{"fname":"Convert freedraw to line.svg","mtime":1645960639000},{"fname":"Convert selected text elements to sticky notes.md","mtime":1670169501383},{"fname":"Convert selected text elements to sticky notes.svg","mtime":1645960639000},{"fname":"Convert text to link with folder and alias.md","mtime":1641639819000},{"fname":"Convert text to link with folder and alias.svg","mtime":1645960639000},{"fname":"Copy Selected Element Styles to Global.md","mtime":1642232088000},{"fname":"Copy Selected Element Styles to Global.svg","mtime":1645960639000},{"fname":"Create new markdown file and embed into active drawing.md","mtime":1640866935000},{"fname":"Create new markdown file and embed into active drawing.svg","mtime":1645960639000},{"fname":"Darken background color.md","mtime":1663059051059},{"fname":"Darken background color.svg","mtime":1645960639000},{"fname":"Elbow connectors.md","mtime":1671126911490},{"fname":"Elbow connectors.svg","mtime":1645960639000},{"fname":"Expand rectangles horizontally keep text centered.md","mtime":1646563692000},{"fname":"Expand rectangles horizontally keep text centered.svg","mtime":1645967510000},{"fname":"Expand rectangles horizontally.md","mtime":1644950235000},{"fname":"Expand rectangles horizontally.svg","mtime":1645967510000},{"fname":"Expand rectangles vertically keep text centered.md","mtime":1646563692000},{"fname":"Expand rectangles vertically keep text centered.svg","mtime":1645967510000},{"fname":"Expand rectangles vertically.md","mtime":1658686599427},{"fname":"Expand rectangles vertically.svg","mtime":1645967510000},{"fname":"Fixed horizontal distance between centers.md","mtime":1646743234000},{"fname":"Fixed horizontal distance between centers.svg","mtime":1645960639000},{"fname":"Fixed inner distance.md","mtime":1646743234000},{"fname":"Fixed inner distance.svg","mtime":1645960639000},{"fname":"Fixed spacing.md","mtime":1646743234000},{"fname":"Fixed spacing.svg","mtime":1645967510000},{"fname":"Fixed vertical distance between centers.md","mtime":1646743234000},{"fname":"Fixed vertical distance between centers.svg","mtime":1645967510000},{"fname":"Fixed vertical distance.md","mtime":1646743234000},{"fname":"Fixed vertical distance.svg","mtime":1645967510000},{"fname":"Lighten background color.md","mtime":1663059051059},{"fname":"Lighten background color.svg","mtime":1645959546000},{"fname":"Modify background color opacity.md","mtime":1644924415000},{"fname":"Modify background color opacity.svg","mtime":1645944722000},{"fname":"Normalize Selected Arrows.md","mtime":1670403743278},{"fname":"Normalize Selected Arrows.svg","mtime":1645960639000},{"fname":"Organic Line.md","mtime":1672920172531},{"fname":"Organic Line.svg","mtime":1645964261000},{"fname":"Organic Line Legacy.md","mtime":1690607372668},{"fname":"Organic Line Legacy.svg","mtime":1690607372668},{"fname":"README.md","mtime":1645175700000},{"fname":"Repeat Elements.md","mtime":1663059051059},{"fname":"Repeat Elements.svg","mtime":1645960639000},{"fname":"Reverse arrows.md","mtime":1645305706000},{"fname":"Reverse arrows.svg","mtime":1645960639000},{"fname":"Scribble Helper.md","mtime":1682228345043},{"fname":"Scribble Helper.svg","mtime":1645944722000},{"fname":"Select Elements of Type.md","mtime":1643464321000},{"fname":"Select Elements of Type.svg","mtime":1645960639000},{"fname":"Set Dimensions.md","mtime":1645305706000},{"fname":"Set Dimensions.svg","mtime":1645944722000},{"fname":"Set Font Family.md","mtime":1645305706000},{"fname":"Set Font Family.svg","mtime":1645944722000},{"fname":"Set Grid.md","mtime":1693725826368},{"fname":"Set Grid.svg","mtime":1645960639000},{"fname":"Set Link Alias.md","mtime":1645305706000},{"fname":"Set Link Alias.svg","mtime":1645960639000},{"fname":"Set Stroke Width of Selected Elements.md","mtime":1723788773662},{"fname":"Set Stroke Width of Selected Elements.svg","mtime":1645960639000},{"fname":"Set Text Alignment.md","mtime":1645305706000},{"fname":"Set Text Alignment.svg","mtime":1645960639000},{"fname":"Set background color of unclosed line object by adding a shadow clone.md","mtime":1681665030892},{"fname":"Set background color of unclosed line object by adding a shadow clone.svg","mtime":1645960639000},{"fname":"Split text by lines.md","mtime":1705160236797},{"fname":"Split text by lines.svg","mtime":1645944722000},{"fname":"Zoom to Fit Selected Elements.md","mtime":1640770602000},{"fname":"Zoom to Fit Selected Elements.svg","mtime":1645960639000},{"fname":"directory-info.json","mtime":1646583437000},{"fname":"index-new.md","mtime":1645986149000},{"fname":"index.md","mtime":1645175700000},{"fname":"Grid Selected Images.md","mtime":1701630797839},{"fname":"Grid Selected Images.svg","mtime":1649614401982},{"fname":"Palette loader.md","mtime":1686511890942},{"fname":"Palette loader.svg","mtime":1649614401982},{"fname":"Rename Image.md","mtime":1663678478785},{"fname":"Rename Image.svg","mtime":1663678478785},{"fname":"Text Arch.md","mtime":1705160236797},{"fname":"Text Arch.svg","mtime":1670403743278},{"fname":"Deconstruct selected elements into new drawing.md","mtime":1734769839046},{"fname":"Deconstruct selected elements into new drawing.svg","mtime":1668541145255},{"fname":"Slideshow.md","mtime":1734940475468},{"fname":"Slideshow.svg","mtime":1670017348333},{"fname":"Auto Layout.md","mtime":1670403743278},{"fname":"Auto Layout.svg","mtime":1670175947081},{"fname":"Uniform size.md","mtime":1670175947081},{"fname":"Uniform size.svg","mtime":1670175947081},{"fname":"Mindmap format.md","mtime":1684484694228},{"fname":"Mindmap format.svg","mtime":1674944958059},{"fname":"Text to Sticky Notes.md","mtime":1678537561724},{"fname":"Text to Sticky Notes.svg","mtime":1678537561724},{"fname":"Folder Note Core - Make Current Drawing a Folder.md","mtime":1678973697470},{"fname":"Folder Note Core - Make Current Drawing a Folder.svg","mtime":1678973697470},{"fname":"Invert colors.md","mtime":1708870608219},{"fname":"Invert colors.svg","mtime":1678973697470},{"fname":"PDF Page Text to Clipboard.md","mtime":1683984041712},{"fname":"PDF Page Text to Clipboard.svg","mtime":1680418321236},{"fname":"Excalidraw Collaboration Frame.md","mtime":1687881495985},{"fname":"Excalidraw Collaboration Frame.svg","mtime":1687881495985},{"fname":"Create DrawIO file.md","mtime":1688243858267},{"fname":"Create DrawIO file.svg","mtime":1688243858267},{"fname":"Ellipse Selected Elements.md","mtime":1690131476331},{"fname":"Ellipse Selected Elements.svg","mtime":1690131476331},{"fname":"Select Similar Elements.md","mtime":1734859973735},{"fname":"Select Similar Elements.svg","mtime":1691270949338},{"fname":"Toggle Grid.md","mtime":1692125382945},{"fname":"Toggle Grid.svg","mtime":1692124753386},{"fname":"Split Ellipse.md","mtime":1693134104356},{"fname":"Split Ellipse.svg","mtime":1693134104356},{"fname":"Text Aura.md","mtime":1693731979540},{"fname":"Text Aura.svg","mtime":1693731979540},{"fname":"Boolean Operations.md","mtime":1695746839537},{"fname":"Boolean Operations.svg","mtime":1695746839537},{"fname":"Concatenate lines.md","mtime":1696175301525},{"fname":"Concatenate lines.svg","mtime":1696175301525},{"fname":"GPT-Draw-a-UI.md","mtime":1703324727900},{"fname":"GPT-Draw-a-UI.svg","mtime":1700511998048},{"fname":"ExcaliAI.md","mtime":1722056859912},{"fname":"ExcaliAI.svg","mtime":1701011028767},{"fname":"Repeat Texts.md","mtime":1701969627758},{"fname":"Repeat Texts.svg","mtime":1701969627758},{"fname":"Relative Font Size Cycle.md","mtime":1701969627758},{"fname":"Relative Font Size Cycle.svg","mtime":1701969627758},{"fname":"Golden Ratio.md","mtime":1725174200469},{"fname":"Golden Ratio.svg","mtime":1702812404286},{"fname":"Crop Vintage Mask.md","mtime":1706565166174},{"fname":"Crop Vintage Mask.svg","mtime":1705836797730},{"fname":"Custom Zoom.md", "mtime": 1710424027192},{"fname":"Custom Zoom.svg", "mtime":1710424027192},{"fname":"Excalidraw Writing Machine.md", "mtime":1724677454036},{"fname":"Excalidraw Writing Machine.svg", "mtime":1724356709706},{"fname":"Reset LaTeX Size.md", "mtime":1725296010813},{"fname":"Reset LaTeX Size.svg", "mtime":1725296010813},{"fname":"Shade Master.md", "mtime":1735252821829},{"fname":"Shade Master.svg", "mtime":1735252821829}]
\ No newline at end of file
+[{"fname":"Mindmap connector.md","mtime":1658686599427},{"fname":"Mindmap connector.svg","mtime":1658686599427},{"fname":"Add Connector Point.md","mtime":1645305706000},{"fname":"Add Connector Point.svg","mtime":1645944722000},{"fname":"Add Link to Existing File and Open.md","mtime":1647807918345},{"fname":"Add Link to Existing File and Open.svg","mtime":1645964261000},{"fname":"Add Link to New Page and Open.md","mtime":1654168862138},{"fname":"Add Link to New Page and Open.svg","mtime":1645960639000},{"fname":"Add Next Step in Process.md","mtime":1688304760357},{"fname":"Add Next Step in Process.svg","mtime":1645960639000},{"fname":"Box Each Selected Groups.md","mtime":1645305706000},{"fname":"Box Each Selected Groups.svg","mtime":1645967510000},{"fname":"Box Selected Elements.md","mtime":1645305706000},{"fname":"Box Selected Elements.svg","mtime":1645960639000},{"fname":"Change shape of selected elements.md","mtime":1652701169236},{"fname":"Change shape of selected elements.svg","mtime":1645960775000},{"fname":"Connect elements.md","mtime":1645305706000},{"fname":"Connect elements.svg","mtime":1645960639000},{"fname":"Convert freedraw to line.md","mtime":1645305706000},{"fname":"Convert freedraw to line.svg","mtime":1645960639000},{"fname":"Convert selected text elements to sticky notes.md","mtime":1670169501383},{"fname":"Convert selected text elements to sticky notes.svg","mtime":1645960639000},{"fname":"Convert text to link with folder and alias.md","mtime":1641639819000},{"fname":"Convert text to link with folder and alias.svg","mtime":1645960639000},{"fname":"Copy Selected Element Styles to Global.md","mtime":1642232088000},{"fname":"Copy Selected Element Styles to Global.svg","mtime":1645960639000},{"fname":"Create new markdown file and embed into active drawing.md","mtime":1640866935000},{"fname":"Create new markdown file and embed into active drawing.svg","mtime":1645960639000},{"fname":"Darken background color.md","mtime":1663059051059},{"fname":"Darken background color.svg","mtime":1645960639000},{"fname":"Elbow connectors.md","mtime":1671126911490},{"fname":"Elbow connectors.svg","mtime":1645960639000},{"fname":"Expand rectangles horizontally keep text centered.md","mtime":1646563692000},{"fname":"Expand rectangles horizontally keep text centered.svg","mtime":1645967510000},{"fname":"Expand rectangles horizontally.md","mtime":1644950235000},{"fname":"Expand rectangles horizontally.svg","mtime":1645967510000},{"fname":"Expand rectangles vertically keep text centered.md","mtime":1646563692000},{"fname":"Expand rectangles vertically keep text centered.svg","mtime":1645967510000},{"fname":"Expand rectangles vertically.md","mtime":1658686599427},{"fname":"Expand rectangles vertically.svg","mtime":1645967510000},{"fname":"Fixed horizontal distance between centers.md","mtime":1646743234000},{"fname":"Fixed horizontal distance between centers.svg","mtime":1645960639000},{"fname":"Fixed inner distance.md","mtime":1646743234000},{"fname":"Fixed inner distance.svg","mtime":1645960639000},{"fname":"Fixed spacing.md","mtime":1646743234000},{"fname":"Fixed spacing.svg","mtime":1645967510000},{"fname":"Fixed vertical distance between centers.md","mtime":1646743234000},{"fname":"Fixed vertical distance between centers.svg","mtime":1645967510000},{"fname":"Fixed vertical distance.md","mtime":1646743234000},{"fname":"Fixed vertical distance.svg","mtime":1645967510000},{"fname":"Lighten background color.md","mtime":1663059051059},{"fname":"Lighten background color.svg","mtime":1645959546000},{"fname":"Modify background color opacity.md","mtime":1644924415000},{"fname":"Modify background color opacity.svg","mtime":1645944722000},{"fname":"Normalize Selected Arrows.md","mtime":1670403743278},{"fname":"Normalize Selected Arrows.svg","mtime":1645960639000},{"fname":"Organic Line.md","mtime":1672920172531},{"fname":"Organic Line.svg","mtime":1645964261000},{"fname":"Organic Line Legacy.md","mtime":1690607372668},{"fname":"Organic Line Legacy.svg","mtime":1690607372668},{"fname":"README.md","mtime":1645175700000},{"fname":"Repeat Elements.md","mtime":1663059051059},{"fname":"Repeat Elements.svg","mtime":1645960639000},{"fname":"Reverse arrows.md","mtime":1645305706000},{"fname":"Reverse arrows.svg","mtime":1645960639000},{"fname":"Scribble Helper.md","mtime":1682228345043},{"fname":"Scribble Helper.svg","mtime":1645944722000},{"fname":"Select Elements of Type.md","mtime":1643464321000},{"fname":"Select Elements of Type.svg","mtime":1645960639000},{"fname":"Set Dimensions.md","mtime":1645305706000},{"fname":"Set Dimensions.svg","mtime":1645944722000},{"fname":"Set Font Family.md","mtime":1645305706000},{"fname":"Set Font Family.svg","mtime":1645944722000},{"fname":"Set Grid.md","mtime":1693725826368},{"fname":"Set Grid.svg","mtime":1645960639000},{"fname":"Set Link Alias.md","mtime":1645305706000},{"fname":"Set Link Alias.svg","mtime":1645960639000},{"fname":"Set Stroke Width of Selected Elements.md","mtime":1723788773662},{"fname":"Set Stroke Width of Selected Elements.svg","mtime":1645960639000},{"fname":"Set Text Alignment.md","mtime":1645305706000},{"fname":"Set Text Alignment.svg","mtime":1645960639000},{"fname":"Set background color of unclosed line object by adding a shadow clone.md","mtime":1681665030892},{"fname":"Set background color of unclosed line object by adding a shadow clone.svg","mtime":1645960639000},{"fname":"Split text by lines.md","mtime":1705160236797},{"fname":"Split text by lines.svg","mtime":1645944722000},{"fname":"Zoom to Fit Selected Elements.md","mtime":1640770602000},{"fname":"Zoom to Fit Selected Elements.svg","mtime":1645960639000},{"fname":"directory-info.json","mtime":1646583437000},{"fname":"index-new.md","mtime":1645986149000},{"fname":"index.md","mtime":1645175700000},{"fname":"Grid Selected Images.md","mtime":1701630797839},{"fname":"Grid Selected Images.svg","mtime":1649614401982},{"fname":"Palette loader.md","mtime":1686511890942},{"fname":"Palette loader.svg","mtime":1649614401982},{"fname":"Rename Image.md","mtime":1663678478785},{"fname":"Rename Image.svg","mtime":1663678478785},{"fname":"Text Arch.md","mtime":1705160236797},{"fname":"Text Arch.svg","mtime":1670403743278},{"fname":"Deconstruct selected elements into new drawing.md","mtime":1735252821829},{"fname":"Deconstruct selected elements into new drawing.svg","mtime":1668541145255},{"fname":"Slideshow.md","mtime":1734940475468},{"fname":"Slideshow.svg","mtime":1670017348333},{"fname":"Auto Layout.md","mtime":1670403743278},{"fname":"Auto Layout.svg","mtime":1670175947081},{"fname":"Uniform size.md","mtime":1670175947081},{"fname":"Uniform size.svg","mtime":1670175947081},{"fname":"Mindmap format.md","mtime":1684484694228},{"fname":"Mindmap format.svg","mtime":1674944958059},{"fname":"Text to Sticky Notes.md","mtime":1678537561724},{"fname":"Text to Sticky Notes.svg","mtime":1678537561724},{"fname":"Folder Note Core - Make Current Drawing a Folder.md","mtime":1678973697470},{"fname":"Folder Note Core - Make Current Drawing a Folder.svg","mtime":1678973697470},{"fname":"Invert colors.md","mtime":1708870608219},{"fname":"Invert colors.svg","mtime":1678973697470},{"fname":"PDF Page Text to Clipboard.md","mtime":1683984041712},{"fname":"PDF Page Text to Clipboard.svg","mtime":1680418321236},{"fname":"Excalidraw Collaboration Frame.md","mtime":1687881495985},{"fname":"Excalidraw Collaboration Frame.svg","mtime":1687881495985},{"fname":"Create DrawIO file.md","mtime":1688243858267},{"fname":"Create DrawIO file.svg","mtime":1688243858267},{"fname":"Ellipse Selected Elements.md","mtime":1690131476331},{"fname":"Ellipse Selected Elements.svg","mtime":1690131476331},{"fname":"Select Similar Elements.md","mtime":1734859973735},{"fname":"Select Similar Elements.svg","mtime":1691270949338},{"fname":"Toggle Grid.md","mtime":1692125382945},{"fname":"Toggle Grid.svg","mtime":1692124753386},{"fname":"Split Ellipse.md","mtime":1693134104356},{"fname":"Split Ellipse.svg","mtime":1693134104356},{"fname":"Text Aura.md","mtime":1693731979540},{"fname":"Text Aura.svg","mtime":1693731979540},{"fname":"Boolean Operations.md","mtime":1695746839537},{"fname":"Boolean Operations.svg","mtime":1695746839537},{"fname":"Concatenate lines.md","mtime":1696175301525},{"fname":"Concatenate lines.svg","mtime":1696175301525},{"fname":"GPT-Draw-a-UI.md","mtime":1703324727900},{"fname":"GPT-Draw-a-UI.svg","mtime":1700511998048},{"fname":"ExcaliAI.md","mtime":1722056859912},{"fname":"ExcaliAI.svg","mtime":1701011028767},{"fname":"Repeat Texts.md","mtime":1701969627758},{"fname":"Repeat Texts.svg","mtime":1701969627758},{"fname":"Relative Font Size Cycle.md","mtime":1701969627758},{"fname":"Relative Font Size Cycle.svg","mtime":1701969627758},{"fname":"Golden Ratio.md","mtime":1725174200469},{"fname":"Golden Ratio.svg","mtime":1702812404286},{"fname":"Crop Vintage Mask.md","mtime":1706565166174},{"fname":"Crop Vintage Mask.svg","mtime":1705836797730},{"fname":"Custom Zoom.md", "mtime": 1710424027192},{"fname":"Custom Zoom.svg", "mtime":1710424027192},{"fname":"Excalidraw Writing Machine.md", "mtime":1724677454036},{"fname":"Excalidraw Writing Machine.svg", "mtime":1724356709706},{"fname":"Reset LaTeX Size.md", "mtime":1725296010813},{"fname":"Reset LaTeX Size.svg", "mtime":1725296010813},{"fname":"Shade Master.md", "mtime":1735322670334},{"fname":"Shade Master.svg", "mtime":1735252821829}]
\ No newline at end of file
diff --git a/ea-scripts/index-new.md b/ea-scripts/index-new.md
index 392cdb7..e833e1a 100644
--- a/ea-scripts/index-new.md
+++ b/ea-scripts/index-new.md
@@ -568,7 +568,7 @@ https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea
```excalidraw-script-install
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Shade%20Master.md
```
-
You can modify the colors of SVG images, embedded files, and Excalidraw elements in a drawing by changing Hue, Saturation, Lightness and Transparency; and if only a single SVG or nested Excalidraw drawing is selected, then you can remap image colors.
You can modify the colors of SVG images, embedded files, and Excalidraw elements in a drawing by changing Hue, Saturation, Lightness and Transparency; and if only a single SVG or nested Excalidraw drawing is selected, then you can remap image colors.
## Slideshow
diff --git a/manifest-beta.json b/manifest-beta.json
index 2e409bf..13eb6d7 100644
--- a/manifest-beta.json
+++ b/manifest-beta.json
@@ -1,7 +1,7 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
- "version": "2.7.2",
+ "version": "2.7.3",
"minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian",
diff --git a/manifest.json b/manifest.json
index 19d5d37..579653c 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"id": "obsidian-excalidraw-plugin",
"name": "Excalidraw",
- "version": "2.7.2",
+ "version": "2.7.3",
"minAppVersion": "1.1.6",
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
"author": "Zsolt Viczian",
diff --git a/src/shared/Dialogs/Messages.ts b/src/shared/Dialogs/Messages.ts
index d24a730..7018497 100644
--- a/src/shared/Dialogs/Messages.ts
+++ b/src/shared/Dialogs/Messages.ts
@@ -18,16 +18,20 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
`,
"2.7.3":`
+
+
+
+
## Fixed
- Toggling image size anchoring on and off by modifying the image link did not update the image in the view until the user forced saved it or closed and opened the drawing again. This was a side-effect of the less frequent view save introduced in 2.7.1
## New
- **Shade Master Script**: A new script that allows you to modify the color lightness, hue, saturation, and transparency of selected Excalidraw elements, SVG images, and nested Excalidraw drawings. When a single image is selected, you can map colors individually. The original image remains unchanged, and a mapping table is added under ${String.fromCharCode(96)}## Embedded Files${String.fromCharCode(96)} for SVG and nested drawings. This helps maintain links between drawings while allowing different color themes.
-- New Command Palette Command: "Duplicate selected image with a different image ID". Creates a copy of the selected image with a new image ID. This allows you to add multiple color mappings to the same image. In the scene the image will be treated as if a different image, but loaded from the same file in the Vault.
+- New Command Palette Command: "Duplicate selected image with a different image ID". Creates a copy of the selected image with a new image ID. This allows you to add multiple color mappings to the same image. In the scene, the image will be treated as if a different image, but loaded from the same file in the Vault.
## QoL Improvements
- New setting under ${String.fromCharCode(96)}Embedding Excalidraw into your notes and Exporting${String.fromCharCode(96)} > ${String.fromCharCode(96)}Image Caching and rendering optimization${String.fromCharCode(96)}. You can now set the number of concurrent workers that render your embedded images. Increasing the number will increase the speed but temporarily reduce the responsiveness of your system in case of large drawings.
-- Moved pen-related settings under ${String.fromCharCode(96)}Excalidraw appearance and behavior${String.fromCharCode(96)} to their own sub-heading called ${String.fromCharCode(96)}Pen${String.fromCharCode(96)}.
+- Moved pen-related settings under ${String.fromCharCode(96)}Excalidraw appearance and behavior${String.fromCharCode(96)} to their sub-heading called ${String.fromCharCode(96)}Pen${String.fromCharCode(96)}.
- Minor error fixing and performance optimizations when loading and updating embedded images.
- Color maps in ${String.fromCharCode(96)}## Embedded Files${String.fromCharCode(96)} may now include color keys "stroke" and "fill". If set, these will change the fill and stroke attributes of the SVG root element of the relevant file.
@@ -57,6 +61,21 @@ getColosFromExcalidrawFile(file:TFile, img: ExcalidrawImageElement): Promise