<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="https://konrad.earth/feed_style.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <tabi:metadata xmlns:tabi="https://github.com/welpo/tabi">
        <tabi:base_url>https:&#x2F;&#x2F;konrad.earth</tabi:base_url>
        <tabi:separator>
            •
        </tabi:separator>
        <tabi:about_feeds>This is a web feed, also known as an Atom feed. Subscribe by copying the URL from the address bar into your newsreader. Visit About Feeds to learn more and get started. It&#x27;s free.</tabi:about_feeds>
        <tabi:visit_the_site>Visit website</tabi:visit_the_site>
        <tabi:recent_posts>Recent posts</tabi:recent_posts>
        <tabi:last_updated_on>Updated on $DATE</tabi:last_updated_on>
        <tabi:default_theme></tabi:default_theme>
        <tabi:post_listing_date>date</tabi:post_listing_date>
        <tabi:current_section>CindyJS</tabi:current_section>
    </tabi:metadata><title>konrad.earth - CindyJS</title>
        <subtitle>Konrad Heidler</subtitle>
    <link href="https://konrad.earth/tags/cindyjs/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="https://konrad.earth/tags/cindyjs/" rel="alternate" type="text/html"/>
    <generator uri="https://www.getzola.org/">Zola</generator><updated>2020-05-16T09:00:00+01:00</updated><id>https://konrad.earth/tags/cindyjs/atom.xml</id><entry xml:lang="en">
        <title>Metaballs</title>
        <published>2020-05-16T09:00:00+01:00</published>
        <updated>2020-05-16T09:00:00+01:00</updated>
        <author>
            <name>Konrad Heidler</name>
        </author>
        <link rel="alternate" href="https://konrad.earth/blog/metaballs/" type="text/html"/>
        <id>https://konrad.earth/blog/metaballs/</id>
        
            <content type="html">&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Metaballs&quot;&gt;Metaballs&lt;&#x2F;a&gt;
are a fun way of creating blobby looking shapes.
The idea stems from a method for rendering molecules,
where each atom contributes to the overall electron density&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the easy case of hydrogen, this contribution is a radially symmetric shape centered around the
atom’s center \(c\):&lt;&#x2F;p&gt;
&lt;p&gt;$$
f(v; c) = a \exp(- \|v - c\|_2^2)
$$&lt;&#x2F;p&gt;
&lt;p&gt;To render a collection of such atoms, one then takes the sum over these contributions,
and renders a level-set:&lt;&#x2F;p&gt;
&lt;p&gt;$$
\left\{\,v \,\middle|\, \sum_{i=1}^n a_i\exp(- \|v - c_i\|_2^2) = L\,\right\}
$$&lt;&#x2F;p&gt;
&lt;p&gt;Here’s a visualization in two dimensions with moving centers:&lt;&#x2F;p&gt;
&lt;div class=&quot;applet&quot;&gt;
  &lt;iframe src=metaballs.html allow=&quot;fullscreen&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
  
    &lt;button
      type=&quot;button&quot;
      class=&quot;fullscreen&quot;
      aria-label=&quot;Open applet fullscreen&quot;
      title=&quot;Fullscreen&quot;
    &gt;
      &lt;svg viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot;&gt;
        &lt;path
          d=&quot;M5 9V5h4M15 5h4v4M19 15v4h-4M9 19H5v-4&quot;
          fill=&quot;none&quot;
          stroke=&quot;currentColor&quot;
          stroke-width=&quot;2&quot;
          stroke-linecap=&quot;round&quot;
        &#x2F;&gt;
      &lt;&#x2F;svg&gt;
    &lt;&#x2F;button&gt;
  
&lt;&#x2F;div&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;dl.acm.org&#x2F;doi&#x2F;10.1145&#x2F;357306.357310&quot;&gt;Blinn, J. (1982). A Generalization of Algebraic Surface Drawing. ACM Trans. Graph., 1, 235-256.&lt;&#x2F;a&gt; &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</content>
        <summary type="html">Moving blobs</summary>
        </entry><entry xml:lang="en">
        <title>Soap Bubbles</title>
        <published>2019-06-06T09:00:00+01:00</published>
        <updated>2019-06-06T09:00:00+01:00</updated>
        <author>
            <name>Konrad Heidler</name>
        </author>
        <link rel="alternate" href="https://konrad.earth/blog/soap-bubbles/" type="text/html"/>
        <id>https://konrad.earth/blog/soap-bubbles/</id>
        
            <content type="html">&lt;p&gt;Have you ever wondered about the rainbows on CDs, gasoline puddles or soap bubbles?
