diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/ExcalidrawAutomate/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\217\214\345\207\273\346\267\273\345\212\240\345\234\206\345\234\210\347\274\226\345\217\267.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/ExcalidrawAutomate/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\217\214\345\207\273\346\267\273\345\212\240\345\234\206\345\234\210\347\274\226\345\217\267.md" new file mode 100644 index 000000000..da4d2eae8 --- /dev/null +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/ExcalidrawAutomate/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\217\214\345\207\273\346\267\273\345\212\240\345\234\206\345\234\210\347\274\226\345\217\267.md" @@ -0,0 +1,257 @@ +--- +uid: 20240221010235 +title: 自定义 Excalidraw 脚本 - 双击添加圆圈编号 +tags: + - Excalidraw脚本 + - 图片注释 +description: 给Excalidraw添加圆圈编号功能 +author: 熊猫别熬夜,一鸣惊人 +type: other +draft: false +editable: false +modified: 20240221010515 +--- + +# 自定义 Excalidraw 脚本 - 双击添加圆圈编号 + +## 效果 + +参考了 [一鸣惊人的脚本](https://www.bilibili.com/video/BV1XZ421m74S/?share_source=copy_web&vd_source=71b5851b6744265a191d3ec972be4787) 和 大叔的 `Scribble Helper` 脚本,用于添加有序的圆圈编号。 + +![2024-01-13_自定义Excalidraw脚本-编号模式-添加圆圈编号_IMG-1](https://cdn.pkmer.cn/images/202402210103272.gif!pkmer) + +> ✅已启动编号模式,双击添加 num +> ⏩双击 num 可以重新编辑编号 +> ⏹再次运行脚本即可退出编号模式 + +## 脚本 + +```js +if (!ea.verifyMinimumPluginVersion || !ea.verifyMinimumPluginVersion("1.8.25")) { + new Notice("This script requires a newer version of Excalidraw. Please install the latest version."); + return; +} + +const DBLCLICKTIMEOUT = 300; +const padding = 6; + +const api = ea.getExcalidrawAPI(); +const win = ea.targetView.ownerWindow; +if (!win.NumberMode) win.NumberMode = {}; + +if (typeof win.NumberMode.penOnly === "undefined") { + win.NumberMode.penOnly = false; +} + +let windowOpen = false; //to prevent the modal window to open again while writing with scribble +let prevZoomValue = api.getAppState().zoom.value; //used to avoid trigger on pinch zoom + +let selectedTextElements = ea.getViewSelectedElements().filter(el => el.type === "text"); + +//------------------------------------------- +// Functions to add and remove event listners +//------------------------------------------- +const addEventHandler = (handler) => { + if (win.NumberMode.eventHandler) { + win.removeEventListner("pointerdown", handler); + } + win.addEventListener("pointerdown", handler); + win.NumberMode.eventHandler = handler; + win.NumberMode.window = win; +}; + +const removeEventHandler = (handler) => { + win.removeEventListener("pointerdown", handler); + delete win.NumberMode.eventHandler; + delete win.NumberMode.window; +}; + +//Stop the script if scribble helper is clicked and no eligable element is selected +let silent = false; +if (win.NumberMode?.eventHandler) { + removeEventHandler(win.NumberMode.eventHandler); + delete win.NumberMode.eventHandler; + delete win.NumberMode.window; + if (!(containerElements.length === 1 || selectedTextElements.length === 1)) { + new Notice("🟠已退出编号模式", 1000); + return; + } + silent = true; +} + +// ---------------------- +// Custom dialog controls +// ---------------------- +if (typeof win.NumberMode.penOnly === "undefined") { + win.NumberMode.penOnly = undefined; +} +if (typeof win.NumberMode.penDetected === "undefined") { + win.NumberMode.penDetected = false; +} +let timer = Date.now(); +let eventHandler = () => { }; + +// ------------------------------- +// Click / dbl click event handler +// ------------------------------- +eventHandler = async (evt) => { + if (windowOpen) return; + if (ea.targetView !== app.workspace.activeLeaf.view) removeEventHandler(eventHandler); + if (evt && evt.target && !evt.target.hasClass("excalidraw__canvas")) return; + if (evt && (evt.ctrlKey || evt.altKey || evt.metaKey || evt.shiftKey)) return; + + const st = api.getAppState(); + + //don't trigger text editor when editing a line or arrow + if (st.editingElement && ["arrow", "line"].contains(st.editingElment.type)) return; + + if (typeof win.NumberMode.penOnly === "undefined") { + win.NumberMode.penOnly = false; + } + const now = Date.now(); + //the <50 condition is to avoid false double click when pinch zooming + if ((now - timer > DBLCLICKTIMEOUT) || (now - timer < 50)) { + prevZoomValue = st.zoom.value; + timer = now; + containerElements = ea.getViewSelectedElements() + .filter(el => ["arrow", "rectangle", "ellipse", "line", "diamond"].contains(el.type)); + selectedTextElements = ea.getViewSelectedElements().filter(el => el.type === "text"); + return; + } + + //further safeguard against triggering when pinch zooming + if (st.zoom.value !== prevZoomValue) return; + + //sleeping to allow keyboard to pop up on mobile devices + await sleep(100); + ea.clear(); + + //if a single element with text is selected, edit the text + //(this can be an arrow, a sticky note, or just a text element) + if (selectedTextElements.length === 1) { + editExistingTextElement(selectedTextElements); + return; + } + + //if no text elements are selected (i.e. not multiple text elements selected), + //check if there is a single eligeable container selected + let containerID; + let container; + if (selectedTextElements.length === 0) { + if (containerElements.length === 1) { + ea.copyViewElementsToEAforEditing(containerElements); + containerID = containerElements[0].id; + container = ea.getElement(containerID); + } + } + + if (ea.targetView !== app.workspace.activeLeaf.view) return; + + // 开始编号 + windowOpen = true; + bulletedNumberIndex = window.bulletedNumberIndex ? window.bulletedNumberIndex : 1; + if (st) { + for (s in st) { + if (s.startsWith("currentItem")) { + ea.style[`${s.charAt(11).toLowerCase() + s.slice(12)}`] = st[s]; + // console.log(`${s}: ${ea.style[s]}`) + } + } + } + // 字体设置 + ea.style.strokeColor = '#1e1e1e'; + // 最好选用3号等宽字体 + ea.style.fontFamily = 3; + // 边框设置 + ea.style.roughness = 0; + ea.style.strokeWidth = 1; + const { width, height } = ea.measureText(`${bulletedNumberIndex}`); + const maxSize = Math.max(width, height) + 2; + const padding = maxSize * 0.5; + const id = ea.addText(0, 0, `${bulletedNumberIndex}`, { + width: maxSize, + height: maxSize, + box: "ellipse", + wrapAt: 0, + boxPadding: padding, + textAlign: "center", + textVerticalAlign: "middle", + boxStrokeColor: "black", + boxPadding: 2 + }); + const box = ea.getElement(id); + const colorList = ["#FF595E", "#FFCA3A", "#8AC926", "#1982C4", "#6A4C93"]; + box.backgroundColor = colorList[(bulletedNumberIndex - 1) % colorList.length]; + box.width = maxSize + 2 * padding; + box.height = maxSize + 2 * padding; + window.bulletedNumberIndex += 1; + ea.addElementsToView(true, true,true); + windowOpen = false; +}; + +// --------------------- +// Edit Existing Element +// --------------------- +const editExistingTextElement = async (elements) => { + windowOpen = true; + let isModified = false; + ea.copyViewElementsToEAforEditing(elements); + const el = ea.getElements()[0]; + ea.style.strokeColor = el.strokeColor; + const text = await utils.inputPrompt( + "重新设置编号", + "输入数字", + elements[0].rawText, + [ + { + caption: "取消", + action: () => { isModified = false; return; } + }, + { + caption: "编辑", + action: () => { isModified = true; return; } + } + ], + 1, + true + ); + if (isModified) { + window.bulletedNumberIndex = Number(text) + 1; + } + windowOpen = false; + if (!text) return; + el.originalText = text; + el.text = text; + el.rawText = text; + ea.refreshTextElementSize(el.id); + await ea.addElementsToView(false, false); + + if (el.containerId) { + const containers = ea.getViewElements().filter(e => e.id === el.containerId); + api.updateContainerSize(containers); + ea.selectElementsInView(containers); + } +}; + +//-------------- +// Start actions +//-------------- +if (!win.NumberMode?.eventHandler) { + if (!silent) new Notice( + "✅已启动编号模式,双击添加num\n" + + "⏩双击num可以重新编辑编号\n" + + "⏹再次运行脚本即可退出编号模式", + 5000 + ); + addEventHandler(eventHandler); +} + +if (containerElements.length === 1 || selectedTextElements.length === 1) { + timer = timer - 100; + eventHandler(); +} +``` + +## References + +- [Obsidian Excalidraw 增加日历元素、圆圈编号小功能](https://www.bilibili.com/video/BV1XZ421m74S/?share_source=copy_web&vd_source=71b5851b6744265a191d3ec972be4787) diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/obsidian-excalidraw-plugin.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/obsidian-excalidraw-plugin.md" index 04cf19361..e4d5f98e6 100644 --- "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/obsidian-excalidraw-plugin.md" +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/obsidian-excalidraw-plugin.md" @@ -7,7 +7,7 @@ author: windilycloud type: basic draft: false editable: false -modified: 20240122220808 +modified: 20240131141540 --- # Obsidian 插件:Excalidraw 完美的绘图工具 @@ -141,16 +141,23 @@ Excalidraw 在早期是有很多问题的,比如没有手写压感,插图太 > EA 脚本开发的介绍: [[ExcalidrawAutomate index]] -- [[Excalidraw脚本-Slideshow完美实现画板幻灯片演示的脚本]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-实现Zotero与Excalidraw的拖拽联动]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-实现Excalidraw与BookxNote的联动]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-建立库外Eagle素材库的连接]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-画板局部或者全局播放动画]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-快速插入时间戳笔记]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-OCR自动提取图片文字]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-默认应用打开图片]] by 熊猫别熬夜 -- [[自定义Excalidraw脚本-插入可以编辑的Mermaid图形]] by 一鸣惊人 -- [[自定义Excalidraw脚本-画板与 Kanban 得梦幻结合-像PPT一样演示]] by 熊猫别熬夜 +- 外部联用 + - [[自定义Excalidraw脚本-实现Zotero与Excalidraw的拖拽联动]] by 熊猫别熬夜 + - [[自定义Excalidraw脚本-实现Excalidraw与BookxNote的联动]] by 熊猫别熬夜 + - [[自定义Excalidraw脚本-建立库外Eagle素材库的连接]] by 熊猫别熬夜 +- 文档编辑 + - [[自定义Excalidraw脚本-快速插入时间戳笔记]] by 熊猫别熬夜 + - [[自定义Excalidraw脚本-双击添加圆圈编号]] by 熊猫别熬夜,一鸣惊人 +- Mermaid + - [[自定义Excalidraw脚本-插入可以编辑的Mermaid图形]] by 一鸣惊人 +- 图片处理 + - [[自定义Excalidraw脚本-默认应用打开图片]] by 熊猫别熬夜 + - [[自定义Excalidraw脚本-OCR自动提取图片文字]] by 熊猫别熬夜 + - [[自定义Excalidraw脚本-AdjustImageSize-统一多个图片宽度或者高度]] by 熊猫别熬夜,一鸣惊人 +- 画布演示 + - [[Excalidraw脚本-Slideshow完美实现画板幻灯片演示的脚本]] + - [[自定义Excalidraw脚本-画板局部或者全局播放动画]] by 熊猫别熬夜 + - [[自定义Excalidraw脚本-画板与 Kanban 得梦幻结合-像PPT一样演示]] by 熊猫别熬夜 ### CSS 美化 diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-AdjustImageSize-\347\273\237\344\270\200\345\244\232\344\270\252\345\233\276\347\211\207\345\256\275\345\272\246\346\210\226\350\200\205\351\253\230\345\272\246.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-AdjustImageSize-\347\273\237\344\270\200\345\244\232\344\270\252\345\233\276\347\211\207\345\256\275\345\272\246\346\210\226\350\200\205\351\253\230\345\272\246.md" new file mode 100644 index 000000000..5cf79deef --- /dev/null +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-AdjustImageSize-\347\273\237\344\270\200\345\244\232\344\270\252\345\233\276\347\211\207\345\256\275\345\272\246\346\210\226\350\200\205\351\253\230\345\272\246.md" @@ -0,0 +1,78 @@ +--- +uid: 20240131140236 +title: 自定义 Excalidraw 脚本 -AdjustImageSize- 统一多个图片宽度或者高度 +tags: [Excalidraw脚本, 图片处理] +description: 用于调整多个图片 (image)、矩形框 (rectangle)、Frame 边框的大小,以选中的元素的最大宽度 (高度) 或者最小宽度 (高度) 进行统一缩放,分别有 `等宽缩放`、`等高缩放`、`完全相等` 这 3 个选项。 +author: 熊猫别熬夜,一鸣惊人 +type: other +draft: false +editable: false +modified: 20240221005748 +--- + +# 自定义 Excalidraw 脚本 -AdjustImageSize- 统一多个图片宽度或者高度 + +## 效果 + +![](https://cdn.pkmer.cn/images/202401311417693.gif!pkmer) + +用于调整多个图片 (image)、矩形框 (rectangle)、Frame 边框的大小,以选中的元素的最大宽度 (高度) 或者最小宽度 (高度) 进行统一缩放,分别有 `等宽缩放`、`等高缩放`、`完全相等` 这 3 个选项。 + +## 脚本 + +该脚本是 @一鸣惊人 分享给我过的 AdjustImageSize 脚本,进行稍加修改。 + +Excalidraw 脚本如何配置脚本请参考:[[Excalidraw如何安装脚本_脚本设置介绍]] + +```js +// 获取选中的元素 +const selectedEls = ea.getViewSelectedElements().filter(el => el.type === "frame" || "image" || "rectangle" || "ellipse"); +const scalingTypes = ["等宽缩放", '等高缩放', '完全相等']; +const inputScalingType = await utils.suggester(scalingTypes, scalingTypes, "选择缩放类型"); +if (!inputScalingType) return; + +const maxMin = ['Max', 'Min']; +const inputMaxMin = await utils.suggester(maxMin, maxMin, "选择等比对象?"); +if (!inputMaxMin) return; + +// 获取所有高度和宽度 +let width, height; +const widths = selectedEls.map(el => el.width); +const heights = selectedEls.map(el => el.height); + +if (inputMaxMin == 'Max') { + width = Math.max(...widths); + height = Math.max(...heights); +} else if (inputMaxMin == 'Min') { + width = Math.min(...widths); + height = Math.min(...heights); +} + +if (inputScalingType === "等宽缩放") { + // 等宽缩放 + for (let selectedEl of selectedEls) { + let rario = width / selectedEl.width; + selectedEl.width = width; + selectedEl.height *= rario; + } + +} else if (inputScalingType === "等高缩放") { + // 等高缩放 + for (let selectedEl of selectedEls) { + let rario = height / selectedEl.height; + selectedEl.width *= rario; + selectedEl.height = height; + } + +} else if (inputScalingType === "完全相等") { + // 完全相等 + for (let selectedEl of selectedEls) { + selectedEl.width = width; + selectedEl.height = height; + } +} + +// 完成编辑 +ea.copyViewElementsToEAforEditing(selectedEls); +ea.addElementsToView(); +``` diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\344\270\212\344\274\240\347\224\273\346\235\277\344\270\255\347\232\204\345\233\276\347\211\207\345\210\260\345\233\276\345\272\212.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\344\270\212\344\274\240\347\224\273\346\235\277\344\270\255\347\232\204\345\233\276\347\211\207\345\210\260\345\233\276\345\272\212.md" new file mode 100644 index 000000000..220303e97 --- /dev/null +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\344\270\212\344\274\240\347\224\273\346\235\277\344\270\255\347\232\204\345\233\276\347\211\207\345\210\260\345\233\276\345\272\212.md" @@ -0,0 +1,137 @@ +--- +uid: 20240221010558 +title: 自定义 Excalidraw 脚本 - 上传画板中的图片到图床 +tags: + - 图床 + - Excalidraw脚本 +description: Excalidraw 画板中引用的图片直接上传到 PicGo 的 Server 转为在线图片 +author: +type: other +draft: false +editable: false +modified: 20240221010700 +--- + +# 自定义 Excalidraw 脚本 - 上传画板中的图片到图床 + +![2024-02-16_自定义Excalidraw脚本-上传画板中的图片到图床_IMG-1](https://cdn.pkmer.cn/images/202402210107269.gif!pkmer) + +## 背景 + +该需求来源于 [Excalidraw文件里面的图片怎样才能默认上传到图床? - 疑问解答 - Obsidian 中文论坛](https://forum-zh.obsidian.md/t/topic/30153): + +![2024-02-16_自定义Excalidraw脚本-上传画板中的图片到图床_IMG-2](https://cdn.pkmer.cn/images/202402210107270.png!pkmer) + +如果是 Markdown 笔记的话,直接使用 `Image auto upload Plugin`(作者:renmu) 插件就可以了,但是在 Excalidraw 画板中,图片是无法上传的,目前 (2024-02-20) 在该插件没有适配的。 + +## 方法 + +既然是上传图床,就应该会用到 PicGo 或者 PicList 软件,那就将 Excalidraw 画板中引用的图片直接上传到 PicGo 的 Server 后删除并将 Excalidraw 画板中的本地图片的应用改为图床连接。 + +## 脚本 + +![2024-02-16_自定义Excalidraw脚本-上传画板中的图片到图床_IMG-3](https://cdn.pkmer.cn/images/202402210107271.png!pkmer) + +```js +await ea.addElementsToView(); +const fs = require('fs'); + +let settings = ea.getScriptSettings(); +//set default values on first run +if (!settings["UploadImageToPicGo"]) { + settings = { + "上传图片后移除原文件": { + value: true, + }, + "PicGo Server接口": { + value: "http://127.0.0.1:36677/upload", + } + }; + ea.setScriptSettings(settings); +} + +const url = settings["PicGo Server接口"].value; + +// 获取笔记的基本路径 +const file = app.workspace.getActiveFile(); +// 获取绝对路径 +const fileFullPath = app.vault.adapter.getFullPath(file.path); +let content = fs.readFileSync(fileFullPath, 'utf8'); + +let imgs = ea.getViewSelectedElements().filter(el => el.type === "image"); +const allImgs = ea.getViewElements().filter(el => el.type === "image"); + +if (Object.keys(imgs).length === 0) { + const isAll = confirm("是否上传全部图片到图床?"); + if (isAll) { + imgs = allImgs; + } +} + +for (i of imgs) { + // 是否为超链接 + if (ea.plugin.filesMaster.get(i.fileId).isHyperLink) { + new Notice("该图片已上传"); + continue; + } + + const currentPath = ea.plugin.filesMaster.get(i.fileId).path; + const imgFile = app.vault.getAbstractFileByPath(currentPath); + + if (!imgFile) { + new Notice("Can't find file: " + currentPath); + continue; + } + + // 获取绝对路径 + const imgFullPath = app.vault.adapter.getFullPath(imgFile.path); + await uploadFiles([imgFullPath], url, content).then(data => { + console.log(data); + if (data.success) { + const imgWiki = `${i.fileId}: [[${imgFile.name}]]`; + const imgLink = `${i.fileId}: ${data.result}`; + content = content.replace(imgWiki, imgLink); + const fs = require('fs'); + + if (settings["上传图片后移除原文件"].value) { + try { + fs.unlinkSync(imgFullPath); + new Notice(`✅已上传${imgFile.name},并删除本地文件`); + } catch (err) { + new Notice(`✅已上传${imgFile.name},💔删除本地文件失败`); + } + } + + } else { + new Notice(`❌上传${imgFile.name}图片失败`); + } + }).catch(error => { + console.error(error); + new Notice(`❌上传${imgFile.name}图片失败`); + }); +} + +// 修改Excalidraw对应的图片键值 +let markdownFile = app.vault.getAbstractFileByPath(file.path); +if (markdownFile) { + app.vault.modify(markdownFile, content); +} + +async function uploadFiles(imagePathList, url, content) { + const length = imagePathList.length; + const response = await requestUrl({ + url: url, + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ list: imagePathList }), + }); + data = await response.json; + return data; +}; + +``` + +## References + +- [[自定义Excalidraw脚本-默认应用打开图片]] +- [PicGo is Here | PicGo](https://picgo.github.io/PicGo-Doc/zh/guide/) diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\256\236\347\216\260Excalidraw\344\270\216BookxNote\347\232\204\350\201\224\345\212\250.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\256\236\347\216\260Excalidraw\344\270\216BookxNote\347\232\204\350\201\224\345\212\250.md" index 500fc3fb0..d90df14de 100644 --- "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\256\236\347\216\260Excalidraw\344\270\216BookxNote\347\232\204\350\201\224\345\212\250.md" +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\256\236\347\216\260Excalidraw\344\270\216BookxNote\347\232\204\350\201\224\345\212\250.md" @@ -166,7 +166,7 @@ const eaApi = ExcalidrawAutomate; let settings = ea.getScriptSettings(); if (!settings["notebooksPath"]) settings["notebooksPath"] = { value: false }; if (!settings["notebooksPath"].value) { - new Notice("🔴请配置Zotero的Library路径和其他相关设置!", 2000); + new Notice("🔴请配置脚本的相关设置!!", 2000); settings = { "notebooksPath": { value: "", diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\277\253\351\200\237\346\217\222\345\205\245\346\227\266\351\227\264\346\210\263\347\254\224\350\256\260.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\277\253\351\200\237\346\217\222\345\205\245\346\227\266\351\227\264\346\210\263\347\254\224\350\256\260.md" index 9886dd008..4fff56efd 100644 --- "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\277\253\351\200\237\346\217\222\345\205\245\346\227\266\351\227\264\346\210\263\347\254\224\350\256\260.md" +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\345\277\253\351\200\237\346\217\222\345\205\245\346\227\266\351\227\264\346\210\263\347\254\224\350\256\260.md" @@ -354,4 +354,155 @@ function getFilePath(files, el) { console.log(filePath); return filePath; } -``` \ No newline at end of file +``` + +### 简化版:直接 Frame 模式 + +![2023-11-10_自定义Excalidraw脚本-快速插入时间戳笔记_IMG-7](https://cdn.pkmer.cn/images/202402210100655.png!pkmer) + +```js +const quickaddApi = this.app.plugins.plugins.quickadd.api; +// const ea = ExcalidrawAutomate; +const path = require("path"); +const fs = require("fs"); + +// 设置 quickerInsetNote 模板设置 +let settings = ea.getScriptSettings(); +//set default values on first run +if (!settings["QuickerInsertZKCardPath"]) { + settings = { + "QuickerInsertZKCardPath": { + value: "D-每日生活记录/QuickNotes", + description: "TimeStampNote 的存放路径(相对路径)
eg:D-每日生活记录/QuickNotes
空值:默认为当前笔记路径" + }, + "QuickerInsertZKCardTemplate": { + value: "[QuickNote]-YYYYMMDDHHmmss", + description: "TimeStampNote 默认名称,若为存储路径用/隔开
eg:YYYYMM/YYYYMMDDHHMMSS" + }, + "QuickerInsertZKCardYaml": { + value: "---\ncssclasses:\n - Excalidraw-Markdown\n---\n\n", + height: "250px", + description: "设定笔记模板" + }, + }; + ea.setScriptSettings(settings); +} + +// 存储路径 +const folderPath = settings["QuickerInsertZKCardPath"].value ? settings["QuickerInsertZKCardPath"].value : path.dirname(app.workspace.getActiveFile().path); + +console.log(folderPath); + +// 调用函数生成时间戳 +const timestamp = quickaddApi.date.now(settings["QuickerInsertZKCardTemplate"].value); +console.log(timestamp); + +// 创建文件夹路径下的 Markdown 文件,fname 为文件名 +const Yaml = settings["QuickerInsertZKCardYaml"].value; + +ea.setView("active"); +const trashFiles = ea.getViewSelectedElements().filter(el => el.link); + +// 获取库所有文件列表 +const files = app.vault.getFiles(); + +if (Object.keys(trashFiles).length) { + + for (let trashFile of trashFiles) { + const filePaths = getFilePath(files, trashFile); + let isConfirm = await quickaddApi.yesNoPrompt("是否删除本地文件", `${filePaths}`); + + if (isConfirm) { + // 删除元素 + ea.deleteViewElements(ea.getViewSelectedElements().filter(el => el.id == trashFile.id)); + + // ea.clear(); + await ea.addElementsToView(false, true); + await ea.getExcalidrawAPI().history.clear(); //避免撤消/重做扰乱 + + // 删除文件 + if ((app.vault.adapter).exists(filePaths)) { + (app.vault.adapter).trashLocal(filePaths); + } + } + + } + await ea.addElementsToView(false, true); + + return; // 提前结束函数的执行 + +} + +// 时间戳笔记路径 +const filePath = `${folderPath}/${timestamp}.md`; +console.log(filePath); +const fileName = path.basename(filePath).replace(/\.md/, ""); +console.log([filePath, fileName]); + +// 获取 Obsidian 文件对象 +const rootFolder = app.vault.getRoot(); +console.log(rootFolder); + +let { insertType, inputText } = await openEditPrompt(); +if (!insertType) return; + +// 设定固定 Yaml +let file = await app.fileManager.createNewFile(rootFolder, filePath, "md", inputText ? `${Yaml}\n${inputText}` : `${Yaml}`); + +// 设置 Frame 样式 +ea.style.strokeColor = "#FFFFFF"; +ea.style.strokeStyle = "solid"; +ea.style.fillStyle = "solid"; +ea.style.backgroundColor = "#ced4da"; +ea.style.roughness = 0; +ea.style.roundness = { type: 3 }; +ea.style.strokeWidth = 2; + +let id = await ea.addIFrame(0, 0, 600, 300, 0, file); +let el = ea.getElement(id); +el.link = `[[${fileName}]]`; + +await ea.addElementsToView(true, true); +ea.moveViewElementToZIndex(el.id, 99); + +return; + +// 打开文本编辑器 +async function openEditPrompt(Text = "") { + // 打开编辑窗口 + let insertType = false; + let inputText = ""; + inputText = await utils.inputPrompt( + "输入笔记内容", + "输入笔记内容,ESC 退出输入,Ctrl + Enter", + Text, + [ + { + caption: "取消编辑", + action: () => { + insertType = false; + return; + } + }, + { + caption: "完成编辑", + action: () => { + insertType = true; + return; + } + } + ], + 10, + false + ); + return { insertType, inputText }; +} + +// 由文件列表和 el 元素获取文件路径(相对路径) +function getFilePath(files, el) { + let files2 = files.filter(f => path.basename(f.path).replace(".md", "").endsWith(el.link.replace(/\[\[/, "").replace(/\|.\*]]/, "").replace(/\]\]/, "").replace(".md", ""))); + let filePath = files2.map((f) => f.path)[0]; + console.log(filePath); + return filePath; +} +``` diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\347\224\273\346\235\277\344\270\216 Kanban \345\276\227\346\242\246\345\271\273\347\273\223\345\220\210-\345\203\217PPT\344\270\200\346\240\267\346\274\224\347\244\272.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\347\224\273\346\235\277\344\270\216 Kanban \345\276\227\346\242\246\345\271\273\347\273\223\345\220\210-\345\203\217PPT\344\270\200\346\240\267\346\274\224\347\244\272.md" index bc8dc2d07..7b3abbee0 100644 --- "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\347\224\273\346\235\277\344\270\216 Kanban \345\276\227\346\242\246\345\271\273\347\273\223\345\220\210-\345\203\217PPT\344\270\200\346\240\267\346\274\224\347\244\272.md" +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Excalidraw/\350\207\252\345\256\232\344\271\211Excalidraw\350\204\232\346\234\254-\347\224\273\346\235\277\344\270\216 Kanban \345\276\227\346\242\246\345\271\273\347\273\223\345\220\210-\345\203\217PPT\344\270\200\346\240\267\346\274\224\347\244\272.md" @@ -39,7 +39,7 @@ modified: 20240122223401 首先感谢群友 @颜凯 提供了以下的使用教程,比我写的好多了,我估计都不会写这些详细,以后注意并学习一下 (by 熊猫 24.01.15) - 前提条件: - - 1、安装 kanban 脚本(教程详见:[[Excalidraw如何安装脚本和脚本设置介绍]])) + - 1、安装 kanban 脚本(教程详见:[[Excalidraw如何安装脚本_脚本设置介绍]]) - 2、安装 kanban 插件 - 脚本设置 - ![自定义 Excalidraw 脚本 - 画板与 Kanban 得梦幻结合 - 像 PPT 一样演示](https://cdn.pkmer.cn/images/202401222205481.png!pkmer) @@ -82,7 +82,7 @@ Kanban 文件的刷新稍微有点延迟,而且 Excalidraw 的局部引用视 ## EA 脚本 -[[Excalidraw如何安装脚本和脚本设置介绍]] +[[Excalidraw如何安装脚本_脚本设置介绍]] ```js const fs = require('fs'); diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/QuickAdd\350\204\232\346\234\254-\344\270\200\351\224\256\345\210\207\346\215\242VimMode.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/QuickAdd\350\204\232\346\234\254-\344\270\200\351\224\256\345\210\207\346\215\242VimMode.md" new file mode 100644 index 000000000..c88c2796f --- /dev/null +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/QuickAdd\350\204\232\346\234\254-\344\270\200\351\224\256\345\210\207\346\215\242VimMode.md" @@ -0,0 +1,51 @@ +--- +uid: 20240221011001 +title: QuickAdd 脚本 - 一键切换 VimMode +tags: + - Vim相关 + - quickadd脚本 +description: 通过Quickadd脚本设置快捷键便捷切换Vim模式,无需插件 +author: 熊猫别熬夜 +type: other +draft: false +editable: false +modified: 20240221011051 +--- + +# QuickAdd 脚本 - 一键切换 VimMode + +如何便捷的切换 Vim Mode,而不是返回 Obsidian 的设置界面切换,在插件市场有 Vim Toggle 插件 (作者:Conner Ohnesorge),可以控制 Vim 模式的开关,不过这需要额外安装一个插件,在中文论坛看到了这篇 [使用User Plugins插件实现Vim Mode的命令/快捷键切换 - 经验分享 - Obsidian 中文论坛](https://forum-zh.obsidian.md/t/topic/29676),直接用 JS 脚本来控制,这里采用他的代码,直接用 QuickAdd 插件设置脚本就可以了。 + +> PS:Quikadd 插件算是必装的一个插件了,而不是为了切换 Vim Mode 而单独安装的,如果不想安装 Quikadd,那就采用 Vim Toggle 插件吧。 + +## 配置 QuickAdd 的 Capture + +### 第一步:添加 VimToggle Capture 选项 + +![2024-02-20_QuickAdd脚本-一键切换VimMode_IMG-1](https://cdn.pkmer.cn/images/202402210110774.png!pkmer) + +### 第二步:配置 VimToggle Capture + +![2024-02-20_QuickAdd脚本-一键切换VimMode_IMG-2](https://cdn.pkmer.cn/images/202402210110775.png!pkmer) + +````md +```js quickadd +if (app.vault.getConfig("vimMode")) { + app.vault.setConfig("vimMode", false); + new Notice("🔴已关闭Vim模式"); +} else { + app.vault.setConfig("vimMode", true); + new Notice("🟢已启动Vim模式"); +} +``` +```` + +### 第三步:配置 VimToggle 快捷键 + +配置快捷键需要把 Quickadd 中勾选⚡的符号来注册快捷键,然后在 Obsidian 设置中配置快捷键: + +![2024-02-20_QuickAdd脚本-一键切换VimMode_IMG-3](https://cdn.pkmer.cn/images/202402210110776.png!pkmer) + +## Reference + +- [使用User Plugins插件实现Vim Mode的命令/快捷键切换 - 经验分享 - Obsidian 中文论坛](https://forum-zh.obsidian.md/t/topic/29676) \ No newline at end of file diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/Quickadd\350\204\232\346\234\254-\346\216\247\345\210\266\350\207\252\345\256\232\344\271\211CSS-\350\256\276\347\275\256\344\272\214\347\273\264\347\240\201\345\255\227\344\275\223.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/Quickadd\350\204\232\346\234\254-\346\216\247\345\210\266\350\207\252\345\256\232\344\271\211CSS-\350\256\276\347\275\256\344\272\214\347\273\264\347\240\201\345\255\227\344\275\223.md" new file mode 100644 index 000000000..7986e51a5 --- /dev/null +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/Quickadd\350\204\232\346\234\254-\346\216\247\345\210\266\350\207\252\345\256\232\344\271\211CSS-\350\256\276\347\275\256\344\272\214\347\273\264\347\240\201\345\255\227\344\275\223.md" @@ -0,0 +1,143 @@ +--- +uid: 20240131162612 +title: Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体 +tags: [quickadd脚本] +description: Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体 +author: 熊猫别熬夜,ProudBenzene,calmwaves +type: other +draft: false +editable: false +modified: 20240221005701 +--- + +# Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体 + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633076.png!pkmer) + +## 概述 + +很多情况下,我们分享自己的 Obsidian 精美界面时,并不希望暴露自己的笔记或者文件夹上面的内容,毕竟隐私很重要,这里提供一个方案——设置全局的隐私字体,这里有 @Calmwaves 推荐的一个 [二维码字体](https://github.com/hnzxs/xiaosongQRfont),个人感觉非常适合当做一种隐私字体,而且看起来也比较好看。 + +> PS:二维码字体可以通过扫描获取文字,安全性并不高,如果分享的界面是极为隐私的内容,请采用其他方法。 + +为了方便调用这个隐私字体,可以配置 Quickadd 脚本 (脚本由 @ProudBenzene 提供),另外用 Commander 插件制作一个控制开关按钮: + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633077.gif!pkmer) + +## 配置教程 + +### 第一步:下载并安装二维码字体 + +- 二维码字体链接: + - 安装字体到系统后可以进行下面操作 + +### 第二步:配置 CSS + +需要配置 CSS 片段,设置 Obsidian 中所有字体为该二维码字体,即复制下面的 CSS 到一个 `.css` 文件中,比如我命名为:`[字体-熊猫]隐私字体.css`,并移动到 `{你的笔记库路径}\.obsidian\snippets` 文件夹中: + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633078.png!pkmer) + +```css +body { + --privacy-font: "xiaosongQRfont"; + --font-default: var(--privacy-font) !important; + --default-font: var(--privacy-font) !important; + --font-family-editor: var(--privacy-font) !important; + --font-monospace-default: var(--privacy-font) !important; + --font-interface-override: var(--privacy-font) !important; + --font-text-override:var(--privacy-font) !important; + --font-monospace-override: var(--privacy-font) !important; +} +``` + +### 第三步:配置 Quickadd 的控制 CSS 开关的脚本 + +Quickadd 可以用 Capture 或者 Macro 来设置脚本,Capture 里面需要放到 `js quickadd` 的代码块里面,Macro 里面就需要配置 js 文件。 + +使用 Capture 就不需要用 Macro 了,不过 Macro 依赖于代码文件,可以实时编辑修改,如果你需要修改代码可能会方便点,麻烦的就是需要自己复制代码文件到一个 js 文件中,以及配置 Macro。 + +> 这个控制 CSS 的脚本基本不需要变动,修改文件名就行了,我个人推荐采用 Capture 的方式比较方便点。 + +#### Capture 配置 + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633080.png!pkmer) + +````md +```js quickadd +const snippetName = "[字体-熊猫]隐私字体"; +const snippetPath = app.customCss.getSnippetPath(snippetName); +if (!snippetPath) { + new Notice(`Snippet ${snippetName} not found`); +} + +const isSnippetsEnabled = app.customCss.enabledSnippets.has(snippetName) + ? true + : false; + +if (isSnippetsEnabled) { + console.log("关闭"); + app.customCss.setCssEnabledStatus(snippetName, false); + app.customCss.requestLoadSnippets(); +} else { + console.log("启动"); + app.customCss.setCssEnabledStatus(snippetName, true); + app.customCss.requestLoadSnippets(); +} +``` +```` + +#### Macro 配置 (可选) + +```js +module.exports = async (params) => { + const snippetName = "[字体-熊猫]隐私字体"; + const snippetPath = app.customCss.getSnippetPath(snippetName); + if (!snippetPath) { + new Notice(`Snippet ${snippetName} not found`); + } + + const isSnippetsEnabled = app.customCss.enabledSnippets.has(snippetName) + ? true + : false; + + if (isSnippetsEnabled) { + console.log("关闭"); + app.customCss.setCssEnabledStatus(snippetName, false); + app.customCss.requestLoadSnippets(); + } else { + console.log("启动"); + app.customCss.setCssEnabledStatus(snippetName, true); + app.customCss.requestLoadSnippets(); + } +}; +``` + +### 第四步:配置快捷键或者 Commander 按钮 + +可以根据自身使用习惯配置对应的快捷键或者一个按钮,或者直接通过 Quickadd 来调用: + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633081.png!pkmer) + +#### 配置快捷键 + +配置快捷键需要把 Quickadd 中勾选⚡的符号来注册快捷键 + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633082.png!pkmer) + +然后在 Obsidian 设置中配置快捷键 + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633083.png!pkmer) + +#### 配置 Commander 按钮 + +配置快捷键需要把 Quickadd 中勾选⚡的符号来注册快捷键 + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633082.png!pkmer) + +在 Commander 中配置该快捷键的按钮,我是注册在**首页**需要在**外观**中开启**显示标签页标题栏**: + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633085.png!pkmer) + +**Commander 配置**: + +![Quickadd 脚本 - 控制自定义 CSS- 设置二维码字体](https://cdn.pkmer.cn/images/202401311633086.png!pkmer) \ No newline at end of file diff --git "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/quickadd.md" "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/quickadd.md" index 9528eac2a..42d98beed 100644 --- "a/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/quickadd.md" +++ "b/10-Obsidian/Obsidian\347\244\276\345\214\272\346\217\222\344\273\266/Quickadd/quickadd.md" @@ -177,6 +177,8 @@ module.exports = async (params) => { - [[Quickadd结合CSS实现挖空复习]] - [[Quickadd脚本-一键在某软件中打开Ob笔记]] - [[Quickadd脚本-一键在系统应用中打开图片编辑]] +- [[Quickadd脚本-控制自定义CSS-设置二维码字体]] +- [[QuickAdd脚本-一键切换VimMode]] ## 视频教程