Compare commits

..

5 Commits

51 changed files with 10642 additions and 59 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,838 @@
---
excalidraw-plugin: parsed
tags: [excalidraw]
---
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
# Text Elements
%%
# Drawing
```compressed-json
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
```
%%

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,848 @@
---
excalidraw-plugin: parsed
tags: [excalidraw]
---
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
# Text Elements
%%
# Drawing
```compressed-json
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
tCGBBexJjXp3oN51B9kJ3fnpfImHi9Ouh/RYawIWiGwTkVKihVb3EKe8jhqw53tX
1j6D9jVMbfxsb3b7gDd+uA/IbzkY7Z1rRBdZTsY74HHYSQfTluDBg7KwDjVGg9M2
eABN0BZAgQ+yyP1Aa0snsdWnXD8nz7tBvfbKAExervkF91R+HHUd2G4Fsar8HbD2
M5QdLjZK2bpep0Gh9K6GJ8JlIQRZiOo5pXQ3nceICwcF6jLNJnFl0ym07YGscZWp
hyfG20ssMy3lTCitSP4kVPyuospXWUO1w0djAPUtx7LnBSZ0+1ruDQFp1dxO7tKz
nstG5PGo6+cRiVatZUcSPO3x1rqkXGX+cLuKU/5HcogbXJyZ/xyWphhapErdu30f
bozt24WqkewkjbhpL+PomlpBk9zdDx0npHwe6UfYKz2hMiT/a2x7EwQrJbGRxpPk
6kzjiGkTS/JuYLVkVMbrOTkoYmZk2YwHg/VLdrXXuJ1P5MzSlqZ7VtsybFPRT2TG
UkEhmDSminfa0pxU6yYlM+ShTfJqTWnRZPin6pspxzPKdDk+0NTq4izRlItTb0yp
PJl4qaYFOS0TTIp5kxaa8kymE6Hk7DL1KdOeTPT6p50z6e1N+mrTvp700GYDMhm9
TbpgKbIl/5emPToZ401GYWVGn3JiZmM76bIlJm7TVteDNajTPamzgLqaaU6YzN5m
EzJZhyeqYLPSsmTlZg2DMm5PqnTgbKi4BGYVoXBMufRV022aM1abtTZ2bKJujpPa
naTcyeMw7R6ljmdaXwZFtMtbNJSIMcibYHObyntmMUjpnyWVi9jZwGzadXOuxkHN
dnWue5q4AeeGlKlBFFZiKdlE0SeVhp151KcmanP3ntgCpiaQhlJLrnYpEcNc1qeK
k2YBpk5hOhmfBClmP62WJaTWd3OhplyO5n2p/VYpcafJJJpMqeYmnwXv6v5j+ok0
+2QWWaIUEGJKMI7f588N2TaQ9ip4QBDU+0hpPTzQAXSaLNSVdB7mBjeQLlL0S6dQ
2ulbZ4ET2ESJ0DqBGBsAAAKXbBcMEAD07VNxE0CEA/sfQR4A0C4ZZri0Oa9Xn40N
66gVQxa3Xqo317qMK1/hKtcEVjR1q9IsXRtXrGbUHBW18RPSKBxJnNY3g+nVY32q
Zm0zXGaaBmaOv7XC5WZU69mc4Q7UpSvIxY+PnzOpwlhUd5O6UqdWtzlM+TD6bdSk
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
AA==
```
%%

View File