All of these have the same cause: The &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Thin-film_interference&quot;&gt;interference of light on thin surfaces&lt;&#x2F;a&gt;.
Today, we’ll try to render something that looks like a soap bubble.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-physics&quot;&gt;Some Physics&lt;&#x2F;h2&gt;
&lt;p&gt;When a ray of light hits the surface of the soap bubble,
it is either instantly reflected, or it enters the soap film and is refracted.
When it is refracted, it can then be reflected off the other end of the soap,
and then leave it again at a slightly different spot.
There are countless other possiblities for the ray to bounce around,
but these are the two that we will focus on here:&lt;&#x2F;p&gt;
&lt;img class=&quot;img-light&quot; src=&quot;paths.svg&quot; loading=&quot;lazy&quot;&gt;
&lt;img class=&quot;img-dark&quot; src=&quot;paths-dark.svg&quot; loading=&quot;lazy&quot;&gt;
&lt;p&gt;Because the width of the soap layer is comparable to the wavelength of visible light,
the resulting color of the light rays will change considerably depending on the
incidence angle.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finished-visualization&quot;&gt;Finished visualization&lt;&#x2F;h2&gt;
&lt;p&gt;Putting it all together,
we get this nice little interactive visualization.&lt;&#x2F;p&gt;
&lt;div class=&quot;applet&quot;&gt;
  &lt;iframe src=bubbles.html allow=&quot;fullscreen&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
  
    &lt;button
      type=&quot;button&quot;
      class=&quot;fullscreen&quot;
      aria-label=&quot;Open applet fullscreen&quot;
      title=&quot;Fullscreen&quot;
    &gt;
      &lt;svg viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot;&gt;
        &lt;path
          d=&quot;M5 9V5h4M15 5h4v4M19 15v4h-4M9 19H5v-4&quot;
          fill=&quot;none&quot;
          stroke=&quot;currentColor&quot;
          stroke-width=&quot;2&quot;
          stroke-linecap=&quot;round&quot;
        &#x2F;&gt;
      &lt;&#x2F;svg&gt;
    &lt;&#x2F;button&gt;
  
&lt;&#x2F;div&gt;
&lt;!-- If you&#x27;re interested in the source code, --&gt;
&lt;!-- # you can find it &lt;a download=&quot;bubbles.html&quot; href=&quot;bubbles.html&quot;&gt;here&lt;&#x2F;a&gt;. --&gt;
</content>
        </entry><entry xml:lang="en">
        <title>Particle Life</title>
        <published>2019-01-31T09:00:00+01:00</published>
        <updated>2019-01-31T09:00:00+01:00</updated>
        <author>
            <name>Konrad Heidler</name>
        </author>
        <link rel="alternate" href="https://konrad.earth/blog/particlelife/" type="text/html"/>
        <id>https://konrad.earth/blog/particlelife/</id>
        
            <content type="html">&lt;p&gt;Particle Simulations are great.
Life Simulations are fun.
Meet Particle Life – the intersection of these two worlds.&lt;&#x2F;p&gt;
&lt;p&gt;Inspired by Biologist &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;evolution.berkeley.edu&#x2F;evolibrary&#x2F;article&#x2F;history_24&quot;&gt;Lynn Margulis’&lt;&#x2F;a&gt;
theory of endosymbiosis, Jeffrey Ventrella invented his &lt;a rel=&quot;external&quot; href=&quot;http:&#x2F;&#x2F;www.ventrella.com&#x2F;Clusters&#x2F;&quot;&gt;Clusters&lt;&#x2F;a&gt;.
The main idea is simulating microorganisms that have pretty basic interaction patterns.
Some species are drawn towards certain others, while some will be repelled by others.
Implementing a particle simulation with these rules leads to very interesting patterns.&lt;&#x2F;p&gt;
&lt;p&gt;Compared to physics-based particle simulations, this approach explicitly violates the
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Momentum#Conservation&quot;&gt;Conservation of Momentum&lt;&#x2F;a&gt;.
This allows for self-propelling structures, clusters that look like biological cells, and much more.&lt;&#x2F;p&gt;
&lt;p&gt;Porting this simulation to WebGL code was pretty straight-forward using
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cindyjs.org&quot;&gt;CindyJS&lt;&#x2F;a&gt;.
Play around with the simulation here:&lt;&#x2F;p&gt;
&lt;div class=&quot;applet&quot;&gt;
  &lt;iframe src=particlelife.html allow=&quot;fullscreen&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
  
    &lt;button
      type=&quot;button&quot;
      class=&quot;fullscreen&quot;
      aria-label=&quot;Open applet fullscreen&quot;
      title=&quot;Fullscreen&quot;
    &gt;
      &lt;svg viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot;&gt;
        &lt;path
          d=&quot;M5 9V5h4M15 5h4v4M19 15v4h-4M9 19H5v-4&quot;
          fill=&quot;none&quot;
          stroke=&quot;currentColor&quot;
          stroke-width=&quot;2&quot;
          stroke-linecap=&quot;round&quot;
        &#x2F;&gt;
      &lt;&#x2F;svg&gt;
    &lt;&#x2F;button&gt;
  
