mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8a5e26030 | ||
|
|
d6c686d230 | ||
|
|
d7446d20dd | ||
|
|
541db2ca2f | ||
|
|
b0fc21b70a | ||
|
|
0b36759f09 | ||
|
|
c94ebb6bcd | ||
|
|
75e179041d | ||
|
|
3d41690359 | ||
|
|
e3d31f49de | ||
|
|
ee48840421 | ||
|
|
b8b08b3edb | ||
|
|
d1f994a8d1 |
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
70
.github/workflows/codeql-analysis.yml
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '38 14 * * 4'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://git.io/codeql-language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
@@ -13,6 +13,7 @@ Please upgrade to Obsidian v0.12.19 or higher to get the latest release.
|
||||
|[](https://youtu.be/VRZVujfVab0)|[](https://youtu.be/D1iBYo1_jjc)|[](https://www.youtube.com/watch?v=_c_0zpBJ4Xc&)|
|
||||
|[](https://youtu.be/r08wk-58DPk)|[](https://youtu.be/tsecSfnTMow)|[](https://youtu.be/K6qZkTz8GHs)|
|
||||
|[](https://youtu.be/hePJcObHIso)|[](https://youtu.be/NOuddK6xrr8)|[](https://youtu.be/lzYdOQ6z8F0)|
|
||||
|[](https://youtu.be/eKFmrSQhFA4)|||
|
||||
|
||||
|
||||
# Key features
|
||||
@@ -61,6 +62,7 @@ Please upgrade to Obsidian v0.12.19 or higher to get the latest release.
|
||||
- `excalidraw-link-prefix: "📍"` preview prefix for internal links
|
||||
- `excalidraw-url-prefix: "🌐"` preview prefix for external links
|
||||
- `excalidraw-link-brackets: true|false` whether or not to display brackets around links in preview
|
||||
- `excalidraw-default-mode: view|zen` Open this document in view mode or zen mode by defult. Default view mode is excellent for presentation slides.
|
||||
- Embed complete markdown files into your drawings
|
||||
- Drag from the desired file from the Obsidian file explorer and hold down CTRL/CMD while dropping the file onto the canvas.
|
||||
- Use the command palette action: `Insert markdown file from vault`
|
||||
|
||||
@@ -17,7 +17,7 @@ export interface ExcalidrawAutomate {
|
||||
roughness: number;
|
||||
opacity: number;
|
||||
strokeSharpness: StrokeSharpness; //type StrokeSharpness = "round" | "sharp"
|
||||
fontFamily: number; //1: Virgil, 2:Helvetica, 3:Cascadia
|
||||
fontFamily: number; //1: Virgil, 2:Helvetica, 3:Cascadia, 4:LocalFont
|
||||
fontSize: number;
|
||||
textAlign: string; //"left"|"right"|"center"
|
||||
verticalAlign: string; //"top"|"bottom"|"middle" :for future use, has no effect currently
|
||||
|
||||
78
ea-scripts/Box Each Selected Groups.md
Normal file
78
ea-scripts/Box Each Selected Groups.md
Normal file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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
|
||||
*/
|
||||
const paddingStr = await utils.inputPrompt("padding?","string","8");
|
||||
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 elements = ea.getViewSelectedElements();
|
||||
const groups = ea.getMaximumGroups(elements);
|
||||
|
||||
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
|
||||
);
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addToGroup([id].concat(elements.map((el)=>el.id)));
|
||||
ea.addElementsToView(false);
|
||||
ea.reset();
|
||||
}
|
||||
43
ea-scripts/Copy Selected Element Styles to Global.md
Normal file
43
ea-scripts/Copy Selected Element Styles to Global.md
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,75 +1,86 @@
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the width of the selected rectangles until they are all the same width and keep the text centered.
|
||||
|
||||
See documentation for more details:
|
||||
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupWidths = topGroups
|
||||
.map((g) =>
|
||||
g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minLeft: cur.x,
|
||||
maxRight: cur.x + cur.width,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft,
|
||||
maxRight:
|
||||
cur.x + cur.width > pre.maxRight
|
||||
? cur.x + cur.width
|
||||
: pre.maxRight,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minLeft: 0, maxRight: 0 }
|
||||
)
|
||||
)
|
||||
.map((r) => {
|
||||
r.width = r.maxRight - r.minLeft;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
const texts = topGroups[i]
|
||||
.filter((el) => el.type === "text")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
const groupWith = groupWidths[i].width;
|
||||
if (groupWith < maxGroupWidth) {
|
||||
const distance = maxGroupWidth - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
rect.x = rect.x + perRectDistance * j - perRectDistance / 2;
|
||||
rect.width += perRectDistance;
|
||||
}
|
||||
for (var j = 0; j < texts.length; j++) {
|
||||
const text = texts[j];
|
||||
text.x = text.x + perRectDistance * j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the width of the selected rectangles until they are all the same width and keep the text centered.
|
||||
|
||||
See documentation for more details:
|
||||
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupWidths = topGroups
|
||||
.map((g) => {
|
||||
if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) {
|
||||
// ignore individual lines
|
||||
return { minLeft: 0, maxRight: 0 };
|
||||
}
|
||||
return g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minLeft: cur.x,
|
||||
maxRight: cur.x + cur.width,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft,
|
||||
maxRight:
|
||||
cur.x + cur.width > pre.maxRight
|
||||
? cur.x + cur.width
|
||||
: pre.maxRight,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minLeft: 0, maxRight: 0 }
|
||||
);
|
||||
})
|
||||
.map((r) => {
|
||||
r.width = r.maxRight - r.minLeft;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
const texts = topGroups[i]
|
||||
.filter((el) => el.type === "text")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
const groupWith = groupWidths[i].width;
|
||||
if (groupWith < maxGroupWidth) {
|
||||
const distance = maxGroupWidth - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
const rectLeft = rect.x;
|
||||
const rectTop = rect.y;
|
||||
const rectRight = rect.x + rect.width;
|
||||
const rectBottom = rect.y + rect.height;
|
||||
|
||||
rect.x = rect.x + perRectDistance * j - perRectDistance / 2;
|
||||
rect.width += perRectDistance;
|
||||
|
||||
const textsWithRect = texts.filter(text => text.x >= rectLeft && text.x <= rectRight
|
||||
&& text.y >= rectTop && text.y <= rectBottom);
|
||||
for(const text of textsWithRect) {
|
||||
text.x = text.x + perRectDistance * j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
|
||||
@@ -1,76 +1,74 @@
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the width of the selected rectangles until they are all the same width.
|
||||
|
||||
See documentation for more details:
|
||||
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupWidths = topGroups
|
||||
.map((g) =>
|
||||
g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minLeft: cur.x,
|
||||
maxRight: cur.x + cur.width,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft,
|
||||
maxRight:
|
||||
cur.x + cur.width > pre.maxRight
|
||||
? cur.x + cur.width
|
||||
: pre.maxRight,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minLeft: 0, maxRight: 0 }
|
||||
)
|
||||
)
|
||||
.map((r) => {
|
||||
r.width = r.maxRight - r.minLeft;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
const texts = topGroups[i]
|
||||
.filter((el) => el.type === "text")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
const groupWith = groupWidths[i].width;
|
||||
if (groupWith < maxGroupWidth) {
|
||||
const distance = maxGroupWidth - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
rect.x = rect.x + perRectDistance * j;
|
||||
rect.width += perRectDistance;
|
||||
}
|
||||
for (var j = 0; j < texts.length; j++) {
|
||||
const text = texts[j];
|
||||
text.x = text.x + perRectDistance * j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the width of the selected rectangles until they are all the same width.
|
||||
|
||||
See documentation for more details:
|
||||
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupWidths = topGroups
|
||||
.map((g) => {
|
||||
if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) {
|
||||
// ignore individual lines
|
||||
return { minLeft: 0, maxRight: 0 };
|
||||
}
|
||||
return g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minLeft: cur.x,
|
||||
maxRight: cur.x + cur.width,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minLeft: cur.x < pre.minLeft ? cur.x : pre.minLeft,
|
||||
maxRight:
|
||||
cur.x + cur.width > pre.maxRight
|
||||
? cur.x + cur.width
|
||||
: pre.maxRight,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minLeft: 0, maxRight: 0 }
|
||||
);
|
||||
})
|
||||
.map((r) => {
|
||||
r.width = r.maxRight - r.minLeft;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupWidth = Math.max(...groupWidths.map((g) => g.width));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.x - rha.x);
|
||||
|
||||
const groupWith = groupWidths[i].width;
|
||||
if (groupWith < maxGroupWidth) {
|
||||
const distance = maxGroupWidth - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
rect.x = rect.x + perRectDistance * j;
|
||||
rect.width += perRectDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
|
||||
|
||||
@@ -1,75 +1,86 @@
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the height of the selected rectangles until they are all the same height and keep the text centered.
|
||||
|
||||
See documentation for more details:
|
||||
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupHeights = topGroups
|
||||
.map((g) =>
|
||||
g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minTop: cur.y,
|
||||
maxBottom: cur.y + cur.height,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minTop: cur.y < pre.minTop ? cur.y : pre.minTop,
|
||||
maxBottom:
|
||||
cur.y + cur.height > pre.maxBottom
|
||||
? cur.y + cur.height
|
||||
: pre.maxBottom,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minTop: 0, maxBottom: 0 }
|
||||
)
|
||||
)
|
||||
.map((r) => {
|
||||
r.height = r.maxBottom - r.minTop;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
const texts = topGroups[i]
|
||||
.filter((el) => el.type === "text")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
const groupWith = groupHeights[i].height;
|
||||
if (groupWith < maxGroupHeight) {
|
||||
const distance = maxGroupHeight - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
rect.y = rect.y + perRectDistance * j - perRectDistance / 2;
|
||||
rect.height += perRectDistance;
|
||||
}
|
||||
for (var j = 0; j < texts.length; j++) {
|
||||
const text = texts[j];
|
||||
text.y = text.y + perRectDistance * j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the height of the selected rectangles until they are all the same height and keep the text centered.
|
||||
|
||||
See documentation for more details:
|
||||
https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupHeights = topGroups
|
||||
.map((g) => {
|
||||
if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) {
|
||||
// ignore individual lines
|
||||
return { minTop: 0, maxBottom: 0 };
|
||||
}
|
||||
return g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minTop: cur.y,
|
||||
maxBottom: cur.y + cur.height,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minTop: cur.y < pre.minTop ? cur.y : pre.minTop,
|
||||
maxBottom:
|
||||
cur.y + cur.height > pre.maxBottom
|
||||
? cur.y + cur.height
|
||||
: pre.maxBottom,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minTop: 0, maxBottom: 0 }
|
||||
);
|
||||
})
|
||||
.map((r) => {
|
||||
r.height = r.maxBottom - r.minTop;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
const texts = topGroups[i]
|
||||
.filter((el) => el.type === "text")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
const groupWith = groupHeights[i].height;
|
||||
if (groupWith < maxGroupHeight) {
|
||||
const distance = maxGroupHeight - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
const rectLeft = rect.x;
|
||||
const rectTop = rect.y;
|
||||
const rectRight = rect.x + rect.width;
|
||||
const rectBottom = rect.y + rect.height;
|
||||
|
||||
rect.y = rect.y + perRectDistance * j - perRectDistance / 2;
|
||||
rect.height += perRectDistance;
|
||||
|
||||
const textsWithRect = texts.filter(text => text.x >= rectLeft && text.x <= rectRight
|
||||
&& text.y >= rectTop && text.y <= rectBottom);
|
||||
for(const text of textsWithRect) {
|
||||
text.y = text.y + perRectDistance * j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
|
||||
@@ -1,73 +1,71 @@
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the height of the selected rectangles until they are all the same height.
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupHeights = topGroups
|
||||
.map((g) =>
|
||||
g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minTop: cur.y,
|
||||
maxBottom: cur.y + cur.height,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minTop: cur.y < pre.minTop ? cur.y : pre.minTop,
|
||||
maxBottom:
|
||||
cur.y + cur.height > pre.maxBottom
|
||||
? cur.y + cur.height
|
||||
: pre.maxBottom,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minTop: 0, maxBottom: 0 }
|
||||
)
|
||||
)
|
||||
.map((r) => {
|
||||
r.height = r.maxBottom - r.minTop;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
const texts = topGroups[i]
|
||||
.filter((el) => el.type === "text")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
const groupWith = groupHeights[i].height;
|
||||
if (groupWith < maxGroupHeight) {
|
||||
const distance = maxGroupHeight - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
rect.y = rect.y + perRectDistance * j;
|
||||
rect.height += perRectDistance;
|
||||
}
|
||||
for (var j = 0; j < texts.length; j++) {
|
||||
const text = texts[j];
|
||||
text.y = text.y + perRectDistance * j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
|
||||
/*
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
This script expands the height of the selected rectangles until they are all the same height.
|
||||
|
||||
```javascript
|
||||
*/
|
||||
|
||||
const elements = ea.getViewSelectedElements();
|
||||
const topGroups = ea.getMaximumGroups(elements);
|
||||
|
||||
const groupHeights = topGroups
|
||||
.map((g) => {
|
||||
if(g.length === 1 && (g[0].type === 'arrow' || g[0].type === 'line')) {
|
||||
// ignore individual lines
|
||||
return { minTop: 0, maxBottom: 0 };
|
||||
}
|
||||
return g.reduce(
|
||||
(pre, cur, i) => {
|
||||
if (i === 0) {
|
||||
return {
|
||||
minTop: cur.y,
|
||||
maxBottom: cur.y + cur.height,
|
||||
index: i,
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
minTop: cur.y < pre.minTop ? cur.y : pre.minTop,
|
||||
maxBottom:
|
||||
cur.y + cur.height > pre.maxBottom
|
||||
? cur.y + cur.height
|
||||
: pre.maxBottom,
|
||||
index: i,
|
||||
};
|
||||
}
|
||||
},
|
||||
{ minTop: 0, maxBottom: 0 }
|
||||
);
|
||||
})
|
||||
.map((r) => {
|
||||
r.height = r.maxBottom - r.minTop;
|
||||
return r;
|
||||
});
|
||||
|
||||
const maxGroupHeight = Math.max(...groupHeights.map((g) => g.height));
|
||||
|
||||
for (var i = 0; i < topGroups.length; i++) {
|
||||
const rects = topGroups[i]
|
||||
.filter((el) => el.type === "rectangle")
|
||||
.sort((lha, rha) => lha.y - rha.y);
|
||||
|
||||
const groupWith = groupHeights[i].height;
|
||||
if (groupWith < maxGroupHeight) {
|
||||
const distance = maxGroupHeight - groupWith;
|
||||
const perRectDistance = distance / rects.length;
|
||||
for (var j = 0; j < rects.length; j++) {
|
||||
const rect = rects[j];
|
||||
rect.y = rect.y + perRectDistance * j;
|
||||
rect.height += perRectDistance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ea.copyViewElementsToEAforEditing(elements);
|
||||
ea.addElementsToView(false, false);
|
||||
|
||||
|
||||
@@ -14,10 +14,12 @@ Open the script you are interested in and save it to your Obsidian Vault includi
|
||||
## List of available scripts
|
||||
|Title|Description|Icon|Contributor|
|
||||
|----|----|----|----|
|
||||
|[Box Each Selected Groups](Box%20Each%20Selected%20Groups.md)|This script will add encapsulating boxes around each of the currently selected groups in Excalidraw.||[@1-2-3](https://github.com/1-2-3)|
|
||||
|[Box Selected Elements](Box%20Selected%20Elements.md)|This script will add an encapsulating box around the currently selected elements in Excalidraw.||[@zsviczian](https://github.com/zsviczian)|
|
||||
|[Bullet Point](Bullet%20Point.md)|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.||[@zsviczian](https://github.com/zsviczian)|
|
||||
|[Connect elements](Connect%20elements.md)|This script will connect two objects with an arrow. If either of the objects are a set of grouped elements (e.g. a text element grouped with an encapsulating rectangle), the script will identify these groups, and connect the arrow to the largest object in the group (assuming you want to connect the arrow to the box around the text element).||[@zsviczian](https://github.com/zsviczian)|
|
||||
|[Convert text to link with folder and alias](Convert%20text%20to%20link%20with%20folder%20and%20alias.md)|Converts text elements to links pointing to a file in a selected folder and with the alias set as the original text. The script will prompt the user to select an existing folder from the vault.|`original text` => `[[selected folder/original text\|original text]]`|[@zsviczian](https://github.com/zsviczian)|
|
||||
|[Copy Selected Element Styles to Global](Copy%20Selected%20Element%20Styles%20to%20Global)|This script will copy styles of any selected element into Excalidraw's global styles.||[@1-2-3](https://github.com/1-2-3)|
|
||||
|[Create new markdown file and embed into active drawing](Create%20new%20markdown%20file%20and%20embed%20into%20active%20drawing.md)|The script will prompt you for a filename, then create a new markdown document with the file name provided, open the new markdown document in an adjacent pane, and embed the markdown document into the active Excalidraw drawing.||[@zsviczian](https://github.com/zsviczian)|
|
||||
|[Darken background color](Darken%20background%20color.md)|This script darkens the background color of the selected element by 2% at a time. You can use this script several times until you are satisfied. It is recommended to set a shortcut key for this script so that you can quickly try to DARKEN and LIGHTEN the color effect. In contrast to the `Modify background color opacity` script, the advantage is that the background color of the element is not affected by the canvas color, and the color value does not appear in a strange rgba() form.||[@1-2-3](https://github.com/1-2-3)|
|
||||
|[Dimensions](Dimensions.md)|Currently there is no way to specify the exact location and size of objects in Excalidraw. You can bridge this gap with the following simple script.||[@zsviczian](https://github.com/zsviczian)|
|
||||
|
||||
@@ -25,10 +25,12 @@ I would love to include your contribution in the script library. If you have a s
|
||||
---
|
||||
|
||||
# List of available scripts
|
||||
- [[#Box Each Selected Groups]]
|
||||
- [[#Box Selected Elements]]
|
||||
- [[#Bullet Point]]
|
||||
- [[#Connect elements]]
|
||||
- [[#Convert text to link with folder and alias]]
|
||||
- [[#Copy Selected Element Styles to Global]]
|
||||
- [[#Create new markdown file and embed into active drawing]]
|
||||
- [[#Darken background color]]
|
||||
- [[#Dimensions]]
|
||||
@@ -52,6 +54,11 @@ I would love to include your contribution in the script library. If you have a s
|
||||
- [[#Transfer TextElements to Excalidraw markdown metadata]]
|
||||
- [[#Zoom to Fit Selected Elements]]
|
||||
|
||||
## Box Each Selected Groups
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Box%20Each%20Selected%20Groups.md
|
||||
```
|
||||
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/1-2-3'>@1-2-3</a></td></tr><tr valign='top'><td class="label">Source</td><td class="data"><a href='https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/master/ea-scripts/Box%20Each%20Selected%20Groups.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">This script will add encapsulating boxes around each of the currently selected groups in Excalidraw.<br><img src='https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-box-each-selected-groups.png'></td></tr></table>
|
||||
|
||||
## Box Selected Elements
|
||||
```excalidraw-script-install
|
||||
@@ -77,6 +84,12 @@ https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea
|
||||
```
|
||||
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/zsviczian'>@zsviczian</a></td></tr><tr valign='top'><td class="label">Source</td><td class="data"><a href='https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/master/ea-scripts/Convert%20text%20to%20link%20with%20folder%20and%20alias.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">Converts text elements to links pointing to a file in a selected folder and with the alias set as the original text. The script will prompt the user to select an existing folder from the vault.<br><code>original text</code> - <code>[[selected folder/original text|original text]]</code></td></tr></table>
|
||||
|
||||
## Copy Selected Element Styles to Global
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Copy%20Selected%20Element%20Styles%20to%20Global.md
|
||||
```
|
||||
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/1-2-3'>@1-2-3</a></td></tr><tr valign='top'><td class="label">Source</td><td class="data"><a href='https://github.com/zsviczian/obsidian-excalidraw-plugin/blob/master/ea-scripts/Copy%20Selected%20Element%20Styles%20to%20Global.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">This script will copy styles of any selected element into Excalidraw's global styles.<br><img src='https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-copy-selected-element-styles-to-global.png'></td></tr></table>
|
||||
|
||||
## Create new markdown file and embed into active drawing
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Create%20new%20markdown%20file%20and%20embed%20into%20active%20drawing.md
|
||||
|
||||
BIN
images/scripts-box-each-selected-groups.png
Normal file
BIN
images/scripts-box-each-selected-groups.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
BIN
images/scripts-copy-selected-element-styles-to-global.png
Normal file
BIN
images/scripts-copy-selected-element-styles-to-global.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 46 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "1.5.16",
|
||||
"version": "1.5.19",
|
||||
"minAppVersion": "0.12.16",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@zsviczian/excalidraw": "0.10.0-obsidian-33",
|
||||
"@zsviczian/excalidraw": "0.10.0-obsidian-35",
|
||||
"monkey-around": "^2.2.0",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
|
||||
@@ -19,6 +19,8 @@ import { tex2dataURL } from "./LaTeX";
|
||||
import ExcalidrawPlugin from "./main";
|
||||
import {
|
||||
errorlog,
|
||||
getDataURL,
|
||||
getFontDataURL,
|
||||
getImageSize,
|
||||
getLinkParts,
|
||||
LinkParts,
|
||||
@@ -397,25 +399,9 @@ const convertMarkdownToSVG = async (
|
||||
fontDef = "";
|
||||
break;
|
||||
default:
|
||||
const f = plugin.app.metadataCache.getFirstLinkpathDest(
|
||||
fontName,
|
||||
file.path,
|
||||
);
|
||||
if (f) {
|
||||
const ab = await plugin.app.vault.readBinary(f);
|
||||
const mimeType = f.extension.startsWith("woff")
|
||||
? "application/font-woff"
|
||||
: "font/truetype";
|
||||
fontName = f.basename;
|
||||
fontDef = ` @font-face {font-family: "${fontName}";src: url("${await getDataURL(
|
||||
ab,
|
||||
mimeType,
|
||||
)}") format("${f.extension === "ttf" ? "truetype" : f.extension}");}`;
|
||||
const split = fontDef.split(";base64,", 2);
|
||||
fontDef = `${split[0]};charset=utf-8;base64,${split[1]}`;
|
||||
} else {
|
||||
fontDef = "";
|
||||
}
|
||||
const font = await getFontDataURL(plugin.app,fontName,file.path);
|
||||
fontDef = font.fontDef;
|
||||
fontName = font.fontName;
|
||||
}
|
||||
|
||||
const fontColor = fileCache?.frontmatter
|
||||
@@ -552,21 +538,6 @@ const convertMarkdownToSVG = async (
|
||||
return svgToBase64(finalSVG) as DataURL;
|
||||
};
|
||||
|
||||
const getDataURL = async (
|
||||
file: ArrayBuffer,
|
||||
mimeType: string,
|
||||
): Promise<DataURL> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
const dataURL = reader.result as DataURL;
|
||||
resolve(dataURL);
|
||||
};
|
||||
reader.onerror = (error) => reject(error);
|
||||
reader.readAsDataURL(new Blob([new Uint8Array(file)], { type: mimeType }));
|
||||
});
|
||||
};
|
||||
|
||||
const generateIdFromFile = async (file: ArrayBuffer): Promise<FileId> => {
|
||||
let id: FileId;
|
||||
try {
|
||||
|
||||
@@ -52,7 +52,7 @@ export interface ExcalidrawAutomate {
|
||||
roughness: number;
|
||||
opacity: number;
|
||||
strokeSharpness: StrokeSharpness; //type StrokeSharpness = "round" | "sharp"
|
||||
fontFamily: number; //1: Virgil, 2:Helvetica, 3:Cascadia
|
||||
fontFamily: number; //1: Virgil, 2:Helvetica, 3:Cascadia, 4:LocalFont
|
||||
fontSize: number;
|
||||
textAlign: string; //"left"|"right"|"center"
|
||||
verticalAlign: string; //"top"|"bottom"|"middle" :for future use, has no effect currently
|
||||
@@ -289,14 +289,17 @@ export async function initExcalidrawAutomate(
|
||||
setFontFamily(val: number) {
|
||||
switch (val) {
|
||||
case 1:
|
||||
this.style.fontFamily = 1;
|
||||
return getFontFamily(1);
|
||||
this.style.fontFamily = 4;
|
||||
return getFontFamily(4);
|
||||
case 2:
|
||||
this.style.fontFamily = 2;
|
||||
return getFontFamily(2);
|
||||
default:
|
||||
case 3:
|
||||
this.style.strokeSharpness = 3;
|
||||
return getFontFamily(3);
|
||||
default:
|
||||
this.style.strokeSharpness = 1;
|
||||
return getFontFamily(1);
|
||||
}
|
||||
},
|
||||
setTheme(val: number) {
|
||||
@@ -1333,6 +1336,8 @@ function getFontFamily(id: number) {
|
||||
return "Helvetica, Segoe UI Emoji";
|
||||
case 3:
|
||||
return "Cascadia, Segoe UI Emoji";
|
||||
case 4:
|
||||
return "LocalFont";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1546,7 +1551,7 @@ export async function createSVG(
|
||||
if (template?.hasSVGwithBitmap) {
|
||||
svg.setAttribute("hasbitmap", "true");
|
||||
}
|
||||
return embedFont ? embedFontsInSVG(svg) : svg;
|
||||
return embedFont ? embedFontsInSVG(svg,plugin) : svg;
|
||||
}
|
||||
|
||||
function estimateLineBound(points: any): [number, number, number, number] {
|
||||
|
||||
@@ -152,9 +152,9 @@ export default class ExcalidrawView extends TextFileView {
|
||||
private preventReload: boolean = true;
|
||||
public compatibilityMode: boolean = false;
|
||||
//store key state for view mode link resolution
|
||||
private ctrlKeyDown = false;
|
||||
/*private ctrlKeyDown = false;
|
||||
private shiftKeyDown = false;
|
||||
private altKeyDown = false;
|
||||
private altKeyDown = false;*/
|
||||
|
||||
//https://stackoverflow.com/questions/27132796/is-there-any-javascript-event-fired-when-the-on-screen-keyboard-on-mobile-safari
|
||||
private isEditingText: boolean = false;
|
||||
@@ -205,7 +205,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
return;
|
||||
}
|
||||
const serializer = new XMLSerializer();
|
||||
const svgString = serializer.serializeToString(embedFontsInSVG(svg));
|
||||
const svgString = serializer.serializeToString(embedFontsInSVG(svg,this.plugin));
|
||||
if (file && file instanceof TFile) {
|
||||
await this.app.vault.modify(file, svgString);
|
||||
} else {
|
||||
@@ -823,6 +823,10 @@ export default class ExcalidrawView extends TextFileView {
|
||||
? om.zenModeEnabled
|
||||
: this.excalidrawAPI.getAppState().zenModeEnabled;
|
||||
//debug({where:"ExcalidrawView.loadDrawing",file:this.file.name,dataTheme:excalidrawData.appState.theme,before:"updateScene"})
|
||||
this.excalidrawAPI.setLocalFont(
|
||||
this.plugin.settings.experimentalEnableFourthFont
|
||||
);
|
||||
|
||||
this.excalidrawAPI.updateScene({
|
||||
elements: excalidrawData.elements,
|
||||
appState: {
|
||||
@@ -1007,7 +1011,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
if (!svg) {
|
||||
return null;
|
||||
}
|
||||
svg = embedFontsInSVG(svg);
|
||||
svg = embedFontsInSVG(svg,this.plugin);
|
||||
download(
|
||||
null,
|
||||
svgToBase64(svg.outerHTML),
|
||||
@@ -1070,6 +1074,10 @@ export default class ExcalidrawView extends TextFileView {
|
||||
this.excalidrawAPI = api;
|
||||
//console.log({where:"ExcalidrawView.React.ReadyPromise"});
|
||||
//debug({where:"ExcalidrawView.React.useEffect",file:this.file.name,before:"this.loadSceneFiles"});
|
||||
this.excalidrawAPI.setLocalFont(
|
||||
this.plugin.settings.experimentalEnableFourthFont
|
||||
);
|
||||
|
||||
this.loadSceneFiles();
|
||||
this.updateContainerSize(null, true);
|
||||
});
|
||||
@@ -1517,8 +1525,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const event = new MouseEvent("click", {
|
||||
ctrlKey: true,
|
||||
metaKey: true,
|
||||
shiftKey: this.shiftKeyDown,
|
||||
altKey: this.altKeyDown,
|
||||
shiftKey: this.plugin.shiftKeyDown,
|
||||
altKey: this.plugin.altKeyDown,
|
||||
});
|
||||
this.handleLinkClick(this, event);
|
||||
selectedTextElement = null;
|
||||
@@ -1528,8 +1536,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
const event = new MouseEvent("click", {
|
||||
ctrlKey: true,
|
||||
metaKey: true,
|
||||
shiftKey: this.shiftKeyDown,
|
||||
altKey: this.altKeyDown,
|
||||
shiftKey: this.plugin.shiftKeyDown,
|
||||
altKey: this.plugin.altKeyDown,
|
||||
});
|
||||
this.handleLinkClick(this, event);
|
||||
selectedImageElement = null;
|
||||
@@ -1538,6 +1546,73 @@ export default class ExcalidrawView extends TextFileView {
|
||||
|
||||
let mouseEvent: any = null;
|
||||
|
||||
const showHoverPreview = () => {
|
||||
let linktext = "";
|
||||
const selectedElement = getTextElementAtPointer(currentPosition);
|
||||
if (!selectedElement || !selectedElement.text) {
|
||||
const selectedImgElement =
|
||||
getImageElementAtPointer(currentPosition);
|
||||
if (!selectedImgElement || !selectedImgElement.fileId) {
|
||||
return;
|
||||
}
|
||||
if (!this.excalidrawData.hasFile(selectedImgElement.fileId)) {
|
||||
return;
|
||||
}
|
||||
const ef = this.excalidrawData.getFile(
|
||||
selectedImgElement.fileId,
|
||||
);
|
||||
const ref = ef.linkParts.ref
|
||||
? `#${ef.linkParts.isBlockRef ? "^" : ""}${ef.linkParts.ref}`
|
||||
: "";
|
||||
linktext =
|
||||
this.excalidrawData.getFile(selectedImgElement.fileId).file
|
||||
.path + ref;
|
||||
} else {
|
||||
const text: string =
|
||||
this.textMode === TextMode.parsed
|
||||
? this.excalidrawData.getRawText(selectedElement.id)
|
||||
: selectedElement.text;
|
||||
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
if (text.match(REG_LINKINDEX_HYPERLINK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parts = REGEX_LINK.getRes(text).next();
|
||||
if (!parts.value) {
|
||||
return;
|
||||
}
|
||||
linktext = REGEX_LINK.getLink(parts); //parts.value[2] ? parts.value[2]:parts.value[6];
|
||||
if (linktext.match(REG_LINKINDEX_HYPERLINK)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.plugin.hover.linkText = linktext;
|
||||
this.plugin.hover.sourcePath = this.file.path;
|
||||
hoverPreviewTarget = this.contentEl; //e.target;
|
||||
this.app.workspace.trigger("hover-link", {
|
||||
event: mouseEvent,
|
||||
source: VIEW_TYPE_EXCALIDRAW,
|
||||
hoverParent: hoverPreviewTarget,
|
||||
targetEl: hoverPreviewTarget,
|
||||
linktext: this.plugin.hover.linkText,
|
||||
sourcePath: this.plugin.hover.sourcePath,
|
||||
});
|
||||
hoverPoint = currentPosition;
|
||||
if (this.isFullscreen()) {
|
||||
const self = this;
|
||||
setTimeout(() => {
|
||||
const popover = document.body.querySelector("div.popover");
|
||||
if (popover) {
|
||||
self.contentEl.append(popover);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
}
|
||||
|
||||
const excalidrawDiv = React.createElement(
|
||||
"div",
|
||||
{
|
||||
@@ -1554,83 +1629,20 @@ export default class ExcalidrawView extends TextFileView {
|
||||
this.exitFullscreen();
|
||||
}
|
||||
|
||||
/*
|
||||
this.ctrlKeyDown = e[CTRL_OR_CMD]; //.ctrlKey||e.metaKey;
|
||||
this.shiftKeyDown = e.shiftKey;
|
||||
this.altKeyDown = e.altKey;
|
||||
this.altKeyDown = e.altKey;*/
|
||||
|
||||
if (e[CTRL_OR_CMD] && !e.shiftKey && !e.altKey) {
|
||||
//.ctrlKey||e.metaKey) && !e.shiftKey && !e.altKey) {
|
||||
let linktext = "";
|
||||
const selectedElement = getTextElementAtPointer(currentPosition);
|
||||
if (!selectedElement || !selectedElement.text) {
|
||||
const selectedImgElement =
|
||||
getImageElementAtPointer(currentPosition);
|
||||
if (!selectedImgElement || !selectedImgElement.fileId) {
|
||||
return;
|
||||
}
|
||||
if (!this.excalidrawData.hasFile(selectedImgElement.fileId)) {
|
||||
return;
|
||||
}
|
||||
const ef = this.excalidrawData.getFile(
|
||||
selectedImgElement.fileId,
|
||||
);
|
||||
const ref = ef.linkParts.ref
|
||||
? `#${ef.linkParts.isBlockRef ? "^" : ""}${ef.linkParts.ref}`
|
||||
: "";
|
||||
linktext =
|
||||
this.excalidrawData.getFile(selectedImgElement.fileId).file
|
||||
.path + ref;
|
||||
} else {
|
||||
const text: string =
|
||||
this.textMode === TextMode.parsed
|
||||
? this.excalidrawData.getRawText(selectedElement.id)
|
||||
: selectedElement.text;
|
||||
|
||||
if (!text) {
|
||||
return;
|
||||
}
|
||||
if (text.match(REG_LINKINDEX_HYPERLINK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const parts = REGEX_LINK.getRes(text).next();
|
||||
if (!parts.value) {
|
||||
return;
|
||||
}
|
||||
linktext = REGEX_LINK.getLink(parts); //parts.value[2] ? parts.value[2]:parts.value[6];
|
||||
if (linktext.match(REG_LINKINDEX_HYPERLINK)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.plugin.hover.linkText = linktext;
|
||||
this.plugin.hover.sourcePath = this.file.path;
|
||||
hoverPreviewTarget = this.contentEl; //e.target;
|
||||
this.app.workspace.trigger("hover-link", {
|
||||
event: mouseEvent,
|
||||
source: VIEW_TYPE_EXCALIDRAW,
|
||||
hoverParent: hoverPreviewTarget,
|
||||
targetEl: hoverPreviewTarget,
|
||||
linktext: this.plugin.hover.linkText,
|
||||
sourcePath: this.plugin.hover.sourcePath,
|
||||
});
|
||||
hoverPoint = currentPosition;
|
||||
if (this.isFullscreen()) {
|
||||
const self = this;
|
||||
setTimeout(() => {
|
||||
const popover = document.body.querySelector("div.popover");
|
||||
if (popover) {
|
||||
self.contentEl.append(popover);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
showHoverPreview();
|
||||
}
|
||||
},
|
||||
onKeyUp: (e: any) => {
|
||||
/* onKeyUp: (e: any) => {
|
||||
this.ctrlKeyDown = e[CTRL_OR_CMD]; //.ctrlKey||e.metaKey;
|
||||
this.shiftKeyDown = e.shiftKey;
|
||||
this.altKeyDown = e.altKey;
|
||||
},
|
||||
},*/
|
||||
onClick: (e: MouseEvent): any => {
|
||||
if (!e[CTRL_OR_CMD]) {
|
||||
return;
|
||||
@@ -1699,7 +1711,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
blockOnMouseButtonDown = true;
|
||||
|
||||
//ctrl click
|
||||
if (this.ctrlKeyDown) {
|
||||
if (this.plugin.ctrlKeyDown) {
|
||||
handleLinkClick();
|
||||
return;
|
||||
}
|
||||
@@ -1715,6 +1727,9 @@ export default class ExcalidrawView extends TextFileView {
|
||||
if (p.button === "up") {
|
||||
blockOnMouseButtonDown = false;
|
||||
}
|
||||
if (this.plugin.ctrlKeyDown) {
|
||||
showHoverPreview();
|
||||
}
|
||||
},
|
||||
onChange: (et: ExcalidrawElement[], st: AppState) => {
|
||||
viewModeEnabled = st.viewModeEnabled;
|
||||
|
||||
@@ -127,7 +127,7 @@ const getIMG = async (
|
||||
if (!svg) {
|
||||
return null;
|
||||
}
|
||||
svg = embedFontsInSVG(svg);
|
||||
svg = embedFontsInSVG(svg,plugin);
|
||||
svg.removeAttribute("width");
|
||||
svg.removeAttribute("height");
|
||||
img.setAttribute("src", svgToBase64(svg.outerHTML));
|
||||
@@ -312,7 +312,10 @@ const tmpObsidianWYSIWYG = async (
|
||||
if(hasHeight)
|
||||
attr.fheight = internalEmbedDiv.getAttribute("height");
|
||||
const alt = internalEmbedDiv.getAttribute("alt");
|
||||
const hasAttr = alt && alt!=="" && alt!==basename;
|
||||
const hasAttr = alt
|
||||
&& alt !== ""
|
||||
&& alt !== basename
|
||||
&& alt !== internalEmbedDiv.getAttribute("src");
|
||||
if(hasAttr) {
|
||||
//1:width, 2:height, 3:style 1 2 3
|
||||
const parts = alt.match(/(\d*%?)x?(\d*%?)\|?(.*)/);
|
||||
|
||||
87
src/Utils.ts
87
src/Utils.ts
@@ -3,13 +3,14 @@ import {
|
||||
App,
|
||||
normalizePath,
|
||||
Notice,
|
||||
request,
|
||||
TAbstractFile,
|
||||
TFolder,
|
||||
Vault,
|
||||
WorkspaceLeaf,
|
||||
} from "obsidian";
|
||||
import { Random } from "roughjs/bin/math";
|
||||
import { Zoom } from "@zsviczian/excalidraw/types/types";
|
||||
import { DataURL, Zoom } from "@zsviczian/excalidraw/types/types";
|
||||
import { CASCADIA_FONT, REG_BLOCK_REF_CLEAN, VIRGIL_FONT } from "./constants";
|
||||
import ExcalidrawPlugin from "./main";
|
||||
import { ExcalidrawElement } from "@zsviczian/excalidraw/types/element/types";
|
||||
@@ -34,14 +35,35 @@ export const checkExcalidrawVersion = async (app:App) => {
|
||||
versionUpdateChecked = true;
|
||||
//@ts-ignore
|
||||
const manifest = app.plugins.manifests["obsidian-excalidraw-plugin"];
|
||||
//@ts-ignore
|
||||
const latestVersion = await app.plugins.getLatestVersion("obsidian-excalidraw-plugin",manifest)
|
||||
if(latestVersion>manifest.version) {
|
||||
new Notice(`A newer version of Excalidraw is available in Community Plugins. You are using ${manifest.version}. The latest version is ${latestVersion}`);
|
||||
|
||||
try {
|
||||
const gitAPIrequest = async () => {
|
||||
return JSON.parse(await request({
|
||||
url: `https://api.github.com/repos/zsviczian/obsidian-excalidraw-plugin/releases?per_page=5&page=1`,
|
||||
}))
|
||||
}
|
||||
|
||||
const latestVersion = ((await gitAPIrequest())
|
||||
.map((el:any) => {
|
||||
return {
|
||||
version: el.tag_name,
|
||||
published: new Date(el.published_at),
|
||||
};
|
||||
})
|
||||
.filter((el:any) => el.version.match(/^\d+\.\d+\.\d+$/))
|
||||
.sort((el1:any,el2:any)=>el2.published-el1.published))[0].version;
|
||||
|
||||
if(latestVersion>manifest.version) {
|
||||
new Notice(`A newer version of Excalidraw is available in Community Plugins.\n\nYou are using ${manifest.version}.\nThe latest is ${latestVersion}`);
|
||||
}
|
||||
} catch(e) {
|
||||
errorlog({where:"Utils/checkExcalidrawVersion", error:e});
|
||||
}
|
||||
setTimeout(()=>versionUpdateChecked=false,28800000);//reset after 8 hours
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Splits a full path including a folderpath and a filename into separate folderpath and filename components
|
||||
* @param filepath
|
||||
@@ -281,6 +303,53 @@ export const getNewOrAdjacentLeaf = (
|
||||
return plugin.app.workspace.createLeafBySplit(leaf);
|
||||
};
|
||||
|
||||
export const getDataURL = async (
|
||||
file: ArrayBuffer,
|
||||
mimeType: string,
|
||||
): Promise<DataURL> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
reader.onload = () => {
|
||||
const dataURL = reader.result as DataURL;
|
||||
resolve(dataURL);
|
||||
};
|
||||
reader.onerror = (error) => reject(error);
|
||||
reader.readAsDataURL(new Blob([new Uint8Array(file)], { type: mimeType }));
|
||||
});
|
||||
};
|
||||
|
||||
export const getFontDataURL = async (
|
||||
app:App,
|
||||
fontFileName: string,
|
||||
sourcePath: string,
|
||||
name?:string
|
||||
):Promise<{fontDef: string, fontName: string, dataURL: string}> => {
|
||||
let fontDef:string = "";
|
||||
let fontName = "";
|
||||
let dataURL = "";
|
||||
const f = app.metadataCache.getFirstLinkpathDest(
|
||||
fontFileName,
|
||||
sourcePath,
|
||||
);
|
||||
if (f) {
|
||||
const ab = await app.vault.readBinary(f);
|
||||
const mimeType = f.extension.startsWith("woff")
|
||||
? "application/font-woff"
|
||||
: "font/truetype";
|
||||
fontName = name??f.basename;
|
||||
dataURL = await getDataURL(
|
||||
ab,
|
||||
mimeType,
|
||||
);
|
||||
fontDef = ` @font-face {font-family: "${fontName}";src: url("${
|
||||
dataURL
|
||||
}") format("${f.extension === "ttf" ? "truetype" : f.extension}");}`;
|
||||
const split = fontDef.split(";base64,", 2);
|
||||
fontDef = `${split[0]};charset=utf-8;base64,${split[1]}`;
|
||||
}
|
||||
return {fontDef,fontName,dataURL};
|
||||
}
|
||||
|
||||
export const svgToBase64 = (svg: string): string => {
|
||||
return `data:image/svg+xml;base64,${btoa(
|
||||
unescape(encodeURIComponent(svg.replaceAll(" ", " "))),
|
||||
@@ -379,17 +448,19 @@ export const getPNG = async (
|
||||
}
|
||||
};
|
||||
|
||||
export const embedFontsInSVG = (svg: SVGSVGElement): SVGSVGElement => {
|
||||
export const embedFontsInSVG = (svg: SVGSVGElement, plugin: ExcalidrawPlugin): SVGSVGElement => {
|
||||
//replace font references with base64 fonts
|
||||
const includesVirgil =
|
||||
svg.querySelector("text[font-family^='Virgil']") != null;
|
||||
const includesCascadia =
|
||||
svg.querySelector("text[font-family^='Cascadia']") != null;
|
||||
const includesLocalFont =
|
||||
svg.querySelector("text[font-family^='LocalFont']") != null;
|
||||
const defs = svg.querySelector("defs");
|
||||
if (defs && (includesCascadia || includesVirgil)) {
|
||||
if (defs && (includesCascadia || includesVirgil || includesLocalFont)) {
|
||||
defs.innerHTML = `<style>${includesVirgil ? VIRGIL_FONT : ""}${
|
||||
includesCascadia ? CASCADIA_FONT : ""
|
||||
}</style>`;
|
||||
}${includesLocalFont ? plugin.fourthFontDef : ""}</style>`;
|
||||
}
|
||||
return svg;
|
||||
};
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -275,6 +275,15 @@ export default {
|
||||
LIVEPREVIEW_DESC: "Turn this on to support image embedding styles such as ![[drawing|width|style]] in live preview editing mode. " +
|
||||
"The setting will not effect the currently open documents. You need close the open documents and re-open them for the change " +
|
||||
"to take effect.",
|
||||
ENABLE_FOURTH_FONT_NAME: "Enable fourth font option",
|
||||
ENABLE_FOURTH_FONT_DESC: "By turning this on, you will see a fourth font button on the properties panel for text elements. " +
|
||||
"Files that use this fourth font will (partly) lose their paltform independence. " +
|
||||
"Depending on the cutom font set in settings, they will look differently when loaded in another vault, or at a later time. " +
|
||||
"Also the 4th font will display as system default font on excalidraw.com, or other Excalidraw versions.",
|
||||
FOURTH_FONT_NAME: "Forth font file",
|
||||
FOURTH_FONT_DESC: "Select a .ttf, .woff or .woff2 font file from your vault to use as the fourth font. " +
|
||||
"If no file is selected excalidraw will use the Virgil font by default.",
|
||||
|
||||
|
||||
//openDrawings.ts
|
||||
SELECT_FILE: "Select a file then press enter.",
|
||||
|
||||
56
src/main.ts
56
src/main.ts
@@ -39,6 +39,8 @@ import {
|
||||
CTRL_OR_CMD,
|
||||
SCRIPT_INSTALL_CODEBLOCK,
|
||||
SCRIPT_INSTALL_FOLDER,
|
||||
VIRGIL_FONT,
|
||||
VIRGIL_DATAURL,
|
||||
} from "./constants";
|
||||
import ExcalidrawView, { ExportSettings, TextMode } from "./ExcalidrawView";
|
||||
import { getMarkdownDrawingSection } from "./ExcalidrawData";
|
||||
@@ -67,6 +69,7 @@ import {
|
||||
embedFontsInSVG,
|
||||
errorlog,
|
||||
getAttachmentsFolderAndFilePath,
|
||||
getFontDataURL,
|
||||
getIMGFilename,
|
||||
getIMGPathFromExcalidrawFile,
|
||||
getNewUniqueFilepath,
|
||||
@@ -120,7 +123,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
public mathjax: any = null;
|
||||
private mathjaxDiv: HTMLDivElement = null;
|
||||
public scriptEngine: ScriptEngine;
|
||||
|
||||
public fourthFontDef: string = VIRGIL_FONT;
|
||||
constructor(app: App, manifest: PluginManifest) {
|
||||
super(app, manifest);
|
||||
this.filesMaster = new Map<
|
||||
@@ -155,6 +158,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
this.experimentalFileTypeDisplayToggle(this.settings.experimentalFileType);
|
||||
this.registerCommands();
|
||||
this.registerEventListeners();
|
||||
this.initializeFourthFont();
|
||||
|
||||
//inspiration taken from kanban:
|
||||
//https://github.com/mgmeyers/obsidian-kanban/blob/44118e25661bff9ebfe54f71ae33805dc88ffa53/src/main.ts#L267
|
||||
@@ -186,6 +190,31 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
});
|
||||
}
|
||||
|
||||
public initializeFourthFont() {
|
||||
this.app.workspace.onLayoutReady(async() => {
|
||||
const font = (await getFontDataURL(this.app,this.settings.experimantalFourthFont,"","LocalFont"));
|
||||
const fourthFontDataURL = font.dataURL === "" ? VIRGIL_DATAURL : font.dataURL;
|
||||
this.fourthFontDef = font.fontDef
|
||||
const newStylesheet = document.createElement("style");
|
||||
newStylesheet.id = "local-font-stylesheet";
|
||||
newStylesheet.textContent = `
|
||||
@font-face {
|
||||
font-family: 'LocalFont';
|
||||
src: url("${fourthFontDataURL}");
|
||||
font-display: swap;
|
||||
}
|
||||
`;
|
||||
// replace the old local font <style> element with the one we just created
|
||||
const oldStylesheet = document.getElementById(newStylesheet.id);
|
||||
document.head.appendChild(newStylesheet);
|
||||
if (oldStylesheet) {
|
||||
document.head.removeChild(oldStylesheet);
|
||||
}
|
||||
|
||||
await (document as any).fonts.load(`20px LocalFont`);
|
||||
});
|
||||
}
|
||||
|
||||
private loadMathJax() {
|
||||
//loading Obsidian MathJax as fallback
|
||||
this.app.workspace.onLayoutReady(() => {
|
||||
@@ -1097,10 +1126,32 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
);
|
||||
}
|
||||
|
||||
public ctrlKeyDown:boolean;
|
||||
public shiftKeyDown:boolean;
|
||||
public altKeyDown:boolean;
|
||||
public onKeyUp:any;
|
||||
public onKeyDown:any;
|
||||
|
||||
private popScope: Function = null;
|
||||
private registerEventListeners() {
|
||||
const self = this;
|
||||
this.app.workspace.onLayoutReady(async () => {
|
||||
|
||||
self.onKeyUp = (e:KeyboardEvent) => {
|
||||
self.ctrlKeyDown = e[CTRL_OR_CMD];
|
||||
self.shiftKeyDown = e.shiftKey;
|
||||
self.altKeyDown = e.altKey;
|
||||
}
|
||||
|
||||
self.onKeyDown = (e:KeyboardEvent) => {
|
||||
this.ctrlKeyDown = e[CTRL_OR_CMD];
|
||||
this.shiftKeyDown = e.shiftKey;
|
||||
this.altKeyDown = e.altKey;
|
||||
}
|
||||
|
||||
window.addEventListener("keydown",self.onKeyDown,false);
|
||||
window.addEventListener("keyup",self.onKeyUp,false);
|
||||
|
||||
//watch filename change to rename .svg, .png; to sync to .md; to update links
|
||||
const renameEventHandler = async (
|
||||
file: TAbstractFile,
|
||||
@@ -1273,6 +1324,9 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
}
|
||||
|
||||
onunload() {
|
||||
window.removeEventListener("keydown",this.onKeyDown,false);
|
||||
window.removeEventListener("keyup",this.onKeyUp,false);
|
||||
|
||||
destroyExcalidrawAutomate();
|
||||
if (this.popScope) {
|
||||
this.popScope();
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
normalizePath,
|
||||
PluginSettingTab,
|
||||
Setting,
|
||||
TFile,
|
||||
} from "obsidian";
|
||||
import { VIEW_TYPE_EXCALIDRAW } from "./constants";
|
||||
import ExcalidrawView from "./ExcalidrawView";
|
||||
@@ -46,6 +47,8 @@ export interface ExcalidrawSettings {
|
||||
experimentalFileType: boolean;
|
||||
experimentalFileTag: string;
|
||||
experimentalLivePreview: boolean;
|
||||
experimentalEnableFourthFont: boolean;
|
||||
experimantalFourthFont: string;
|
||||
loadCount: number; //version 1.2 migration counter
|
||||
drawingOpenCount: number;
|
||||
library: string;
|
||||
@@ -97,6 +100,8 @@ export const DEFAULT_SETTINGS: ExcalidrawSettings = {
|
||||
experimentalFileType: false,
|
||||
experimentalFileTag: "✏️",
|
||||
experimentalLivePreview: true,
|
||||
experimentalEnableFourthFont: false,
|
||||
experimantalFourthFont: "Virgil",
|
||||
compatibilityMode: false,
|
||||
loadCount: 0,
|
||||
drawingOpenCount: 0,
|
||||
@@ -131,11 +136,6 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
}
|
||||
|
||||
applySettingsUpdate(requestReloadDrawings: boolean = false) {
|
||||
/*clearTimeout(this.applyDebounceTimer);
|
||||
const plugin = this.plugin;
|
||||
this.applyDebounceTimer = window.setTimeout(() => {
|
||||
plugin.saveSettings();
|
||||
}, 500);*/
|
||||
if (requestReloadDrawings) {
|
||||
this.requestReloadDrawings = true;
|
||||
}
|
||||
@@ -542,18 +542,24 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("MD_DEFAULT_FONT_NAME"))
|
||||
.setDesc(t("MD_DEFAULT_FONT_DESC"))
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("Virgil|Cascadia|Filename")
|
||||
.setValue(this.plugin.settings.mdFont)
|
||||
.setName(t("MD_DEFAULT_FONT_NAME"))
|
||||
.setDesc(t("MD_DEFAULT_FONT_DESC"))
|
||||
.addDropdown(async (d: DropdownComponent) => {
|
||||
d.addOption("Virgil", "Virgil");
|
||||
d.addOption("Cascadia", "Cascadia");
|
||||
this.app.vault.getFiles()
|
||||
.filter((f)=>["ttf", "woff", "woff2"].contains(f.extension))
|
||||
.forEach((f:TFile)=>{
|
||||
d.addOption(f.path,f.name)
|
||||
})
|
||||
d.setValue(this.plugin.settings.mdFont)
|
||||
.onChange((value) => {
|
||||
this.requestReloadDrawings = true;
|
||||
this.plugin.settings.mdFont = value;
|
||||
this.applySettingsUpdate(true);
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("MD_DEFAULT_COLOR_NAME"))
|
||||
@@ -844,5 +850,37 @@ export class ExcalidrawSettingTab extends PluginSettingTab {
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("ENABLE_FOURTH_FONT_NAME"))
|
||||
.setDesc(t("ENABLE_FOURTH_FONT_DESC"))
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.experimentalEnableFourthFont)
|
||||
.onChange(async (value) => {
|
||||
this.requestReloadDrawings = true;
|
||||
this.plugin.settings.experimentalEnableFourthFont = value;
|
||||
this.applySettingsUpdate();
|
||||
}),
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("FOURTH_FONT_NAME"))
|
||||
.setDesc(t("FOURTH_FONT_DESC"))
|
||||
.addDropdown(async (d: DropdownComponent) => {
|
||||
d.addOption("Virgil", "Virgil");
|
||||
this.app.vault.getFiles()
|
||||
.filter((f)=>["ttf", "woff", "woff2"].contains(f.extension))
|
||||
.forEach((f:TFile)=>{
|
||||
d.addOption(f.path,f.name)
|
||||
})
|
||||
d.setValue(this.plugin.settings.experimantalFourthFont)
|
||||
.onChange((value) => {
|
||||
this.requestReloadDrawings = true;
|
||||
this.plugin.settings.experimantalFourthFont = value;
|
||||
this.applySettingsUpdate(true);
|
||||
this.plugin.initializeFourthFont();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"1.5.16": "0.12.16",
|
||||
"1.5.19": "0.12.16",
|
||||
"1.4.2": "0.11.13"
|
||||
}
|
||||
|
||||
@@ -1232,10 +1232,10 @@
|
||||
"@typescript-eslint/types" "5.6.0"
|
||||
"eslint-visitor-keys" "^3.0.0"
|
||||
|
||||
"@zsviczian/excalidraw@0.10.0-obsidian-33":
|
||||
"integrity" "sha512-ych61N48QASpcU3YJGX5nCWmnsdku5vsm6RLp7eiE8HzAdGGDFTlbwYg6p+uBw7MeJIu9gQx2hET9Gnx79LFRg=="
|
||||
"resolved" "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.10.0-obsidian-33.tgz"
|
||||
"version" "0.10.0-obsidian-33"
|
||||
"@zsviczian/excalidraw@0.10.0-obsidian-35":
|
||||
"integrity" "sha512-ENNMBqXb1keqZzOlyaMswmpOBh+Drr7EeuZ9sp4psdtFbjHyS3ZmPpQ9EIZEcFd75sbciK2Klu439/ioogC+Yg=="
|
||||
"resolved" "https://registry.npmjs.org/@zsviczian/excalidraw/-/excalidraw-0.10.0-obsidian-35.tgz"
|
||||
"version" "0.10.0-obsidian-35"
|
||||
dependencies:
|
||||
"dotenv" "10.0.0"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user