@@ -0,0 +1,25 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-bullet-point.jpg)
This script will add a small circle to the top left of each text element in the selection and add the text and the "bullet point" into a group.
See documentation for more details:
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
```javascript
*/
elements = ea.getViewSelectedElements().filter((el)=>el.type==="text");
ea.copyViewElementsToEAforEditing(elements);
const padding = 10;
elements.forEach((el)=>{
ea.style.strokeColor = el.strokeColor;
const size = el.fontSize/2;
const ellipseId = ea.addEllipse(
el.x-padding-size,
el.y+size/2,
size,
size
);
ea.addToGroup([el.id,ellipseId]);
});
ea.addElementsToView(false,false);

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="100 100 500 400"><path fill-rule="evenodd" d="M414.57 183.49a11.194 11.194 0 0 0-10.344 6.914 11.21 11.21 0 0 0-.851 4.285v74.086h-110.09c-5.57-47.172-45.852-83.945-94.48-83.945-52.418 0-95.2 42.715-95.2 95.145 0 52.43 42.782 95.141 95.2 95.141 48.629 0 88.91-36.773 94.48-83.945h110.09v74.145c0 1.465.293 2.93.851 4.285a11.184 11.184 0 0 0 10.344 6.91H585.2c1.465 0 2.93-.292 4.285-.85a11.184 11.184 0 0 0 6.91-10.344v-170.63c0-1.466-.293-2.93-.851-4.286a11.246 11.246 0 0 0-2.426-3.633c-1.035-1.035-2.277-1.867-3.633-2.43s-2.82-.851-4.285-.851z"/></svg>

After

Width:  |  Height:  |  Size: 604 B

View File

@@ -0,0 +1,65 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-add-link-and-open.jpg)
Prompts for a file from the vault. Adds a link to the selected element pointing to the selected file. You can control in settings to open the file in the current active pane or an adjacent pane.
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.5.21")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
settings = ea.getScriptSettings();
if(!settings["Open link in active pane"]) {
settings = {
"Open link in active pane": {
value: false,
description: "Open the link in the current active pane (on) or a new pane (off)."
},
...settings
};
ea.setScriptSettings(settings);
}
const openInCurrentPane = settings["Open link in active pane"].value;
elements = ea.getViewSelectedElements();
if(elements.length === 0) {
new Notice("No selected elements");
return;
}
const files = app.vault.getFiles()
const filePaths = files.map((f)=>f.path);
file = await utils.suggester(filePaths,files,"Select a file");
if(!file) return;
const link = `[[${app.metadataCache.fileToLinktext(file,ea.targetView.file.path,true)}]]`;
ea.style.backgroundColor = "transparent";
ea.style.strokeColor = "rgba(70,130,180,0.05)"
ea.style.strokeWidth = 2;
ea.style.roughness = 0;
if(elements.length===1 && elements[0].type !== "text") {
ea.copyViewElementsToEAforEditing(elements);
ea.getElements()[0].link = link;
} else {
const b = ea.getBoundingBox(elements);
const id = ea.addEllipse(b.topX+b.width-5, b.topY, 5, 5);
ea.getElement(id).link = link;
ea.copyViewElementsToEAforEditing(elements);
ea.addToGroup(elements.map((e)=>e.id).concat([id]));
}
await ea.addElementsToView(false,true,true);
ea.selectElementsInView(ea.getElements());
if(openInCurrentPane) {
app.workspace.openLinkText(file.path,ea.targetView.file.path,false);
return;
}
ea.openFileInNewOrAdjacentLeaf(file);

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="5 5 130 110" stroke="#000"><path fill="none" stroke-linecap="round" stroke-width="4" d="M10 30h40m-40 0h40m0 0 20 20M50 30l20 20m0 0v60m0-60v60m0 0H10m60 0H10m0 0V30m0 80V30"/><path fill="none" stroke-linecap="round" stroke-width="2" d="M50 30v20m0-20v20m0 0h20m-20 0h20"/><path fill="none" stroke-linecap="round" stroke-width="4" d="M110 10H90m20 0H90m0 0v40m0-40v40m0 0h40m-40 0h40m0 0V30m0 20V30M110 30l20-20m-20 20 20-20M120 10h10m-10 0h10m0 0v10m0-10v10"/></svg>

After

Width:  |  Height:  |  Size: 519 B

View File

@@ -0,0 +1,141 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-add-process-step.jpg)
This script will prompt you for the title of the process step, then will create a stick note with the text. If an element is selected then the script will connect this new step with an arrow to the previous step (the selected element). If no element is selected, then the script assumes this is the first step in the process and will only output the sticky note with the text that was entered.
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.5.24")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
settings = ea.getScriptSettings();
//set default values on first run
if(!settings["Starting arrowhead"]) {
settings = {
"Starting arrowhead" : {
value: "none",
valueset: ["none","arrow","triangle","bar","dot"]
},
"Ending arrowhead" : {
value: "triangle",
valueset: ["none","arrow","triangle","bar","dot"]
},
"Line points" : {
value: 0,
description: "Number of line points between start and end"
},
"Gap between elements": {
value: 100
},
"Wrap text at (number of characters)": {
value: 25,
},
"Fix width": {
value: true,
description: "The object around the text should have fix width to fit the wrapped text"
}
};
ea.setScriptSettings(settings);
}
const arrowStart = settings["Starting arrowhead"].value === "none" ? null : settings["Starting arrowhead"].value;
const arrowEnd = settings["Ending arrowhead"].value === "none" ? null : settings["Ending arrowhead"].value;
// workaround until https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/388 is fixed
if (!arrowEnd) ea.style.endArrowHead = null;
if (!arrowStart) ea.style.startArrowHead = null;
const linePoints = Math.floor(settings["Line points"].value);
const gapBetweenElements = Math.floor(settings["Gap between elements"].value);
const wrapLineLen = Math.floor(settings["Wrap text at (number of characters)"].value);
const fixWidth = settings["Fix width"];
const textPadding = 10;
const text = await utils.inputPrompt("Text?");
const elements = ea.getViewSelectedElements();
const isFirst = (!elements || elements.length === 0);
const width = ea.measureText("w".repeat(wrapLineLen)).width;
let id = "";
if(!isFirst) {
const fromElement = ea.getLargestElement(elements);
ea.copyViewElementsToEAforEditing([fromElement]);
const previousTextElements = elements.filter((el)=>el.type==="text");
const previousRectElements = elements.filter((el)=> ['ellipse', 'rectangle', 'diamond'].includes(el.type));
if(previousTextElements.length>0) {
const el = previousTextElements[0];
ea.style.strokeColor = el.strokeColor;
ea.style.fontSize = el.fontSize;
ea.style.fontFamily = el.fontFamily;
}
textWidth = ea.measureText(text).width;
id = ea.addText(
fixWidth
? fromElement.x+fromElement.width/2-width/2
: fromElement.x+fromElement.width/2-textWidth/2-textPadding,
fromElement.y+fromElement.height+gapBetweenElements,
text,
{
wrapAt: wrapLineLen,
textAlign: "center",
textVerticalAlign: "middle",
box: previousRectElements.length > 0 ? previousRectElements[0].type : false,
...fixWidth
? {width: width, boxPadding:0}
: {boxPadding: textPadding}
}
);
ea.connectObjects(
fromElement.id,
null,
id,
null,
{
endArrowHead: arrowEnd,
startArrowHead: arrowStart,
numberOfPoints: linePoints
}
);
if (previousRectElements.length>0) {
const rect = ea.getElement(id);
rect.strokeColor = fromElement.strokeColor;
rect.strokeWidth = fromElement.strokeWidth;
rect.strokeStyle = fromElement.strokeStyle;
rect.roughness = fromElement.roughness;
rect.roundness = fromElement.roundness;
rect.strokeSharpness = fromElement.strokeSharpness;
rect.backgroundColor = fromElement.backgroundColor;
rect.fillStyle = fromElement.fillStyle;
rect.width = fromElement.width;
rect.height = fromElement.height;
}
await ea.addElementsToView(false,false);
} else {
id = ea.addText(
0,
0,
text,
{
wrapAt: wrapLineLen,
textAlign: "center",
textVerticalAlign: "middle",
box: "rectangle",
boxPadding: textPadding,
...fixWidth?{width: width}:null
}
);
await ea.addElementsToView(true,false);
}
ea.selectElementsInView([ea.getElement(id)]);

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,67 @@
/*
Automatically switches between the select and draw tools, based on whether a pen is being used.
1. Choose the select tool
2. Hover/use the pen to draw, move it away to return to select mode
*This is based on pen hover status, so will only work if your pen supports hover!*
If you click draw with the mouse or press select with the pen, switching will be disabled until the opposite input method is used.
**Note:** This script will stay active until the *Obsidian* window is closed.
Compatible with my *Hardware Eraser Support* script
```javascript
*/
(function() {
'use strict';
let promise
let timeout
let disable
function handlePointer(e) {
ea.setView("active");
var activeTool = ea.getExcalidrawAPI().getAppState().activeTool;
function setActiveTool(t) {
ea.getExcalidrawAPI().setActiveTool(t)
}
if (e.pointerType === 'pen') {
if (disable) return
if (!promise && activeTool.type==='selection') {
setActiveTool({type:"freedraw"})
}
if (timeout) clearTimeout(timeout)
function setTimeoutX(a,b) {
timeout = setTimeout(a,b)
return timeout
}
function revert() {
activeTool = ea.getExcalidrawAPI().getAppState().activeTool;
disable = false
if (activeTool.type==='freedraw') {
setActiveTool({type:"selection"})
} else if (activeTool.type==='selection') {
disable = true
}
promise = false
}
promise = new Promise(resolve => setTimeoutX(resolve, 500))
promise.then(() => revert())
}
}
function handleClick(e) {
ea.setView("active");
if (e.pointerType !== 'pen') {
disable = false
}
}
window.addEventListener('pointermove', handlePointer, { capture: true })
window.addEventListener('pointerdown', handleClick, { capture: true })
})();

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 448 512" style="enable-background:new 0 0 448 512;" xml:space="preserve">
<style type="text/css">
.st0{stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
</style>
<g>
<g>
<path class="st0" d="M355.8,234.1"/>
</g>
<g>
<path d="M32.3,139.7l28.8,24.2l63.5-71.7L95.7,67c-7.2-6.3-18.2-5.6-24.5,1.6l-40.6,46.6C24.3,122.4,25,133.3,32.3,139.7z"/>
<path d="M61.2,165.3l-29.6-24.9c-3.7-3.3-5.9-7.8-6.3-12.7c-0.3-4.9,1.3-9.6,4.5-13.2L70.5,68c6.7-7.6,18.3-8.4,25.9-1.7L126,92.1
L61.2,165.3z M32.9,138.9l28,23.6l62.2-70.2l-28-24.6c-6.8-5.9-17.1-5.2-23.1,1.5l-40.6,46.6c-2.9,3.3-4.3,7.5-4,11.8
C27.6,132,29.6,136,32.9,138.9z"/>
</g>
<g>
<polygon points="218.7,240.1 212.3,168.6 197.2,155.4 133.7,228.1 148.9,241.3 "/>
<path d="M148.5,242.3l-16.2-14.1l64.8-74.2l16.2,14.1l6.5,73L148.5,242.3z M135.1,228l14.1,12.3l68.4-1.2l-6.2-70.1l-14.1-12.3
L135.1,228z"/>
</g>
<g>
<polygon points="192.6,151.6 129.1,224.3 66.2,168.4 129.6,96.7 "/>
<path d="M129.2,225.7l-64.5-57.2l64.8-73.2l64.5,56.2L129.2,225.7z M67.6,168.3l61.5,54.6l62.2-71.2l-61.5-53.6L67.6,168.3z"/>
</g>
<g>
<path d="M109.7,381.6c-23.7-22.2-40-49.3-48.9-78.2c8.2-0.9,22.4-3.6,30.1-12.3c-12.6-12.5-25.3-25-37.9-37.5c0-0.1,0-0.3,0-0.4
l-23.6-22c-6,60.7,15.5,123.7,63.7,168.8s112.5,62.4,172.7,52.4l-24.1-22.6C194.8,432.3,146.9,416.4,109.7,381.6z"/>
<path d="M232.6,456.1c-19.6,0-39.2-2.8-57.9-8.3c-30.9-9.1-58.6-24.9-82.3-47.1C68.7,378.6,51.1,352,40,321.8
c-10.6-28.8-14.6-60.2-11.6-90.7l0.2-2L54,252.8v0.4c6.2,6.1,12.4,12.3,18.6,18.4c6.3,6.3,12.7,12.5,19,18.8l0.7,0.7l-0.6,0.7
c-7.2,8.1-19.8,11.3-29.5,12.5c9.2,29.2,25.9,55.6,48.3,76.6l0,0c35.8,33.5,82.4,50.5,131.3,47.9l0.4,0l25.9,24.3l-2,0.3
C255,455.2,243.8,456.1,232.6,456.1z M30.2,233.3c-5.6,62.5,17.5,122.9,63.6,166c46,43.1,107.8,62.1,169.8,52.5l-22.3-20.9
c-49.2,2.5-96.2-14.7-132.3-48.5l0,0c-22.9-21.5-39.9-48.7-49.2-78.6l-0.4-1.2l1.2-0.1c9.3-1,21.6-3.8,28.8-11.3
c-6.1-6-12.2-12.1-18.3-18.1c-6.3-6.2-12.6-12.5-18.9-18.7L52,254v-0.4L30.2,233.3z"/>
</g>
<g>
<path d="M368.8,105.4c-56-52.4-133.5-67.2-201.3-45.5l21,19.6c56.1-13.2,117.7,1.1,163.1,43.7c33,30.9,51.7,71.2,55.9,112.7
c-0.2-0.4-0.3-0.6-0.3-0.6s-25.1-0.1-36.5,12.7c11.8,11.6,23.5,23.3,35.3,34.9v0.1l2.4,2.3c0.4,0.4,0.9,0.9,1.3,1.3l0,0l17.7,16.6
C444.7,234.1,424.8,157.7,368.8,105.4z"/>
<path d="M428,305.1L409,287.3l-1.3-1.3l-2.7-2.6v-0.1c-5.8-5.7-11.5-11.4-17.3-17.1c-5.9-5.8-11.8-11.7-17.7-17.5l-0.7-0.7
l0.6-0.7c10.5-11.8,31.7-12.9,36.4-13c-4.7-42.1-24.3-81.3-55.4-110.4c-43.5-40.9-104.2-57.1-162.2-43.5l-0.5,0.1l-22.6-21.1
l1.6-0.5c70.5-22.6,148-5,202.3,45.7c54.3,50.7,76.9,126.9,58.9,198.8L428,305.1z M407,282.6l3.4,3.3l16.4,15.4
c17.1-70.7-5.3-145.3-58.7-195.2l0,0c-53.3-49.9-129.3-67.4-198.7-45.8l19.4,18.1c58.5-13.6,119.6,2.9,163.5,44.1
c31.9,29.8,51.8,70.1,56.2,113.3l0.5,5.4l-2.5-4.9c-3.8,0.1-24.3,1.1-34.5,11.7c5.7,5.6,11.3,11.2,17,16.8
c5.9,5.8,11.7,11.6,17.6,17.4L407,282.6L407,282.6z"/>
</g>
<polygon points="425.2,382.2 302.7,283.9 299.4,437.6 340.9,383.8 382.3,456.5 398,447.5 359.4,379.8 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -0,0 +1,369 @@
/*
With This Script it is possible to make boolean Operations on Shapes.
The style of the resulting shape will be the style of the highest ranking Element that was used.
The ranking of the elemtns is based on their background. The "denser" the background, the higher the ranking (the order of backgroundstyles is shown below). If they have the same background the opacity will decide. If thats also the same its decided by the order they were created.
The ranking is also important for the diffrence operation, so a tranparent object for example will cut a hole into a solid object.
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-boolean-operations-showcase.png)
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-boolean-operations-element-ranking.png)
See documentation for more details:
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.9.20")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
const ShadowGroupMarker = "ShadowCloneOf-";
const elements = ea.getViewSelectedElements().filter(
el=>["ellipse", "rectangle", "diamond"].includes(el.type) ||
el.groupIds.some(id => id.startsWith(ShadowGroupMarker)) ||
(["line", "arrow"].includes(el.type) && el.roundness === null)
);
if(elements.length === 0) {
new Notice ("Select ellipses, rectangles or diamonds");
return;
}
const PolyBool = ea.getPolyBool();
const polyboolAction = await utils.suggester(["union (a + b)", "intersect (a && b)", "diffrence (a - b)", "reversed diffrence (b - a)", "xor"], [
PolyBool.union, PolyBool.intersect, PolyBool.difference, PolyBool.differenceRev, PolyBool.xor
], "What would you like todo with the object");
const shadowClones = elements.filter(element => element.groupIds.some(id => id.startsWith(ShadowGroupMarker)));
shadowClones.forEach(shadowClone => {
let parentId = shadowClone.groupIds
.filter(id => id.startsWith(ShadowGroupMarker))[0]
.slice(ShadowGroupMarker.length);
const shadowCloneIndex = elements.findIndex(element => element.id == parentId);
if (shadowCloneIndex == -1) return;
elements[shadowCloneIndex].backgroundColor = shadowClone.backgroundColor;
elements[shadowCloneIndex].fillStyle = shadowClone.fillStyle;
})
const borderElements = elements.filter(element => !element.groupIds.some(id => id.startsWith(ShadowGroupMarker)));
groups = ea.getMaximumGroups(borderElements);
groups = groups.map((group) => group.sort((a, b) => RankElement(b) - RankElement(a)));
groups.sort((a, b) => RankElement(b[0]) - RankElement(a[0]));
ea.style.strokeColor = groups[0][0].strokeColor;
ea.style.backgroundColor = groups[0][0].backgroundColor;
ea.style.fillStyle = groups[0][0].fillStyle;
ea.style.strokeWidth = groups[0][0].strokeWidth;
ea.style.strokeStyle = groups[0][0].strokeStyle;
ea.style.roughness = groups[0][0].roughness;
ea.style.opacity = groups[0][0].opacity;
const basePolygons = groups.shift().map(element => traceElement(element));
const toolPolygons = groups.flatMap(group => group.map(element => traceElement(element)));
const result = polyboolAction({
regions: basePolygons,
inverted: false
}, {
regions: toolPolygons,
inverted: false
});
const polygonHierachy = subordinateInnerPolygons(result.regions);
drawPolygonHierachy(polygonHierachy);
ea.deleteViewElements(elements);
ea.addElementsToView(false,false,true);
return;
function traceElement(element) {
const diamondPath = (diamond) => [
SxVEC(1/2, [0, diamond.height]),
SxVEC(1/2, [diamond.width, 0]),
addVec([SxVEC(1/2, [0, diamond.height]), ([diamond.width, 0])]),
addVec([SxVEC(1/2, [diamond.width, 0]), ([0, diamond.height])]),
SxVEC(1/2, [0, diamond.height])
];
const rectanglePath = (rectangle) => [
[0,0],
[0, rectangle.height],
[rectangle.width, rectangle.height],
[rectangle.width, 0],
[0, 0]
]
const ellipsePath = (ellipse) => {
const angle = ellipse.angle;
const width = ellipse.width;
const height = ellipse.height;
const ellipseAtPoint = (t) => {
const spanningVector = [width/2*Math.cos(t), height/2*Math.sin(t)];
const baseVector = [width/2, height/2];
return addVec([spanningVector, baseVector]);
}
let points = [];
step = (2*Math.PI)/64
for (let t = 0; t < 2*Math.PI; t = t + step) {
points.push(ellipseAtPoint(t));
}
return points;
}
let polygon;
let correctForPolygon = [0, 0];
switch (element.type) {
case "diamond":
polygon = diamondPath(element);
break;
case "rectangle":
polygon = rectanglePath(element);
break;
case "ellipse":
polygon = ellipsePath(element);
break;
case "line":
case "arrow":
if (element.angle != 0) {
let smallestX = 0;
let smallestY = 0;
element.points.forEach(point => {
if (point[0] < smallestX) smallestX = point[0];
if (point[1] < smallestY) smallestY = point[1];
});
polygon = element.points.map(point => {
return [
point[0] -= smallestX,
point[1] -= smallestY
];
});
correctForPolygon = [smallestX, smallestY];
break;
}
if (element.roundness) {
new Notice("This script does not work with curved lines or arrows yet!");
return [];
}
polygon = element.points;
default:
break;
}
if (element.angle == 0) return polygon.map(v => addVec([v, [element.x, element.y]]));
polygon = polygon.map(v => addVec([v, SxVEC(-1/2, [element.width, element.height])]));
polygon = rotateVectorsByAngle(polygon, element.angle);
return polygon.map(v => addVec([v, [element.x, element.y], SxVEC(1/2, [element.width, element.height]), correctForPolygon]));
}
function RankElement(element) {
let score = 0;
const backgroundRank = [
"dashed",
"none",
"hachure",
"zigzag",
"zigzag-line",
"cross-hatch",
"solid"
]
score += (backgroundRank.findIndex((fillStyle) => fillStyle == element.fillStyle) + 1) * 10;
if (element.backgroundColor == "transparent") score -= 100;
if (element.points && getVectorLength(element.points[element.points.length - 1]) > 8) score -= 100;
if (score < 0) score = 0;
score += element.opacity / 100;
return score;
}
function drawPolygonHierachy(polygonHierachy) {
const backgroundColor = ea.style.backgroundColor;
const strokeColor = ea.style.strokeColor;
const setInnerStyle = () => {
ea.style.backgroundColor = backgroundColor;
ea.style.strokeColor = "transparent";
}
const setBorderStyle = () => {
ea.style.backgroundColor = "transparent";
ea.style.strokeColor = strokeColor;
}
const setFilledStyle = () => {
ea.style.backgroundColor = backgroundColor;
ea.style.strokeColor = strokeColor;
}
polygonHierachy.forEach(polygon => {
setFilledStyle();
let path = polygon.path;
path.push(polygon.path[0]);
if (polygon.innerPolygons.length === 0) {
ea.addLine(path);
return;
}
const outerBorder = path;
const innerPolygons = addInnerPolygons(polygon.innerPolygons);
path = path.concat(innerPolygons.backgroundPath);
path.push(polygon.path[0]);
setInnerStyle();
const backgroundId = ea.addLine(path);
setBorderStyle();
const outerBorderId = ea.addLine(outerBorder)
const innerBorderIds = innerPolygons.borderPaths.map(path => ea.addLine(path));
const allIds = [innerBorderIds, outerBorderId, backgroundId].flat();
ea.addToGroup(allIds);
const background = ea.getElement(backgroundId);
background.groupIds.push(ShadowGroupMarker + outerBorderId);
});
}
function addInnerPolygons(polygonHierachy) {
let firstPath = [];
let secondPath = [];
let borderPaths = [];
polygonHierachy.forEach(polygon => {
let path = polygon.path;
path.push(polygon.path[0]);
borderPaths.push(path);
firstPath = firstPath.concat(path);
secondPath.push(polygon.path[0]);
drawPolygonHierachy(polygon.innerPolygons);
});
return {
backgroundPath: firstPath.concat(secondPath.reverse()),
borderPaths: borderPaths
};
}
function subordinateInnerPolygons(polygons) {
const polygonObjectPrototype = (polygon) => {
return {
path: polygon,
innerPolygons: []
};
}
const insertPolygonIntoHierachy = (polygon, hierarchy) => {
for (let i = 0; i < hierarchy.length; i++) {
const polygonObject = hierarchy[i];
let inside = null;
let pointIndex = 0;
do {
inside = pointInPolygon(polygon[pointIndex], polygonObject.path);
pointIndex++
} while (inside === null);
if (inside) {
hierarchy[i].innerPolygons = insertPolygonIntoHierachy(polygon, hierarchy[i].innerPolygons);
return hierarchy;
}
}
polygon = polygonObjectPrototype(polygon);
for (let i = 0; i < hierarchy.length; i++) {
const polygonObject = hierarchy[i];
let inside = null;
let pointIndex = 0;
do {
inside = pointInPolygon(polygonObject.path[pointIndex], polygon.path);
pointIndex++
} while (inside === null);
if (inside) {
polygon.innerPolygons.push(hierarchy.splice(i, 1)[0]);
i--;
}
}
hierarchy.push(polygon);
return hierarchy;
}
let polygonHierachy = [];
polygons.forEach(polygon => {
polygonHierachy = insertPolygonIntoHierachy(polygon, polygonHierachy);
})
return polygonHierachy;
}
/**
* Checks if the given point lays in the polygon
* @param point array [x, y]
* @param polygon array [[x, y], ...]
* @returns true if inside, false if not, null if the point is on one of the polygons vertecies
*/
function pointInPolygon(point, polygon) {
const x = point[0];
const y = point[1];
let inside = false;
// odd even test if point is in polygon
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
const xi = polygon[i][0];
const yi = polygon[i][1];
const xj = polygon[j][0];
const yj = polygon[j][1];
const intersect =
yi > y !== yj > y &&
x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
if (intersect) {
inside = !inside;
}
if ((x === xi && y === yi) || (x === xj && y === yj)) {
return null;
}
}
return inside;
}
function getVectorLength(vector) {
return Math.sqrt(vector[0]**2+vector[1]**2);
}
/**
* Adds two Vectors together
*/
function addVec(vectors) {
return vectors.reduce((acc, vec) => [acc[0] + vec[0], acc[1] + vec[1]], [0, 0]);
}
/**
* Returns the negative of the vector
*/
function negVec(vector) {
return [-vector[0], -vector[1]];
}
/**
* Multiplies Vector with a scalar
*/
function SxVEC(scalar, vector) {
return [vector[0] * scalar, vector[1] * scalar];
}
function rotateVector (vec, ang) {
var cos = Math.cos(ang);
var sin = Math.sin(ang);
return [vec[0] * cos - vec[1] * sin, vec[0] * sin + vec[1] * cos];
}
function rotateVectorsByAngle(vectors, angle) {
const cosAngle = Math.cos(angle);
const sinAngle = Math.sin(angle);
const rotationMatrix = [
[cosAngle, -sinAngle],
[sinAngle, cosAngle]
];
return applyTranformationMatrix(vectors, rotationMatrix);
}
function applyTranformationMatrix(vectors, transformationMatrix) {
const result = [];
for (const vector of vectors) {
const x = vector[0];
const y = vector[1];
const newX = transformationMatrix[0][0] * x + transformationMatrix[0][1] * y;
const newY = transformationMatrix[1][0] * x + transformationMatrix[1][1] * y;
result.push([newX, newY]);
}
return result;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,181 @@
/*
![](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-box-each-selected-groups.png)
This script will add encapsulating boxes around each of the currently selected groups in Excalidraw.
You can focus on content creation first, and then batch add consistent style boxes to each group of text.
Tips 1: You can copy the desired style to the global state using script `Copy Selected Element Style to Global`, then add boxes with the same global style using script `Box Each Selected Groups`.
Tips 2: Next you can use scripts `Expand rectangles horizontally keep text centered` and `Expand rectangles vertically keep text centered` to make the boxes the same size, if you wish.
Tips 3: If you want the left and right margins to be different from the top and bottom margins, input something like `32,16`, this will create a box with left and right margins of `32` and top and bottom margins of `16`.
See documentation for more details:
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.5.21")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
settings = ea.getScriptSettings();
//set default values on first run
if(!settings["Default padding"]) {
settings = {
"Prompt for padding?": true,
"Default padding" : {
value: 10,
description: "Padding between the bounding box of the selected elements, and the box the script creates"
},
"Remember last padding?": false
};
ea.setScriptSettings(settings);
}
let paddingStr = settings["Default padding"].value.toString();
const rememberLastPadding = settings["Remember last padding?"];
if(settings["Prompt for padding?"]) {
paddingStr = await utils.inputPrompt("padding?","string",paddingStr);
}
if(!paddingStr) {
return;
}
if(rememberLastPadding) {
settings["Default padding"].value = paddingStr;
ea.setScriptSettings(settings);
}
var paddingLR = 0;
var paddingTB = 0;
if(paddingStr.indexOf(',') > 0) {
const paddingParts = paddingStr.split(',');
paddingLR = parseInt(paddingParts[0]);
paddingTB = parseInt(paddingParts[1]);
}
else {
paddingLR = paddingTB = parseInt(paddingStr);
}
if(isNaN(paddingLR) || isNaN(paddingTB)) {
return;
}
const selectedElements = ea.getViewSelectedElements();
const groups = ea.getMaximumGroups(selectedElements);
const allIndividualArrows = ea.getMaximumGroups(ea.getViewElements())
.reduce((result, group) => (group.length === 1 && (group[0].type === 'arrow' || group[0].type === 'line')) ?
[...result, group[0]] : result, []);
for(const elements of groups) {
if(elements.length === 1 && elements[0].type ==="arrow" || elements[0].type==="line") {
// individual arrows or lines are not affected
continue;
}
const box = ea.getBoundingBox(elements);
color = ea
.getExcalidrawAPI()
.getAppState()
.currentItemStrokeColor;
// use current stroke with and style
const appState = ea.getExcalidrawAPI().getAppState();
const strokeWidth = appState.currentItemStrokeWidth;
const strokeStyle = appState.currentItemStrokeStyle;
const strokeSharpness = appState.currentItemStrokeSharpness;
const roughness = appState.currentItemRoughness;
const fillStyle = appState.currentItemFillStyle;
const backgroundColor = appState.currentItemBackgroundColor;
ea.style.strokeWidth = strokeWidth;
ea.style.strokeStyle = strokeStyle;
ea.style.strokeSharpness = strokeSharpness;
ea.style.roughness = roughness;
ea.style.fillStyle = fillStyle;
ea.style.backgroundColor = backgroundColor;
ea.style.strokeColor = color;
const id = ea.addRect(
box.topX - paddingLR,
box.topY - paddingTB,
box.width + 2*paddingLR,
box.height + 2*paddingTB
);
// Change the join point in the group to the new box
const elementsWithBounded = elements.filter(el => (el.boundElements || []).length > 0);
const boundedElementsCollection = elementsWithBounded.reduce((result, el) => [...result, ...el.boundElements], []);
for(const el of elementsWithBounded) {
el.boundElements = [];
}
const newRect = ea.getElement(id);
newRect.boundElements = boundedElementsCollection;
const elementIds = elements.map(el => el.id);
const startBindingLines = allIndividualArrows.filter(el => elementIds.includes((el.startBinding||{}).elementId));
for(startBindingLine of startBindingLines) {
startBindingLine.startBinding.elementId = id;
recalculateStartPointOfLine(startBindingLine, newRect);
}
const endBindingLines = allIndividualArrows.filter(el => elementIds.includes((el.endBinding||{}).elementId));
for(endBindingLine of endBindingLines) {
endBindingLine.endBinding.elementId = id;
recalculateEndPointOfLine(endBindingLine, newRect);
}
ea.copyViewElementsToEAforEditing(elements);
ea.addToGroup([id].concat(elements.map((el)=>el.id)));
}
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<line.points.length; i++) {
line.points[i][0] -= intersectA[0][0] - line.x;
line.points[i][1] -= intersectA[0][1] - line.y;
}
line.x = intersectA[0][0];
line.y = intersectA[0][1];
}
}
function recalculateEndPointOfLine(line, el) {
const aX = el.x + el.width/2;
const bX = line.x + line.points[line.points.length-2][0];
const aY = el.y + el.height/2;
const bY = line.y + line.points[line.points.length-2][1];
line.endBinding.gap = 8;
line.endBinding.focus = 0;
const intersectA = ea.intersectElementWithLine(
el,
[bX, bY],
[aX, aY],
line.endBinding.gap
);
if(intersectA.length > 0) {
line.points[line.points.length - 1] = [intersectA[0][0] - line.x, intersectA[0][1] - line.y];
}
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250 160" stroke="#000"><path fill="none" stroke-linecap="round" stroke-width="4" d="M10 30h70m-70 0h70M10 20h70m-70 0h70M60 55c0 .87-.08 1.75-.23 2.6-.15.86-.38 1.71-.67 2.53-.3.82-.68 1.62-1.11 2.37-.43.75-.94 1.48-1.5 2.14-.56.67-1.18 1.29-1.85 1.85-.66.56-1.39 1.07-2.14 1.5-.75.43-1.55.81-2.37 1.11-.82.29-1.67.52-2.53.67-.85.15-1.73.23-2.6.23-.87 0-1.75-.08-2.6-.23-.86-.15-1.71-.38-2.53-.67-.82-.3-1.62-.68-2.37-1.11-.75-.43-1.48-.94-2.14-1.5-.67-.56-1.29-1.18-1.85-1.85-.56-.66-1.07-1.39-1.5-2.14-.43-.75-.81-1.55-1.11-2.37-.29-.82-.52-1.67-.67-2.53-.15-.85-.23-1.73-.23-2.6 0-.87.08-1.75.23-2.6.15-.86.38-1.71.67-2.53.3-.82.68-1.62 1.11-2.37.43-.75.94-1.48 1.5-2.14.56-.67 1.18-1.29 1.85-1.85.66-.56 1.39-1.07 2.14-1.5.75-.43 1.55-.81 2.37-1.11.82-.29 1.67-.52 2.53-.67.85-.15 1.73-.23 2.6-.23.87 0 1.75.08 2.6.23.86.15 1.71.38 2.53.67.82.3 1.62.68 2.37 1.11.75.43 1.48.94 2.14 1.5.67.56 1.29 1.18 1.85 1.85.56.66 1.07 1.39 1.5 2.14.43.75.81 1.55 1.11 2.37.29.82.52 1.67.67 2.53.15.85.19 2.17.23 2.6.04.43.04-.43 0 0M26 110c4.05 4.62 8.09 9.25 14 16m-14-16 14 16m0 0-14 14m14-14-14 14m0 0-16-14m16 14c-3.54-3.1-7.09-6.2-16-14m0 0 16-16m-16 16 16-16M50 110h30m-30 0h30M50 140h30m-30 0h30M160 30h70m-70 0h70M160 20h70m-70 0h70M210 55c0 .87-.08 1.75-.23 2.6-.15.86-.38 1.71-.67 2.53-.3.82-.68 1.62-1.11 2.37-.43.75-.94 1.48-1.5 2.14-.56.67-1.18 1.29-1.85 1.85-.66.56-1.39 1.07-2.14 1.5-.75.43-1.55.81-2.37 1.11-.82.29-1.67.52-2.53.67-.85.15-1.73.23-2.6.23-.87 0-1.75-.08-2.6-.23-.86-.15-1.71-.38-2.53-.67-.82-.3-1.62-.68-2.37-1.11-.75-.43-1.48-.94-2.14-1.5-.67-.56-1.29-1.18-1.85-1.85-.56-.66-1.07-1.39-1.5-2.14-.43-.75-.81-1.55-1.11-2.37-.29-.82-.52-1.67-.67-2.53-.15-.85-.23-1.73-.23-2.6 0-.87.08-1.75.23-2.6.15-.86.38-1.71.67-2.53.3-.82.68-1.62 1.11-2.37.43-.75.94-1.48 1.5-2.14.56-.67 1.18-1.29 1.85-1.85.66-.56 1.39-1.07 2.14-1.5.75-.43 1.55-.81 2.37-1.11.82-.29 1.67-.52 2.53-.67.85-.15 1.73-.23 2.6-.23.87 0 1.75.08 2.6.23.86.15 1.71.38 2.53.67.82.3 1.62.68 2.37 1.11.75.43 1.48.94 2.14 1.5.67.56 1.29 1.18 1.85 1.85.56.66 1.07 1.39 1.5 2.14.43.75.81 1.55 1.11 2.37.29.82.52 1.67.67 2.53.15.85.19 2.17.23 2.6.04.43.04-.43 0 0M176 110c4.53 5.17 9.05 10.34 14 16m-14-16c5.5 6.28 10.99 12.56 14 16m0 0-14 14m14-14-14 14m0 0-16-14m16 14c-5.47-4.79-10.94-9.57-16-14m0 0 16-16m-16 16 16-16M200 110h30m-30 0h30M200 140h30m-30 0h30M150 10h90m-90 0h90m0 0v70m0-70v70m0 0h-90m90 0h-90m0 0V10m0 70V10M150 100h90m-90 0h90m0 0v50m0-50v50m0 0h-90m90 0h-90m0 0v-50m0 50v-50"/><g fill-rule="evenodd" stroke-linecap="round"><path stroke-width="0" d="m100 20 31.17 59.33-28.84 60L100 20"/><path fill="none" stroke-width="4" d="M100 20c11.09 21.12 22.19 42.24 31.17 59.33M100 20c9.23 17.58 18.47 35.16 31.17 59.33m0 0c-8.1 16.84-16.19 33.68-28.84 60m28.84-60c-10.41 21.65-20.81 43.3-28.84 60m0 0C101.45 94.2 100.57 49.07 100 20m2.33 119.33c-.57-29.27-1.15-58.55-2.33-119.33m0 0s0 0 0 0m0 0s0 0 0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 2.9 KiB

View File

@@ -0,0 +1,52 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-change-shape.jpg)
The script allows you to change the shape and fill style of selected Rectangles, Diamonds, Ellipses, Lines, Arrows and Freedraw.
```javascript
*/
const fillStylesDispaly=["Dots (⚠ VERY SLOW performance on large objects!)","Zigzag","Zigzag-line", "Dashed", "Hachure", "Cross-hatch", "Solid"];
const fillStyles=["dots","zigzag","zigzag-line", "dashed", "hachure", "cross-hatch", "solid"];
const fillShapes=["ellipse","rectangle","diamond", "freedraw", "line"];
const boxShapesDispaly=["○ ellipse","□ rectangle","◇ diamond"];
const boxShapes=["ellipse","rectangle","diamond"];
const lineShapesDispaly=["- line","⭢ arrow"];
const lineShapes=["line","arrow"];
let editedElements = [];
let elements = ea.getViewSelectedElements().filter(el=>boxShapes.contains(el.type));
if (elements.length>0) {
newShape = await utils.suggester(boxShapesDispaly, boxShapes, "Change shape of 'box' type elements in selection, press ESC to skip");
if(newShape) {
editedElements = elements;
elements.forEach(el=>el.type = newShape);
}
}
elements = ea.getViewSelectedElements().filter(el=>fillShapes.contains(el.type));
if (elements.length>0) {
newFillStyle = await utils.suggester(fillStylesDispaly, fillStyles, "Change the fill style of elements in selection, press ESC to skip");
if(newFillStyle) {
editedElements = editedElements.concat(elements.filter(e=>!editedElements.some(el=>el.id===e.id)));
elements.forEach(el=>el.fillStyle = newFillStyle);
}
}
elements = ea.getViewSelectedElements().filter(el=>lineShapes.contains(el.type));
if (elements.length>0) {
newShape = await utils.suggester(lineShapesDispaly, lineShapes, "Change shape of 'line' type elements in selection, press ESC to skip");
if(newShape) {
editedElements = editedElements.concat(elements.filter(e=>!editedElements.some(el=>el.id===e.id)));
elements.forEach((el)=>{
el.type = newShape;
if(newShape === "arrow") {
el.endArrowhead = "triangle";
}
});
}
}
ea.copyViewElementsToEAforEditing(editedElements);
ea.addElementsToView(false,false);

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="5 5 170 70" stroke="#000"><path fill="none" stroke-linecap="round" stroke-width="4" d="M10 10h60m-60 0h60m0 0v60m0-60v60m0 0H10m60 0H10m0 0V10m0 60V10M141 10c6.47 6.91 12.94 13.83 29 31m-29-31c9.29 9.93 18.57 19.86 29 31m0 0-29 29m29-29-29 29m0 0c-10.49-9.82-20.99-19.64-31-29m31 29c-7.35-6.88-14.71-13.76-31-29m0 0 31-31m-31 31 31-31"/><g stroke-linecap="round"><path fill="none" stroke-width="4" d="M80 40h20m-20 0h20"/><path fill-rule="evenodd" stroke-width="0" d="m100 40-9.06 4.23v-8.46L100 40"/><path fill="none" stroke-width="4" d="M100 40c-3.14 1.47-6.29 2.93-9.06 4.23M100 40c-3.13 1.46-6.27 2.92-9.06 4.23m0 0v-8.46m0 8.46v-8.46m0 0c3.38 1.58 6.76 3.16 9.06 4.23m-9.06-4.23c2.17 1.02 4.34 2.03 9.06 4.23m0 0s0 0 0 0m0 0s0 0 0 0"/></g></svg>

After

Width:  |  Height:  |  Size: 802 B

View File

@@ -0,0 +1,102 @@
/*
Connects two lines. Lines may be type of arrow or line. The resulting line will carry the style of the line higher in the drawing layers (bring to front the one you want to control the look and feel). Arrows are connected intelligently.
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-concatenate-lines.png)
```js*/
const lines = ea.getViewSelectedElements().filter(el=>el.type==="line" || el.type==="arrow");
if(lines.length !== 2) {
new Notice ("Select two lines or arrows");
return;
}
// https://math.stackexchange.com/questions/2204520/how-do-i-rotate-a-line-segment-in-a-specific-point-on-the-line
const rotate = (point, element) => {
const [x1, y1] = point;
const x2 = element.x + element.width/2;
const y2 = element.y - element.height/2;
const angle = element.angle;
return [
(x1 - x2) * Math.cos(angle) - (y1 - y2) * Math.sin(angle) + x2,
(x1 - x2) * Math.sin(angle) + (y1 - y2) * Math.cos(angle) + y2,
];
}
const points = lines.map(
el=>el.points.map(p=>rotate([p[0]+el.x, p[1]+el.y],el))
);
const last = (p) => p[p.length-1];
const first = (p) => p[0];
const distance = (p1,p2) => Math.sqrt((p1[0]-p2[0])**2+(p1[1]-p2[1])**2);
const distances = [
distance(first(points[0]),first(points[1])),
distance(first(points[0]),last (points[1])),
distance(last (points[0]),first(points[1])),
distance(last (points[0]),last (points[1]))
];
const connectDirection = distances.indexOf(Math.min(...distances));
let newPoints = [];
switch(connectDirection) {
case 0: //first-first
newPoints = [...points[0].reverse(),...points[1].slice(1)];
break;
case 1: //first-last
newPoints = [...points[0].reverse(),...points[1].reverse().slice(1)];
break;
case 2: //last-first
newPoints = [...points[0],...points[1].slice(1)];
break;
case 3: //last-last
newPoints = [...points[0],...points[1].reverse().slice(1)];
break;
}
["strokeColor", "backgrounColor", "fillStyle", "roundness", "roughness", "strokeWidth", "strokeStyle", "opacity"].forEach(prop=>{
ea.style[prop] = lines[1][prop];
})
ea.style.startArrowHead = null;
ea.style.endArrowHead = null;
ea.copyViewElementsToEAforEditing(lines);
ea.getElements().forEach(el=>{el.isDeleted = true});
const lineTypes = parseInt(lines.map(line => line.type === "line" ? '1' : '0').join(''),2);
switch (lineTypes) {
case 0: //arrow - arrow
ea.addArrow(
newPoints,
connectDirection === 0 //first-first
? { startArrowHead: lines[0].endArrowhead, endArrowHead: lines[1].endArrowhead }
: connectDirection === 1 //first-last
? { startArrowHead: lines[0].endArrowhead, endArrowHead: lines[1].startArrowhead }
: connectDirection === 2 //last-first
? { startArrowHead: lines[0].startArrowhead, endArrowHead: lines[1].endArrowhead }
//3: last-last
: { startArrowHead: lines[0].startArrowhead, endArrowHead: lines[1].startArrowhead }
);
break;
case 1: //arrow - line
reverse = connectDirection === 0 || connectDirection === 1;
ea.addArrow(newPoints,{
startArrowHead: reverse ? lines[0].endArrowhead : lines[0].startArrowhead,
endArrowHead: reverse ? lines[0].startArrowhead : lines[0].endArrowhead
});
break;
case 2: //line - arrow
reverse = connectDirection === 1 || connectDirection === 3;
ea.addArrow(newPoints,{
startArrowHead: reverse ? lines[1].endArrowhead : lines[1].startArrowhead,
endArrowHead: reverse ? lines[1].startArrowhead : lines[1].endArrowhead
});
break;
case 3: //line - line
ea.addLine(newPoints);
break;
}
ea.addElementsToView();

View File

@@ -0,0 +1,17 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 72.75819749055177 80.03703336574608" width="72.75819749055177" height="80.03703336574608">
<!-- svg-source:excalidraw -->
<defs>
<style class="style-fonts">
@font-face {
font-family: "Virgil";
src: url("https://excalidraw.com/Virgil.woff2");
}
@font-face {
font-family: "Cascadia";
src: url("https://excalidraw.com/Cascadia.woff2");
}
</style>
</defs>
<g stroke-linecap="round"><g transform="translate(4 4) rotate(0 12.71901889991409 17.183109917454658)"><path d="M0 0 C0 7.02, 0 14.05, 0 34.37 M0 34.37 C7.62 34.37, 15.24 34.37, 25.44 34.37" stroke="black" stroke-width="4.5" fill="none" stroke-dasharray="1.5 10"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(51.379765518092086 61.93633577499986) rotate(0 5.684341886080802e-14 7.050348795373111)"><path d="M0 0 C0 4.06, 0 8.11, 0 14.1" stroke="black" stroke-width="4.5" fill="none" stroke-dasharray="1.5 10"></path></g></g><mask></mask><g stroke-linecap="round" transform="translate(34.0013341989918 20.987787610339183) rotate(0 17.378431645779926 17.378431645779983)"><path d="M34.76 17.38 C34.76 18.38, 34.67 19.41, 34.49 20.4 C34.32 21.39, 34.05 22.38, 33.71 23.32 C33.36 24.27, 32.93 25.2, 32.43 26.07 C31.93 26.94, 31.34 27.78, 30.69 28.55 C30.04 29.32, 29.32 30.04, 28.55 30.69 C27.78 31.34, 26.94 31.93, 26.07 32.43 C25.2 32.93, 24.27 33.36, 23.32 33.71 C22.38 34.05, 21.39 34.32, 20.4 34.49 C19.41 34.67, 18.38 34.76, 17.38 34.76 C16.37 34.76, 15.35 34.67, 14.36 34.49 C13.37 34.32, 12.38 34.05, 11.43 33.71 C10.49 33.36, 9.56 32.93, 8.69 32.43 C7.82 31.93, 6.98 31.34, 6.21 30.69 C5.44 30.04, 4.71 29.32, 4.07 28.55 C3.42 27.78, 2.83 26.94, 2.33 26.07 C1.83 25.2, 1.39 24.27, 1.05 23.32 C0.7 22.38, 0.44 21.39, 0.26 20.4 C0.09 19.41, 0 18.38, 0 17.38 C0 16.37, 0.09 15.35, 0.26 14.36 C0.44 13.37, 0.7 12.38, 1.05 11.43 C1.39 10.49, 1.83 9.56, 2.33 8.69 C2.83 7.82, 3.42 6.98, 4.07 6.21 C4.71 5.44, 5.44 4.71, 6.21 4.07 C6.98 3.42, 7.82 2.83, 8.69 2.33 C9.56 1.83, 10.49 1.39, 11.43 1.05 C12.38 0.7, 13.37 0.44, 14.36 0.26 C15.35 0.09, 16.37 0, 17.38 0 C18.38 0, 19.41 0.09, 20.4 0.26 C21.39 0.44, 22.38 0.7, 23.32 1.05 C24.27 1.39, 25.2 1.83, 26.07 2.33 C26.94 2.83, 27.78 3.42, 28.55 4.07 C29.32 4.71, 30.04 5.44, 30.69 6.21 C31.34 6.98, 31.93 7.82, 32.43 8.69 C32.93 9.56, 33.36 10.49, 33.71 11.43 C34.05 12.38, 34.32 13.37, 34.49 14.36 C34.67 15.35, 34.71 16.88, 34.76 17.38 C34.8 17.88, 34.8 16.88, 34.76 17.38" stroke="black" stroke-width="4" fill="none"></path></g><g stroke-linecap="round"><g transform="translate(41.72257566145686 38.36621939788711) rotate(0 9.65718949485347 0)"><path d="M0 0 C4.11 0, 8.22 0, 19.31 0 M0 0 C6.95 0, 13.9 0, 19.31 0" stroke="black" stroke-width="4" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(41.72257587602678 38.36622004108449) rotate(89.99999999999994 9.65718949485347 0)"><path d="M0 0 C5.31 0, 10.62 0, 19.31 0 M0 0 C4.56 0, 9.13 0, 19.31 0" stroke="black" stroke-width="4" fill="none"></path></g></g><mask></mask></svg>

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@@ -0,0 +1,43 @@
/*
![](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-copy-selected-element-styles-to-global.png)
This script will copy styles of any selected element into Excalidraw's global styles.
After copying the styles of element such as box, text, or arrow using this script, You can then use Excalidraw's box, arrow, and other tools to create several elements with the same style. This is sometimes more convenient than `Copy Styles` and `Paste Styles`, especially when used with the script `Box Each Selected Groups`.
See documentation for more details:
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
```javascript
*/
const element = ea.getViewSelectedElement();
const appState = ea.getExcalidrawAPI().getAppState();
if(!element) {
return;
}
appState.currentItemStrokeWidth = element.strokeWidth;
appState.currentItemStrokeStyle = element.strokeStyle;
appState.currentItemStrokeSharpness = element.strokeSharpness;
appState.currentItemRoughness = element.roughness;
appState.currentItemFillStyle = element.fillStyle;
appState.currentItemBackgroundColor = element.backgroundColor;
appState.currentItemStrokeColor = element.strokeColor;
if(element.type === 'text') {
appState.currentItemFontFamily = element.fontFamily;
appState.currentItemFontSize = element.fontSize;
appState.currentItemTextAlign = element.textAlign;
}
if(element.type === 'arrow') {
appState.currentItemStartArrowhead = element.startArrowhead;
appState.currentItemEndArrowhead = element.endArrowhead;
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path d="M224 0H336C362.5 0 384 21.49 384 48V256H0V48C0 21.49 21.49 0 48 0H64L96 64L128 0H160L192 64L224 0zM384 288V320C384 355.3 355.3 384 320 384H256V448C256 483.3 227.3 512 192 512C156.7 512 128 483.3 128 448V384H64C28.65 384 0 355.3 0 320V288H384zM192 464C200.8 464 208 456.8 208 448C208 439.2 200.8 432 192 432C183.2 432 176 439.2 176 448C176 456.8 183.2 464 192 464z"/></svg>

After

Width:  |  Height:  |  Size: 443 B

View File

@@ -0,0 +1,61 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-ellipse-elements.png)
This script will add an encapsulating ellipse around the currently selected elements in Excalidraw.
See documentation for more details:
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.5.21")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
settings = ea.getScriptSettings();
//set default values on first run
if(!settings["Default padding"]) {
settings = {
"Prompt for padding?": true,
"Default padding" : {
value: 10,
description: "Padding between the bounding box of the selected elements, and the ellipse the script creates"
}
};
ea.setScriptSettings(settings);
}
let padding = settings["Default padding"].value;
if(settings["Prompt for padding?"]) {
padding = parseInt (await utils.inputPrompt("padding?","number",padding.toString()));
}
if(isNaN(padding)) {
new Notice("The padding value provided is not a number");
return;
}
elements = ea.getViewSelectedElements();
const box = ea.getBoundingBox(elements);
color = ea
.getExcalidrawAPI()
.getAppState()
.currentItemStrokeColor;
//uncomment for random color:
//color = '#'+(Math.random()*0xFFFFFF<<0).toString(16).padStart(6,"0");
ea.style.strokeColor = color;
const ellipseWidth = box.width/Math.sqrt(2);
const ellipseHeight = box.height/Math.sqrt(2);
const topX = box.topX - (ellipseWidth - box.width/2);
const topY = box.topY - (ellipseHeight - box.height/2);
id = ea.addEllipse(
topX - padding,
topY - padding,
2*ellipseWidth + 2*padding,
2*ellipseHeight + 2*padding
);
ea.copyViewElementsToEAforEditing(elements);
ea.addToGroup([id].concat(elements.map((el)=>el.id)));
ea.addElementsToView(false,false);

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,12 @@
/*
Creates a new Excalidraw.com collaboration room and places the link to the room on the clipboard.
```js*/
const room = Array.from(window.crypto.getRandomValues(new Uint8Array(10))).map((byte) => `0${byte.toString(16)}`.slice(-2)).join("");
const key = (await window.crypto.subtle.exportKey("jwk",await window.crypto.subtle.generateKey({name:"AES-GCM",length:128},true,["encrypt", "decrypt"]))).k;
const link = `https://excalidraw.com/#room=${room},${key}`;
ea.addIFrame(0,0,800,600,link);
ea.addElementsToView(true,true);
window.navigator.clipboard.writeText(link);
new Notice("The collaboration room link is available on the clipboard.",4000);

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke-width="2" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"><g stroke-width="1.5"></path><circle cx="9" cy="7" r="4"></circle><path d="M3 21v-2a4 4 0 0 1 4 -4h4a4 4 0 0 1 4 4v2"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path><path d="M21 21v-2a4 4 0 0 0 -3 -3.85"></path></g></svg>

After

Width:  |  Height:  |  Size: 382 B

View File

@@ -0,0 +1,67 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-grid-selected-images.png)
This script arranges selected images into compact grid view, removing gaps in-between, resizing when necessary and breaking into multiple rows/columns.
```javascript
*/
try {
let els = ea.getViewSelectedElements().filter(el => el.type == 'image');
new Notice(els.length);
if (els.length == 0) throw new Error('No image elements selected');
const bounds = ea.getBoundingBox(els);
const { topX, topY, width, height } = bounds;
els.sort((a, b) => a.x + a.y < b.x + b.y);
const areaAvailable = width * height;
let elWidth = els[0].width;
let elHeight = els[0].height;
if (elWidth * elHeight > areaAvailable) {
while (elWidth * elHeight > areaAvailable) {
elWidth /= 1.1;
elHeight /= 1.1;
}
} else if (elWidth * elHeight < areaAvailable) {
while (elWidth * elHeight > areaAvailable) {
elWidth *= 1.1;
elHeight *= 1.1;
}
}
const rows = (width - elWidth) / elWidth;
let row = 0, column = 0;
for (const element of els) {
element.x = topX + (elWidth * row);
element.y = topY + (elHeight * column);
if (element.width > elWidth) {
while (element.width >= elWidth) {
element.width /= 1.1;
element.height /= 1.1;
}
} else if (element.width < elWidth) {
while (element.width <= elWidth) {
element.width *= 1.1;
element.height *= 1.1;
}
}
row++;
if (row > rows) {
row = 0;
column++;
}
}
ea.addElementsToView(false, true, true);
} catch (err) {
_ = new Notice(err.toString())
}

View File

@@ -0,0 +1,2 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 376.3492303436433 256.64929991179815" stroke="#000">
<g stroke-linecap="round" transform="translate(10 10) rotate(0 58.5858154296875 58.5858154296875)"><path d="M-1.64 1.57 C38.67 2.87, 77.63 0.2, 117.31 1.14 M-0.05 -0.5 C40.75 0.3, 82.48 0.12, 118.09 0.99 M116.67 0.11 C118.02 47.69, 116.43 92.18, 118.63 118.15 M117.41 0.39 C116.57 38.93, 117.51 79.53, 116.57 116.49 M118.65 117.22 C92.96 119.01, 66.56 117.46, -0.42 117.17 M117.21 116.56 C91.43 117.53, 63.4 117.03, -0.23 117.71 M1.5 116.9 C-2.3 91.83, 1.37 68.12, -0.05 -0.85 M-0.84 116.86 C-1.03 87.92, -0.86 61.1, 0.54 0.72" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(128.96603337932902 10.2586194164669) rotate(0 58.5858154296875 58.5858154296875)"><path d="M0.05 1.78 C24.68 -1.8, 48.73 0.22, 118.17 0.33 M-0.27 0.22 C34.72 0.61, 69.52 1.58, 118.12 0.36 M117.6 1.43 C115.71 34.53, 118.33 70.74, 117.89 116.98 M116.68 -0.46 C117.9 41.7, 116.85 81.21, 116.34 117.29 M118.4 119.11 C83.22 117.59, 48.31 117.2, -1.44 117.99 M118.15 116.77 C74.14 115.56, 31.55 116.99, -0.96 117.69 M-1.69 115.77 C1.1 78.33, -0.93 41, -1.14 1.03 M-0.43 116.37 C0.72 90.14, 1.52 62.17, 0.55 -0.66" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(248.3020093440573 10.465294492851172) rotate(0 58.5858154296875 58.5858154296875)"><path d="M0.39 -0.88 C44.51 0.1, 89.74 -0.71, 117.03 -0.11 M0.42 0.03 C30.22 0.74, 59.56 0.11, 117.15 -0.25 M116 -0.35 C118.88 36.78, 118.14 71.41, 118.16 117.65 M117.62 0.75 C115.99 39.07, 115.76 79.63, 117.09 117.91 M117.44 117.56 C81.29 118.3, 44.81 119.12, 1.29 117.25 M116.84 116.27 C88.98 117.24, 60.29 117.22, 0.21 117.92 M1.97 115.99 C0.94 82.75, -0.15 51.05, -1.24 -1.67 M-0.26 118 C1.05 86.36, 1.06 53.45, 0.95 0.65" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(10.875590140210988 129.01237455957016) rotate(0 58.5858154296875 58.5858154296875)"><path d="M0.24 -0.16 C29.59 1.02, 57.45 2.91, 117.44 0.38 M0.41 0.64 C32.74 0.23, 66.39 0.45, 116.84 -0.9 M118.21 0.43 C119.3 32.21, 116.11 63.55, 119.15 115.99 M117.68 -0.62 C115.84 34.54, 116.24 68.9, 116.91 118 M115.86 119.08 C76.96 118.61, 32.48 117.59, -1.75 116.45 M117.39 116.77 C85.7 116.42, 54.91 116.16, 0.1 118.13 M-0.18 118.45 C-0.52 71.18, -0.96 24.41, 1.23 0.16 M0.3 117.66 C0.57 92.18, 0.07 65.33, -0.4 0.17" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(129.84162351954 129.27099397603888) rotate(0 58.5858154296875 58.5858154296875)"><path d="M-0.16 1.48 C27.24 1.09, 56.31 0.13, 117.56 -0.42 M0.64 0.04 C34.52 0.5, 69.88 -0.81, 116.27 -0.23 M117.6 1.5 C115.78 39.75, 114.64 84.85, 115.99 117.12 M116.55 -0.84 C116.19 29.74, 115.7 60.09, 118 117.71 M119.08 118.46 C74.37 114.72, 29.76 114.66, -0.72 116.45 M116.77 116.64 C81.73 117.03, 46.47 117.52, 0.96 118.05 M1.28 117.07 C0.37 77.34, -0.95 39.83, 0.16 -1.64 M0.49 117.63 C0.17 83.07, -1.11 48.64, 0.17 0.23" stroke-width="2" fill="none"></path></g><g stroke-linecap="round" transform="translate(249.17759948426828 129.47766905242315) rotate(0 58.5858154296875 58.5858154296875)"><path d="M1.48 0.05 C26.67 2.03, 51.16 0.48, 116.75 0 M0.04 -0.61 C27.7 -1.15, 53.12 -1.65, 116.94 0.54 M118.67 -0.27 C116.09 22.53, 119.75 46.69, 117.12 116.32 M116.34 -0.31 C117.34 27.65, 117.51 57.73, 117.71 117.89 M118.46 117.96 C73.87 118.06, 32.19 117.57, -0.72 117.14 M116.64 116.71 C84.55 115.98, 52.82 117.66, 0.88 117.52 M-0.11 116.63 C-0.44 89.26, 1.33 65.24, -1.64 -0.19 M0.46 117.75 C-0.38 77.25, -0.75 38.91, 0.23 0.69" stroke-width="2" fill="none"></path></g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View File

@@ -0,0 +1,75 @@
/*
Adds support for pen inversion, a.k.a. the hardware eraser on the back of your pen.
Simply use the eraser on a supported pen, and it will erase. Your previous tool will be restored when the eraser leaves the screen.
(Tested with a surface pen, but should work with all windows ink devices, and probably others)
**Note:** This script will stay active until the *Obsidian* window is closed.
Compatible with my *Auto Draw for Pen* script
```javascript
*/
(function() {
'use strict';
let activated
let revert
function handlePointer(e) {
const activeTool = ea.getExcalidrawAPI().getAppState().activeTool;
const isEraser = e.pointerType === 'pen' && e.buttons & 32
function setActiveTool(t) {
ea.getExcalidrawAPI().setActiveTool(t)
}
if (!activated && isEraser) {
//Store previous tool
const btns = document.querySelectorAll('.App-toolbar input.ToolIcon_type_radio')
for (const i in btns) {
if (btns[i]?.checked) {
revert = btns[i]
}
}
revert = activeTool
// Activate eraser tool
setActiveTool({type: "eraser"})
activated = true
// Force Excalidraw to recognize this the same as pen tip
// https://github.com/excalidraw/excalidraw/blob/4a9fac2d1e5c4fac334201ef53c6f5d2b5f6f9f5/src/components/App.tsx#L2945-L2951
Object.defineProperty(e, 'button', {
value: 0,
writable: false
});
}
// Keep on eraser!
if (isEraser && activated) {
setActiveTool({type: "eraser"})
}
if (activated && !isEraser) {
// Revert tool on release
// revert.click()
setActiveTool(revert)
activated = false
// Force delete "limbo" elements
// This doesn't happen on the web app
// It's a bug caused by switching to eraser during a stroke
ea.setView("active");
var del = []
for (const i in ea.getViewElements()) {
const element = ea.getViewElements()[i];
if (element.opacity === 20) {
del.push(element)
}
}
ea.deleteViewElements(del)
setActiveTool(revert)
}
}
window.addEventListener('pointerdown', handlePointer, { capture: true })
window.addEventListener('pointermove', handlePointer, { capture: true })
})();

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 448 512" style="enable-background:new 0 0 448 512;" xml:space="preserve">
<style type="text/css">
.st0{stroke:#000000;stroke-width:2;stroke-miterlimit:10;}
</style>
<path class="st0" d="M355.8,234.1"/>
<g>
<path class="st0" d="M404.8,293.5L306.9,208l-120,137.4l97.9,85.5c13.6,11.9,34.4,10.5,46.3-3.1l76.8-88
C419.9,326.2,418.5,305.5,404.8,293.5z M389.4,322.2l-78.2,89.6c-3.8,4.3-10.4,4.8-14.8,1l-77.8-68l92-105.3l77.8,68
C392.8,311.2,393.2,317.8,389.4,322.2z"/>
<polygon class="st0" points="52.4,103.7 64.4,238.9 93,263.8 213,126.4 184.4,101.4 "/>
<rect x="108.3" y="185.1" transform="matrix(0.6578 -0.7532 0.7532 0.6578 -108.9276 230.7956)" class="st0" width="182.4" height="100.3"/>
<path class="st0" d="M109.7,381.6c-23.7-22.2-40-49.3-48.9-78.2c8.2-0.9,22.4-3.6,30.1-12.3c-12.6-12.5-25.3-25-37.9-37.5
c0-0.1,0-0.3,0-0.4l-23.6-22c-6,60.7,15.5,123.7,63.7,168.8s112.5,62.4,172.7,52.4l-24.1-22.6C194.8,432.3,146.9,416.4,109.7,381.6
z"/>
<path class="st0" d="M368.8,105.4c-56-52.4-133.5-67.2-201.3-45.5l21,19.6c56.1-13.2,117.7,1.1,163.1,43.7
c33,30.9,51.7,71.2,55.9,112.7c-0.2-0.4-0.3-0.6-0.3-0.6s-25.1-0.1-36.5,12.7c11.8,11.6,23.5,23.3,35.3,34.9c0,0,0,0.1,0,0.1
l2.4,2.3c0.4,0.4,0.9,0.9,1.3,1.3c0,0,0,0,0,0l17.7,16.6C444.7,234.1,424.8,157.7,368.8,105.4z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,370 @@
/*
format **the left to right** mind map
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-mindmap-format-1.png)
# tree
Mind map is actually a tree, so you must have a **root node**. The script will determine **the leftmost element** of the selected element as the root element (node is excalidraw element, e.g. rectangle, diamond, ellipse, text, image, but it can't be arrow, line, freedraw, **group**)
The element connecting node and node must be an **arrow** and have the correct direction, e.g. **parent node -> children node**
# sort
The order of nodes in the Y axis or vertical direction is determined by **the creation time** of the arrow connecting it
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-mindmap-format-2.png)
So if you want to readjust the order, you can **delete arrows and reconnect them**
# setting
Script provides options to adjust the style of mind map, The option is at the bottom of the option of the exalidraw plugin(e.g. Settings -> Community plugins -> Excalidraw -> drag to bottom)
# problem
1. since the start bingding and end bingding of the arrow are easily disconnected from the node, so if there are unformatted parts, please **check the connection** and use the script to **reformat**
```javascript
*/
let settings = ea.getScriptSettings();
//set default values on first run
if (!settings["MindMap Format"]) {
settings = {
"MindMap Format": {
value: "Excalidraw/MindMap Format",
description:
"This is prepared for the namespace of MindMap Format and does not need to be modified",
},
"default gap": {
value: 10,
description: "Interval size of element",
},
"curve length": {
value: 40,
description: "The length of the curve part in the mind map line",
},
"length between element and line": {
value: 50,
description:
"The distance between the tail of the connection and the connecting elements of the mind map",
},
};
ea.setScriptSettings(settings);
}
const sceneElements = ea.getExcalidrawAPI().getSceneElements();
// default X coordinate of the middle point of the arc
const defaultDotX = Number(settings["curve length"].value);
// The default length from the middle point of the arc on the X axis
const defaultLengthWithCenterDot = Number(
settings["length between element and line"].value
);
// Initial trimming distance of the end point on the Y axis
const initAdjLength = 4;
// default gap
const defaultGap = Number(settings["default gap"].value);
const setCenter = (parent, line) => {
// Focus and gap need the api calculation of excalidraw
// e.g. determineFocusDistance, but they are not available now
// so they are uniformly set to 0/1
line.startBinding.focus = 0;
line.startBinding.gap = 1;
line.endBinding.focus = 0;
line.endBinding.gap = 1;
line.x = parent.x + parent.width;
line.y = parent.y + parent.height / 2;
};
/**
* set the middle point of curve
* @param {any} lineEl the line element of excalidraw
* @param {number} height height of dot on Y axis
* @param {number} [ratio=1] coefficient of the initial trimming distance of the end point on the Y axis, default is 1
*/
const setTopCurveDotOnLine = (lineEl, height, ratio = 1) => {
if (lineEl.points.length < 3) {
lineEl.points.splice(1, 0, [defaultDotX, lineEl.points[0][1] - height]);
} else if (lineEl.points.length === 3) {
lineEl.points[1] = [defaultDotX, lineEl.points[0][1] - height];
} else {
lineEl.points.splice(2, lineEl.points.length - 3);
lineEl.points[1] = [defaultDotX, lineEl.points[0][1] - height];
}
lineEl.points[2][0] = lineEl.points[1][0] + defaultLengthWithCenterDot;
// adjust the curvature of the second line segment
lineEl.points[2][1] = lineEl.points[1][1] - initAdjLength * ratio * 0.8;
};
const setMidCurveDotOnLine = (lineEl) => {
if (lineEl.points.length < 3) {
lineEl.points.splice(1, 0, [defaultDotX, lineEl.points[0][1]]);
} else if (lineEl.points.length === 3) {
lineEl.points[1] = [defaultDotX, lineEl.points[0][1]];
} else {
lineEl.points.splice(2, lineEl.points.length - 3);
lineEl.points[1] = [defaultDotX, lineEl.points[0][1]];
}
lineEl.points[2][0] = lineEl.points[1][0] + defaultLengthWithCenterDot;
lineEl.points[2][1] = lineEl.points[1][1];
};
/**
* set the middle point of curve
* @param {any} lineEl the line element of excalidraw
* @param {number} height height of dot on Y axis
* @param {number} [ratio=1] coefficient of the initial trimming distance of the end point on the Y axis, default is 1
*/
const setBottomCurveDotOnLine = (lineEl, height, ratio = 1) => {
if (lineEl.points.length < 3) {
lineEl.points.splice(1, 0, [defaultDotX, lineEl.points[0][1] + height]);
} else if (lineEl.points.length === 3) {
lineEl.points[1] = [defaultDotX, lineEl.points[0][1] + height];
} else {
lineEl.points.splice(2, lineEl.points.length - 3);
lineEl.points[1] = [defaultDotX, lineEl.points[0][1] + height];
}
lineEl.points[2][0] = lineEl.points[1][0] + defaultLengthWithCenterDot;
// adjust the curvature of the second line segment
lineEl.points[2][1] = lineEl.points[1][1] + initAdjLength * ratio * 0.8;
};
const setTextXY = (rect, text) => {
text.x = rect.x + (rect.width - text.width) / 2;
text.y = rect.y + (rect.height - text.height) / 2;
};
const setChildrenXY = (parent, children, line, elementsMap) => {
x = parent.x + parent.width + line.points[2][0];
y = parent.y + parent.height / 2 + line.points[2][1] - children.height / 2;
distX = children.x - x;
distY = children.y - y;
ea.getElementsInTheSameGroupWithElement(children, sceneElements).forEach((el) => {
el.x = el.x - distX;
el.y = el.y - distY;
});
if (
["rectangle", "diamond", "ellipse"].includes(children.type) &&
![null, undefined].includes(children.boundElements)
) {
const textDesc = children.boundElements.filter(
(el) => el.type === "text"
)[0];
if (textDesc !== undefined) {
const textEl = elementsMap.get(textDesc.id);
setTextXY(children, textEl);
}
}
};
/**
* returns the height of the upper part of all child nodes
* and the height of the lower part of all child nodes
* @param {Number[]} childrenTotalHeightArr
* @returns {Number[]} [topHeight, bottomHeight]
*/
const getNodeCurrentHeight = (childrenTotalHeightArr) => {
if (childrenTotalHeightArr.length <= 0) return [0, 0];
else if (childrenTotalHeightArr.length === 1)
return [childrenTotalHeightArr[0] / 2, childrenTotalHeightArr[0] / 2];
const heightArr = childrenTotalHeightArr;
let topHeight = 0,
bottomHeight = 0;
const isEven = heightArr.length % 2 === 0;
const mid = Math.floor(heightArr.length / 2);
const topI = mid - 1;
const bottomI = isEven ? mid : mid + 1;
topHeight = isEven ? 0 : heightArr[mid] / 2;
for (let i = topI; i >= 0; i--) {
topHeight += heightArr[i];
}
bottomHeight = isEven ? 0 : heightArr[mid] / 2;
for (let i = bottomI; i < heightArr.length; i++) {
bottomHeight += heightArr[i];
}
return [topHeight, bottomHeight];
};
/**
* handle the height of each point in the single-level tree
* @param {Array} lines
* @param {Map} elementsMap
* @param {Boolean} isEven
* @param {Number} mid 'lines' array midpoint index
* @returns {Array} height array corresponding to 'lines'
*/
const handleDotYValue = (lines, elementsMap, isEven, mid) => {
const getTotalHeight = (line, elementsMap) => {
return elementsMap.get(line.endBinding.elementId).totalHeight;
};
const getTopHeight = (line, elementsMap) => {
return elementsMap.get(line.endBinding.elementId).topHeight;
};
const getBottomHeight = (line, elementsMap) => {
return elementsMap.get(line.endBinding.elementId).bottomHeight;
};
const heightArr = new Array(lines.length).fill(0);
const upI = mid === 0 ? 0 : mid - 1;
const bottomI = isEven ? mid : mid + 1;
let initHeight = isEven ? 0 : getTopHeight(lines[mid], elementsMap);
for (let i = upI; i >= 0; i--) {
heightArr[i] = initHeight + getBottomHeight(lines[i], elementsMap);
initHeight += getTotalHeight(lines[i], elementsMap);
}
initHeight = isEven ? 0 : getBottomHeight(lines[mid], elementsMap);
for (let i = bottomI; i < lines.length; i++) {
heightArr[i] = initHeight + getTopHeight(lines[i], elementsMap);
initHeight += getTotalHeight(lines[i], elementsMap);
}
return heightArr;
};
/**
* format single-level tree
* @param {any} parent
* @param {Array} lines
* @param {Map} childrenDescMap
* @param {Map} elementsMap
*/
const formatTree = (parent, lines, childrenDescMap, elementsMap) => {
lines.forEach((item) => setCenter(parent, item));
const isEven = lines.length % 2 === 0;
const mid = Math.floor(lines.length / 2);
const heightArr = handleDotYValue(lines, childrenDescMap, isEven, mid);
lines.forEach((item, index) => {
if (isEven) {
if (index < mid) setTopCurveDotOnLine(item, heightArr[index], index + 1);
else setBottomCurveDotOnLine(item, heightArr[index], index - mid + 1);
} else {
if (index < mid) setTopCurveDotOnLine(item, heightArr[index], index + 1);
else if (index === mid) setMidCurveDotOnLine(item);
else setBottomCurveDotOnLine(item, heightArr[index], index - mid);
}
});
lines.forEach((item) => {
if (item.endBinding !== null) {
setChildrenXY(
parent,
elementsMap.get(item.endBinding.elementId),
item,
elementsMap
);
}
});
};
const generateTree = (elements) => {
const elIdMap = new Map([[elements[0].id, elements[0]]]);
let minXEl = elements[0];
for (let i = 1; i < elements.length; i++) {
elIdMap.set(elements[i].id, elements[i]);
if (
!(elements[i].type === "arrow" || elements[i].type === "line") &&
elements[i].x < minXEl.x
) {
minXEl = elements[i];
}
}
const root = {
el: minXEl,
totalHeight: minXEl.height,
topHeight: 0,
bottomHeight: 0,
linkChildrensLines: [],
isLeafNode: false,
children: [],
};
const preIdSet = new Set(); // The id_set of Elements that is already in the tree, avoid a dead cycle
const dfsForTreeData = (root) => {
if (preIdSet.has(root.el.id)) {
return 0;
}
preIdSet.add(root.el.id);
let lines = root.el.boundElements.filter(
(el) =>
el.type === "arrow" &&
!preIdSet.has(el.id) &&
elIdMap.get(el.id)?.startBinding?.elementId === root.el.id
);
if (lines.length === 0) {
root.isLeafNode = true;
root.totalHeight = root.el.height + 2 * defaultGap;
[root.topHeight, root.bottomHeight] = [
root.totalHeight / 2,
root.totalHeight / 2,
];
return root.totalHeight;
} else {
lines = lines.map((elementDesc) => {
preIdSet.add(elementDesc.id);
return elIdMap.get(elementDesc.id);
});
}
const linkChildrensLines = [];
lines.forEach((el) => {
const line = el;
if (
line &&
line.endBinding !== null &&
line.endBinding !== undefined &&
!preIdSet.has(elIdMap.get(line.endBinding.elementId).id)
) {
const children = elIdMap.get(line.endBinding.elementId);
linkChildrensLines.push(line);
root.children.push({
el: children,
totalHeight: 0,
topHeight: 0,
bottomHeight: 0,
linkChildrensLines: [],
isLeafNode: false,
children: [],
});
}
});
let totalHeight = 0;
root.children.forEach((el) => (totalHeight += dfsForTreeData(el)));
root.linkChildrensLines = linkChildrensLines;
if (root.children.length === 0) {
root.isLeafNode = true;
root.totalHeight = root.el.height + 2 * defaultGap;
[root.topHeight, root.bottomHeight] = [
root.totalHeight / 2,
root.totalHeight / 2,
];
} else if (root.children.length > 0) {
root.totalHeight = Math.max(root.el.height + 2 * defaultGap, totalHeight);
[root.topHeight, root.bottomHeight] = getNodeCurrentHeight(
root.children.map((item) => item.totalHeight)
);
}
return totalHeight;
};
dfsForTreeData(root);
const dfsForFormat = (root) => {
if (root.isLeafNode) return;
const childrenDescMap = new Map(
root.children.map((item) => [item.el.id, item])
);
formatTree(root.el, root.linkChildrensLines, childrenDescMap, elIdMap);
root.children.forEach((el) => dfsForFormat(el));
};
dfsForFormat(root);
};
const elements = ea.getViewSelectedElements();
generateTree(elements);
ea.copyViewElementsToEAforEditing(elements);
await ea.addElementsToView(false, false);

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1673428425027" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1642" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="24"><path d="M388.7 542.88c-16.57 0-30-13.43-30-30s13.43-30 30-30c52.3 0 94.85-42.55 94.85-94.85v-67.81c0-40.96 15.84-79.58 44.6-108.74 28.76-29.16 67.16-45.53 108.12-46.1l3.43-0.05c16.57-0.22 30.18 13.02 30.41 29.58 0.23 16.57-13.02 30.18-29.58 30.41l-3.43 0.05c-51.58 0.71-93.55 43.25-93.55 94.84v67.81c0 85.4-69.47 154.86-154.85 154.86z" fill="#000000" p-id="1643"></path><path d="M640.12 860.42h-0.42l-3.43-0.05c-40.96-0.56-79.36-16.93-108.12-46.09s-44.6-67.78-44.6-108.74v-67.8c0-52.3-42.55-94.85-94.85-94.85-16.57 0-30-13.43-30-30s13.43-30 30-30c85.38 0 154.85 69.47 154.85 154.85v67.8c0 51.59 41.96 94.13 93.55 94.84l3.43 0.05c16.57 0.23 29.81 13.84 29.59 30.41-0.24 16.42-13.62 29.58-30 29.58z" fill="#000000" p-id="1644"></path><path d="M640.11 542.88H388.7c-16.57 0-30-13.43-30-30s13.43-30 30-30h251.42c16.57 0 30 13.43 30 30-0.01 16.57-13.44 30-30.01 30z" fill="#000000" p-id="1645"></path><path d="M343.89 638.95H137.78c-38.6 0-70-31.4-70-70V456.81c0-38.6 31.4-70 70-70h206.11c38.6 0 70 31.4 70 70v112.13c0 38.6-31.4 70.01-70 70.01zM137.78 446.81c-5.51 0-10 4.49-10 10v112.13c0 5.51 4.49 10 10 10h206.11c5.51 0 10-4.49 10-10V456.81c0-5.51-4.49-10-10-10H137.78zM830.16 316.96h-93.98c-69.51 0-126.07-56.55-126.07-126.07S666.66 64.83 736.18 64.83h93.98c69.51 0 126.07 56.55 126.07 126.07-0.01 69.5-56.56 126.06-126.07 126.06z m-93.98-192.13c-36.43 0-66.07 29.64-66.07 66.07s29.64 66.07 66.07 66.07h93.98c36.43 0 66.07-29.64 66.07-66.07s-29.64-66.07-66.07-66.07h-93.98zM830.16 638.95h-93.98c-69.51 0-126.07-56.55-126.07-126.07 0-69.51 56.55-126.07 126.07-126.07h93.98c69.51 0 126.07 56.55 126.07 126.07-0.01 69.51-56.56 126.07-126.07 126.07z m-93.98-192.14c-36.43 0-66.07 29.64-66.07 66.07 0 36.43 29.64 66.07 66.07 66.07h93.98c36.43 0 66.07-29.64 66.07-66.07 0-36.43-29.64-66.07-66.07-66.07h-93.98z" fill="#000000" p-id="1646"></path><path d="M830.16 959.17h-93.98c-69.51 0-126.07-56.55-126.07-126.07s56.55-126.07 126.07-126.07h93.98c69.51 0 126.07 56.55 126.07 126.07s-56.56 126.07-126.07 126.07z m-93.98-192.13c-36.43 0-66.07 29.64-66.07 66.07s29.64 66.07 66.07 66.07h93.98c36.43 0 66.07-29.64 66.07-66.07s-29.64-66.07-66.07-66.07h-93.98z" fill="#000000" p-id="1647"></path></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -0,0 +1,216 @@
/*
![](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-modify-background-color-opacity.png)
This script changes the opacity of the background color of the selected boxes.
The default background color in Excalidraw is so dark that the text is hard to read. You can lighten the color a bit by setting transparency. And you can tweak the transparency over and over again until you're happy with it.
Although excalidraw has the opacity option in its native property Settings, it also changes the transparency of the border. Use this script to change only the opacity of the background color without affecting the border.
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.5.21")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
settings = ea.getScriptSettings();
//set default values on first run
if(!settings["Default opacity"]) {
settings = {
"Prompt for opacity?": true,
"Default opacity" : {
value: 0.6,
description: "Element's background color transparency"
},
"Remember last opacity?": false
};
ea.setScriptSettings(settings);
}
let opacityStr = settings["Default opacity"].value.toString();
const rememberLastOpacity = settings["Remember last opacity?"];
if(settings["Prompt for opacity?"]) {
opacityStr = await utils.inputPrompt("Background color opacity?","number",opacityStr);
}
const alpha = parseFloat(opacityStr);
if(isNaN(alpha)) {
return;
}
if(rememberLastOpacity) {
settings["Default opacity"].value = alpha;
ea.setScriptSettings(settings);
}
const elements=ea.getViewSelectedElements().filter((el)=>["rectangle","ellipse","diamond","line","image"].includes(el.type));
ea.copyViewElementsToEAforEditing(elements);
ea.getElements().forEach((el)=>{
const color = colorNameToHex(el.backgroundColor);
const rgbColor = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(color);
if(rgbColor) {
const r = parseInt(rgbColor[1], 16);
const g = parseInt(rgbColor[2], 16);
const b = parseInt(rgbColor[3], 16);
el.backgroundColor=`rgba(${r},${g},${b},${alpha})`;
}
else {
const rgbaColor = /^rgba\((\d+,\d+,\d+,)(\d*\.?\d*)\)$/i.exec(color);
if(rgbaColor) {
el.backgroundColor=`rgba(${rgbaColor[1]}${alpha})`;
}
}
});
await ea.addElementsToView(false, false);
function colorNameToHex(color) {
const colors = {
"aliceblue":"#f0f8ff",
"antiquewhite":"#faebd7",
"aqua":"#00ffff",
"aquamarine":"#7fffd4",
"azure":"#f0ffff",
"beige":"#f5f5dc",
"bisque":"#ffe4c4",
"black":"#000000",
"blanchedalmond":"#ffebcd",
"blue":"#0000ff",
"blueviolet":"#8a2be2",
"brown":"#a52a2a",
"burlywood":"#deb887",
"cadetblue":"#5f9ea0",
"chartreuse":"#7fff00",
"chocolate":"#d2691e",
"coral":"#ff7f50",
"cornflowerblue":"#6495ed",
"cornsilk":"#fff8dc",
"crimson":"#dc143c",
"cyan":"#00ffff",
"darkblue":"#00008b",
"darkcyan":"#008b8b",
"darkgoldenrod":"#b8860b",
"darkgray":"#a9a9a9",
"darkgreen":"#006400",
"darkkhaki":"#bdb76b",
"darkmagenta":"#8b008b",
"darkolivegreen":"#556b2f",
"darkorange":"#ff8c00",
"darkorchid":"#9932cc",
"darkred":"#8b0000",
"darksalmon":"#e9967a",
"darkseagreen":"#8fbc8f",
"darkslateblue":"#483d8b",
"darkslategray":"#2f4f4f",
"darkturquoise":"#00ced1",
"darkviolet":"#9400d3",
"deeppink":"#ff1493",
"deepskyblue":"#00bfff",
"dimgray":"#696969",
"dodgerblue":"#1e90ff",
"firebrick":"#b22222",
"floralwhite":"#fffaf0",
"forestgreen":"#228b22",
"fuchsia":"#ff00ff",
"gainsboro":"#dcdcdc",
"ghostwhite":"#f8f8ff",
"gold":"#ffd700",
"goldenrod":"#daa520",
"gray":"#808080",
"green":"#008000",
"greenyellow":"#adff2f",
"honeydew":"#f0fff0",
"hotpink":"#ff69b4",
"indianred ":"#cd5c5c",
"indigo":"#4b0082",
"ivory":"#fffff0",
"khaki":"#f0e68c",
"lavender":"#e6e6fa",
"lavenderblush":"#fff0f5",
"lawngreen":"#7cfc00",
"lemonchiffon":"#fffacd",
"lightblue":"#add8e6",
"lightcoral":"#f08080",
"lightcyan":"#e0ffff",
"lightgoldenrodyellow":"#fafad2",
"lightgrey":"#d3d3d3",
"lightgreen":"#90ee90",
"lightpink":"#ffb6c1",
"lightsalmon":"#ffa07a",
"lightseagreen":"#20b2aa",
"lightskyblue":"#87cefa",
"lightslategray":"#778899",
"lightsteelblue":"#b0c4de",
"lightyellow":"#ffffe0",
"lime":"#00ff00",
"limegreen":"#32cd32",
"linen":"#faf0e6",
"magenta":"#ff00ff",
"maroon":"#800000",
"mediumaquamarine":"#66cdaa",
"mediumblue":"#0000cd",
"mediumorchid":"#ba55d3",
"mediumpurple":"#9370d8",
"mediumseagreen":"#3cb371",
"mediumslateblue":"#7b68ee",
"mediumspringgreen":"#00fa9a",
"mediumturquoise":"#48d1cc",
"mediumvioletred":"#c71585",
"midnightblue":"#191970",
"mintcream":"#f5fffa",
"mistyrose":"#ffe4e1",
"moccasin":"#ffe4b5",
"navajowhite":"#ffdead",
"navy":"#000080",
"oldlace":"#fdf5e6",
"olive":"#808000",
"olivedrab":"#6b8e23",
"orange":"#ffa500",
"orangered":"#ff4500",
"orchid":"#da70d6",
"palegoldenrod":"#eee8aa",
"palegreen":"#98fb98",
"paleturquoise":"#afeeee",
"palevioletred":"#d87093",
"papayawhip":"#ffefd5",
"peachpuff":"#ffdab9",
"peru":"#cd853f",
"pink":"#ffc0cb",
"plum":"#dda0dd",
"powderblue":"#b0e0e6",
"purple":"#800080",
"rebeccapurple":"#663399",
"red":"#ff0000",
"rosybrown":"#bc8f8f",
"royalblue":"#4169e1",
"saddlebrown":"#8b4513",
"salmon":"#fa8072",
"sandybrown":"#f4a460",
"seagreen":"#2e8b57",
"seashell":"#fff5ee",
"sienna":"#a0522d",
"silver":"#c0c0c0",
"skyblue":"#87ceeb",
"slateblue":"#6a5acd",
"slategray":"#708090",
"snow":"#fffafa",
"springgreen":"#00ff7f",
"steelblue":"#4682b4",
"tan":"#d2b48c",
"teal":"#008080",
"thistle":"#d8bfd8",
"tomato":"#ff6347",
"turquoise":"#40e0d0",
"violet":"#ee82ee",
"wheat":"#f5deb3",
"white":"#ffffff",
"whitesmoke":"#f5f5f5",
"yellow":"#ffff00",
"yellowgreen":"#9acd32"
};
if (typeof colors[color.toLowerCase()] != 'undefined')
return colors[color.toLowerCase()];
return color;
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 700 550"><path d="M478.98 137.02A205.802 205.802 0 0 0 255.062 22.364a205.785 205.785 0 0 0-115.79 65.234 205.78 205.78 0 0 0-51.773 122.4 205.1 205.1 0 0 0 120.399 201.249 210.043 210.043 0 0 0 88.988 102.84 210 210 0 0 0 255.1-33.793 209.995 209.995 0 0 0 59.137-122.46 209.99 209.99 0 0 0-28.293-133.02 209.985 209.985 0 0 0-103.86-87.793zm-186.9-84.523h10.5a170.974 170.974 0 0 1 102.6 42.441 170.932 170.932 0 0 1 54.898 96.508l-194.95-136.68a171.623 171.623 0 0 1 26.949-2.273zm-70 15.051 230.12 161.88 9.45 6.648a171.28 171.28 0 0 1-22.048 71.75l-275.62-197.4a170.925 170.925 0 0 1 58.45-42.875zm-78.398 71.398 276.32 197.4a171.807 171.807 0 0 1-58.102 43.047l-239.4-175.7a169.266 169.266 0 0 1 21.176-64.75zm-21.176 108.32 197.57 144.73a165.295 165.295 0 0 1-38.5 2.102 171.169 171.169 0 0 1-105.7-45.07 171.164 171.164 0 0 1-53.375-101.76zm280 260.23a176.25 176.25 0 0 1-84.371-21.984 176.27 176.27 0 0 1-63.504-59.742 197.049 197.049 0 0 0 24.852 3.328h12.773a206.319 206.319 0 0 0 140.66-55.766 206.312 206.312 0 0 0 64.789-136.73 202.42 202.42 0 0 0-3.848-52.5 175.017 175.017 0 0 1 70.512 85.367 175.016 175.016 0 0 1 5.157 110.61 174.986 174.986 0 0 1-62.262 91.562 175.008 175.008 0 0 1-104.76 35.863z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,80 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-organic-line.jpg)
Converts selected freedraw lines such that pencil pressure will decrease from maximum to minimum from the beginning of the line to its end. The resulting line is placed at the back of the layers, under all other items. Helpful when drawing organic mindmaps.
```javascript
*/
if(!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.8.8")) {
new Notice("This script requires a newer version of Excalidraw. Please install the latest version.");
return;
}
let elements = ea.getViewSelectedElements().filter((el)=>["freedraw","line","arrow"].includes(el.type));
//if nothing is selected find the last element that was drawn and use it if it is the right element type
if(elements.length === 0) {
elements = ea.getViewSelectedElements();
const len = elements.length;
if(len === 0 || ["freedraw","line","arrow"].includes(elements[len].type)) {
return;
}
elements = [elements[len]];
}
const lineType = await utils.suggester(["Thick to thin", "Thin to thick to thin"],["l1","l2"],"Select the type of line");
if(!lineType) return;
ea.copyViewElementsToEAforEditing(elements);
ea.getElements().forEach((el)=>{
el.simulatePressure = false;
el.type = "freedraw";
el.pressures = Array(el.points.length).fill(1);
el.customData = {
strokeOptions: {
... lineType === "l1"
? {
options: {
thinning: 1,
smoothing: 0.5,
streamline: 0.5,
easing: "linear",
start: {
taper: 0,
cap: true
},
end: {
taper: true,
easing: "linear",
cap: false
}
}
}
: {
options: {
thinning: 4,
smoothing: 0.5,
streamline: 0.5,
easing: "linear",
start: {
taper: true,
easing: "linear",
cap: true
},
end: {
taper: true,
easing: "linear",
cap: false
}
}
}
}
};
});
await ea.addElementsToView(false,true);
elements.forEach((el)=>ea.moveViewElementToZIndex(el.id,0));
const ids=ea.getElements().map(el=>el.id);
ea.selectElementsInView(ea.getViewElements().filter(el=>ids.contains(el.id)));

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

@@ -0,0 +1,70 @@
/*
![](https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-text-aura.jpg)
Select a single text element, or a text element in a container. The container must have a transparent background.
The script will add an aura to the text by adding 4 copies of the text each with the inverted stroke color of the original text element and with a very small X and Y offset. The resulting 4 + 1 (original) text elements or containers will be grouped.
If you copy a color string on the clipboard before running the script, the script will use that color instead of the inverted color.
```js*/
els = ea.getViewSelectedElements();
const isText = (els.length === 1) && els[0].type === "text";
const isContainer = (els.length === 2) &&
((els[0].type === "text" && els[1].id === els[0].containerId && els[1].backgroundColor.toLowerCase() === "transparent") ||
(els[1].type === "text" && els[0].id === els[1].containerId && els[0].backgroundColor.toLowerCase() === "transparent"));
if (!(isText || isContainer)) {
new Notice ("Select a single text element, or a container with a text element and with transparent background color",10000);
return;
}
let strokeColor = ea
.getCM(els.filter(el=>el.type === "text")[0].strokeColor)
.invert({alpha: false})
.stringHEX({alpha: false});
clipboardText = await navigator.clipboard.readText();
if(clipboardText) {
const cm1 = ea.getCM(clipboardText);
if(cm1.format !== "invalid") {
strokeColor = cm1.stringHEX();
} else {
const cm2 = ea.getCM("#"+clipboardText);
if(cm2.format !== "invalid") {
strokeColor = cm2.stringHEX();
}
}
}
const offset = els.filter(el=>el.type === "text")[0].fontSize/24;
let ids = [];
const addClone = (offsetX, offsetY) => {
els.forEach(el=>{
const clone = ea.cloneElement(el);
ids.push(clone.id);
clone.x += offsetX;
clone.y += offsetY;
if(offsetX!==0 || offsetY!==0) {
switch (clone.type) {
case "text":
clone.strokeColor = strokeColor;
break;
default:
clone.strokeColor = "transparent";
break;
}
}
ea.elementsDict[clone.id] = clone;
})
}
addClone(-offset,0);
addClone(offset,0);
addClone(0,offset);
addClone(0,-offset);
addClone(0,0);
ea.copyViewElementsToEAforEditing(els);
els.forEach(el=>ea.elementsDict[el.id].isDeleted = true);
ea.addToGroup(ids);
ea.addElementsToView(false, true, true);

View File

@@ -0,0 +1,17 @@
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="120" height="120">
<!-- svg-source:excalidraw -->
<defs>
<style class="style-fonts">
@font-face {
font-family: "Virgil";
src: url("https://excalidraw.com/Virgil.woff2");
}
@font-face {
font-family: "Cascadia";
src: url("https://excalidraw.com/Cascadia.woff2");
}
</style>
</defs>
<g stroke-linecap="round"><g transform="translate(0 0) rotate(0 60 60)" fill-rule="evenodd"><path d="M0 0 L120 0 L120 40 L80 40 L80 120 L40 120 L40 40 L0 40 L0 0" stroke="none" stroke-width="0" fill="red" fill-rule="evenodd"></path><path d="M0 0 C41.51 0, 83.02 0, 120 0 M0 0 C30.58 0, 61.16 0, 120 0 M120 0 C120 12.11, 120 24.22, 120 40 M120 0 C120 13.92, 120 27.84, 120 40 M120 40 C108.75 40, 97.49 40, 80 40 M120 40 C107.65 40, 95.29 40, 80 40 M80 40 C80 66.51, 80 93.01, 80 120 M80 40 C80 70.33, 80 100.66, 80 120 M80 120 C66.08 120, 52.16 120, 40 120 M80 120 C70.07 120, 60.13 120, 40 120 M40 120 C40 89.21, 40 58.42, 40 40 M40 120 C40 92.66, 40 65.33, 40 40 M40 40 C25.35 40, 10.71 40, 0 40 M40 40 C27.7 40, 15.4 40, 0 40 M0 40 C0 24.03, 0 8.05, 0 0 M0 40 C0 27.82, 0 15.65, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="transparent" stroke-width="0.5" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(110 10) rotate(0 -50 50)" fill-rule="evenodd"><path d="M0 0 L-100 0 L-100 20 L-60 20 L-60 100 L-40 100 L-40 20 L0 20 L0 0" stroke="none" stroke-width="0" fill="currentColor" fill-rule="evenodd"></path><path d="M0 0 C-23.27 0, -46.54 0, -100 0 M0 0 C-23.31 0, -46.62 0, -100 0 M-100 0 C-100 6.13, -100 12.26, -100 20 M-100 0 C-100 5.84, -100 11.69, -100 20 M-100 20 C-87.37 20, -74.74 20, -60 20 M-100 20 C-88.34 20, -76.68 20, -60 20 M-60 20 C-60 37.78, -60 55.56, -60 100 M-60 20 C-60 39.34, -60 58.68, -60 100 M-60 100 C-52.58 100, -45.17 100, -40 100 M-60 100 C-54.72 100, -49.43 100, -40 100 M-40 100 C-40 83.83, -40 67.67, -40 20 M-40 100 C-40 77.76, -40 55.51, -40 20 M-40 20 C-25.4 20, -10.8 20, 0 20 M-40 20 C-28.47 20, -16.93 20, 0 20 M0 20 C0 15.42, 0 10.84, 0 0 M0 20 C0 14.54, 0 9.08, 0 0 M0 0 C0 0, 0 0, 0 0 M0 0 C0 0, 0 0, 0 0" stroke="currentColor" stroke-width="0.5" fill="none"></path></g></g><mask></mask></svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -0,0 +1,776 @@
---
excalidraw-plugin: parsed
tags: [excalidraw]
---
==⚠ Switch to EXCALIDRAW VIEW in the MORE OPTIONS menu of this document. ⚠==
# Text Elements
%%
# Drawing
```compressed-json
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
gAD8EAA=
```
%%

View File

@@ -5,5 +5,5 @@
"textFontFamily": "Lexend Deca",
"monospaceFontFamily": "SauceCodePro Nerd Font Mono",
"accentColor": "#ef6b6b",
"baseFontSize": 18
"baseFontSize": 20
}