&lt;&#x2F;div&gt;
</content>
        </entry><entry xml:lang="en">
        <title>Pachelballs</title>
        <published>2018-12-25T09:00:00+01:00</published>
        <updated>2018-12-25T09:00:00+01:00</updated>
        <author>
            <name>Konrad Heidler</name>
        </author>
        <link rel="alternate" href="https://konrad.earth/blog/pachelballs/" type="text/html"/>
        <id>https://konrad.earth/blog/pachelballs/</id>
        
            <content type="html">&lt;p&gt;When I was a kid, I really enjoyed this game called &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Electroplankton&quot;&gt;Electroplankton&lt;&#x2F;a&gt;.
Especially the game mode called &lt;em&gt;Hanenbow&lt;&#x2F;em&gt;,
where you launched small tadpoles onto leaves.
On impact the leaves would emit glockenspiel sounds, and create a nice sounding melody.
Here’s what it looked like:&lt;&#x2F;p&gt;
&lt;div class=&quot;embed video-player&quot; style=&quot;text-align:center;&quot;&gt;
  &lt;iframe
    class=&quot;youtube-player&quot;
    type=&quot;text&#x2F;html&quot;
    width=&quot;640&quot;
    height=&quot;385&quot;
    src=&quot;https:&#x2F;&#x2F;www.youtube-nocookie.com&#x2F;embed&#x2F;it7wvZmgYYA&quot;
    allowfullscreen
    frameborder=&quot;0&quot;
  &gt;
  &lt;&#x2F;iframe&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I wondered, how hard could it be to implement something similar?
If you just want to see the animation, click &lt;a href=&quot;https:&#x2F;&#x2F;konrad.earth&#x2F;blog&#x2F;pachelballs&#x2F;#finished-animation&quot;&gt;here&lt;&#x2F;a&gt;.
If you’re interested in the background, read on!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;concept&quot;&gt;Concept&lt;&#x2F;h2&gt;
&lt;figure &gt;
    
    &lt;img src=concept.svg &#x2F;&gt;
    &lt;figcaption&gt;
      
      &lt;p&gt;
         The basic idea: Cannon, Balls, Bouncers 
        
        
        
      &lt;&#x2F;p&gt;
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;First we have a cannon that shoots out balls at a certain frequency.
These balls then fly through a field of bouncers, that act like small trampolines for the balls.
Upon hitting a bouncer, a ball will emit a certain tone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;physics&quot;&gt;Physics&lt;&#x2F;h2&gt;
&lt;p&gt;We’re going to be using the wonderful &lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;cindyjs.org&quot;&gt;CindyJS Framework&lt;&#x2F;a&gt;,
that does a lot of the heavy lifting behind the scenes.&lt;&#x2F;p&gt;
&lt;p&gt;Ball flying physics is easy.
A ball with position \(x\) and velocity \(v\) will be updated in two steps:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Updating the speed: \(v \gets v + dt \cdot g\), with a time step \(dt\) and the gravity vector \(g\)&lt;&#x2F;li&gt;
&lt;li&gt;Updating the position: \(x \gets x + dt \cdot v\)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The collisions with the bouncers are where it gets tricky.
First of all, how do we detect a collision?&lt;&#x2F;p&gt;
&lt;figure &gt;
    
    &lt;img src=collision.svg &#x2F;&gt;
    &lt;figcaption&gt;
      
      &lt;p&gt;
         This is what we want to detect: \(x\) and \(\bar x\) are on opposite sides of the bouncer. 
        
        
        
      &lt;&#x2F;p&gt;
    &lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Say a ball is updated from position \(x\) to position \(\bar x\).
