<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>JavaScript · Jared Lynskey</title>
    <link>https://jared.lynskey.co.nz/en/tags/javascript/</link>
    <description>Short stories of value on software engineering and engineering leadership — performance reviews, hiring and scaling teams, CI/CD, DevOps monitoring and agentic AI. Written from Seoul.</description>
    <generator>Hugo</generator>
    <language>en</language>
    <copyright>© 2026 Jared Lynskey</copyright>
    <lastBuildDate>Wed, 28 Oct 2026 00:00:00 +1300</lastBuildDate>
    <atom:link href="https://jared.lynskey.co.nz/en/tags/javascript/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Zdog: A Pseudo-3D JavaScript Library, and a Korean Flag for Gwangbokjeol</title>
      <link>https://jared.lynskey.co.nz/en/posts/2019/2019-08-08-gwangbokjeol/</link>
      <guid isPermaLink="true">https://jared.lynskey.co.nz/en/posts/2019/2019-08-08-gwangbokjeol/</guid>
      <pubDate>Thu, 08 Aug 2019 00:00:00 +0000</pubDate>
      <dc:creator>Jared Lynskey</dc:creator>
      <category>Zdog</category>
      <category>JavaScript</category>
      <category>Frontend</category>
      <category>Canvas</category>
      <category>Korea</category>
      <description>Zdog is a small pseudo-3D engine for canvas and SVG: shapes live in 3D space but are drawn flat. A minimal example, and the CodePen where I used it to fly a Korean flag for Gwangbokjeol.</description>
      <content:encoded><![CDATA[<p>Next week is Gwangbokjeol in South Korea. Traditionally people fly the flag outside their home or apartment room. To commemorate this day and to sharpen my JavaScript skills, I decided to take this as an opportunity to apply a nice pseudo 3D library.</p>
<p>Gwangbokjeol (광복절), on 15 August, is Korea&rsquo;s National Liberation Day, marking the end of Japanese colonial rule in 1945. Zdog is a small JavaScript library for drawing 3D-ish illustrations on a <code>&lt;canvas&gt;</code> or in SVG. Its shapes have real positions in 3D space and turn like 3D objects, but they&rsquo;re drawn as flat shapes, so you get something that looks like a flat illustration you can spin rather than a 3D render. That suits something simple like a flag.</p>

<h2 class="relative group">A minimal Zdog example
    <div id="a-minimal-zdog-example" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#a-minimal-zdog-example" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p>Two shapes, drag to rotate, and an animation loop:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">canvas</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;zdog-canvas&#34;</span> <span class="na">width</span><span class="o">=</span><span class="s">&#34;240&#34;</span> <span class="na">height</span><span class="o">=</span><span class="s">&#34;240&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">canvas</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;https://unpkg.com/zdog@1/dist/zdog.dist.min.js&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">illo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Zdog</span><span class="p">.</span><span class="nx">Illustration</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">element</span><span class="o">:</span> <span class="s1">&#39;.zdog-canvas&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">dragRotate</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span> <span class="c1">// drag to turn the scene
</span></span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// a square, pushed back
</span></span></span><span class="line"><span class="cl">  <span class="k">new</span> <span class="nx">Zdog</span><span class="p">.</span><span class="nx">Rect</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">addTo</span><span class="o">:</span> <span class="nx">illo</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">width</span><span class="o">:</span> <span class="mi">80</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">height</span><span class="o">:</span> <span class="mi">80</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">translate</span><span class="o">:</span> <span class="p">{</span> <span class="nx">z</span><span class="o">:</span> <span class="o">-</span><span class="mi">30</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">stroke</span><span class="o">:</span> <span class="mi">8</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">color</span><span class="o">:</span> <span class="s1">&#39;#0047a0&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">// a filled circle, pulled forward
</span></span></span><span class="line"><span class="cl">  <span class="k">new</span> <span class="nx">Zdog</span><span class="p">.</span><span class="nx">Ellipse</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">addTo</span><span class="o">:</span> <span class="nx">illo</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">diameter</span><span class="o">:</span> <span class="mi">60</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">translate</span><span class="o">:</span> <span class="p">{</span> <span class="nx">z</span><span class="o">:</span> <span class="mi">30</span> <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="nx">stroke</span><span class="o">:</span> <span class="mi">8</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">color</span><span class="o">:</span> <span class="s1">&#39;#cd2e3a&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">fill</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kd">function</span> <span class="nx">animate</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">illo</span><span class="p">.</span><span class="nx">rotate</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mf">0.02</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="nx">illo</span><span class="p">.</span><span class="nx">updateRenderGraph</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="nx">requestAnimationFrame</span><span class="p">(</span><span class="nx">animate</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="nx">animate</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span></span></span></code></pre></div></div>
<p>Each shape joins the scene with <code>addTo</code>, and <code>translate.z</code> is what makes it 3D: turn the scene and the circle swings round in front of the square. <code>updateRenderGraph()</code> updates and redraws everything, which is why it sits inside the loop.</p>

<h2 class="relative group">Official Docs
    <div id="official-docs" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#official-docs" aria-label="Anchor">#</a>
    </span>
    
</h2>
<p><a href="https://zzz.dog/"  target="_blank" rel="noreferrer">https://zzz.dog/</a></p>
<p>The code used is available to view on CodePen.</p>

<h2 class="relative group">My Example
    <div id="my-example" class="anchor"></div>
    
    <span
        class="absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none">
        <a class="text-primary-300 dark:text-neutral-700 !no-underline" href="#my-example" aria-label="Anchor">#</a>
    </span>
    
</h2>
<div class="codepen" data-height="700" data-theme-id="light" data-default-tab="result" data-user="jared-lynskey" data-slug-hash="voRGqp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="광복절">
  <span>See the Pen <a href="https://codepen.io/jared-lynskey/pen/voRGqp/">
  광복절</a> by Jared Lynskey (<a href="https://codepen.io/jared-lynskey">@jared-lynskey</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</div>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>]]></content:encoded>
      <media:content url="https://jared.lynskey.co.nz/en/posts/2019/2019-08-08-gwangbokjeol/featured.jpeg" medium="image" type="image/jpeg" />
    </item>
  </channel>
</rss>