View File

@@ -1366,6 +1366,7 @@ Plan
Pragma
Przez
Pułka
Przedstawić
obj
oh
oq
@@ -2735,6 +2736,7 @@ oikonomos
ognisku
ograniczoności
obecnie
odwrotnym
GoTo
GS
Gl
@@ -3994,6 +3996,7 @@ Goqg
Gcge
GLkr
Głośnikowe
Gliwice
Outline
ON
OD
@@ -5321,6 +5324,7 @@ Oblicz
Odbiornikowe
OiZ
Opara
Odwr
endobj
endstream
ea
@@ -6709,6 +6713,7 @@ elementami
ekonomia
ekonomię
efekt
egzaminy
Length
Link
LN
@@ -10792,6 +10797,7 @@ szeregowe
stających
sformułowania
systemów
starostą
JQ
Js
JX
@@ -33382,6 +33388,7 @@ Detale
Dana
Dany
Diraca
Dop
dA
dET
dg
@@ -34787,6 +34794,9 @@ decision
domowym
dobra
decimal
downey
dopełnieniowym
dodanie
YI
YT
Yv
@@ -38888,6 +38898,7 @@ bitem
bff
bcc
bogactwa
book
jW
je
jz
@@ -42855,6 +42866,7 @@ ukształtował
ulepszona
usług
ułamkowa
ustalić
Mh
MediaBox
MI
@@ -45545,6 +45557,7 @@ logarytmiczne
leży
lewo
ludzi
little
Kz
KM
Kw
@@ -52168,6 +52181,7 @@ rydarkowska
ręka
rynku
rudnicki
range
tI
tU
ta
@@ -54859,6 +54873,7 @@ wprowadzenie
wykładu
wytwarzane
więcej
wyjdzie
pDJ
parenleftbigg
parenrightbigg
@@ -56337,6 +56352,8 @@ przyszłości
proporcjach
podział
państwowo
poza
przeniesienie
HD
Ho
Hg
@@ -62911,6 +62928,7 @@ możliwości
mają
metod
masowo
modułowym
nD
nF
nZ
@@ -64267,6 +64285,7 @@ naturą
narodów
nowoczesną
nowoczesna
następujące
gNx
gHI
gri
@@ -67017,6 +67036,7 @@ kurzbauer
klasyczna
krachu
kogo
kato
üx
ün
ür
@@ -69756,6 +69776,7 @@ zaspokojenia
zrównoważony
zasobów
zmitac
zapisie
ÜI
Üj
ÜX