We want to check if it collides with a bouncer during that update.
A bouncer is essentially a line between two points \(b_1\) and \(b_2\).&lt;&#x2F;p&gt;
&lt;p&gt;One can see that we have a collision if and only if these two conditions are fulfilled:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;\(x\) and \(\bar x\) lie on opposing sides of the line \(b_1b_2\).&lt;&#x2F;li&gt;
&lt;li&gt;\(b_1\) and \(b_2\) lie on opposing sides of the line \(x\bar x\).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is a neat way of calculating which side of a line a point is on using determinants.
The determinant&lt;&#x2F;p&gt;
&lt;p&gt;$$\det\begin{pmatrix}x_A&amp;amp;x_B&amp;amp;x_C\\ y_A&amp;amp;y_B&amp;amp;y_C\\ 1&amp;amp;1&amp;amp;1\end{pmatrix}$$&lt;&#x2F;p&gt;
&lt;p&gt;will have a positive sign if \(C\) lies left of the line \(AB\), and a negative one if it lies on the right:&lt;&#x2F;p&gt;
&lt;div class=&quot;applet&quot;&gt;
  &lt;iframe src=determinantorientation.html allow=&quot;fullscreen&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
  
    &lt;button
      type=&quot;button&quot;
      class=&quot;fullscreen&quot;
      aria-label=&quot;Open applet fullscreen&quot;
      title=&quot;Fullscreen&quot;
    &gt;
      &lt;svg viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot;&gt;
        &lt;path
          d=&quot;M5 9V5h4M15 5h4v4M19 15v4h-4M9 19H5v-4&quot;
          fill=&quot;none&quot;
          stroke=&quot;currentColor&quot;
          stroke-width=&quot;2&quot;
          stroke-linecap=&quot;round&quot;
        &#x2F;&gt;
      &lt;&#x2F;svg&gt;
    &lt;&#x2F;button&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;So a collision is equivalent to these two expressions being true at the same time:
$${\det(b_1,b_2,x) \cdot \det(b_1,b_2,\bar x) \leq 0}$$
$${\det(x, \bar x, b_1) \cdot \det(x, \bar x, b_2) \leq 0}$$&lt;&#x2F;p&gt;
&lt;p&gt;Upon collision, we want to play a sound and reflect the ball.
This is done by setting the velocity
\(v \gets v - 2\langle v,n \rangle n\),
where \(n\) is the bouncer’s normal.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;music&quot;&gt;Music&lt;&#x2F;h2&gt;
&lt;p&gt;If we were to just emit random tones,
the result would be disharmony.
We must therefore pick the tones we play from some harmonic distribution.
The easiest way to do this is to limit the tones to a certain chord.
We can then change the chords over time, to get a nice little tune.&lt;&#x2F;p&gt;
&lt;p&gt;As you have probably guessed from the title,
we’ll be using the chord progression from
&lt;a rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pachelbel%27s_Canon&quot;&gt;Pachelbel’s Canon&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;img class=&quot;invertible-image&quot; src=&quot;https:&amp;#x2F;&amp;#x2F;konrad.earth&amp;#x2F;blog&amp;#x2F;pachelballs&amp;#x2F;pachelbel.svg?h=16d783a7566f55eb256f&quot; loading=&quot;lazy&quot; width=&quot;1184&quot; height=&quot;241&quot; &#x2F;&gt;
&lt;p&gt;CindyJS has a MIDI Interface, that just enumerates musical notes starting with &lt;code&gt;C0&lt;&#x2F;code&gt;.
So our chord progression can be transcribed into&lt;&#x2F;p&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;javascript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite&quot;&gt;chords&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; [&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;63&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 68&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 72&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Ab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;63&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 67&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 70&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Eb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;60&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 68&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Fm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;60&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 67&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Cm&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;56&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Db&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;56&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 60&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Ab&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;56&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 61&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 65&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt; &#x2F;&#x2F; Db&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;    [&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;58&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 63&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt; 67&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;  &#x2F;&#x2F; Eb&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;]&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each one of the bouncers will play a tone based on this chord table,
where the row will cycle through time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finished-animation&quot;&gt;Finished animation&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a name=&quot;finished&quot;&gt;&lt;&#x2F;a&gt;
Putting it all together,
we get this nice little interactive animation.&lt;&#x2F;p&gt;
&lt;div class=&quot;applet&quot;&gt;
  &lt;iframe src=pachelballs.html allow=&quot;fullscreen&quot; allowfullscreen&gt;&lt;&#x2F;iframe&gt;
  
    &lt;button
      type=&quot;button&quot;
      class=&quot;fullscreen&quot;
      aria-label=&quot;Open applet fullscreen&quot;
      title=&quot;Fullscreen&quot;
    &gt;
      &lt;svg viewBox=&quot;0 0 24 24&quot; aria-hidden=&quot;true&quot;&gt;
        &lt;path
          d=&quot;M5 9V5h4M15 5h4v4M19 15v4h-4M9 19H5v-4&quot;
          fill=&quot;none&quot;
          stroke=&quot;currentColor&quot;
          stroke-width=&quot;2&quot;
          stroke-linecap=&quot;round&quot;
        &#x2F;&gt;
      &lt;&#x2F;svg&gt;
    &lt;&#x2F;button&gt;
  
&lt;&#x2F;div&gt;
&lt;p&gt;If you’re interested in the source code,
you can find it &lt;a download=&quot;pachelballs.html&quot; href=&quot;&#x2F;static&#x2F;pachelballs.html&quot;&gt;here&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        </entry>
</feed>
