Excalidraw Script Engine Coding Example: Building a Gallery View

Поділитися
Вставка
  • Опубліковано 30 вер 2024
  • 📽️ ✏️ Sign up for the Visual Thinking Workshop: www.visual-thi...
    ------
    This is a technical video walking you through the process of importing many Excalidraw-based UA-cam Thumbnails into a drawing for further processing.
    ---
    If you find my videos helpful, please say thanks by buying me a coffee: ko-fi.com/zsolt
    📩 If you want to connect, you can reach me: (@zsviczian) on the Obsidian Members Group (OMG) on Discord, or on 🐦 Twitter: / zsviczian
    -----
    🍿Watch next:
    📽️ Example: Automate on file-open actions • Excalidraw Scripting -...
    📽️ Excalidraw Script Engine: • Obsidian Excalidraw 1....
    📽️ My UA-cam Workflow • My UA-cam Workflow in...
    ------
    Visual Thinking Workshop: www.visual-thi...
    My blog: zsolt.blog/
    Obsidian: obsidian.md
    Excalidraw-Obsidian: github.com/zsv...

КОМЕНТАРІ • 14

  • @farzadmf
    @farzadmf 9 місяців тому +3

    Very nice walkthough, super useful and informative (specially seeing you figuring out the issues etc as they happen)

  • @gavada8596
    @gavada8596 9 місяців тому +3

    Great video, thanks!

  • @quietlyworking
    @quietlyworking 9 місяців тому +1

    We're back in school kids!
    My old brain melted a couple times but dang that was so helpful to learn this way. I'd LOVE to see more vids like this sprinkled throughout the year. 🙏Thank you, this was empowering!

  • @GFXHDTV
    @GFXHDTV 2 місяці тому

    Can we get the code ?

  • @bobbyv3
    @bobbyv3 9 місяців тому

    string nextTask = refactorCode(Storyboard); 😜

  • @曲超-e1q
    @曲超-e1q 6 місяців тому

    Every time i think the Exxcalidraw is as good as it chould ever get,you make it even better

  • @마승현-t9n
    @마승현-t9n 9 місяців тому

    I didn't know where to leave my question, so I ended up posting it here. I am using ExcaliDraw with my Galaxy Tab. However, there is a problem that even if you change the font, it does not take effect and only the default font appears. It works on PC, but not on Android. How to solve this? For your information, I am from South Korea.

    • @VisualPKM
      @VisualPKM  9 місяців тому

      This is about the Obsidian plugin - correct?
      In Obsidian under community plugins you will find the link to the GitHub repository for each plugin. That is where you can raise issues for any of your installed plugins. This is the link for the Excalidraw-Obsidian issue log: github.com/zsviczian/obsidian-excalidraw-plugin/issues
      If this relates to excalidraw.com then the issue log is this: github.com/excalidraw/excalidraw/issues
      I tested fonts on my Galaxy S23 Ultra - and I cannot reproduce the problem.

  • @vincenzocapuzziello3466
    @vincenzocapuzziello3466 9 місяців тому

    Hi Zsolt! Could you create a script where the size of Excalidraw rectangles adjustes itself automatically to fit the text inside?
    So that, if in the rectangle
    [Word1 Word2]
    I remove the Word2, the rectangle gets smaller, and, instead of being
    [ Word1 ]
    it would be
    [Word1]
    Is there a place where I can suggest ideas for new scripts?
    Anyway, thanks for you work! I am currently using Excalidraw for my university studies ✨

    • @VisualPKM
      @VisualPKM  9 місяців тому +1

      You could use ea.measureText() to measure the width of the text then adjust the bound rectangle's width.
      Currently there is no hook to automate when the drawing changes, but you could add this script to a keyboard shortcut that would do the cleanup on demand. I could add an onSave hook. I am reluctant about the onChange hook, because there are many changes and it would result in performance impact.
      As for list of script ideas... I rather recommend taking things into your own hand and creating the script instead of waiting for someone else to do it instead of you. It may take a bit of time to learn scripting, but once you know your way around - it becomes a superpower.

  • @colechristensen
    @colechristensen 9 місяців тому

    What do you do with the script after, when you want to rerun to update for example? Do you just run manually in the developer console again or is there a more permanent or automatic thing to do?

    • @VisualPKM
      @VisualPKM  9 місяців тому +2

      This was a once off thing, so I just left it in developer console... but normally after experimenting with a script I save it either as an Excalidraw script in the Excalidraw/Scripts folder or as a Templater script in my Templater folder.
      Incidentally, I did not stop working on this script after the video. In the end I realized that downloading thumbnails from UA-cam suits my needs better especially because I have a bunch of videos that I published before moving my workflow to Obsidian, but also because the loading of thumbnails from the .md files slowed things down (as you can see in the video as well), plus I wanted to add the youtube links... so I converted my script to use the UA-cam API and saved this modified script to my Excalidraw/Scripts folder for reuse later, since now, I can choose any channel I like on YT and download all the thumbnails in one go.
      Here's the resulting page with my videos: excalidraw-obsidian.online/Hobbies/Excalidraw+Blog/Catalogue+of+Videos
      Here's the final code I saved to scripts:
      /*
      ```js*/
      const API_KEY = ""; //add your own API key
      const CHANNEL_ID = ""; //the channel ID of the channel I want to download
      let allVideos = [];
      const fetchVideos = async (token) => {
      const url = `www.googleapis.com/youtube/v3/search?key=${
      API_KEY}&channelId=${CHANNEL_ID}&part=snippet,id&order=date&maxResults=50${
      token ? `&pageToken=${token}` : ``}`;
      try {
      const response = await fetch(url);
      const data = await response.json();
      if (data.items) {
      allVideos = allVideos.concat(data.items); // Concatenate fetched videos to the array
      if (data.nextPageToken) {
      // Fetch next page of results by recursively calling fetchVideos
      await fetchVideos(data.nextPageToken);
      }
      }
      } catch (error) {
      console.error('Error fetching data:', error);
      }
      };
      // Initial call to fetch the first page of results
      await fetchVideos();
      console.log(allVideos);
      const w = 320; const h = 180; const padding = 20;
      row = -1;
      idx = 0;
      for(video of allVideos) {
      const link = video.id.videoId;
      if(!link) continue;
      col = idx++ % 16;
      if(col === 0) row++;
      const imgID = await ea.addImage(col*(padding + w), row*(padding+h),video.snippet.thumbnails.medium.url);
      const imgEl = ea.getElement(imgID);
      imgEl.link = `youtu.be/${link}`;
      }
      ea.addElementsToView();