View File

@@ -224397,7 +224397,10 @@
"latexBoilerplate": "\\color{blue}",
"taskboneEnabled": false,
"taskboneAPIkey": "",
"pinnedScripts": [],
"pinnedScripts": [
"!Załączniki/Excalidraw/Scripts/Downloaded/Hardware Eraser Support.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Repeat Elements.md"
],
"customPens": [
{
"type": "default",

View File

@@ -4,35 +4,22 @@
"type": "split",
"children": [
{
"id": "003a0fb52376c630",
"id": "c5519d39154c583a",
"type": "tabs",
"children": [
{
"id": "de054390e12f6929",
"id": "92c1866c2ef5d3f5",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "PI/PI.md",
"mode": "source",
"source": false
}
}
},
{
"id": "812edd82a4cf8911",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "ASC/1 SEM/Ćwiczenia/1. Konwersja Systemów.md",
"file": "ASC/1 SEM/Ćwiczenia/Mnożenie.md",
"mode": "source",
"source": false
}
}
}
],
"currentTab": 1
]
}
],
"direction": "vertical"
@@ -106,7 +93,7 @@
"state": {
"type": "backlink",
"state": {
"file": "ASC/1 SEM/Ćwiczenia/1. Konwersja Systemów.md",
"file": "ASC/1 SEM/Ćwiczenia/Mnożenie.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
@@ -123,7 +110,7 @@
"state": {
"type": "outgoing-link",
"state": {
"file": "ASC/1 SEM/Ćwiczenia/1. Konwersja Systemów.md",
"file": "ASC/1 SEM/Ćwiczenia/Mnożenie.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
}
@@ -146,7 +133,7 @@
"state": {
"type": "outline",
"state": {
"file": "ASC/1 SEM/Ćwiczenia/1. Konwersja Systemów.md"
"file": "ASC/1 SEM/Ćwiczenia/Mnożenie.md"
}
}
},
@@ -242,54 +229,54 @@
"breadcrumbs:Breadcrumbs Visualisation": false
}
},
"active": "812edd82a4cf8911",
"active": "92c1866c2ef5d3f5",
"lastOpenFiles": [
"ASC/1 SEM/Ćwiczenia/Ćwiczenia.md",
"TC/Wykład/Wykład.md",
"TC/TC.md",
"ASC/1 SEM/Wykłady/Wykłady.md",
"ASC/1 SEM/Wykłady/Untitled.md",
"ASC/1 SEM/Ćwiczenia/3. BCD i EXCESS-3.md",
"ASC/1 SEM/Ćwiczenia/Mnożenie.md",
"ASC/ASC.md",
"!Załączniki/02. Pot. węzłowe 2023-11-08 09.17.19.excalidraw.md",
"PE/Ćwiczenia/1 SEM/02. Pot. węzłowe.md",
"!Załączniki/02. Pot. węzłowe 2023-11-08 08.38.58.excalidraw.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Text Aura.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Text Aura.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Organic Line.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Organic Line.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Modify background color opacity.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Modify background color opacity.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Mindmap format.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Mindmap format.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Hardware Eraser Support.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Hardware Eraser Support.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Grid Selected Images.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Grid Selected Images.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Excalidraw Collaboration Frame.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Excalidraw Collaboration Frame.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Ellipse Selected Elements.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Ellipse Selected Elements.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Copy Selected Element Styles to Global.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Copy Selected Element Styles to Global.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Concatenate lines.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Concatenate lines.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Change shape of selected elements.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Box Each Selected Groups.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Boolean Operations.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Auto Draw for Pen.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Add Next Step in Process.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Add Link to Existing File and Open.md",
"!Załączniki/Excalidraw/Scripts/Downloaded/Add Connector Point.md",
"TUC/Bezhazardówki.md",
"ASC/1 SEM/Ćwiczenia/2. Reprezentacja liczb ujemnych.md",
"ASC/1 SEM/Ćwiczenia/Ćwiczenia.md",
"ASC/1 SEM/Wykłady",
"PE/Wykład/Wykład.md",
"PE/Wykład/000.md",
"PE/Ćwiczenia/1 SEM/01. Wstęp.md",
"PE/Wykład",
"AMiAL/ICT/Ćwiczenia/Zadania/Całki/Zadanie 1.md",
"!Załączniki/20221125102535 2022-11-25 10.39.55.excalidraw.md",
"Elektrotechnika/Ćwiczenia/20221125102535.md",
"Elektrotechnika/Ćwiczenia/20221123102116.md",
"Elektrotechnika/Ćwiczenia/20221028102800.md",
"Elektrotechnika/Ćwiczenia/20221014103322.md",
"!Załączniki/01. Wstęp 2023-10-11 08.42.12.excalidraw.md",
"TC/Ćwiczenia/3. Układy iteracyjne.md",
"PE/Ćwiczenia/1 SEM",
"PE/Ćwiczenia",
"TC/Ćwiczenia/2. Realizacja układów na stykach.md",
"TC/Ćwiczenia/1. Algebra Boola.md",
"TC/Ćwiczenia/Ćwiczenia.md",
"TC/Ściągi/ALGEBRA BOOLOWSKA.md",
"TC/Wykład/1. Optymalizacja.md",
"TC/Ćwiczenia/aaa.md",
"TC/Ćwiczenia/Untitled.md",
"TC/Laboratorium/Laboratorium.md",
"PI/Ćwiczenia/1.Rekurencja.md",
"ASC/1 SEM",
"ASC/1 SEM/Ćwiczenia/Untitled",
"ASC/1 SEM/Ćwiczenia",
"AMiAL/CS/Ćwiczenia/1 SEM",
"AMiAL/CS/Ćwiczenia",
"AMiAL/CS",
"!Załączniki/Pasted image 20230620141025.png",
"!Załączniki/Excalidraw/Scripts/Downloaded/Normalize Selected Arrows.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Fixed inner distance.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Alternative Pens.svg",
"!Załączniki/Pasted image 20230314104143.png",
"!Załączniki/Excalidraw/Scripts/Downloaded/Box Selected Elements.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Text Arch.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Repeat Elements.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Elbow connectors.svg",
"!Załączniki/Excalidraw/Scripts/Downloaded/Convert freedraw to line.svg",
"TC/Untitled.canvas"
]
}

