Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Working with Obsidian and Excalidraw for Animation and PDF Export

Tech May 10 3

1

My motivation stemmed from creating a series of frames illustrating the implementation of window functions in PostgreSQL using Excalidraw within Obsidian. When played sequentially, these frames create an animation effect.

The Excalidraw plugin in Obsidian supports customizations. To achieve the animation playback, I modified the SlideShow plugin settings:

const TRANSITION_STEP_COUNT = 1;
const TRANSITION_DELAY = 0; //maximum time for transition between slides in milliseconds
const FRAME_SLEEP = 0; //milliseconds


This configuration enabled the desired frame-by-frame presentation within Obsidian.

2

For better sharing of my Excalidraw diagrams, I needed to export each frame as an image and compile them into a PDF document. I explored the obsidian-excalidraw-plugin capabilities.

The tutorial video: https://www.youtube.com/watch?v=hePJcObHIso&t=424s.

Ultimately, I was able to execute the following script in the Obsidian developer console to export all frames as SVG files:

exca = ExcalidrawAutomate
exca.setView('active')
eapi = exca.getExcalidrawAPI()

elements = exca.getViewElements()
frames = elements.filter(e => e.type == 'frame').sort((a, b) => a.name.localeCompare(b.name))

async function ssvg(index) {
    activeView = exca.targetView;
    vault = activeView.app.vault;
    p = activeView.file.path;
    p.indexOf('/') == -1 ? p = p : p = p.substring(p.lastIndexOf('/') + 1);
	d = '/' + p.substring(0, p.indexOf(".")) + '_slides';
    if (vault.getFolderByPath(d) == null)
        vault.createFolder(d);
    n = d + '/slide' + index + '.svg';
	e = exca.getElementsInFrame(frames[index - 1], elements);
    a = await activeView.svg({
	        elements: e,
			appState: eapi.getAppState(),
            files: exca.getExcalidrawAPI().getFiles(),
	    }, undefined, undefined, true);
    o = (new XMLSerializer).serializeToString(a);
    await vault.create(n, o);
}

for (var i = 1; i <= frames.length; i++) await ssvg(i);


With this, I could reference these images in Markdown files and export them to PDF.

3

To enhance the visual appeal of the generated PDF, I customized Obsidian's CSS snippets.

Relevant CSS snippet:

@media print {
    hr {
        page-break-after: always;
        opacity: 0;
    }

    * {
        font-size: 1.2em;
    }

    .HyperMD-list-line {
        font-size: 1.4em;
    }

    /* Center images in exported PDF pages */
    img {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100vh;
        text-align: center;
        margin: 0 auto;
    }
}


I used this code block for displaying a title page:

<div style="font-size: 2em;text-align: center; display: flex; justify-content: center; align-items: center; height: 100vh">
internals of<br/> window function implementation
</div>


Final result: https://ldd.cool/pdf/windowagg.pdf

Tags: obsidian

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.