mirror of
https://github.com/zsviczian/obsidian-excalidraw-plugin.git
synced 2025-08-06 05:46:28 +00:00
Compare commits
10 Commits
2.4.2
...
2.5.0-beta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b1f504b5b | ||
|
|
d8f2776b40 | ||
|
|
2fd800e0a0 | ||
|
|
712402f7b1 | ||
|
|
b5c034ed92 | ||
|
|
d2805e7a8a | ||
|
|
4011b1c89a | ||
|
|
5bc348611c | ||
|
|
dd24affdbb | ||
|
|
d8542824a1 |
68
.github/ISSUE_TEMPLATE/How-to.yml
vendored
Normal file
68
.github/ISSUE_TEMPLATE/How-to.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
name: How to? Support request
|
||||
description: Ask for help with using the plugin or understanding its features.
|
||||
title: "SUPPORT: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
ℹ️ **Important: Please Read Before Submitting a Support Request** ℹ️
|
||||
|
||||
I am a one-person team working on this plugin as a part-time hobby. Please help me manage the workload by following these guidelines. **Support requests that don't include enough details may be closed without review**.
|
||||
|
||||
Before submitting a support request, please:
|
||||
1. **Review the [documentation](https://github.com/zsviczian/obsidian-excalidraw-plugin/wiki)** – your question may already be answered.
|
||||
2. **[Search issues](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues) (including closed ones)** to see if your question has already been addressed.
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please help by providing the following details. Requests without this information may be closed without review.
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
---
|
||||
|
||||
- type: checkboxes
|
||||
id: search_existing_resources
|
||||
attributes:
|
||||
label: Have you checked the documentation and searched existing issues?
|
||||
description: Please confirm that you've reviewed available resources before submitting your request.
|
||||
options:
|
||||
- label: Yes, I have reviewed the documentation and searched for related issues.
|
||||
|
||||
- type: textarea
|
||||
id: support_question
|
||||
attributes:
|
||||
label: "Your question"
|
||||
description: "Provide a clear and concise description of the question or issue you need help with."
|
||||
placeholder: "Describe your question or the problem you are trying to solve..."
|
||||
|
||||
- type: textarea
|
||||
id: steps_tried
|
||||
attributes:
|
||||
label: "Steps you've already tried"
|
||||
description: "List any steps you've taken to try to resolve or understand the issue."
|
||||
placeholder: |
|
||||
1. Tried reading the documentation.
|
||||
2. Searched the issues for similar questions.
|
||||
|
||||
- type: textarea
|
||||
id: expected_outcome
|
||||
attributes:
|
||||
label: "Expected outcome"
|
||||
description: "Describe what you expected to happen or what you are trying to achieve."
|
||||
placeholder: "Describe the result you are aiming for..."
|
||||
|
||||
- type: textarea
|
||||
id: additional_context
|
||||
attributes:
|
||||
label: "Additional context"
|
||||
description: "Add any other context or details that may help."
|
||||
placeholder: "Include any other information that may be relevant..."
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Attachments: Screenshots and files are critical!**
|
||||
A picture speaks a thousand words, and a screen recording even more. **Please attach screenshots, screen recordings, or sample files** to help illustrate your question or issue. Drag and drop them into the comment area or directly into any of the text fields above.
|
||||
69
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
69
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
name: Feature request
|
||||
description: Request a new feature for the Excalidraw plugin.
|
||||
title: "FR: "
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
🛠️ **Important: Please Read Before Submitting a Feature Request** 🛠️
|
||||
|
||||
I develop Excalidraw primarily as a hobby, and I prioritize features that I personally use regularly. Features I don't use often break without me noticing, which is why the plugin is as stable as it is—because I rely on it every day.
|
||||
|
||||
**Your task isn't just to describe the feature you want, but to sell me on the idea**. If I'm not convinced that the feature would significantly benefit my own workflow, it's unlikely I'll spend my free hobby time on it.
|
||||
|
||||
When creating your feature request:
|
||||
- **Provide real-life usage scenarios**: How will this feature help you? How do you imagine using it in practice?
|
||||
- **Sell the idea**: Convince me that I need this feature too.
|
||||
- **Include supporting materials**: Reference other solutions? Include relevant screenshots, screen recordings, and links. The more work I need to do to understand your request, the less likely it is to be implemented.
|
||||
|
||||
**Additional Guidelines:**
|
||||
- **Excalidraw Core Features**: If your request relates to core Excalidraw features, and not the Obsidian integration specifically, please raise it with the Excalidraw product team here: [Excalidraw Issues](https://github.com/excalidraw/excalidraw/issues).
|
||||
- **Cross-Platform Compatibility**: Obsidian and Excalidraw are cross-platform solutions. I cannot develop platform-specific features like Apple Pencil or Samsung S-Pen support due to technical limitations. Please only request features that make sense across all platforms (Windows, Linux, ChromeOS, macOS, Android, iOS).
|
||||
|
||||
Remember: You're not asking from a genie. You're pitching to someone who will need to spend hours (even for small changes) on testing, releasing, documenting, and supporting the feature. If you don't sell it well, it won't get done.
|
||||
|
||||
**Explore Scripting First:**
|
||||
Many feature requests can already be achieved with scripts using Excalidraw Automate. While the documentation is somewhat dated, there are nearly a hundred published scripts available. With a little determination, you can explore the possibilities. Feeding relevant scripts into GPT can often generate a working solution. Start here: [Excalidraw Automate Documentation](https://zsviczian.github.io/obsidian-excalidraw-plugin/ExcalidrawScriptsEngine.html).
|
||||
|
||||
- type: textarea
|
||||
id: problem_description
|
||||
attributes:
|
||||
label: "Is your feature request related to a problem? Please describe."
|
||||
description: "Provide a clear and concise description of the problem. Ex. I'm always frustrated when..."
|
||||
placeholder: "Describe the problem you are facing..."
|
||||
|
||||
- type: textarea
|
||||
id: solution_description
|
||||
attributes:
|
||||
label: "Describe the solution you'd like"
|
||||
description: "Provide a clear and concise description of what you want to happen."
|
||||
placeholder: "Describe the feature you are requesting..."
|
||||
|
||||
- type: textarea
|
||||
id: usage_scenario
|
||||
attributes:
|
||||
label: "Real-life usage scenarios"
|
||||
description: "Provide specific examples of how you would use this feature. Convince me that this is a feature I need in my own workflow."
|
||||
placeholder: |
|
||||
1. In this scenario, I would use the feature to...
|
||||
2. Another use case is when I...
|
||||
|
||||
- type: textarea
|
||||
id: alternatives_considered
|
||||
attributes:
|
||||
label: "Describe alternatives you've considered"
|
||||
description: "Provide a clear and concise description of any alternative solutions or features you've considered."
|
||||
placeholder: "Describe any alternative approaches you have considered..."
|
||||
|
||||
- type: textarea
|
||||
id: additional_context
|
||||
attributes:
|
||||
label: "Additional context"
|
||||
description: "Include any other context, screenshots, or references about the feature request."
|
||||
placeholder: "Include screenshots, recordings, or other supporting material..."
|
||||
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
**Attachments: Make your case visually!**
|
||||
Supporting images, screenshots, or screen recordings are critical for helping me understand your request. Drag and drop them into the comment area or directly into any of the text fields above. Every bit of detail increases the chance of your request being understood and prioritized.
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
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 })
|
||||
|
||||
})();
|
||||
@@ -1,50 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 3.3 KiB |
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
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 })
|
||||
})();
|
||||
@@ -1,23 +0,0 @@
|
||||
<?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>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
File diff suppressed because one or more lines are too long
@@ -115,14 +115,12 @@ I would love to include your contribution in the script library. If you have a s
|
||||
|
||||
| | |
|
||||
|----|-----|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Auto%20Draw%20for%20Pen.svg"/></div>|[[#Auto Draw for Pen]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Boolean%20Operations.svg"/></div>|[[#Boolean Operations]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Custom%20Zoom.svg"/></div>|[[#Custom Zoom]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Copy%20Selected%20Element%20Styles%20to%20Global.svg"/></div>|[[#Copy Selected Element Styles to Global]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/ExcaliAI.svg"/></div>|[[#ExcaliAI]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Excalidraw%20Writing%20Machine.svg"/></div>|[[#Excalidraw Writing Machine]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/GPT-Draw-a-UI.svg"/></div>|[[#GPT Draw-a-UI]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Hardware%20Eraser%20Support.svg"/></div>|[[#Hardware Eraser Support]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Palette%20loader.svg"/></div>|[[#Palette Loader]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/PDF%20Page%20Text%20to%20Clipboard.svg"/></div>|[[#PDF Page Text to Clipboard]]|
|
||||
|<div><img src="https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Rename%20Image.svg"/></div>|[[#Rename Image]]|
|
||||
@@ -184,12 +182,6 @@ 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/Add%20Next%20Step%20in%20Process.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">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.<br><img src='https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-add-process-step.jpg'></td></tr></table>
|
||||
|
||||
## Auto Draw for Pen
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Auto%20Draw%20for%20Pen.md
|
||||
```
|
||||
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/threethan'>@threethan</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/Auto%20Draw%20for%20Pen.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">Automatically switches from select mode to drawing mode when hovering a pen, and then back.</td></tr></table>
|
||||
|
||||
## Auto Layout
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Auto%20Layout.md
|
||||
@@ -403,13 +395,6 @@ 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/GPT-Draw-a-UI.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">This script was discontinued in favor of ExcaliAI. Draw a UI and let GPT create the code for you.<br><iframe width="400" height="225" src="https://www.youtube.com/embed/y3kHl_6Ll4w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><img src='https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/images/scripts-draw-a-ui.jpg'></td></tr></table>
|
||||
|
||||
|
||||
## Hardware Eraser Support
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Hardware%20Eraser%20Support.md
|
||||
```
|
||||
<table><tr valign='top'><td class="label">Author</td><td class="data"><a href='https://github.com/threethan'>@threethan</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/Hardware%20Eraser%20Support.md'>File on GitHub</a></td></tr><tr valign='top'><td class="label">Description</td><td class="data">Allows you to use inversion, aka hardware eraser, on supported pens.</td></tr></table>
|
||||
|
||||
## Invert colors
|
||||
```excalidraw-script-install
|
||||
https://raw.githubusercontent.com/zsviczian/obsidian-excalidraw-plugin/master/ea-scripts/Invert%20colors.md
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.4.2",
|
||||
"version": "2.5.0-beta-1",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "obsidian-excalidraw-plugin",
|
||||
"name": "Excalidraw",
|
||||
"version": "2.4.2",
|
||||
"version": "2.4.3",
|
||||
"minAppVersion": "1.1.6",
|
||||
"description": "An Obsidian plugin to edit and view Excalidraw drawings",
|
||||
"author": "Zsolt Viczian",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@zsviczian/excalidraw": "0.17.1-obsidian-48",
|
||||
"@zsviczian/excalidraw": "0.17.1-obsidian-50",
|
||||
"chroma-js": "^2.4.2",
|
||||
"clsx": "^2.0.0",
|
||||
"@zsviczian/colormaster": "^1.2.2",
|
||||
|
||||
@@ -593,6 +593,7 @@ export class EmbeddedFilesLoader {
|
||||
addFiles: (files: FileData[], isDark: boolean, final?: boolean) => void,
|
||||
depth:number,
|
||||
isThemeChange:boolean = false,
|
||||
fileIDWhiteList?: Set<FileId>,
|
||||
) {
|
||||
|
||||
if(depth > 7) {
|
||||
@@ -607,6 +608,7 @@ export class EmbeddedFilesLoader {
|
||||
let entry: IteratorResult<[FileId, EmbeddedFile]>;
|
||||
const files: FileData[] = [];
|
||||
while (!this.terminate && !(entry = entries.next()).done) {
|
||||
if(fileIDWhiteList && !fileIDWhiteList.has(entry.value[0])) continue;
|
||||
const embeddedFile: EmbeddedFile = entry.value[1];
|
||||
if (!embeddedFile.isLoaded(this.isDark)) {
|
||||
//debug({where:"EmbeddedFileLoader.loadSceneFiles",uid:this.uid,status:"embedded Files are not loaded"});
|
||||
@@ -653,6 +655,7 @@ export class EmbeddedFilesLoader {
|
||||
let equation;
|
||||
const equations = excalidrawData.getEquationEntries();
|
||||
while (!this.terminate && !(equation = equations.next()).done) {
|
||||
if(fileIDWhiteList && !fileIDWhiteList.has(entry.value[0])) continue;
|
||||
if (!excalidrawData.getEquation(equation.value[0]).isLoaded) {
|
||||
const latex = equation.value[1].latex;
|
||||
const data = await tex2dataURL(latex);
|
||||
|
||||
@@ -2963,27 +2963,6 @@ async function getTemplate(
|
||||
}
|
||||
|
||||
let scene = excalidrawData.scene;
|
||||
if (loadFiles) {
|
||||
//debug({where:"getTemplate",template:file.name,loader:loader.uid});
|
||||
await loader.loadSceneFiles(excalidrawData, (fileArray: FileData[]) => {
|
||||
//, isDark: boolean) => {
|
||||
if (!fileArray || fileArray.length === 0) {
|
||||
return;
|
||||
}
|
||||
for (const f of fileArray) {
|
||||
if (f.hasSVGwithBitmap) {
|
||||
hasSVGwithBitmap = true;
|
||||
}
|
||||
excalidrawData.scene.files[f.id] = {
|
||||
mimeType: f.mimeType,
|
||||
id: f.id,
|
||||
dataURL: f.dataURL,
|
||||
created: f.created,
|
||||
};
|
||||
}
|
||||
scene = scaleLoadedImage(excalidrawData.scene, fileArray).scene;
|
||||
}, depth);
|
||||
}
|
||||
|
||||
let groupElements:ExcalidrawElement[] = scene.elements;
|
||||
if(filenameParts.hasGroupref) {
|
||||
@@ -3010,8 +2989,41 @@ async function getTemplate(
|
||||
));
|
||||
}
|
||||
|
||||
const fileIDWhiteList = new Set<FileId>();
|
||||
groupElements.filter(el=>el.type==="image").forEach((el:ExcalidrawImageElement)=>fileIDWhiteList.add(el.fileId));
|
||||
|
||||
if (loadFiles) {
|
||||
//debug({where:"getTemplate",template:file.name,loader:loader.uid});
|
||||
await loader.loadSceneFiles(excalidrawData, (fileArray: FileData[]) => {
|
||||
//, isDark: boolean) => {
|
||||
if (!fileArray || fileArray.length === 0) {
|
||||
return;
|
||||
}
|
||||
for (const f of fileArray) {
|
||||
if (f.hasSVGwithBitmap) {
|
||||
hasSVGwithBitmap = true;
|
||||
}
|
||||
excalidrawData.scene.files[f.id] = {
|
||||
mimeType: f.mimeType,
|
||||
id: f.id,
|
||||
dataURL: f.dataURL,
|
||||
created: f.created,
|
||||
};
|
||||
}
|
||||
scene = scaleLoadedImage(excalidrawData.scene, fileArray).scene;
|
||||
}, depth, false, fileIDWhiteList);
|
||||
}
|
||||
|
||||
excalidrawData.destroy();
|
||||
const filehead = data.substring(0, trimLocation);
|
||||
let files:any = {};
|
||||
const sceneFilesSize = Object.values(scene.files).length;
|
||||
if (sceneFilesSize > 0) {
|
||||
if(sceneFilesSize === fileIDWhiteList.size)
|
||||
Object.values(scene.files).filter((f: any) => fileIDWhiteList.has(f.id)).forEach((f: any) => {
|
||||
files[f.id] = f;
|
||||
});
|
||||
}
|
||||
return {
|
||||
elements: convertMarkdownLinksToObsidianURLs
|
||||
? updateElementLinksToObsidianLinks({
|
||||
@@ -3020,7 +3032,7 @@ async function getTemplate(
|
||||
}) : groupElements,
|
||||
appState: scene.appState,
|
||||
frontmatter: filehead.match(/^---\n.*\n---\n/ms)?.[0] ?? filehead,
|
||||
files: scene.files,
|
||||
files,
|
||||
hasSVGwithBitmap,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -763,6 +763,8 @@ export default class ExcalidrawView extends TextFileView {
|
||||
this.clearPreventReloadTimer();
|
||||
|
||||
this.semaphores.preventReload = preventReload;
|
||||
await this.prepareGetViewData();
|
||||
|
||||
//added this to avoid Electron crash when terminating a popout window and saving the drawing, need to check back
|
||||
//can likely be removed once this is resolved: https://github.com/electron/electron/issues/40607
|
||||
if(this.semaphores?.viewunload) {
|
||||
@@ -774,10 +776,10 @@ export default class ExcalidrawView extends TextFileView {
|
||||
await plugin.app.vault.modify(file,d);
|
||||
await imageCache.addBAKToCache(file.path,d);
|
||||
},200)
|
||||
this.semaphores.saving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
await this.prepareGetViewData();
|
||||
await super.save();
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (DEBUGGING) {
|
||||
@@ -1548,7 +1550,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
|
||||
this.registerDomEvent(this.ownerWindow, "keydown", onKeyDown, false);
|
||||
this.registerDomEvent(this.ownerWindow, "keyup", onKeyUp, false);
|
||||
this.registerDomEvent(this.contentEl, "mouseleave", onBlurOrLeave, false);
|
||||
//this.registerDomEvent(this.contentEl, "mouseleave", onBlurOrLeave, false); //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2004
|
||||
this.registerDomEvent(this.ownerWindow, "blur", onBlurOrLeave, false);
|
||||
});
|
||||
|
||||
@@ -1787,7 +1789,7 @@ export default class ExcalidrawView extends TextFileView {
|
||||
//deliberately not calling super.onUnloadFile() to avoid autosave (saved in unload)
|
||||
(process.env.NODE_ENV === 'development') && DEBUGGING && debug(this.onUnloadFile,`ExcalidrawView.onUnloadFile, file:${this.file?.name}`);
|
||||
let counter = 0;
|
||||
while (this.semaphores.saving) {
|
||||
while (this.semaphores.saving && (counter++ < 200)) {
|
||||
await sleep(50); //https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/1988
|
||||
if(counter++ === 15) {
|
||||
new Notice(t("SAVE_IS_TAKING_LONG"));
|
||||
@@ -1796,6 +1798,10 @@ export default class ExcalidrawView extends TextFileView {
|
||||
new Notice(t("SAVE_IS_TAKING_VERY_LONG"));
|
||||
}
|
||||
}
|
||||
if(counter >= 200) {
|
||||
new Notice("Unknown error, save is taking too long");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private async forceSaveIfRequired():Promise<boolean> {
|
||||
|
||||
@@ -17,6 +17,17 @@ I develop this plugin as a hobby, spending my free time doing this. If you find
|
||||
|
||||
<div class="ex-coffee-div"><a href="https://ko-fi.com/zsolt"><img src="https://cdn.ko-fi.com/cdn/kofi3.png?v=3" height=45></a></div>
|
||||
`,
|
||||
"2.4.3": `
|
||||
Check out the [Excalidraw Plugin's Community WIKI](https://excalidraw-obsidian.online/Hobbies/Excalidraw+Blog/WIKI/Welcome+to+the+WIKI) and help with your content contribution.
|
||||
|
||||
## Fixed
|
||||
- In some situations Excalidraw hangs indefinitely when opening a different file in the same tab
|
||||
- Can't exit arrow tool on phone [#2006](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2006)
|
||||
- Save is triggered every few seconds, leading to glitches in handwriting [#2004](https://github.com/zsviczian/obsidian-excalidraw-plugin/issues/2004)
|
||||
- Canvas shifts when editing text reaches right hand side of the canvas, especially at higher zoom values
|
||||
- Minor styling tweaks to adapt to Obsidian 1.7.1 new stylesheet, in particular to scale Excalidraw properly in line with Obsidian Appearance Setting Font-Size value.
|
||||
- Tweaked Compatibilty Setting description to mention Obsidian 1.7.1 Footnotes support
|
||||
`,
|
||||
"2.4.2": `
|
||||
This release addresses critical issues for all Obsidian Mobile users.
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ export class ScriptInstallPrompt extends Modal {
|
||||
searchBar.type = "text";
|
||||
searchBar.id = "search-bar";
|
||||
searchBar.placeholder = "Search...";
|
||||
searchBar.style.width = "calc(100% - 120px)"; // space for the buttons and hit count
|
||||
//searchBar.style.width = "calc(100% - 120px)"; // space for the buttons and hit count
|
||||
|
||||
const nextButton = document.createElement("button");
|
||||
nextButton.textContent = "→";
|
||||
|
||||
@@ -913,7 +913,7 @@ export const FRONTMATTER_KEYS_INFO: SuggesterInfo[] = [
|
||||
after: ": 1",
|
||||
},
|
||||
{
|
||||
field: "excalidraw-export-embed-scene",
|
||||
field: "export-embed-scene",
|
||||
code: null,
|
||||
desc: "If this key is present it will override the default excalidraw embed and export setting.",
|
||||
after: ": false",
|
||||
|
||||
@@ -653,7 +653,7 @@ FILENAME_HEAD: "Filename",
|
||||
"Use this setting if for good reasons you have decided to ignore my recommendation and configured linting of Excalidraw files.<br> " +
|
||||
"The <code>## Text Elements</code> section is sensitive to empty lines. A common linting approach is to add an empty line after section headings. In case of Excalidraw this will break/change the first text element in your drawing. " +
|
||||
"To overcome this, you can enable this setting. When enabled, Excalidraw will add a dummy element to the beginning of <code>## Text Elements</code> that the linter can safely modify." ,
|
||||
PRESERVE_TEXT_AFTER_DRAWING_NAME: "Zotero compatibility",
|
||||
PRESERVE_TEXT_AFTER_DRAWING_NAME: "Zotero and Footnotes compatibility",
|
||||
PRESERVE_TEXT_AFTER_DRAWING_DESC: "Preserve text after the ## Drawing section of the markdown file. This may have a very slight performance impact when saving very large drawings.",
|
||||
DEBUGMODE_NAME: "Enable debug messages",
|
||||
DEBUGMODE_DESC: "I recommend restarting Obsidian after enabling/disabling this setting. This enable debug messages in the console. This is useful for troubleshooting issues. " +
|
||||
|
||||
@@ -2851,14 +2851,7 @@ export default class ExcalidrawPlugin extends Plugin {
|
||||
// Force handlers to the front of the list
|
||||
overrideHandlers.forEach(() => scope.keys.unshift(scope.keys.pop()));
|
||||
|
||||
const handler_ctrlF = scope.register(["Mod"], "f", () => {
|
||||
const view = this.app.workspace.getActiveViewOfType(ExcalidrawView);
|
||||
if (view) {
|
||||
search(view);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
const handler_ctrlF = scope.register(["Mod"], "f", () => true);
|
||||
scope.keys.unshift(scope.keys.pop()); // Force our handler to the front of the list
|
||||
const overridSaveShortcut = (
|
||||
this.forceSaveCommand &&
|
||||
|
||||
@@ -17,6 +17,7 @@ import { ExportDialog } from "src/dialogs/ExportDialog";
|
||||
import { openExternalLink } from "src/utils/ExcalidrawViewUtils";
|
||||
import { UniversalInsertFileModal } from "src/dialogs/UniversalInsertFileModal";
|
||||
import { DEBUGGING, debug } from "src/utils/DebugHelper";
|
||||
import { REM_VALUE } from "src/utils/StylesManager";
|
||||
|
||||
declare const PLUGIN_VERSION:string;
|
||||
const dark = '<svg style="stroke:#ced4da;#212529;color:#ced4da;fill:#ced4da" ';
|
||||
@@ -42,7 +43,7 @@ export type PanelState = {
|
||||
scriptIconMap: ScriptIconMap | null;
|
||||
};
|
||||
|
||||
const TOOLS_PANEL_WIDTH = 228;
|
||||
const TOOLS_PANEL_WIDTH = () => REM_VALUE * 14.2;
|
||||
|
||||
export class ToolsPanel extends React.Component<PanelProps, PanelState> {
|
||||
pos1: number = 0;
|
||||
@@ -155,11 +156,11 @@ export class ToolsPanel extends React.Component<PanelProps, PanelState> {
|
||||
return {
|
||||
left:
|
||||
(this.containerRef.current.clientWidth -
|
||||
TOOLS_PANEL_WIDTH -
|
||||
(isMobileOrZen ? 0 : TOOLS_PANEL_WIDTH + 4)) /
|
||||
TOOLS_PANEL_WIDTH() -
|
||||
(isMobileOrZen ? 0 : TOOLS_PANEL_WIDTH() + 4)) /
|
||||
2 +
|
||||
this.containerRef.current.parentElement.offsetLeft +
|
||||
(isMobileOrZen ? 0 : TOOLS_PANEL_WIDTH + 4),
|
||||
(isMobileOrZen ? 0 : TOOLS_PANEL_WIDTH() + 4),
|
||||
top: 64 + this.containerRef.current.parentElement.offsetTop,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -3,6 +3,8 @@ import ExcalidrawPlugin from "src/main";
|
||||
import { getAllWindowDocuments } from "./ObsidianUtils";
|
||||
import { DEBUGGING, debug } from "./DebugHelper";
|
||||
|
||||
export let REM_VALUE = 16;
|
||||
|
||||
const STYLE_VARIABLES = [
|
||||
"--background-modifier-cover",
|
||||
"--background-primary-alt",
|
||||
@@ -77,6 +79,11 @@ export class StylesManager {
|
||||
}
|
||||
|
||||
private async harvestStyles() {
|
||||
REM_VALUE = parseInt(window.getComputedStyle(document.body).getPropertyValue('--font-text-size').trim());
|
||||
if (isNaN(REM_VALUE)) {
|
||||
REM_VALUE = 16;
|
||||
}
|
||||
|
||||
const body = document.body;
|
||||
const iframe:HTMLIFrameElement = document.createElement("iframe");
|
||||
iframe.style.display = "none";
|
||||
|
||||
15
styles.css
15
styles.css
@@ -226,7 +226,7 @@ li[data-testid] {
|
||||
}
|
||||
|
||||
.excalidraw .ToolIcon__icon img{
|
||||
height: 1em;
|
||||
height: 1rem;
|
||||
}
|
||||
|
||||
.excalidraw-scriptengine-install tbody>tr>td>div>img {
|
||||
@@ -394,23 +394,28 @@ div.excalidraw-draginfo {
|
||||
|
||||
.modal-content.excalidraw-scriptengine-install .search-bar-wrapper {
|
||||
position: sticky;
|
||||
top: 1em;
|
||||
margin-right: 1em;
|
||||
top: 1rem;
|
||||
margin-right: 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
flex-wrap: nowrap;
|
||||
z-index: 10;
|
||||
background: var(--background-secondary);
|
||||
padding: 0.5em;
|
||||
padding: 0.5rem;
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
float: right;
|
||||
max-width: 28em;
|
||||
max-width: 28rem;
|
||||
}
|
||||
|
||||
div.search-bar-wrapper input {
|
||||
margin-right: -0.5rem;
|
||||
}
|
||||
|
||||
.modal-content.excalidraw-scriptengine-install .hit-count {
|
||||
margin-left: 0.5em;
|
||||
white-space: nowrap;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
.modal-content.excalidraw-scriptengine-install .active-highlight {
|
||||
|
||||
Reference in New Issue
Block a user