View File

@@ -0,0 +1,22 @@
Przedstawić w zapisie modułowym odwrotnym i dopełnieniowym następujące liczby:
|$x_2$| `.1011,0110`|
|-|-|
|ZM+ | `01011.0110`
|ZM- | `11011.0110`
|ZU1 | `00100.1001`
|ZU1- | `10100.1001`
|ZU2+ | `00100.1010`
|ZU2- | `10100.1010`
|$x_2$| `.29,7`|
|-|-|
|ZM+ | `029.7`
|ZM- | `129.7`
|ZU1 | `070.2`
|ZU1- | `170.2`
|ZU2+ | `070.3`
|ZU2- | `170.3`
A1B,5F

View File

@@ -0,0 +1,49 @@
29.7
bCD
0 0010 1001 0111
\- 1 0010 1001 0111
\+0 0110 0110 0110
1 1000 1111 1101
1 0111 0000 0010
+1
1 0111 0000 0011
Ex-3
0010 1001 0111
\+0011 0011 0011
0101 1100 1010
-x m 1 0101 1100 1010
0 1 1010 0011 0101
d 1 1010 0011 0110
z = \pm X \pm Y
x=74.5 Y=29.1
Odwr i Dop w 8421 i ex3
x=74.5= 0000 0111 0100 .0101
-x = 1 0000 0111 0100 0101
-x = 1 0110 1101 1010 1011
-xo = 1 1001 0010 0101 0100
-xd = 1 1001 0010 0101 0101
y=29.1=0000 0010 1001 0001
-y = 1 0000 0010 1001 0001
-y = 1 0110 1000 1111 0111
-yo = 1 1001 0111 0000 1000
-yd = 1 1001 0111 0000 1001
jeżeli wyjdzie poza range 0-9 to dodanie 6 i przeniesienie
x+y
0 0000 0111 0100 0101
0 0000 0010 1001 0001
0110 0110
0 0001 0000 0011 0110
10 0000 0100 0101 0011
\\------------------------->1
0 0000 0100 0101 0100

