Skip to content

Instantly share code, notes, and snippets.

@zsviczian
Last active June 4, 2024 02:28
Show Gist options
  • Save zsviczian/33ff695d5b990de1ebe8b82e541c26ad to your computer and use it in GitHub Desktop.
Save zsviczian/33ff695d5b990de1ebe8b82e541c26ad to your computer and use it in GitHub Desktop.
Excalidraw Icon Library

<%* /*

*/
s = await navigator.clipboard.readText();
navigator.clipboard.writeText(s.replaceAll("\n","").replaceAll(/\s{2,}/g," "));
%>

/*

FILENAME_FILTER=/^icon -/i;
KEYWORD_GRABBER=/(?:icon -)?([^-]*)-?/i;
COLS=22;
HEIGHT=180;
WIDTH=180;
TEXTHEIGHT=40;
PADDING=50;
const api = ea.getExcalidrawAPI();
const f=ea.targetView.file;
icons=app.vault.getFiles().filter(f=>(f.extension!=='md'||ea.isExcalidrawFile(f))&&f.basename.toLowerCase().match(FILENAME_FILTER)).sort((a,b)=>a.basename.toLowerCase()<b.basename.toLowerCase()?-1:1);
const {
  zenModeEnabled,
  viewModeEnabled,
  linkOpacity,
  trayModeEnabled,
  penMode,
  penDetected,
  allowPinchZoom,
  allowWheelZoom,
  pinnedScripts,
  customPens
} = api.getAppState();
api.resetScene();
api.updateScene({appState: {
  zenModeEnabled,
  viewModeEnabled,
  linkOpacity,
  trayModeEnabled,
  penMode,
  penDetected,
  allowPinchZoom,
  allowWheelZoom,
  pinnedScripts,
  customPens
}});
col=0;
row=0;
for(icon of icons) {
  id=await ea.addImage(col*(WIDTH+PADDING),row*(HEIGHT+PADDING+TEXTHEIGHT),icon);
  if(f!==ea.targetView.file && ea.targetView?.getViewType?.()!=='excalidraw') return;
  if(!id) continue;
  keywords=icon.basename.match(KEYWORD_GRABBER)[1].trim();
  ea.style.verticalAlign='top';
  ea.style.textAlign='center';
  ea.style.fontSize=12;  
  el=ea.getElement(id);
  ratio=el.width/WIDTH;
  if(el.height/ratio>HEIGHT) ratio=el.height/HEIGHT;
  el.width=el.width/ratio;
  el.height=el.height/ratio;
  ea.style.strokeColor='black';
  boxID=ea.addText(col*(WIDTH+PADDING)-PADDING/2+10,row*(HEIGHT+PADDING+TEXTHEIGHT)+HEIGHT+PADDING/2-10,keywords,{
    width:WIDTH+PADDING-20,
    height:TEXTHEIGHT-20,
    boxPadding:10,
    textAlign:'center',
    textVerticalAlign:'top',
    boxStrokeColor:'transparent',
    box:'box'
  });		
  if(++col===COLS) {
    row++;
    col=0;
    await ea.addElementsToView(false,false,false);
    ea.targetView.clearDirty();
    ea.clear();
  }
}
await ea.addElementsToView(false,false,false);
ea.targetView.clearDirty();
api.zoomToFit();
api.updateContainerSize(ea.getViewElements().filter(el=>el.type==='rectangle'));
api.setActiveTool({type: 'hand'});
excalidraw-plugin excalidraw-onload-script
parsed
FILENAME_FILTER=/^icon -/i;KEYWORD_GRABBER=/(?:icon -)?([^-]*)-?/i;COLS=22;HEIGHT=180;WIDTH=180;TEXTHEIGHT=40;PADDING=50;const api = ea.getExcalidrawAPI();const f=ea.targetView.file;icons=app.vault.getFiles().filter(f=>(f.extension!=='md'||ea.isExcalidrawFile(f))&&f.basename.toLowerCase().match(FILENAME_FILTER)).sort((a,b)=>a.basename.toLowerCase()<b.basename.toLowerCase()?-1:1);const { zenModeEnabled, viewModeEnabled, linkOpacity, trayModeEnabled, penMode, penDetected, allowPinchZoom, allowWheelZoom, pinnedScripts, customPens} = api.getAppState();api.resetScene();api.updateScene({appState: { zenModeEnabled, viewModeEnabled, linkOpacity, trayModeEnabled, penMode, penDetected, allowPinchZoom, allowWheelZoom, pinnedScripts, customPens}});col=0;row=0;for(icon of icons) { id=await ea.addImage(col*(WIDTH+PADDING),row*(HEIGHT+PADDING+TEXTHEIGHT),icon); if(f!==ea.targetView.file && ea.targetView?.getViewType?.()!=='excalidraw') return; if(!id) continue; keywords=icon.basename.match(KEYWORD_GRABBER)[1].trim(); ea.style.verticalAlign='top'; ea.style.textAlign='center'; ea.style.fontSize=12; el=ea.getElement(id); ratio=el.width/WIDTH; if(el.height/ratio>HEIGHT) ratio=el.height/HEIGHT; el.width=el.width/ratio; el.height=el.height/ratio; ea.style.strokeColor='black'; boxID=ea.addText(col*(WIDTH+PADDING)-PADDING/2+10,row*(HEIGHT+PADDING+TEXTHEIGHT)+HEIGHT+PADDING/2-10,keywords,{ width:WIDTH+PADDING-20, height:TEXTHEIGHT-20, boxPadding:10, textAlign:'center', textVerticalAlign:'top', boxStrokeColor:'transparent', box:'box' }); if(++col===COLS) { row++; col=0; await ea.addElementsToView(false,false,false); ea.targetView.clearDirty(); ea.clear(); }}await ea.addElementsToView(false,false,false);ea.targetView.clearDirty();api.zoomToFit();api.updateContainerSize(ea.getViewElements().filter(el=>el.type==='rectangle'));api.setActiveTool({type: 'hand'});

#exclude

Text Elements

%%

Drawing

{
	"type": "excalidraw",
	"version": 2,
	"source": "https://github.com/zsviczian/obsidian-excalidraw-plugin/releases/tag/2.0.17",
	"elements": [],
	"appState": {
		"theme": "light",
		"viewBackgroundColor": "#ffffff",
		"currentItemStrokeColor": "#1e1e1e",
		"currentItemBackgroundColor": "transparent",
		"currentItemFillStyle": "solid",
		"currentItemStrokeWidth": 2,
		"currentItemStrokeStyle": "solid",
		"currentItemRoughness": 1,
		"currentItemOpacity": 100,
		"currentItemFontFamily": 1,
		"currentItemFontSize": 20,
		"currentItemTextAlign": "left",
		"currentItemStartArrowhead": null,
		"currentItemEndArrowhead": "arrow",
		"scrollX": 0,
		"scrollY": 0,
		"zoom": {
			"value": 1
		},
		"currentItemRoundness": "round",
		"gridSize": null,
		"gridColor": {
			"Bold": "#C9C9C9FF",
			"Regular": "#EDEDEDFF"
		},
		"currentStrokeOptions": null,
		"previousGridSize": null,
		"frameRendering": {
			"enabled": true,
			"clip": true,
			"name": true,
			"outline": true
		}
	},
	"files": {}
}

%%

@TheHuntyBadger
Copy link

Is there a filter option to point the script to a specific directory? I migrated from Joplin to Obsidian and I noticed it catches file with icon in the name. Even after changing it to "icon-"

@OXiOSDev
Copy link

Thank you very much for the icon library and the script.
The icon library works fine but I have some questions about the display of the icon library on your video:

  1. the name "Icon Library" does not display the ".excalibrain" as on mine (number 1)
  2. the excalidraw or image icons is on the left of the panel (number 2 and 3)
  3. on your panel, in the video, we also see, on the right of the "Icon Library", a number (number 4 and 5) and two opposite arrows (number 6 and 7).
    Display

I assume this is only a setting in Obsidian or in the Excalidraw setting but I can't find it.

Thanks for your work !!!!

@zsviczian
Copy link
Author

I did not notice these comments here:

  • The filter is now set for files beginning with "Icon -" or "icon -". You can change the filter by changing the FILENAME_FILTER=/^icon -/i; regular expression at the beginning of the script
  • @OXiOSDev: "Icon Library" vs. "Icon Library.excalidraw" is just a difference in filenames. Simply delete the ".excalidraw" part of the filename. It is not needed. You can set the default file naming in Excalidraw settings.
  • @JuergenKaettnis My library is also just an excalidraw file. You can drag any file (markdown, excalidraw, anything) to the side pane and pin it there.
  • @OXiOSDev regarding #3: I think those come from the PaneRelief plugin.

@OXiOSDev
Copy link

OXiOSDev commented Apr 2, 2023

@zsviczian Thank you very much for your answers

@LEEJOOPIL
Copy link

whein i install this script its not working.
so i debug my console, the line below

if(f!==ea.targetView.file && ea.targetView?.getViewType?.()!=="excalidraw") return;

at this line code error said return is not defined.

do you know what meaning is?

@zsviczian
Copy link
Author

@LEEJOOPIL
Did you download the .md file following this link? Icon Library.excalidraw.md

@zsviczian
Copy link
Author

I think the error message says return is not defined.

@LEEJOOPIL
Copy link

I used lcon library.excalidraw.md but still not working...
still return is not defined..

@briilt
Copy link

briilt commented May 26, 2024

Hi! Any way to automatically set "invert colors"?

@sjr001917
Copy link

I had the same issue as LEEJOOPIL.
Added the script to a new installation with only the bare minimum of community plugins.
The error is "Uncaught SyntaxError: Illegal return statement" and points to this code: if(f!==ea.targetView.file && ea.targetView?.getViewType?.()!=="excalidraw") return;
Removing that line doesn't help either.

@zsviczian
Copy link
Author

This sounds like a plugin is automatically modifying files, e.g. adding some metadata, etc, that creates a syntax error.
Disable other plugins. Delete and re-add the script. Is the error still happening?

Please share the output of command palette "Debug info" so I can see your definition of bare minimum.

@sjr001917
Copy link

Debug Info:
SYSTEM INFO:
Obsidian version: v1.5.12
Installer version: v1.5.3
Operating system: Windows 10 Home 10.0.22631
Login status: not logged in
Insider build toggle: off
Live preview: on
Base theme: dark
Community theme: AnuPpuccin v1.4.5
Snippets enabled: 3
Restricted mode: off
Plugins installed: 1
Plugins enabled: 1
1: Excalidraw v2.2.4

RECOMMENDATIONS:
Custom theme and snippets: for cosmetic issues, please first try updating your theme and disabling your snippets. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community theme and snippets.
Community plugins: for bugs, please first try updating all your plugins to latest. If still not fixed, please try to make the issue happen in the Sandbox Vault or disable community plugins.

I deleted all plugins except Excalidraw.
Deleted the Icon Library script and Icon Library.md from the vault.
Copied the raw Icon Library script.
Created a new empty drawing
opened the Console
added ea=excalidraw.automate
ea.setview('first')
pasted in the icon library script
and still the same error.
Drawing_2024-06-03_19 25 20_-_Icon-O_-_Obsidian_v12406-05

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment