diff --git a/ea-scripts/Elbow connectors.md b/ea-scripts/Elbow connectors.md index 3366311..df0d7fd 100644 --- a/ea-scripts/Elbow connectors.md +++ b/ea-scripts/Elbow connectors.md @@ -1,56 +1,56 @@ -/* - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) - -Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/elbow-connectors.png) - -This script converts the selected connectors to elbows. - -See documentation for more details: -https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html - -```javascript -*/ -const elements = ea.getViewSelectedElements(); - -const lines = elements.filter((el)=>el.type==="arrow" || el.type==="line"); - -for (const line of lines) { - if (line.points.length >= 3) { - for (var i = 0; i < line.points.length - 2; i++) { - var p1; - var p3; - if (line.points[i][0] < line.points[i + 2][0]) { - p1 = line.points[i]; - p3 = line.points[i+2]; - } else { - p1 = line.points[i + 2]; - p3 = line.points[i]; - } - const p2 = line.points[i + 1]; - - if (p1[0] === p3[0]) { - continue; - } - - const k = (p3[1] - p1[1]) / (p3[0] - p1[0]); - const b = p1[1] - k * p1[0]; - - y0 = k * p2[0] + b; - const up = p2[1] < y0; - - if ((k > 0 && !up) || (k < 0 && up)) { - p2[0] = p1[0]; - p2[1] = p3[1]; - } else { - p2[0] = p3[0]; - p2[1] = p1[1]; - } - } - } -} - -ea.copyViewElementsToEAforEditing(lines); -await ea.addElementsToView(); +/* + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) + +Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/elbow-connectors.png) + +This script converts the selected connectors to elbows. + +See documentation for more details: +https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html + +```javascript +*/ +const elements = ea.getViewSelectedElements(); + +const lines = elements.filter((el)=>el.type==="arrow" || el.type==="line"); + +for (const line of lines) { + if (line.points.length >= 3) { + for (var i = 0; i < line.points.length - 2; i++) { + var p1; + var p3; + if (line.points[i][0] < line.points[i + 2][0]) { + p1 = line.points[i]; + p3 = line.points[i+2]; + } else { + p1 = line.points[i + 2]; + p3 = line.points[i]; + } + const p2 = line.points[i + 1]; + + if (p1[0] === p3[0]) { + continue; + } + + const k = (p3[1] - p1[1]) / (p3[0] - p1[0]); + const b = p1[1] - k * p1[0]; + + y0 = k * p2[0] + b; + const up = p2[1] < y0; + + if ((k > 0 && !up) || (k < 0 && up)) { + p2[0] = p1[0]; + p2[1] = p3[1]; + } else { + p2[0] = p3[0]; + p2[1] = p1[1]; + } + } + } +} + +ea.copyViewElementsToEAforEditing(lines); +await ea.addElementsToView(); diff --git a/ea-scripts/Expand rectangles horizontally keep text centered.md b/ea-scripts/Expand rectangles horizontally keep text centered.md index e86947e..28d3047 100644 --- a/ea-scripts/Expand rectangles horizontally keep text centered.md +++ b/ea-scripts/Expand rectangles horizontally keep text centered.md @@ -1,146 +1,146 @@ -/* - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) - -Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) - -This script expands the width of the selected rectangles until they are all the same width and keep the text centered. - -See documentation for more details: -https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html - -```javascript -*/ - -const elements = ea.getViewSelectedElements(); -const topGroups = ea.getMaximumGroups(elements); -const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) - .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow')) ? - [...result, group[0]] : result, []); - -const groupWidths = topGroups - .map((g) => { - if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { - // ignore individual lines - return { minLeft: 0, maxRight: 0 }; - } - return g.reduce( - (pre, cur, i) => { - if (i === 0) { - return { - minLeft: cur.x, - maxRight: cur.x + cur.width, - index: i, - }; - } else { - return { - minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft, - maxRight: - cur.x + cur.width > pre.maxRight - ? cur.x + cur.width - : pre.maxRight, - index: i, - }; - } - }, - { minLeft: 0, maxRight: 0 } - ); - }) - .map((r) => { - r.width = r.maxRight - r.minLeft; - return r; - }); - -const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width)); - -for (var i = 0; i < topGroups.length; i++) { - const rects = topGroups[i] - .filter((el) => el.type === "rectangle") - .sort((lha, rha) => lha.x - rha.x); - const texts = topGroups[i] - .filter((el) => el.type === "text") - .sort((lha, rha) => lha.x - rha.x); - const groupWith = groupWidths[i].width; - if (groupWith < maxGroupWidth) { - const distance = maxGroupWidth - groupWith; - const perRectDistance = distance / rects.length; - for (var j = 0; j < rects.length; j++) { - const rect = rects[j]; - const rectLeft = rect.x; - const rectTop = rect.y; - const rectRight = rect.x + rect.width; - const rectBottom = rect.y + rect.height; - - rect.x = rect.x + perRectDistance * j - perRectDistance / 2; - rect.width += perRectDistance; - - const textsWithRect = texts.filter(text => text.x >= rectLeft && text.x <= rectRight - && text.y >= rectTop && text.y <= rectBottom); - for(const text of textsWithRect) { - text.x = text.x + perRectDistance * j; - } - - // recalculate the position of the points - const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); - for(startBindingLine of startBindingLines) { - recalculateStartPointOfLine(startBindingLine, rect); - } - - const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); - for(endBindingLine of endBindingLines) { - recalculateEndPointOfLine(endBindingLine, rect); - } - } - } -} - -ea.copyViewElementsToEAforEditing(elements); -await ea.addElementsToView(false, false); - -function recalculateStartPointOfLine(line, el) { - const aX = el.x + el.width/2; - const bX = line.x + line.points[1][0]; - const aY = el.y + el.height/2; - const bY = line.y + line.points[1][1]; - - line.startBinding.gap = 8; - line.startBinding.focus = 0; - const intersectA = ea.intersectElementWithLine( - el, - [bX, bY], - [aX, aY], - line.startBinding.gap - ); - - if(intersectA.length > 0) { - line.points[0] = [0, 0]; - for(var i = 1; i 0) { - line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; - } +/* + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) + +Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) + +This script expands the width of the selected rectangles until they are all the same width and keep the text centered. + +See documentation for more details: +https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html + +```javascript +*/ + +const elements = ea.getViewSelectedElements(); +const topGroups = ea.getMaximumGroups(elements); +const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) + .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow')) ? + [...result, group[0]] : result, []); + +const groupWidths = topGroups + .map((g) => { + if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { + // ignore individual lines + return { minLeft: 0, maxRight: 0 }; + } + return g.reduce( + (pre, cur, i) => { + if (i === 0) { + return { + minLeft: cur.x, + maxRight: cur.x + cur.width, + index: i, + }; + } else { + return { + minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft, + maxRight: + cur.x + cur.width > pre.maxRight + ? cur.x + cur.width + : pre.maxRight, + index: i, + }; + } + }, + { minLeft: 0, maxRight: 0 } + ); + }) + .map((r) => { + r.width = r.maxRight - r.minLeft; + return r; + }); + +const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width)); + +for (var i = 0; i < topGroups.length; i++) { + const rects = topGroups[i] + .filter((el) => el.type === "rectangle") + .sort((lha, rha) => lha.x - rha.x); + const texts = topGroups[i] + .filter((el) => el.type === "text") + .sort((lha, rha) => lha.x - rha.x); + const groupWith = groupWidths[i].width; + if (groupWith < maxGroupWidth) { + const distance = maxGroupWidth - groupWith; + const perRectDistance = distance / rects.length; + for (var j = 0; j < rects.length; j++) { + const rect = rects[j]; + const rectLeft = rect.x; + const rectTop = rect.y; + const rectRight = rect.x + rect.width; + const rectBottom = rect.y + rect.height; + + rect.x = rect.x + perRectDistance * j - perRectDistance / 2; + rect.width += perRectDistance; + + const textsWithRect = texts.filter(text => text.x >= rectLeft && text.x <= rectRight + && text.y >= rectTop && text.y <= rectBottom); + for(const text of textsWithRect) { + text.x = text.x + perRectDistance * j; + } + + // recalculate the position of the points + const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); + for(startBindingLine of startBindingLines) { + recalculateStartPointOfLine(startBindingLine, rect); + } + + const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); + for(endBindingLine of endBindingLines) { + recalculateEndPointOfLine(endBindingLine, rect); + } + } + } +} + +ea.copyViewElementsToEAforEditing(elements); +await ea.addElementsToView(false, false); + +function recalculateStartPointOfLine(line, el) { + const aX = el.x + el.width/2; + const bX = line.x + line.points[1][0]; + const aY = el.y + el.height/2; + const bY = line.y + line.points[1][1]; + + line.startBinding.gap = 8; + line.startBinding.focus = 0; + const intersectA = ea.intersectElementWithLine( + el, + [bX, bY], + [aX, aY], + line.startBinding.gap + ); + + if(intersectA.length > 0) { + line.points[0] = [0, 0]; + for(var i = 1; i 0) { + line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; + } } \ No newline at end of file diff --git a/ea-scripts/Expand rectangles horizontally.md b/ea-scripts/Expand rectangles horizontally.md index 40340ee..e855a04 100644 --- a/ea-scripts/Expand rectangles horizontally.md +++ b/ea-scripts/Expand rectangles horizontally.md @@ -1,133 +1,133 @@ -/* - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) - -Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) - -This script expands the width of the selected rectangles until they are all the same width. - -See documentation for more details: -https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html - -```javascript -*/ - -const elements = ea.getViewSelectedElements(); -const topGroups = ea.getMaximumGroups(elements); -const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) - .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ? - [...result, group[0]] : result, []); - -const groupWidths = topGroups - .map((g) => { - if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { - // ignore individual lines - return { minLeft: 0, maxRight: 0 }; - } - return g.reduce( - (pre, cur, i) => { - if (i === 0) { - return { - minLeft: cur.x, - maxRight: cur.x + cur.width, - index: i, - }; - } else { - return { - minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft, - maxRight: - cur.x + cur.width > pre.maxRight - ? cur.x + cur.width - : pre.maxRight, - index: i, - }; - } - }, - { minLeft: 0, maxRight: 0 } - ); - }) - .map((r) => { - r.width = r.maxRight - r.minLeft; - return r; - }); - -const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width)); - -for (var i = 0; i < topGroups.length; i++) { - const rects = topGroups[i] - .filter((el) => el.type === "rectangle") - .sort((lha, rha) => lha.x - rha.x); - - const groupWith = groupWidths[i].width; - if (groupWith < maxGroupWidth) { - const distance = maxGroupWidth - groupWith; - const perRectDistance = distance / rects.length; - for (var j = 0; j < rects.length; j++) { - const rect = rects[j]; - rect.x = rect.x + perRectDistance * j; - rect.width += perRectDistance; - - // recalculate the position of the points - const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); - for(startBindingLine of startBindingLines) { - recalculateStartPointOfLine(startBindingLine, rect); - } - - const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); - for(endBindingLine of endBindingLines) { - recalculateEndPointOfLine(endBindingLine, rect); - } - } - } -} - -ea.copyViewElementsToEAforEditing(elements); -await ea.addElementsToView(false, false); - -function recalculateStartPointOfLine(line, el) { - const aX = el.x + el.width/2; - const bX = line.x + line.points[1][0]; - const aY = el.y + el.height/2; - const bY = line.y + line.points[1][1]; - - line.startBinding.gap = 8; - line.startBinding.focus = 0; - const intersectA = ea.intersectElementWithLine( - el, - [bX, bY], - [aX, aY], - line.startBinding.gap - ); - - if(intersectA.length > 0) { - line.points[0] = [0, 0]; - for(var i = 1; i 0) { - line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; - } +/* + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) + +Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) + +This script expands the width of the selected rectangles until they are all the same width. + +See documentation for more details: +https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html + +```javascript +*/ + +const elements = ea.getViewSelectedElements(); +const topGroups = ea.getMaximumGroups(elements); +const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) + .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ? + [...result, group[0]] : result, []); + +const groupWidths = topGroups + .map((g) => { + if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { + // ignore individual lines + return { minLeft: 0, maxRight: 0 }; + } + return g.reduce( + (pre, cur, i) => { + if (i === 0) { + return { + minLeft: cur.x, + maxRight: cur.x + cur.width, + index: i, + }; + } else { + return { + minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft, + maxRight: + cur.x + cur.width > pre.maxRight + ? cur.x + cur.width + : pre.maxRight, + index: i, + }; + } + }, + { minLeft: 0, maxRight: 0 } + ); + }) + .map((r) => { + r.width = r.maxRight - r.minLeft; + return r; + }); + +const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width)); + +for (var i = 0; i < topGroups.length; i++) { + const rects = topGroups[i] + .filter((el) => el.type === "rectangle") + .sort((lha, rha) => lha.x - rha.x); + + const groupWith = groupWidths[i].width; + if (groupWith < maxGroupWidth) { + const distance = maxGroupWidth - groupWith; + const perRectDistance = distance / rects.length; + for (var j = 0; j < rects.length; j++) { + const rect = rects[j]; + rect.x = rect.x + perRectDistance * j; + rect.width += perRectDistance; + + // recalculate the position of the points + const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); + for(startBindingLine of startBindingLines) { + recalculateStartPointOfLine(startBindingLine, rect); + } + + const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); + for(endBindingLine of endBindingLines) { + recalculateEndPointOfLine(endBindingLine, rect); + } + } + } +} + +ea.copyViewElementsToEAforEditing(elements); +await ea.addElementsToView(false, false); + +function recalculateStartPointOfLine(line, el) { + const aX = el.x + el.width/2; + const bX = line.x + line.points[1][0]; + const aY = el.y + el.height/2; + const bY = line.y + line.points[1][1]; + + line.startBinding.gap = 8; + line.startBinding.focus = 0; + const intersectA = ea.intersectElementWithLine( + el, + [bX, bY], + [aX, aY], + line.startBinding.gap + ); + + if(intersectA.length > 0) { + line.points[0] = [0, 0]; + for(var i = 1; i 0) { + line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; + } } \ No newline at end of file diff --git a/ea-scripts/Expand rectangles vertically keep text centered.md b/ea-scripts/Expand rectangles vertically keep text centered.md index 1206522..e2afed2 100644 --- a/ea-scripts/Expand rectangles vertically keep text centered.md +++ b/ea-scripts/Expand rectangles vertically keep text centered.md @@ -1,146 +1,146 @@ -/* - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) - -Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) - -This script expands the height of the selected rectangles until they are all the same height and keep the text centered. - -See documentation for more details: -https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html - -```javascript -*/ - -const elements = ea.getViewSelectedElements(); -const topGroups = ea.getMaximumGroups(elements); -const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) - .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ? - [...result, group[0]] : result, []); - -const groupHeights = topGroups - .map((g) => { - if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { - // ignore individual lines - return { minTop: 0, maxBottom: 0 }; - } - return g.reduce( - (pre, cur, i) => { - if (i === 0) { - return { - minTop: cur.y, - maxBottom: cur.y + cur.height, - index: i, - }; - } else { - return { - minTop: cur.y < pre.minTop ? cur.y : pre.minTop, - maxBottom: - cur.y + cur.height > pre.maxBottom - ? cur.y + cur.height - : pre.maxBottom, - index: i, - }; - } - }, - { minTop: 0, maxBottom: 0 } - ); - }) - .map((r) => { - r.height = r.maxBottom - r.minTop; - return r; - }); - -const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height)); - -for (var i = 0; i < topGroups.length; i++) { - const rects = topGroups[i] - .filter((el) => el.type === "rectangle") - .sort((lha, rha) => lha.y - rha.y); - const texts = topGroups[i] - .filter((el) => el.type === "text") - .sort((lha, rha) => lha.y - rha.y); - const groupWith = groupHeights[i].height; - if (groupWith < maxGroupHeight) { - const distance = maxGroupHeight - groupWith; - const perRectDistance = distance / rects.length; - for (var j = 0; j < rects.length; j++) { - const rect = rects[j]; - const rectLeft = rect.x; - const rectTop = rect.y; - const rectRight = rect.x + rect.width; - const rectBottom = rect.y + rect.height; - - rect.y = rect.y + perRectDistance * j - perRectDistance / 2; - rect.height += perRectDistance; - - const textsWithRect = texts.filter(text => text.x >= rectLeft && text.x <= rectRight - && text.y >= rectTop && text.y <= rectBottom); - for(const text of textsWithRect) { - text.y = text.y + perRectDistance * j; - } - - // recalculate the position of the points - const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); - for(startBindingLine of startBindingLines) { - recalculateStartPointOfLine(startBindingLine, rect); - } - - const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); - for(endBindingLine of endBindingLines) { - recalculateEndPointOfLine(endBindingLine, rect); - } - } - } -} - -ea.copyViewElementsToEAforEditing(elements); -await ea.addElementsToView(false, false); - -function recalculateStartPointOfLine(line, el) { - const aX = el.x + el.width/2; - const bX = line.x + line.points[1][0]; - const aY = el.y + el.height/2; - const bY = line.y + line.points[1][1]; - - line.startBinding.gap = 8; - line.startBinding.focus = 0; - const intersectA = ea.intersectElementWithLine( - el, - [bX, bY], - [aX, aY], - line.startBinding.gap - ); - - if(intersectA.length > 0) { - line.points[0] = [0, 0]; - for(var i = 1; i 0) { - line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; - } +/* + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) + +Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) + +This script expands the height of the selected rectangles until they are all the same height and keep the text centered. + +See documentation for more details: +https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html + +```javascript +*/ + +const elements = ea.getViewSelectedElements(); +const topGroups = ea.getMaximumGroups(elements); +const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) + .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ? + [...result, group[0]] : result, []); + +const groupHeights = topGroups + .map((g) => { + if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { + // ignore individual lines + return { minTop: 0, maxBottom: 0 }; + } + return g.reduce( + (pre, cur, i) => { + if (i === 0) { + return { + minTop: cur.y, + maxBottom: cur.y + cur.height, + index: i, + }; + } else { + return { + minTop: cur.y < pre.minTop ? cur.y : pre.minTop, + maxBottom: + cur.y + cur.height > pre.maxBottom + ? cur.y + cur.height + : pre.maxBottom, + index: i, + }; + } + }, + { minTop: 0, maxBottom: 0 } + ); + }) + .map((r) => { + r.height = r.maxBottom - r.minTop; + return r; + }); + +const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height)); + +for (var i = 0; i < topGroups.length; i++) { + const rects = topGroups[i] + .filter((el) => el.type === "rectangle") + .sort((lha, rha) => lha.y - rha.y); + const texts = topGroups[i] + .filter((el) => el.type === "text") + .sort((lha, rha) => lha.y - rha.y); + const groupWith = groupHeights[i].height; + if (groupWith < maxGroupHeight) { + const distance = maxGroupHeight - groupWith; + const perRectDistance = distance / rects.length; + for (var j = 0; j < rects.length; j++) { + const rect = rects[j]; + const rectLeft = rect.x; + const rectTop = rect.y; + const rectRight = rect.x + rect.width; + const rectBottom = rect.y + rect.height; + + rect.y = rect.y + perRectDistance * j - perRectDistance / 2; + rect.height += perRectDistance; + + const textsWithRect = texts.filter(text => text.x >= rectLeft && text.x <= rectRight + && text.y >= rectTop && text.y <= rectBottom); + for(const text of textsWithRect) { + text.y = text.y + perRectDistance * j; + } + + // recalculate the position of the points + const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); + for(startBindingLine of startBindingLines) { + recalculateStartPointOfLine(startBindingLine, rect); + } + + const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); + for(endBindingLine of endBindingLines) { + recalculateEndPointOfLine(endBindingLine, rect); + } + } + } +} + +ea.copyViewElementsToEAforEditing(elements); +await ea.addElementsToView(false, false); + +function recalculateStartPointOfLine(line, el) { + const aX = el.x + el.width/2; + const bX = line.x + line.points[1][0]; + const aY = el.y + el.height/2; + const bY = line.y + line.points[1][1]; + + line.startBinding.gap = 8; + line.startBinding.focus = 0; + const intersectA = ea.intersectElementWithLine( + el, + [bX, bY], + [aX, aY], + line.startBinding.gap + ); + + if(intersectA.length > 0) { + line.points[0] = [0, 0]; + for(var i = 1; i 0) { + line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; + } } \ No newline at end of file diff --git a/ea-scripts/Expand rectangles vertically.md b/ea-scripts/Expand rectangles vertically.md index 18d8272..c57982e 100644 --- a/ea-scripts/Expand rectangles vertically.md +++ b/ea-scripts/Expand rectangles vertically.md @@ -1,131 +1,131 @@ -/* - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) - -Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. - -![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) - -This script expands the height of the selected rectangles until they are all the same height. - -```javascript -*/ - -const elements = ea.getViewSelectedElements(); -const topGroups = ea.getMaximumGroups(elements); -const allLines = ea.getViewElements().filter(el => el.type === 'arrow' || el.type === 'line'); -const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) - .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ? - [...result, group[0]] : result, []); - -const groupHeights = topGroups - .map((g) => { - if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { - // ignore individual lines - return { minTop: 0, maxBottom: 0 }; - } - return g.reduce( - (pre, cur, i) => { - if (i === 0) { - return { - minTop: cur.y, - maxBottom: cur.y + cur.height, - index: i, - }; - } else { - return { - minTop: cur.y < pre.minTop ? cur.y : pre.minTop, - maxBottom: - cur.y + cur.height > pre.maxBottom - ? cur.y + cur.height - : pre.maxBottom, - index: i, - }; - } - }, - { minTop: 0, maxBottom: 0 } - ); - }) - .map((r) => { - r.height = r.maxBottom - r.minTop; - return r; - }); - -const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height)); - -for (var i = 0; i < topGroups.length; i++) { - const rects = topGroups[i] - .filter((el) => el.type === "rectangle") - .sort((lha, rha) => lha.y - rha.y); - - const groupWith = groupHeights[i].height; - if (groupWith < maxGroupHeight) { - const distance = maxGroupHeight - groupWith; - const perRectDistance = distance / rects.length; - for (var j = 0; j < rects.length; j++) { - const rect = rects[j]; - rect.y = rect.y + perRectDistance * j; - rect.height += perRectDistance; - - // recalculate the position of the points - const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); - for(startBindingLine of startBindingLines) { - recalculateStartPointOfLine(startBindingLine, rect); - } - - const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); - for(endBindingLine of endBindingLines) { - recalculateEndPointOfLine(endBindingLine, rect); - } - } - } -} - -ea.copyViewElementsToEAforEditing(elements); -await ea.addElementsToView(false, false); - -function recalculateStartPointOfLine(line, el) { - const aX = el.x + el.width/2; - const bX = line.x + line.points[1][0]; - const aY = el.y + el.height/2; - const bY = line.y + line.points[1][1]; - - line.startBinding.gap = 8; - line.startBinding.focus = 0; - const intersectA = ea.intersectElementWithLine( - el, - [bX, bY], - [aX, aY], - line.startBinding.gap - ); - - if(intersectA.length > 0) { - line.points[0] = [0, 0]; - for(var i = 1; i 0) { - line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; - } +/* + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-download-raw.jpg) + +Download this file and save to your Obsidian Vault including the first line, or open it in "Raw" and copy the entire contents to Obsidian. + +![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-expand-rectangles.gif) + +This script expands the height of the selected rectangles until they are all the same height. + +```javascript +*/ + +const elements = ea.getViewSelectedElements(); +const topGroups = ea.getMaximumGroups(elements); +const allLines = ea.getViewElements().filter(el => el.type === 'arrow' || el.type === 'line'); +const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements()) + .reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ? + [...result, group[0]] : result, []); + +const groupHeights = topGroups + .map((g) => { + if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) { + // ignore individual lines + return { minTop: 0, maxBottom: 0 }; + } + return g.reduce( + (pre, cur, i) => { + if (i === 0) { + return { + minTop: cur.y, + maxBottom: cur.y + cur.height, + index: i, + }; + } else { + return { + minTop: cur.y < pre.minTop ? cur.y : pre.minTop, + maxBottom: + cur.y + cur.height > pre.maxBottom + ? cur.y + cur.height + : pre.maxBottom, + index: i, + }; + } + }, + { minTop: 0, maxBottom: 0 } + ); + }) + .map((r) => { + r.height = r.maxBottom - r.minTop; + return r; + }); + +const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height)); + +for (var i = 0; i < topGroups.length; i++) { + const rects = topGroups[i] + .filter((el) => el.type === "rectangle") + .sort((lha, rha) => lha.y - rha.y); + + const groupWith = groupHeights[i].height; + if (groupWith < maxGroupHeight) { + const distance = maxGroupHeight - groupWith; + const perRectDistance = distance / rects.length; + for (var j = 0; j < rects.length; j++) { + const rect = rects[j]; + rect.y = rect.y + perRectDistance * j; + rect.height += perRectDistance; + + // recalculate the position of the points + const startBindingLines = allIndividualArrows.filter(el => (el.startBinding||{}).elementId === rect.id); + for(startBindingLine of startBindingLines) { + recalculateStartPointOfLine(startBindingLine, rect); + } + + const endBindingLines = allIndividualArrows.filter(el => (el.endBinding||{}).elementId === rect.id); + for(endBindingLine of endBindingLines) { + recalculateEndPointOfLine(endBindingLine, rect); + } + } + } +} + +ea.copyViewElementsToEAforEditing(elements); +await ea.addElementsToView(false, false); + +function recalculateStartPointOfLine(line, el) { + const aX = el.x + el.width/2; + const bX = line.x + line.points[1][0]; + const aY = el.y + el.height/2; + const bY = line.y + line.points[1][1]; + + line.startBinding.gap = 8; + line.startBinding.focus = 0; + const intersectA = ea.intersectElementWithLine( + el, + [bX, bY], + [aX, aY], + line.startBinding.gap + ); + + if(intersectA.length > 0) { + line.points[0] = [0, 0]; + for(var i = 1; i 0) { + line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y]; + } } \ No newline at end of file diff --git a/manifest.json b/manifest.json index 0592f9e..e7be63b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "obsidian-excalidraw-plugin", "name": "Excalidraw", - "version": "1.6.10", + "version": "1.6.11", "minAppVersion": "0.12.16", "description": "An Obsidian plugin to edit and view Excalidraw drawings", "author": "Zsolt Viczian", diff --git a/src/ExcalidrawAutomate.ts b/src/ExcalidrawAutomate.ts index 91c1924..2ac3c82 100644 --- a/src/ExcalidrawAutomate.ts +++ b/src/ExcalidrawAutomate.ts @@ -1140,12 +1140,13 @@ export async function initExcalidrawAutomate( )?.file; }, copyViewElementsToEAforEditing(elements: ExcalidrawElement[]): void { - elements.forEach((el:any) => { - el.version = el.version + 1; - el.updated = Date.now(); - el.versionNonce = Math.floor(Math.random()*1000000000); - this.elementsDict[el.id] = el; - }); + elements.forEach((el) => { + this.elementsDict[el.id] = { + ...el, + version: el.version + 1, + updated: Date.now(), + versionNonce: Math.floor(Math.random()*1000000000), + };}); }, viewToggleFullScreen(forceViewMode: boolean = false): void { if (this.plugin.app.isMobile) { diff --git a/src/ExcalidrawView.ts b/src/ExcalidrawView.ts index 095867c..278bdba 100644 --- a/src/ExcalidrawView.ts +++ b/src/ExcalidrawView.ts @@ -894,10 +894,10 @@ export default class ExcalidrawView extends TextFileView { this.excalidrawAPI.updateScene({ elements: excalidrawData.elements, appState: { + ...excalidrawData.appState, zenModeEnabled, viewModeEnabled, linkOpacity: this.plugin.settings.linkOpacity, - ...excalidrawData.appState, }, files: excalidrawData.files, commitToHistory: true, @@ -917,10 +917,10 @@ export default class ExcalidrawView extends TextFileView { this.instantiateExcalidraw({ elements: excalidrawData.elements, appState: { + ...excalidrawData.appState, zenModeEnabled: om.zenModeEnabled, viewModeEnabled: om.viewModeEnabled, linkOpacity: this.plugin.settings.linkOpacity, - ...excalidrawData.appState, }, files: excalidrawData.files, libraryItems: await this.getLibrary(), @@ -1364,14 +1364,11 @@ export default class ExcalidrawView extends TextFileView { } } - const st: AppState = this.excalidrawAPI.getAppState(); - const elements = newElementsOnTop ? el.concat(newElements.filter((e) => !removeList.includes(e.id))) : newElements.filter((e) => !removeList.includes(e.id)).concat(el); this.excalidrawAPI.updateScene({ elements, - appState: st, commitToHistory: true, }); @@ -1390,6 +1387,7 @@ export default class ExcalidrawView extends TextFileView { this.file.path, images[k].file, ); + const st: AppState = this.excalidrawAPI.getAppState(); embeddedFile.setImage( images[k].dataURL, images[k].mimeType, diff --git a/versions.json b/versions.json index 7378851..02e7c66 100644 --- a/versions.json +++ b/versions.json @@ -1,4 +1,4 @@ { - "1.6.10": "0.12.16", + "1.6.11": "0.12.16", "1.4.2": "0.11.13" }