View File

@@ -0,0 +1,14 @@
Direct method
```
0,10011
0,01101
_______2's power is the zero offset
0,0000010011
0,00010011
0,0010011
0,0011110111
z_z = x_z \oplus y_z =1 \oplus 0 = 1
```
Metoda Bootha

View File

@@ -1,4 +1,4 @@
# ASC Overview
b# ASC Overview
```ccard
type: folder_brief_live

View File

@@ -0,0 +1,4 @@
![[02. Pot. węzłowe 2023-10-25 08.38.29.excalidraw]]
![[02. Pot. węzłowe 2023-10-25 08.42.46.excalidraw]]
![[02. Pot. węzłowe 2023-11-08 08.38.58.excalidraw]]
![[02. Pot. węzłowe 2023-11-08 09.17.19.excalidraw]]

View File

@@ -0,0 +1,21 @@
F =
Kod ![[Minimalizacja 2023-10-24 15.05.07.excalidraw]]
Kod graya:
LSB mirrored, MSB Negated
00
01
11
10
|z|x|c|
|-|-|-|
|0|0|0|
|0|0|1|
|0|1|1|
|0|1|0|
|1|1|0|
|1|1|1|
|1|0|1|
|1|0|0|

View File

@@ -19,3 +19,78 @@
%%za a+a=a^2 ban na życie%%
```
\documentclass{article}
\usepackage[rgb]{xcolor}
\usepackage{karnaugh-map}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\definecolor{mycolor0000}{HTML}{F70400}
\definecolor{mycolor0100}{HTML}{AA0154}
\definecolor{mycolor1100}{HTML}{5600AB}
\definecolor{mycolor1000}{HTML}{0003FB}
\definecolor{mycolor0001}{HTML}{FF5500}
\definecolor{mycolor0101}{HTML}{AA5455}
\definecolor{mycolor1101}{HTML}{5555AB}
\definecolor{mycolor1001}{HTML}{0055FE}
\definecolor{mycolor0011}{HTML}{FFAA01}
\definecolor{mycolor0111}{HTML}{AAA956}
\definecolor{mycolor1111}{HTML}{56AAAA}
\definecolor{mycolor1011}{HTML}{00AAFF}
\definecolor{mycolor0010}{HTML}{FEFF02}
\definecolor{mycolor0110}{HTML}{A9FF54}
\definecolor{mycolor1110}{HTML}{55FFAA}
\definecolor{mycolor1010}{HTML}{0FF6FF}
\pgfplotsset{colormap={BR}{%
color(0)=(mycolor0000) color(1)=(mycolor0100) color(2)=(mycolor1100) color(3)=(mycolor1000)
color(4)=(mycolor0001) color(5)=(mycolor0101) color(6)=(mycolor1101) color(7)=(mycolor1001)
color(8)=(mycolor0011) color(9)=(mycolor0111) color(10)=(mycolor1111) color(11)=(mycolor1011)
color(12)=(mycolor0010) color(13)=(mycolor0110) color(14)=(mycolor1110) color(15)=(mycolor1010)
}}
\begin{document}
\begin{tikzpicture}[font=\small\sffamily]
\begin{axis}
[hide axis,shader=flat corner,%colormap name=BR,
plot box ratio = 1 6 1,
view = {0}{15}]
\addplot3[surf,
samples=32,point meta={int(mod(-atan2(y,x)+45+360,360)/90)+
4*int(mod(atan2(z,sqrt(x^2+y^2)-2)+360+180,360)/90)
},domain=0:360,y domain=0:360,
z buffer=sort]
({(2+cos(x))*cos(y+90)},
{(2+cos(x))*sin(y+90)},
{sin(x)});
\node at ({(2+cos(45))*cos(-90)},{(2+cos(45))*sin(-90)},{cos(45)}) {0111};
\node at ({(2+cos(45))*cos(-90)},{(2+cos(45))*sin(-90)},{0.15-cos(45)}) {0101};
\fill ({(2-cos(45))*cos(90-50)},{(2-cos(45))*sin(90-50)},{cos(80)}) circle (1mm);
\end{axis}
\end{tikzpicture}
%
\begin{karnaugh-map}[4][4][1][][]
\end{karnaugh-map}
\end{document}
```
```tikz
\usepackage{karnaugh}
\usepackage{pgfplots}
\begin{axis}
[hide axis,shader=flat corner,
plot box ratio = 1 6 1,
view = {0}{15}]
\addplot3[surf,
samples=32,point meta={int(mod(-atan2(y,x)+45+360,360)/90)+
4*int(mod(atan2(z,sqrt(x^2+y^2)-2)+360+180,360)/90)
},domain=0:360,y domain=0:360,
z buffer=sort]
({(2+cos(x))*cos(y+90)},
{(2+cos(x))*sin(y+90)},
{sin(x)});
\node at ({(2+cos(45))*cos(-90)},{(2+cos(45))*sin(-90)},{cos(45)}) {0111};
\node at ({(2+cos(45))*cos(-90)},{(2+cos(45))*sin(-90)},{0.15-cos(45)}) {0101};
\fill ({(2-cos(45))*cos(90-50)},{(2-cos(45))*sin(90-50)},{cos(80)}) circle (1mm);
\end{axis}
```