Skip to content

Commit

Permalink
Merge pull request #656 from PandaNocturne/PandaDocs-2024-W04
Browse files Browse the repository at this point in the history
Panda docs 2024 w04
  • Loading branch information
juestchaos authored Feb 22, 2024
2 parents 5cf0762 + 34f298b commit 92d0d31
Show file tree
Hide file tree
Showing 10 changed files with 841 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ author: windilycloud
type: basic
draft: false
editable: false
modified: 20240122220808
modified: 20240131141540
---

# Obsidian 插件:Excalidraw 完美的绘图工具
Expand Down Expand Up @@ -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 美化

Expand Down
Original file line number Diff line number Diff line change
@@ -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();
```
Loading

0 comments on commit 92d0d31

Please sign in to comment.