<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Varun Vachhar]]></title><description><![CDATA[I am a developer with a strong focus on design, interactivity and animation. Originally from New Delhi, I currently live in Toronto and am the Director, UI Architecture at Rangle.io. In my spare time, I like to experiment with creative coding, making triangles and other playful experiences for the web.]]></description><link>https://varun.ca</link><generator>GatsbyJS</generator><lastBuildDate>Sat, 09 May 2026 01:44:09 GMT</lastBuildDate><item><title><![CDATA[Iridescent crystal with raymarching and signed distance fields]]></title><description><![CDATA[When building a 3D scene using libraries such as Three.js we generally use meshes. You define a geometry attach some material to it to…]]></description><link>https://varun.ca/ray-march-sdf/</link><guid isPermaLink="false">https://varun.ca/ray-march-sdf/</guid><pubDate>Sat, 03 Jun 2023 00:00:00 GMT</pubDate><content:encoded>&lt;div name=&quot;sdf-iridescent-crystal.js&quot; link=&quot;https://github.com/winkerVSbecks/shader-sketches/blob/main/sketches/sdf-iridescent-crystal.js&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/iridescent-crystal-5b48edeeada72b97ff22c472f386e06c.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;When building a 3D scene using libraries such as Three.js we generally use meshes. You define a geometry attach some material to it to create a mesh. Then add that mesh to the scene to render it. This is also how 3D modelling software like Blender and Cinema4D work. However, in the demoscene world—where the goal of is to create stuff using extremely small and self-contained computer programs—this approach didn’t work. They’d have to package a 3D library or engine along with the demo code which takes up a lot of memory. So, those folks came up with a pretty innovative approach. They used signed distance fields (SDFs) to define the geometry and then use raymarching to render the scene. The whole thing runs in a single shader program.&lt;/p&gt;&lt;p&gt;If you’ve ever come across demos on &lt;a href=&quot;https://www.shadertoy.com/&quot;&gt;Shadertoy&lt;/a&gt; or &lt;a href=&quot;http://glslsandbox.com/&quot;&gt;GLSL Sandbox&lt;/a&gt;, you’ve seen this approach in action. While the initial goal was a small file size, it also allows you to create some &lt;a href=&quot;https://www.shadertoy.com/user/tdhooper/sort=popular&amp;amp;from=0&amp;amp;num=8&quot;&gt;really cool effects&lt;/a&gt; and use boolean operations to create complex shapes. In this article, I’ll show you how to create an iridescent crystal using raymarching and SDFs.&lt;/p&gt;&lt;div&gt;ℹ️ This post assumes foundational knowledge of shaders. If you&amp;#x27;re not familiar with shaders or the GLSL API, check out: &lt;a href=&quot;https://typefully.com/DanHollick/gpnhhud&quot;&gt;Dan Hollick&amp;#x27;s twitter thread&lt;/a&gt; for a brief overview, &lt;a href=&quot;https://youtu.be/f4s1h2YETNY&quot;&gt;kishimisu&amp;#x27;s intro tutorial&lt;/a&gt; that breaks down basic GLSL concepts, or &lt;a href=&quot;https://blog.maximeheckel.com/posts/the-study-of-shaders-with-react-three-fiber/&quot;&gt;Maxime Heckel&amp;#x27;s tutorial&lt;/a&gt; on shaders with React Three Fiber.&lt;/div&gt;&lt;h2 id=&quot;ray-marching&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#ray-marching&quot; aria-label=&quot;ray marching permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Ray Marching&lt;/h2&gt;&lt;p&gt;Ray Marching is a rendering technique that involves sending rays into a scene and checking for collisions with objects. Here’s how it works:&lt;/p&gt;&lt;p&gt;First, we select a position for the camera. Then, we send rays from the camera to each pixel in the output image. Along each ray, we step bit by bit, checking if there is a collision with an object in the scene. If a collision occurs, we’re done! If not, we continue stepping along the ray up to a maximum number of steps.&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;static/ray-march-41bd80ce90cdf1dde6084381abf07d6f.svg&quot; alt=&quot;&quot; mb=&quot;0&quot; width=&quot;100%,75%,50%&quot;/&gt;&lt;figcaption&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Ray_tracing_(graphics)&quot;&gt;from &amp;quot;Ray tracing&amp;quot; on Wikipedia&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The other important distinction is that we’re not using vertices &amp;amp; triangles to define the geometry. If you’ve done any kind of 3D work, you’re probably familiar with the idea of defining geometry using vertices. For example, a cube is defined by 8 vertices and 12 triangles. But with raymarching, we use something called “signed distance field” to represent the geometry.&lt;/p&gt;&lt;h3 id=&quot;signed-distance-field-sdf&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#signed-distance-field-sdf&quot; aria-label=&quot;signed distance field sdf permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Signed Distance Field (SDF)&lt;/h3&gt;&lt;p&gt;While the term SDF may sound daunting, it’s just a function that calculates the shortest distance from any point in space to a shape’s surface. The distance is negative for points within the shape, positive for points outside the shape, and zero for points exactly on the surface of the shape.&lt;/p&gt;&lt;p&gt;For example, a circle can be defined by the following function:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdCircle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; point&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;point&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can find functions for various &lt;a href=&quot;https://iquilezles.org/articles/distfunctions2d/&quot;&gt;2D&lt;/a&gt; and &lt;a href=&quot;https://iquilezles.org/articles/distfunctions/&quot;&gt;3D&lt;/a&gt; SDFs on Inigo Quilez’s website. Or use the &lt;a href=&quot;https://github.com/marklundin/glsl-sdf-primitives&quot;&gt;glsl-sdf-primitives&lt;/a&gt; library. I’ll explain how to use these functions later in the article.&lt;/p&gt;&lt;p width=&quot;50%&quot; mx=&quot;auto&quot;&gt;
  &lt;img src=&quot;/baf8094ed68d7efbc78649ba655b5a69/sdf-marching.svg&quot; alt=&quot;&quot;/&gt;
&lt;/p&gt;&lt;p&gt;Back to raymarching. When stepping along the ray, the obvious option is to take a tiny step at a time and check for collisions. But since SDF provides us with the distance to the surface, we know that we can step by that distance without going through the surface. Doing so both speeds up the process and improves accuracy.&lt;/p&gt;&lt;div&gt;🤔 &lt;b&gt;Raytracing vs Raymarching&lt;/b&gt;&lt;br/&gt;Raytracing is a very similar process to raymarching, the key difference is that geometry is typically defined as triangles, spheres, etc. To find the intersection between the view ray and the scene, we conduct a series of geometric intersection tests. For example, does the ray intersect with a triangle and, if so, which part of the triangle.&lt;/div&gt;&lt;h2 id=&quot;implementing-a-raymarched-scene&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#implementing-a-raymarched-scene&quot; aria-label=&quot;implementing a raymarched scene permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Implementing a raymarched scene&lt;/h2&gt;&lt;p&gt;Alright, onto the crystal. Let’s take the technique I shared above and implement it in GLSL. We’ll start with a basic shader scene, add raymarching to it, and then implement lighting and materials.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 dsJevP&quot;&gt;&lt;figure display=&quot;none,none,block&quot; width=&quot;400&quot; class=&quot;sc-24qoga-0 sc-1lreduh-0 MMxMe&quot;&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 iokpeT&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div display=&quot;none,none,block&quot; class=&quot;sc-24qoga-0 sc-1lreduh-1 iDprnf&quot;&gt;&lt;h3 id=&quot;basic-shader-scene&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#basic-shader-scene&quot; aria-label=&quot;basic shader scene permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Basic shader scene&lt;/h3&gt;&lt;p&gt;My goto tool for creative coding is &lt;a href=&quot;https://github.com/mattdesl/canvas-sketch&quot;&gt;canvas-sketch&lt;/a&gt;. It offers a &lt;a href=&quot;https://github.com/mattdesl/canvas-sketch-util/blob/master/docs/shader.md#shader--createshaderopt&quot;&gt;utility function&lt;/a&gt; that creates a full-screen GLSL shader renderer using &lt;a href=&quot;https://regl.party/&quot;&gt;regl&lt;/a&gt;. You can pass in your shader code and uniforms and it takes care of the rest. Here’s an example of a shader that renders a gradient.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; canvasSketch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;canvas-sketch&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; createShader &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;canvas-sketch-util/shader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; glsl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glslify&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; settings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  dimensions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  context&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;webgl&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; frag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;glsl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  precision highp float;

  uniform float time;
  varying vec2 vUv;

  void main () {
    vec3 col = 0.5 + 0.5 * cos(time + vUv.xyx + vec3(0,2,4));
    gl_FragColor = vec4(col, 1.0);
  }
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sketch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; gl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; canvas &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createShader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    gl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    frag&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    uniforms&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; time &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;playhead&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; playhead &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;canvasSketch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sketch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; settings&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Couple of things to note here. &lt;code class=&quot;language-text&quot;&gt;createShader&lt;/code&gt; bootstraps a default vertex shader (see below) that provides a varying &lt;code class=&quot;language-text&quot;&gt;vUv&lt;/code&gt;. This essentially maps the pixel coordinates to a value between 0 and 1. You can override this by specifying a custom vertex shader. But for most cases, this is sufficient.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;vert.glsl&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; position&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  gl_Position &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xyz&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  vUv &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gl_Position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I’m also using a tool called &lt;code class=&quot;language-text&quot;&gt;glslify&lt;/code&gt; to wrap the shader code. This enables us to import GLSL modules into our shader. We’ll use it to import SDF functions and other raymarching utilities.&lt;/p&gt;&lt;h3 id=&quot;the-raymarching-algorithm&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-raymarching-algorithm&quot; aria-label=&quot;the raymarching algorithm permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Raymarching Algorithm&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;lensLength&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;lensLength&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;lensLength&quot; name=&quot;lensLength&quot; value=&quot;0&quot; min=&quot;0.1&quot; max=&quot;4&quot; step=&quot;0.1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Below is an implementation of the ray marching algorithm. The camera is positioned as the &lt;code class=&quot;language-text&quot;&gt;rayOrigin&lt;/code&gt;, and pointed towards the &lt;code class=&quot;language-text&quot;&gt;rayTarget&lt;/code&gt;—the center of the scene.&lt;/p&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;rayDirection&lt;/code&gt; is a vector that points from the origin towards a a pixel on the screen, while accounting for the camera’s orientation and field of view. It requires a bit of fancy math to figure out this direction. We’ll be using the &lt;code class=&quot;language-text&quot;&gt;glsl-camera-ray&lt;/code&gt; module to run that calculation.&lt;/p&gt;&lt;img class=&quot;show-in-both&quot; src=&quot;static/ray-direction-8b0a68215b4c83cd9236ca43e204a9da.svg&quot; alt=&quot;Ray starts at the camera, goes through the pixel on the screen and moves through the scene&quot;/&gt;&lt;p&gt;Once we obtain the ray direction, we proceed along it, checking for collisions. If a collision is detected, the distance to the surface is returned. Otherwise, we return &lt;code class=&quot;language-text&quot;&gt;-1.0&lt;/code&gt; to signify that no collision was found.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; camera &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-camera-ray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdSphere&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; point&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;point&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; steps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; maxdist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; precis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayDir&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; latest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; precis &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; dist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// March along the ray&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; steps&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Break if we&amp;#x27;re close enough or too far away&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;latest &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; precis &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; dist &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; maxdist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Get the SDF distance&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; latest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdSphere&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDir &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Increment by the latest SDF distance&lt;/span&gt;
    dist &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; latest&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// if we&amp;#x27;re still within bounds,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// set the result to the distance&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dist &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; maxdist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Bootstrap a raymarching scene&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// map from 0 to 1 to -1. to 1.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; screenPos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vUv &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;camera&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayTarget&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; screenPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; collision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If the ray collides, draw the surface&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.678&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.106&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.176&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  gl_FragColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;lensLength&lt;/code&gt; here determines the field of view. Try changing it to see how it affects the scene.&lt;/p&gt;&lt;h3 id=&quot;using-glsl-modules-for-raymarching&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#using-glsl-modules-for-raymarching&quot; aria-label=&quot;using glsl modules for raymarching permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Using GLSL modules for raymarching&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;lensLength&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;lensLength&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;lensLength&quot; name=&quot;lensLength&quot; value=&quot;0&quot; min=&quot;0.1&quot; max=&quot;4&quot; step=&quot;0.1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Implementing your own raymarching function is cool. It’s especially useful when you want to tweak the inner workings to achieve a specific effect. However, in most cases, you can probably just use an off-the-shelf module.&lt;/p&gt;&lt;p&gt;Below, I’ve updated the sketch to use the &lt;code class=&quot;language-text&quot;&gt;glsl-raytrace&lt;/code&gt; module. Additionally, I’m using a &lt;code class=&quot;language-text&quot;&gt;glsl-sdf-primitives&lt;/code&gt; module to generate a torus and &lt;code class=&quot;language-text&quot;&gt;glsl-rotate&lt;/code&gt; to rotate it.&lt;/p&gt;&lt;p&gt;The mechanics remain largely similar. The key difference is that geometry is now defined within a function called &lt;code class=&quot;language-text&quot;&gt;doModel&lt;/code&gt;, and raymarch returns a &lt;code class=&quot;language-text&quot;&gt;vec2&lt;/code&gt; containing the distance and material index. This is useful if you want to render multiple types of objects in a scene.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; camera &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-camera-ray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; raymarch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-raytrace&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; map &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; doModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; steps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; sdTorus &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-sdf-primitives/sdTorus&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; rotate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-rotate/rotate&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Spin the shape&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;yz &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;yz&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate SDF distance&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdTorus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.35&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Bootstrap a raytracing scene&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// map from 0 to 1 to -1. to 1.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; screenPos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vUv &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;camera&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayTarget&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; screenPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; collision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If the ray collides, draw the surface&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.678&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.106&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.176&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  gl_FragColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check it out! We’ve got a spinning donut 🍩 But it looks kinda flat. Let’s add some depth to the scene.&lt;/p&gt;&lt;h3 id=&quot;calculating-normals&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#calculating-normals&quot; aria-label=&quot;calculating normals permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Calculating normals&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;For the classic material and lighting combination, we need to calculate surface normals. That is, a vector that points away from the surface at a given point.&lt;/p&gt;&lt;p&gt;With SDFs, we calculate the normal by taking the gradient of the SDF function (f) at a specific point, denoted as ∇f. I don’t know about you, but the last time I took a gradient was in &lt;a href=&quot;https://apps.ualberta.ca/catalogue/course/mec_e/537&quot;&gt;MEC E 537 - Aerodynamics&lt;/a&gt;. And that was a while ago 😅&lt;/p&gt;&lt;p&gt;Luckily for us, we can use the &lt;code class=&quot;language-text&quot;&gt;glsl-sdf-normal&lt;/code&gt; module to compute normals for us. The module uses the same &lt;code class=&quot;language-text&quot;&gt;doModel&lt;/code&gt; function that we defined for raymarching. If you’re curious about the underlying math, check out &lt;a href=&quot;https://jamie-wong.com/2016/07/15/ray-marching-signed-distance-functions/#surface-normals-and-lighting&quot;&gt;Jamie Wong’s explanation&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; normal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-sdf-normal&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; map &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; doModel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Determine the point of collision&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate the normal&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Convert the normal to a color&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;phong-lighting&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#phong-lighting&quot; aria-label=&quot;phong lighting permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Phong lighting&lt;/h3&gt;&lt;p&gt;My personal philosophy is very much:&lt;/p&gt;&lt;img class=&quot;show-in-both&quot; alt=&quot;Fuck around find out&quot; src=&quot;static/fuck-around-find-out-cc2e14bf2895e5634f02f2f2475d8531.jpg&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;It’s important to understand how things work, but I’m less focused on implementing everything from scratch and more intrigued by applying those concepts to create my own sketches and scenes. That’s why I was super excited to come across &lt;a href=&quot;http://stack.gl/packages&quot;&gt;stack.gl/packages&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The stackgl ecosystem is full of little GLSL modules that you can glue these together to create all kinds of effects.&lt;/p&gt;&lt;p&gt;Interested in adding lighting to the scene? What type would you prefer? Lambert, Phong, Beckmann, or Specular? Just grab the associated module and plug it into the scene.&lt;/p&gt;&lt;p&gt;I chose &lt;code class=&quot;language-text&quot;&gt;glsl-specular-blinn-phong&lt;/code&gt;&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; blinnPhongSpec &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-specular-blinn-phong&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; lightPos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; tint &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.97&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// color of the shape&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; collision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// If the ray collides, draw the surface&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Determine the point of collision&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate the normal&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calculate light intensity&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; eyeDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; lightDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightPos &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blinnPhongSpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eyeDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// light intensity * color of the shape&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; tint&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;iridescent-material&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#iridescent-material&quot; aria-label=&quot;iridescent material permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Iridescent material&lt;/h3&gt;&lt;p&gt;Stackgl isn’t the only place where you can find useful code. My other favourite option is Shadertoy. I’m not going to lie, most things on shadertoy were too daunting for me. I couldn’t even begin to figure out what the code was doing.&lt;/p&gt;&lt;p&gt;That is, until I discovered that most work on shadertoy uses a combo of raymarching + SDF. This was certainly a lightbulb moment for me. It’s like suddenly this cryptic code was deciphered and I could understand what it said.&lt;/p&gt;&lt;p&gt;I’ve been obsessed with iridescence and have been bookmarking cool shaders. Once I learnt the raymarching technique, that was it. I could revisit these shaders and try to understand how they work.&lt;/p&gt;&lt;p&gt;One such shader was &lt;a href=&quot;https://www.shadertoy.com/view/llcXWM&quot;&gt;Thomas Hooper’s Crystals&lt;/a&gt;. It’s way more complex than our scene but the general structure is the same. There’s a function for generating the geometry, there’s raymarching loop and after checking for collision is the bit where the iridescence effect is applied.&lt;/p&gt;&lt;p&gt;Let’s add that to our scene.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;activeLayers&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;activeLayers&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;activeLayers&quot; name=&quot;activeLayers&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;3&quot; step=&quot;1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; d &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6.28318&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;t&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;spectrum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.33&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.67&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; GAMMA &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;gamma&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linearToScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; linearRGB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;gamma&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;linearRGB&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; GAMMA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Determine the point of collision&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; eyeDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; lightDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightPos &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Iridescent lighting&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; reflection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reflect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; dome &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// base layer&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; perturb &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;spectrum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nor &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; perturb &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eyeDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// specular&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; specular &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reflection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lightDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  specular &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;specular &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; specular&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  specular &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  specular &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reflection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lightDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// shadow&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dome&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; specular&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// gamma correction&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linearToScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are three layers to the iridescent material: the base layer (the funky gradients), a little bit of shadow and specular (the concentric light bands). Try toggling them on and off with the slider see their effects.&lt;/p&gt;&lt;h3 id=&quot;mix-phong-and-iridescence&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#mix-phong-and-iridescence&quot; aria-label=&quot;mix phong and iridescence permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Mix Phong and Iridescence&lt;/h3&gt;&lt;p&gt;One last little tweak with the lighting. We can actually blend the phong and iridescence effects. Which enables you to have tinted iridescent objects.&lt;/p&gt;&lt;p&gt;There’s not a whole lot to it. Calculate the colors for the two effects and then blend them with the &lt;code class=&quot;language-text&quot;&gt;mix&lt;/code&gt; function.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;mixBaseAndIridescent&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;mixBaseAndIridescent&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;mixBaseAndIridescent&quot; name=&quot;mixBaseAndIridescent&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;1&quot; step=&quot;0.1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Basic blinn phong lighting&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blinnPhongSpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eyeDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; baseColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; tint&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Iridescent lighting&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; specular&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// mix blinn phong lighting and iridescent lighting&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;baseColor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mixBaseAndIridescent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// gamma correction&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linearToScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;crystal-geometry&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#crystal-geometry&quot; aria-label=&quot;crystal geometry permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Crystal geometry&lt;/h3&gt;&lt;p&gt;We’ve nailed the look, but what about the crystal shape?&lt;/p&gt;&lt;p&gt;You can file this under “stuff I don’t quite understand, but that’s not going to stop me from using it.” The crystal geometry is a Rhombic Triacontahedron, which I discovered in a &lt;a href=&quot;https://www.youtube.com/watch?v=0RWaR7zApEo&amp;amp;t=50s&quot;&gt;The Art Of Code tutorial&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;constructionStep&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;constructionStep&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;constructionStep&quot; name=&quot;constructionStep&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;3&quot; step=&quot;1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This shape is created by folding a plane onto itself using some “magic numbers” and along a “magic direction.” We repeat the process a few times until we achieve the desired crystal shape.&lt;/p&gt;&lt;p&gt;Try using the slider to observe how the shape changes with each fold.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdCrystal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3.1415&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// magic numbers&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// magic direction&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// fold the space to add symmetry&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// fold along the n direction&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// fold the space again and along the n direction&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// repeat the process&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// distance to the surface&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;z &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div display=&quot;block,block,none&quot; class=&quot;sc-24qoga-0 rdEeX&quot;&gt;&lt;h3 id=&quot;basic-shader-scene&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#basic-shader-scene&quot; aria-label=&quot;basic shader scene permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Basic shader scene&lt;/h3&gt;&lt;p&gt;My goto tool for creative coding is &lt;a href=&quot;https://github.com/mattdesl/canvas-sketch&quot;&gt;canvas-sketch&lt;/a&gt;. It offers a &lt;a href=&quot;https://github.com/mattdesl/canvas-sketch-util/blob/master/docs/shader.md#shader--createshaderopt&quot;&gt;utility function&lt;/a&gt; that creates a full-screen GLSL shader renderer using &lt;a href=&quot;https://regl.party/&quot;&gt;regl&lt;/a&gt;. You can pass in your shader code and uniforms and it takes care of the rest. Here’s an example of a shader that renders a gradient.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; canvasSketch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;canvas-sketch&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; createShader &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;canvas-sketch-util/shader&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; glsl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glslify&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; settings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  dimensions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1080&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  context&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;webgl&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; frag &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;glsl&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  precision highp float;

  uniform float time;
  varying vec2 vUv;

  void main () {
    vec3 col = 0.5 + 0.5 * cos(time + vUv.xyx + vec3(0,2,4));
    gl_FragColor = vec4(col, 1.0);
  }
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sketch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; gl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; canvas &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createShader&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    gl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    frag&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    uniforms&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;resolution&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;time&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; time &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;playhead&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; playhead &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;canvasSketch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sketch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; settings&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Couple of things to note here. &lt;code class=&quot;language-text&quot;&gt;createShader&lt;/code&gt; bootstraps a default vertex shader (see below) that provides a varying &lt;code class=&quot;language-text&quot;&gt;vUv&lt;/code&gt;. This essentially maps the pixel coordinates to a value between 0 and 1. You can override this by specifying a custom vertex shader. But for most cases, this is sufficient.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;vert.glsl&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;attribute&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; position&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  gl_Position &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xyz&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  vUv &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; gl_Position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I’m also using a tool called &lt;code class=&quot;language-text&quot;&gt;glslify&lt;/code&gt; to wrap the shader code. This enables us to import GLSL modules into our shader. We’ll use it to import SDF functions and other raymarching utilities.&lt;/p&gt;&lt;h3 id=&quot;the-raymarching-algorithm&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-raymarching-algorithm&quot; aria-label=&quot;the raymarching algorithm permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Raymarching Algorithm&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;lensLength&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;lensLength&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;lensLength&quot; name=&quot;lensLength&quot; value=&quot;0&quot; min=&quot;0.1&quot; max=&quot;4&quot; step=&quot;0.1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Below is an implementation of the ray marching algorithm. The camera is positioned as the &lt;code class=&quot;language-text&quot;&gt;rayOrigin&lt;/code&gt;, and pointed towards the &lt;code class=&quot;language-text&quot;&gt;rayTarget&lt;/code&gt;—the center of the scene.&lt;/p&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;rayDirection&lt;/code&gt; is a vector that points from the origin towards a a pixel on the screen, while accounting for the camera’s orientation and field of view. It requires a bit of fancy math to figure out this direction. We’ll be using the &lt;code class=&quot;language-text&quot;&gt;glsl-camera-ray&lt;/code&gt; module to run that calculation.&lt;/p&gt;&lt;img class=&quot;show-in-both&quot; src=&quot;static/ray-direction-8b0a68215b4c83cd9236ca43e204a9da.svg&quot; alt=&quot;Ray starts at the camera, goes through the pixel on the screen and moves through the scene&quot;/&gt;&lt;p&gt;Once we obtain the ray direction, we proceed along it, checking for collisions. If a collision is detected, the distance to the surface is returned. Otherwise, we return &lt;code class=&quot;language-text&quot;&gt;-1.0&lt;/code&gt; to signify that no collision was found.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; camera &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-camera-ray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdSphere&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; point&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;point&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; steps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; maxdist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; precis &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayDir&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; latest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; precis &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; dist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// March along the ray&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;int&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; steps&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Break if we&amp;#x27;re close enough or too far away&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;latest &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; precis &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; dist &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; maxdist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Get the SDF distance&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; latest &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdSphere&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDir &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Increment by the latest SDF distance&lt;/span&gt;
    dist &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; latest&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// if we&amp;#x27;re still within bounds,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// set the result to the distance&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;dist &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; maxdist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    res &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; res&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Bootstrap a raymarching scene&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// map from 0 to 1 to -1. to 1.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; screenPos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vUv &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;camera&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayTarget&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; screenPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; collision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If the ray collides, draw the surface&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.678&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.106&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.176&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  gl_FragColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;lensLength&lt;/code&gt; here determines the field of view. Try changing it to see how it affects the scene.&lt;/p&gt;&lt;h3 id=&quot;using-glsl-modules-for-raymarching&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#using-glsl-modules-for-raymarching&quot; aria-label=&quot;using glsl modules for raymarching permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Using GLSL modules for raymarching&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;lensLength&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;lensLength&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;lensLength&quot; name=&quot;lensLength&quot; value=&quot;0&quot; min=&quot;0.1&quot; max=&quot;4&quot; step=&quot;0.1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Implementing your own raymarching function is cool. It’s especially useful when you want to tweak the inner workings to achieve a specific effect. However, in most cases, you can probably just use an off-the-shelf module.&lt;/p&gt;&lt;p&gt;Below, I’ve updated the sketch to use the &lt;code class=&quot;language-text&quot;&gt;glsl-raytrace&lt;/code&gt; module. Additionally, I’m using a &lt;code class=&quot;language-text&quot;&gt;glsl-sdf-primitives&lt;/code&gt; module to generate a torus and &lt;code class=&quot;language-text&quot;&gt;glsl-rotate&lt;/code&gt; to rotate it.&lt;/p&gt;&lt;p&gt;The mechanics remain largely similar. The key difference is that geometry is now defined within a function called &lt;code class=&quot;language-text&quot;&gt;doModel&lt;/code&gt;, and raymarch returns a &lt;code class=&quot;language-text&quot;&gt;vec2&lt;/code&gt; containing the distance and material index. This is useful if you want to render multiple types of objects in a scene.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; camera &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-camera-ray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; raymarch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-raytrace&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; map &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; doModel&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; steps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; sdTorus &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-sdf-primitives/sdTorus&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; rotate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-rotate/rotate&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;doModel&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Spin the shape&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;yz &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;rotate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;yz&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate SDF distance&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdTorus&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.35&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Bootstrap a raytracing scene&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayTarget &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// map from 0 to 1 to -1. to 1.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; screenPos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vUv &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;camera&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayTarget&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; screenPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lensLength&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; collision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// If the ray collides, draw the surface&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.678&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.106&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.176&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  gl_FragColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check it out! We’ve got a spinning donut 🍩 But it looks kinda flat. Let’s add some depth to the scene.&lt;/p&gt;&lt;h3 id=&quot;calculating-normals&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#calculating-normals&quot; aria-label=&quot;calculating normals permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Calculating normals&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;For the classic material and lighting combination, we need to calculate surface normals. That is, a vector that points away from the surface at a given point.&lt;/p&gt;&lt;p&gt;With SDFs, we calculate the normal by taking the gradient of the SDF function (f) at a specific point, denoted as ∇f. I don’t know about you, but the last time I took a gradient was in &lt;a href=&quot;https://apps.ualberta.ca/catalogue/course/mec_e/537&quot;&gt;MEC E 537 - Aerodynamics&lt;/a&gt;. And that was a while ago 😅&lt;/p&gt;&lt;p&gt;Luckily for us, we can use the &lt;code class=&quot;language-text&quot;&gt;glsl-sdf-normal&lt;/code&gt; module to compute normals for us. The module uses the same &lt;code class=&quot;language-text&quot;&gt;doModel&lt;/code&gt; function that we defined for raymarching. If you’re curious about the underlying math, check out &lt;a href=&quot;https://jamie-wong.com/2016/07/15/ray-marching-signed-distance-functions/#surface-normals-and-lighting&quot;&gt;Jamie Wong’s explanation&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; normal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-sdf-normal&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; map &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; doModel&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Determine the point of collision&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate the normal&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Convert the normal to a color&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;phong-lighting&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#phong-lighting&quot; aria-label=&quot;phong lighting permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Phong lighting&lt;/h3&gt;&lt;p&gt;My personal philosophy is very much:&lt;/p&gt;&lt;img class=&quot;show-in-both&quot; alt=&quot;Fuck around find out&quot; src=&quot;static/fuck-around-find-out-cc2e14bf2895e5634f02f2f2475d8531.jpg&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;It’s important to understand how things work, but I’m less focused on implementing everything from scratch and more intrigued by applying those concepts to create my own sketches and scenes. That’s why I was super excited to come across &lt;a href=&quot;http://stack.gl/packages&quot;&gt;stack.gl/packages&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The stackgl ecosystem is full of little GLSL modules that you can glue these together to create all kinds of effects.&lt;/p&gt;&lt;p&gt;Interested in adding lighting to the scene? What type would you prefer? Lambert, Phong, Beckmann, or Specular? Just grab the associated module and plug it into the scene.&lt;/p&gt;&lt;p&gt;I chose &lt;code class=&quot;language-text&quot;&gt;glsl-specular-blinn-phong&lt;/code&gt;&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; blinnPhongSpec &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;glsl-specular-blinn-phong&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; lightPos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; tint &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.97&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// color of the shape&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; collision &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;raymarch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rayDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// If the ray collides, draw the surface&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Determine the point of collision&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate the normal&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calculate light intensity&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; eyeDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; lightDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightPos &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blinnPhongSpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eyeDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// light intensity * color of the shape&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; tint&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;iridescent-material&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#iridescent-material&quot; aria-label=&quot;iridescent material permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Iridescent material&lt;/h3&gt;&lt;p&gt;Stackgl isn’t the only place where you can find useful code. My other favourite option is Shadertoy. I’m not going to lie, most things on shadertoy were too daunting for me. I couldn’t even begin to figure out what the code was doing.&lt;/p&gt;&lt;p&gt;That is, until I discovered that most work on shadertoy uses a combo of raymarching + SDF. This was certainly a lightbulb moment for me. It’s like suddenly this cryptic code was deciphered and I could understand what it said.&lt;/p&gt;&lt;p&gt;I’ve been obsessed with iridescence and have been bookmarking cool shaders. Once I learnt the raymarching technique, that was it. I could revisit these shaders and try to understand how they work.&lt;/p&gt;&lt;p&gt;One such shader was &lt;a href=&quot;https://www.shadertoy.com/view/llcXWM&quot;&gt;Thomas Hooper’s Crystals&lt;/a&gt;. It’s way more complex than our scene but the general structure is the same. There’s a function for generating the geometry, there’s raymarching loop and after checking for collision is the bit where the iridescence effect is applied.&lt;/p&gt;&lt;p&gt;Let’s add that to our scene.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;activeLayers&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;activeLayers&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;activeLayers&quot; name=&quot;activeLayers&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;3&quot; step=&quot;1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; a&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; d &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6.28318&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;t&lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;spectrum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.33&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.67&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; GAMMA &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;gamma&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linearToScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; linearRGB&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;gamma&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;linearRGB&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; GAMMA&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Determine the point of collision&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; rayOrigin &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; rayDirection &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; nor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; eyeDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayOrigin &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; lightDirection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightPos &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; pos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Iridescent lighting&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; reflection &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reflect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rayDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; dome &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// base layer&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; perturb &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pos &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;spectrum&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nor &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; perturb &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eyeDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// specular&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; specular &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reflection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lightDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  specular &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;specular &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20.&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; specular&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  specular &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  specular &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;reflection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; lightDirection&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// shadow&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clamp&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dome&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; specular&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// gamma correction&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linearToScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are three layers to the iridescent material: the base layer (the funky gradients), a little bit of shadow and specular (the concentric light bands). Try toggling them on and off with the slider see their effects.&lt;/p&gt;&lt;h3 id=&quot;mix-phong-and-iridescence&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#mix-phong-and-iridescence&quot; aria-label=&quot;mix phong and iridescence permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Mix Phong and Iridescence&lt;/h3&gt;&lt;p&gt;One last little tweak with the lighting. We can actually blend the phong and iridescence effects. Which enables you to have tinted iridescent objects.&lt;/p&gt;&lt;p&gt;There’s not a whole lot to it. Calculate the colors for the two effects and then blend them with the &lt;code class=&quot;language-text&quot;&gt;mix&lt;/code&gt; function.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;mixBaseAndIridescent&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;mixBaseAndIridescent&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;mixBaseAndIridescent&quot; name=&quot;mixBaseAndIridescent&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;1&quot; step=&quot;0.1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;collision&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Basic blinn phong lighting&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;blinnPhongSpec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lightDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; eyeDirection&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; nor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; baseColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; power &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; tint&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Iridescent lighting&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; shadow &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; specular&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// mix blinn phong lighting and iridescent lighting&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;baseColor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; mixBaseAndIridescent&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// gamma correction&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;linearToScreen&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;crystal-geometry&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#crystal-geometry&quot; aria-label=&quot;crystal geometry permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Crystal geometry&lt;/h3&gt;&lt;p&gt;We’ve nailed the look, but what about the crystal shape?&lt;/p&gt;&lt;p&gt;You can file this under “stuff I don’t quite understand, but that’s not going to stop me from using it.” The crystal geometry is a Rhombic Triacontahedron, which I discovered in a &lt;a href=&quot;https://www.youtube.com/watch?v=0RWaR7zApEo&amp;amp;t=50s&quot;&gt;The Art Of Code tutorial&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 jJuLIG&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;constructionStep&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;constructionStep&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;constructionStep&quot; name=&quot;constructionStep&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;3&quot; step=&quot;1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This shape is created by folding a plane onto itself using some “magic numbers” and along a “magic direction.” We repeat the process a few times until we achieve the desired crystal shape.&lt;/p&gt;&lt;p&gt;Try using the slider to observe how the shape changes with each fold.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sdCrystal&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3.1415&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sqrt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;c&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// magic numbers&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// magic direction&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// fold the space to add symmetry&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// fold along the n direction&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// fold the space again and along the n direction&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// repeat the process&lt;/span&gt;
  p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;xy&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  p &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dot&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; n&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;n&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// distance to the surface&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;z &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;and-thats-that&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#and-thats-that&quot; aria-label=&quot;and thats that permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;And that’s that!&lt;/h2&gt;&lt;p&gt;Raymarching with SDF isn’t better than the conventional mesh based approach; it’s just different. However, it offers the ability to create unique and visually striking effects, making it a fantastic tool to have in your creative coding toolbox. Plus, with glslify and the &lt;a href=&quot;http://stack.gl/packages&quot;&gt;stack.gl ecosystem&lt;/a&gt; you can use off-the-shelf modules to get going quickly.&lt;/p&gt;&lt;p&gt;Checkout the &lt;a href=&quot;https://github.com/winkerVSbecks/shader-sketches/blob/main/sketches/sdf-iridescent-crystal.js&quot;&gt;full source&lt;/a&gt; for the crystal sketch on Github. Want to take it a step further? I’ve expanded this sketch to combine refraction and iridescence to make a &lt;a href=&quot;https://github.com/winkerVSbecks/shader-sketches/blob/main/sketches/refraction-iridescent.js&quot;&gt;see through crystal&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&quot;reference&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#reference&quot; aria-label=&quot;reference permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Reference&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://jasmcole.com/2019/10/03/signed-distance-fields/&quot;&gt;Signed distance fields by Jason Cole&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://iquilezles.org/articles/distfunctions/&quot;&gt;3D distance functions by Inigo Quilez&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.shadertoy.com/view/ldfSWs&quot;&gt;Raymarching template&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://youtu.be/NCpaaLkmXI8&quot;&gt;Bending Light by The Art of Code (part 1)&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://youtu.be/0RWaR7zApEo&quot;&gt;part 2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How we built the Storybook Day 3D animation]]></title><description><![CDATA[Storybook just hit a major milestone: version 7.0! With a re-engineered codebase and bunch of new features, it's faster and more stable than…]]></description><link>https://varun.ca/storybook-day/</link><guid isPermaLink="false">https://varun.ca/storybook-day/</guid><pubDate>Thu, 20 Apr 2023 00:00:00 GMT</pubDate><content:encoded>&lt;div name=&quot;Storybook Day&quot; link=&quot;https://storybook.js.org/day&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/storybook-7-c40553eb95e445310a25c05b6afbdab5.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Storybook just hit a major milestone: version 7.0! With a re-engineered codebase and bunch of new features, it’s faster and more stable than ever before. To celebrate, the team hosted their first ever user conference—&lt;a href=&quot;https://storybook.js.org/day&quot;&gt;Storybook Day&lt;/a&gt;. And to make things even more special, we decided to add a visually stunning 3D element to the event landing page.&lt;/p&gt;&lt;p&gt;We used React Three Fiber (R3F) to build an eye-catching 3D illustration, inspired by Storybook’s Tetris blocks branding. In this article, we’ll dive into the nitty-gritty of shipping a 3D scene. Here’s what I’ll cover:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;🏗️ Avoid object overlap with sphere packing&lt;/li&gt;&lt;li&gt;🧱 Model Tetris blocks with extrusion&lt;/li&gt;&lt;li&gt;🎥 Enhance visuals with effects like depth of field and shadows&lt;/li&gt;&lt;li&gt;🏎️ Optimize performance by reducing material count&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;ℹ️ This post assumes foundational knowledge of React Three Fiber. If you&amp;#x27;re new to 3D or not familiar with the R3F API, check out my &lt;a href=&quot;/modular-webgl/&quot;&gt;intro post&lt;/a&gt; for a primer.&lt;/div&gt;&lt;h2 id=&quot;our-strategy&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#our-strategy&quot; aria-label=&quot;our strategy permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Our strategy&lt;/h2&gt;&lt;p&gt;We built the event site using NextJS and &lt;a href=&quot;https://github.com/pmndrs/react-three-fiber&quot;&gt;@react-three/fiber&lt;/a&gt;, with a little help from &lt;a href=&quot;https://github.com/pmndrs/drei&quot;&gt;@react-three/drei&lt;/a&gt;. The animation features floating Tetris blocks surrounding “7.0” extruded text.&lt;/p&gt;&lt;p&gt;Here’s an MVP in code.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h2 id=&quot;the-details&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-details&quot; aria-label=&quot;the details permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Details&lt;/h2&gt;&lt;p&gt;On to the fun stuff. Notice how the blocks are randomly spread across the scene and sometimes overlap with the text or each other. It would be aesthetically more pleasing if the blocks had no overlap. That’s one example of little adjustments we made to take this scene from MVP to production ready. Let’s dive into these techniques.&lt;/p&gt;&lt;h3 id=&quot;sphere-packing-to-place-blocks&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#sphere-packing-to-place-blocks&quot; aria-label=&quot;sphere packing to place blocks permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Sphere packing to place blocks&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/mattdesl/pack-spheres&quot;&gt;pack-sphere&lt;/a&gt; library enabled us to evenly distribute the blocks and prevent any potential overlapping issues. This library employs a brute force approach to arrange spheres of varying radii within a cube.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; spheres &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  maxCount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  minRadius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.125&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  maxRadius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We then scaled the spheres to fit our scene space and stretched them horizontally along the x-axis. Lastly, we placed a block at the center of each sphere, scaled to the sphere’s radius.&lt;/p&gt;&lt;p&gt;That gave us a nice spread of blocks, with a satisfying mix of size and placement.&lt;/p&gt;&lt;div name=&quot;Sphere packing to spread out blocks&quot; link=&quot;https://github.com/storybookjs/storybook-day/blob/main/components/BlocksScene/BlocksScene.tsx#L22&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/sphere-packing-b3000e9c6c626add63eb17e7f3fbff38.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To fix the overlap between the “7.0” text and the blocks, a different approach was needed. Initially, we thought of using pack-sphere to detect collisions between the spheres and the text geometry. However, we ended up opting for a simpler solution: slightly shifting the spheres along the z-axis.&lt;/p&gt;&lt;p&gt;The text essentially parts the sea of blocks.&lt;/p&gt;&lt;div name=&quot;Z axis offset to prevent overlapping with text&quot; link=&quot;https://github.com/storybookjs/storybook-day/blob/main/components/BlocksScene/BlocksScene.tsx#L36&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/z-offset-db8f51771ea86b8421648d55f0036ed0.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Here’s the entire process, in code:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Sphere packing&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; spheres &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  maxCount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  minRadius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.125&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  maxRadius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;sphere&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; inFront &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;sphere&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    position&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// offset to avoid overlapping with the 7.0 text&lt;/span&gt;
      inFront &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// stretch horizontally&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; scale &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; blocks &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; spheres&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;sphere&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;sphere&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  id&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// scale position to scene space&lt;/span&gt;
  position&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;v&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; v &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; scale&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// scale radius to scene space&lt;/span&gt;
  size&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; sphere&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; size &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;pick&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;blockTypes&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  rotation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Quaternion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;quaternion&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;extrusion-to-model-tetris-blocks&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#extrusion-to-model-tetris-blocks&quot; aria-label=&quot;extrusion to model tetris blocks permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Extrusion to model tetris blocks&lt;/h3&gt;&lt;p&gt;You may have noticed that we’ve only used primitive blocks so far. Hey, no hating on primitives, but Storybook branding uses tetris-style blocks, so we had to add those into the mix.&lt;/p&gt;&lt;p&gt;The concept of &lt;a href=&quot;https://threejs.org/docs/#api/en/geometries/ExtrudeGeometry&quot;&gt;ExtrudeGeometry&lt;/a&gt; in Three.js is quite interesting. You can supply it with a 2D shape using a syntax similar to SVG path or CSS shapes, and it’ll extrude it along the z-axis. This feature is perfect for creating Tetris blocks.&lt;/p&gt;&lt;div name=&quot;Extrude a tetris block&quot; link=&quot;https://github.com/storybookjs/storybook-day/blob/main/components/BlocksScene/TetrisBlock.tsx&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/extrude-385701a9f2f9936ec8f1b974118cfa94.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Drei’s Extrude utility offers a relatively straightforward syntax for creating such shapes. Here’s an example of how we generated the “T” block:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useMemo &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;THREE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;three&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Extrude &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;@react-three/drei&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EXTRUDE_SETTINGS&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  steps&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  depth&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5625&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bevelEnabled&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;TBlock&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; shape &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; _shape &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Shape&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;moveTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    _shape&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;lineTo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;SIDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; _shape&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Extrude args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;EXTRUDE_SETTINGS&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meshPhongMaterial color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Extrude&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, we layered on shadows and depth of field effect to add some oomph.&lt;/p&gt;&lt;h3 id=&quot;shadows&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#shadows&quot; aria-label=&quot;shadows permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Shadows&lt;/h3&gt;&lt;p&gt;Shadows bring scenes to life by adding depth and realism. You can configure lights and meshes within the scene to cast shadows using the &lt;a href=&quot;https://threejs.org/docs/#api/en/lights/DirectionalLight.castShadow&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;castShadow&lt;/code&gt;&lt;/a&gt; prop. However, we were looking for a softer look, so once again we reached for Drei, which offers a convenient contact shadows component.&lt;/p&gt;&lt;p&gt;Contact shadows are a “fake shadow” effect. They’re generated by filming the scene from below and rendering the shadow onto a catcher plane. The shadow is accumulated over several frames, making it softer and more realistic.&lt;/p&gt;&lt;p&gt;To use it, add the &lt;code class=&quot;language-text&quot;&gt;ContactShadows&lt;/code&gt; component to the scene. Then customize the look by adjusting the resolution, opacity, blur, color, and other properties.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h3 id=&quot;depth-of-field-effect&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#depth-of-field-effect&quot; aria-label=&quot;depth of field effect permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Depth of field effect&lt;/h3&gt;&lt;p&gt;At this stage, every object in the scene is rendered with the same sharpness, making the scene appear somewhat flat. Photographers, often use wide apertures and shallow depth of field to create a pleasing blurred aesthetic. We mimicked this effect by applying post-processing effects—using &lt;a href=&quot;https://docs.pmnd.rs/react-postprocessing/introduction&quot;&gt;@react-three/postprocessing&lt;/a&gt;—to our scene, giving it a more cinematic feel.&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://pmndrs.github.io/postprocessing/public/docs/class/src/core/EffectComposer.js~EffectComposer.html&quot;&gt;EffectComposer&lt;/a&gt; manages and runs post-processing passes. It begins by rendering the scene to a buffer and then applies filters and effects one at a time before rendering the final image onto the screen.&lt;/p&gt;&lt;h4 id=&quot;picking-a-focus-distance&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#picking-a-focus-distance&quot; aria-label=&quot;picking a focus distance permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Picking a focus distance&lt;/h4&gt;&lt;p&gt;With the DepthOfField effect, you can pinpoint a specific distance (&lt;code class=&quot;language-text&quot;&gt;focusDistance&lt;/code&gt;) within your scene and make everything else beautifully blurry. But how do you define the focus distance? Is it measured in world units or something else?&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Canvas &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;@react-three/fiber&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; EffectComposer&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; DepthOfField &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;@react-three/postprocessing&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Scene&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Canvas&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* Rest of Our scene */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;EffectComposer multisampling&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;DepthOfField focusDistance&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; bokehScale&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; focalLength&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;EffectComposer&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Canvas&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The camera’s view is defined by a pyramid-shaped volume called the “view frustum.” Objects within the minimum (near plane) and maximum (far plane) distances from the camera will be rendered.&lt;/p&gt;&lt;figure px=&quot;4&quot;&gt;
  &lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:594px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:79.8611111111111%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;319\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20319\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M278%2061c-2%203-2%204%201%202%201-1%201%201%201%209v10l-6-5-6-5%204-4%204-4-5%203c-4%204-4%204-5%202l-3-2%201%202%202%203-3%202-2%204%203-3%203-2%203%202%206%206%204%203v64l4%204c6%204%206%204-5%208l-9%204-8-12-9-12%205%208c4%206%204%207%203%208s-1%201%201%201%206%205%206%207l-18%208-5%202-4-4-4-3-37-31c-2-2-2-2%201-5l3-4c-2%200-16%2013-16%2014l4-3%204-3v52l3%203%203%202-3%201a26388%2026388%200%2000-119%2048l-4%202c-3%202-4%201-2-1l1-3-4%204-4%203-1-49v-49c0-2-3%201-3%202l1%201c1-1%201%2016%201%2048v50l9%206%209%206-8-6-7-6h5l58-6%208-1%2010%2010c5%206%2010%2010%2010%209l-8-9-9-9%20102-10%203%208%203%2010%2031-2c24-2%2030-2%2031-1l3%209%202%208%201-1-4-17a505%20505%200%200153-6l-2-10-3-10v-94l-39-33c-47-39-42-36-45-33m-80%20100l1%2024v1c-1%201%200%202%202%203l2%202%2020-8%2020-9-43-36c-2-1-2%200-2%2023m83%200l-9%204v2l2%201c1-1%204%200%208%201l6%202v10l1%2012h-1c-2-1-2%200-5%205-3%208-4%209-4%203l-1-11c0-6%200-6-9-10-6-2-6-2-1-6%204-4%204-5%203-6-2-2-2-2-13%202l-12%205v28l1%2028%20112-10c1-1-68-63-69-64l-9%204m-57%2023l-20%208%209%208%2019%2019%2012%2010v-53l-20%208m74%209c-8%205-8%204%204%208l8%202v5l1%2010%201%204%205-8c6-9%207-10%205-18%200-5%200-5-5-6-11-2-12-2-19%203m-132%2015l-36%2015%204%206a245%20245%200%200031-8c1%200%202%200%202%204%200%202%200%202-1%201%200-4-1-4-17%201-16%204-18%205-12%2011l4%203%2050-5%2051-5c1-1-38-37-40-38l-36%2015m137%2020l-57%205%205%2017a1287%201287%200%2000114-14%20292%20292%200%2001-5-14l-57%206m-199%205l-22%2010%2050-13-4-6-24%209m12%203l-27%207c-14%203-12%204%2015%201%2021-2%2026-3%2028-7v-6l-16%205\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;View Frustum this is a pyramid which has 2 clipping planes. Objects or parts of objects found outside the frustum, won&amp;#x27;t be rendered&quot; title=&quot;View Frustum this is a pyramid which has 2 clipping planes. Objects or parts of objects found outside the frustum, won&amp;#x27;t be rendered&quot; src=&quot;/static/7fdfb6ee3c2b24cdf6025b71b1772d08/5fd3e/viewport-3d-scene.png&quot; srcSet=&quot;/static/7fdfb6ee3c2b24cdf6025b71b1772d08/477c9/viewport-3d-scene.png 288w,/static/7fdfb6ee3c2b24cdf6025b71b1772d08/533c1/viewport-3d-scene.png 576w,/static/7fdfb6ee3c2b24cdf6025b71b1772d08/5fd3e/viewport-3d-scene.png 594w&quot; sizes=&quot;(max-width: 594px) 100vw, 594px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;
  &lt;figcaption&gt;
    &lt;a href=&quot;https://obviam.net/posts/2011/06.3d-perspective-projections/&quot;&gt;
      From: Intro to 3D Programming - Perspective Projections
    &lt;/a&gt;
  &lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;focusDistance&lt;/code&gt; parameter determines the distance from the camera at which objects are considered in focus. Its value is normalized between 0 and 1, where 0 represents the near plane of the camera and 1 represents the far plane.&lt;/p&gt;&lt;div name=&quot;Where to focus within the scene&quot; link=&quot;https://github.com/storybookjs/storybook-day/blob/main/components/BlocksScene/BlocksScene.tsx#L97&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/focus-distance-6c943f963fc798e4980eb000cb85f632.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We set the focus distance to 0.5, which is where the text is located. Objects closer to that threshold will be in focus, while those farther away will be blurred. Try adjusting the &lt;code class=&quot;language-text&quot;&gt;focusDistance&lt;/code&gt; slider in the sandbox below to see how it affects the scene.&lt;/p&gt;&lt;p&gt;You can also further customize this effect by adjusting the &lt;code class=&quot;language-text&quot;&gt;bokehScale&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;focalLength&lt;/code&gt; props.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h3 id=&quot;using-a-material-store-for-performance-optimization&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#using-a-material-store-for-performance-optimization&quot; aria-label=&quot;using a material store for performance optimization permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Using a material store for performance optimization&lt;/h3&gt;&lt;p&gt;Although shadows and depth of field are cool visual effects, they can be quite expensive to render and have a significant impact on performance. Seeking some advice on this topic, I reached out to &lt;a href=&quot;https://twitter.com/0xca0a&quot;&gt;Paul Henschel aka @0xca0a&lt;/a&gt;. Among several perf optimizations, they suggested using a material store to avoid creating a new material instance for each block. Let’s take a closer look at how this works.&lt;/p&gt;&lt;p&gt;The Block component uses the &lt;code class=&quot;language-text&quot;&gt;color&lt;/code&gt; prop to create a unique material for every instance. For example, every orange coloured block will have its own material instance. Pretty wasteful, right?&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Block&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlockProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Component &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BLOCK_TYPES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shape
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Component args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;BLOCK_TYPES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;args &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; any&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; castShadow&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meshPhongMaterial color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Component&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By using a material store, we could reuse the same material across multiple block instances. This improved performance by reducing the number of materials that need to be created and rendered.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;src/components/BlocksScene/store.tsx&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;THREE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;three&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token constant&quot;&gt;THREE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ColorManagement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;legacyMode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; colors&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#FC521F&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#CA90FF&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#1EA7FD&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#FFAE00&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#37D5D3&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#FC521F&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#66BF3C&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#0AB94F&amp;#x27;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;interface&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Materials&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;THREE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MeshPhongMaterial&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; materials&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Materials &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;acc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;acc&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;MeshPhongMaterial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; color &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; materials &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The store generates a material for every possible block color and stores it in a plain object. Now, instead of creating a material for each instance, the block component simply references it from the material store. We went from 40 materials to 8.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Block&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; BlockProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Component &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;BLOCK_TYPES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;shape&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Component
      args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;OTHER_TYPES&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;type &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; OtherBlockType&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;args &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; any&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      material&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;materials&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;wrap-up&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#wrap-up&quot; aria-label=&quot;wrap up permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Wrap up&lt;/h2&gt;&lt;p&gt;3D is now part of the web’s grain, and R3F is a fantastic tool for intertwining HTML and WebGL. The R3F ecosystem is rich, and libraries like drei and postprocessing simplify complex 3D tasks. The Storybook Day 3D scene perfectly showcases the platform’s possibilities. We used sphere packing, extrusion, shadows, depth of field, and a material store to create an memorable event landing page.&lt;/p&gt;&lt;p&gt;In deconstructing this scene, I aimed to shed light on the final 20% of work that elevates a scene from “done” to “ready to ship”. If you have any questions or feedback, feel free to reach out via &lt;a href=&quot;https://twitter.com/winkerVSbecks&quot;&gt;twitter&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Want to dive in deeper? The code is open-source and each aspect of the scene is broken down in the deployed Storybook.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;👨🏽‍💻 &lt;a href=&quot;https://github.com/storybookjs/storybook-day/tree/main/components/BlocksScene&quot;&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;&lt;li&gt;📚 &lt;a href=&quot;https://main--6383d84cd73a2a81d33248b2.chromatic.com&quot;&gt;Deployed Storybook&lt;/a&gt;&lt;/li&gt;&lt;li&gt;🌏 &lt;a href=&quot;https://storybook.js.org/day&quot;&gt;Live site&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Three ways to create 3D particle effects]]></title><description><![CDATA[Particles will never not be cool! I've been obsessed with them since the day I was introduced to generative art. They're super versatile…]]></description><link>https://varun.ca/three-js-particles/</link><guid isPermaLink="false">https://varun.ca/three-js-particles/</guid><pubDate>Sat, 08 Jan 2022 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;Particles will never not be cool! I’ve been obsessed with them since the day I was introduced to generative art. They’re super versatile. You can use them for all kinds of things—flock of birds, snow, fire, fireworks, stars, sparks and so on. I’ve shown you how to build a &lt;a href=&quot;/confetti&quot;&gt;confetti particle system&lt;/a&gt; in the past. This time we’re entering the third dimension.&lt;/p&gt;&lt;p&gt;I’ll break down the demo you see above and share three techniques for creating particle systems:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Using instanced meshes and animating their transforms.&lt;/li&gt;&lt;li&gt;Using dashed lines with an animated offset.&lt;/li&gt;&lt;li&gt;By drawing a line and advancing it step by step.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;⚠️ This post assumes foundational knowledge of React Three Fiber. If you&amp;#x27;re new to 3D or not familiar with the R3F API, check out my &lt;a href=&quot;/modular-webgl/&quot;&gt;intro post&lt;/a&gt; for a primer.&lt;/div&gt;&lt;h2 id=&quot;what-are-we-building&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#what-are-we-building&quot; aria-label=&quot;what are we building permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What are we building?&lt;/h2&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:734px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:54.513888888888886%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;218\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20218\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%20109v109h401V0H0v109m12-83c-2%201-1%204%202%205l2%201-3%201h-2c1%202%205%202%206%201%202-1%202-1%202%201%201%203%203%204%203%202l2-2c3%200%204-5%202-6-3-3-7-2-6%202v3l-2-3-3-2-1-1h2l2-1c-1-2-4-2-6-1m237%2012h-6l-2%201%204%201c3%200%203%200%201%201l-2%201h3c3%200%204%200%206%203l4%203c1%200%202%201%202%204v5c-1-2-1-2-1%200s1%203%202%203c2%201%202%201%201%205%200%205-2%208-2%204s-2-3-2%201l1%201%201%201v4c0%203-2%206-3%206l1-3v-2l-2%203-1%202%201-11v-4l-2%202-1%202-1%204c0%207%200%207-1%206-1-2-2-2-5%201-3%204-3%205%200%202%202-1%202-1%201%201%200%204%201%204%202%200%201-1%201-2%202-1l2-1h4c2%200%202%200%202%202-2%205-2%207-1%207l1-3%203-4v-2c-1%200-1-4%201-11%202-9%202-10%200-17-2-8-3-9-9-13l-4-2%203-1%205%201c1%202%203%202%203%200l-7-2h-4m16%202c0%202%200%203-1%202h-4l-2%202h3c3%200%206%203%206%208l2%207c1%202%201%202%201%200s0-2%203%202l3%204c4%200%207%2041%203%2045-2%201-2%201%200%201%203%200%204-6%203-21%200-15-3-29-6-29-2%200-7-7-7-11l-2-4c-2-1-1-2%202-2s3%200%201-1l-3-1-2-4v2m-72%2028l-2%202c-3%200-14%206-18%2010-9%209-14%2025-12%2036%201%202%200%203-1%203v1l3%203c2%206%207%2012%208%2011v-7c-2-7-3-13-1-10l2%202v-2c-2-2-2-2%201-4%202-3%203-3%209-2h10c3-2%207-3%2017-3h23l2%204%201%205h-1c0-2-2-3-2%200l1%201%201%203-1%203c-2%200-1%202%201%202%204%202%207-14%205-25-4-18-18-30-38-32-5%200-7-1-7-2-1-1-1-1-1%201M55%20110v5c0%204%201%206%203%204%201-2%205-4%206-3l3%201c3%200%203%200%203-4%200-3-1-3-3-3l-3%201v3l-1-2c-1-2-6-4-8-2\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;particles building&quot; title=&quot;particles building&quot; src=&quot;/static/95ef73f9011365a339003e58e9f15c31/c6d67/particles-building.png&quot; srcSet=&quot;/static/95ef73f9011365a339003e58e9f15c31/477c9/particles-building.png 288w,/static/95ef73f9011365a339003e58e9f15c31/533c1/particles-building.png 576w,/static/95ef73f9011365a339003e58e9f15c31/c6d67/particles-building.png 734w&quot; sizes=&quot;(max-width: 734px) 100vw, 734px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;The demo above consists of three particle systems. The space dust moving around in the background. Sparks gently floating around the planet. And the spark storm that engulfs the planet.&lt;/p&gt;&lt;p&gt;Let’s tackle them one by one.&lt;/p&gt;&lt;h2 id=&quot;instanced-meshes&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#instanced-meshes&quot; aria-label=&quot;instanced meshes permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Instanced meshes&lt;/h2&gt;&lt;p&gt;First up is the Space Dust system. It’s just a bunch of dodecahedrons oscillating around a point. The classical approach is to have one object per particle. But you’re usually dealing with hundreds of thousands of particles, and it’s hard to render them all in a performant way. That’s where instanced meshes come in.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:734px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:40.97222222222222%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;163\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20163\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2082v81h28a168%20168%200%200030-1l171%201h172V0H211A6831%206831%200%20008%200H0v82m0%200\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;every white dot is a particle&quot; title=&quot;every white dot is a particle&quot; src=&quot;/static/b2c97551aefa217d48a202357a59f90c/c6d67/space-dust.png&quot; srcSet=&quot;/static/b2c97551aefa217d48a202357a59f90c/477c9/space-dust.png 288w,/static/b2c97551aefa217d48a202357a59f90c/533c1/space-dust.png 576w,/static/b2c97551aefa217d48a202357a59f90c/c6d67/space-dust.png 734w&quot; sizes=&quot;(max-width: 734px) 100vw, 734px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;The Space Dust system consists of ten thousand particles. That would mean ten thousand draw calls. With &lt;a href=&quot;https://threejs.org/docs/?q=inst#api/en/objects/InstancedMesh&quot;&gt;InstancedMesh&lt;/a&gt;, we can cut that down to a single draw call. It accomplishes this by reusing the geometry but applying a unique transformation for each instance.&lt;/p&gt;&lt;p&gt;We start by creating a bunch of particles with a random position, speed and timing.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; particles &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; temp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; time &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; factor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; speed &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.015&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; z &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    temp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; speed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; temp&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then render them all using a single &lt;code class=&quot;language-text&quot;&gt;instancedMesh&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;pointLight ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;light&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; distance&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; intensity&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;lightblue&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;instancedMesh ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;mesh&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;dodecahedronBufferGeometry args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;meshPhongMaterial color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;#050505&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;instancedMesh&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can see that they start off distributed all across the screen.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;We can then update the particle position, scale, and rotation on every frame to create the oscillating motion. For this, we use a dummy object to calculate the updated transformation matrix and then apply that to the particle instance using the &lt;code class=&quot;language-text&quot;&gt;setMatrixAt&lt;/code&gt; call.&lt;/p&gt;&lt;p&gt;Now go ahead and toggle on the animations (in the demo above) to see how the movement builds up.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dummy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Object3D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;useFrame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Run through the list of particles calculate some movement&lt;/span&gt;
  particles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; speed&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Update the particle time&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;time &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; speed&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Update the particle position based on the time&lt;/span&gt;
    dummy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      z &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; factor&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Derive an oscillating value for size and rotation&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dummy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scale&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dummy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rotation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    dummy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;updateMatrix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// And apply the matrix to the instanced item&lt;/span&gt;
    mesh&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setMatrixAt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dummy&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;matrix&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  mesh&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;instanceMatrix&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;needsUpdate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The output for &lt;code class=&quot;language-text&quot;&gt;sin&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;cos&lt;/code&gt; functions yo-yos between -1 and 1, making them perfect for generating an oscillating motion. You can even combine these trigonometric functions (by adding or multiplying them) to create more interesting repeating patterns. That’s what I’ve done for the position animation.&lt;/p&gt;&lt;h2 id=&quot;dashed-line-with-animated-offset&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#dashed-line-with-animated-offset&quot; aria-label=&quot;dashed line with animated offset permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Dashed line with animated offset&lt;/h2&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;Moving on to the floating sparks. The second technique is a bit of a sleight of hand. Instead of creating particle objects, we’ll draw lines and animate the dash offset to make it appear like particles. Kind of like those &lt;a href=&quot;https://css-tricks.com/svg-line-animation-works/&quot;&gt;SVG line animations&lt;/a&gt; but in 3D. This is trick works exceptionally well when you want particles to move along a path.&lt;/p&gt;&lt;p&gt;So, how does it work? It’s a three step process:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Generate a bunch of points&lt;/li&gt;&lt;li&gt;Use &lt;code class=&quot;language-text&quot;&gt;THREE.CatmullRomCurve3&lt;/code&gt; to convert them into a curve&lt;/li&gt;&lt;li&gt;Draw the curve using &lt;code class=&quot;language-text&quot;&gt;THREE.MeshLine&lt;/code&gt; and animate the &lt;code class=&quot;language-text&quot;&gt;dashOffset&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Repeat this process for each line.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;You can play around with the dash ratio, line count and thickness to create different effects.&lt;/p&gt;&lt;p&gt;How you generate the points totally changes the effect. You can use a mathematical equation like polynomials or bezier curves. In my case, I decided to go with a &lt;a href=&quot;/polar-coords&quot;&gt;polar coordinates&lt;/a&gt; approach.&lt;/p&gt;&lt;p&gt;We’ll increment the angle step-by-step from &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;2 PI&lt;/code&gt; radians and use it to calculate the &lt;code class=&quot;language-text&quot;&gt;(x,y)&lt;/code&gt; coordinates and keep &lt;code class=&quot;language-text&quot;&gt;z&lt;/code&gt; as &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt;. Most importantly, adding a bit of variance to the radius for a more organic look.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;radiusVariance&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; lines &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;lineCount&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// starting position&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pos &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Vector3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radiusVariance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radiusVariance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token comment&quot;&gt;// Increment the angle to create the points&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; points &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;_&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; index&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;index &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; pos&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Vector3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;              Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radiusVariance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;              Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radiusVariance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;              Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;radiusVariance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;            &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;          &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;          &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;// convert points into a curve&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; curve &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;CatmullRomCurve3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;points&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPoints&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        width&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        speed&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.004&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        curve&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lastly, we can draw each line and animate the &lt;code class=&quot;language-text&quot;&gt;dashOffset&lt;/code&gt; value using the &lt;code class=&quot;language-text&quot;&gt;useFrame&lt;/code&gt; hook.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;SparkLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; curve&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; speed &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; material &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token function&quot;&gt;useFrame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    material&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;uniforms&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dashOffset&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value &lt;span class=&quot;token operator&quot;&gt;-=&lt;/span&gt; speed&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;mesh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meshLine&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;attach&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;geometry&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;curve&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meshLineMaterial&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;material&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;transparent&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;depthTest&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;lineWidth&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;dashArray&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token attr-name&quot;&gt;dashRatio&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.95&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;mesh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My go-to option for drawing 3D lines is &lt;a href=&quot;https://github.com/spite/THREE.MeshLine&quot;&gt;THREE.MeshLine&lt;/a&gt;. It’s a fantastic feature-rich library. However, it doesn’t yet support Three.js version 128 and up. But, worry not, I’ve included a patched up version in my demo repo that you can use instead: &lt;a href=&quot;https://github.com/winkerVSbecks/3d-particle-effects-demo/tree/main/src/MeshLine&quot;&gt;3d-particle-effects-demo/tree/main/src/MeshLine&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&quot;advance-move-a-line&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#advance-move-a-line&quot; aria-label=&quot;advance move a line permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Advance (move) a line&lt;/h2&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;Lastly, we have the Spark Storm. With particles buzzing around the planet in a peculiar motion. This requires a technique related to the previous one. However, instead of relying on a dash offset, we’ll draw a line and then animate it using a mathematical system. This is a bit more involved, but a whole lot more fun!&lt;/p&gt;&lt;p&gt;You can use all kinds of mathematical models to create the movement. I decided to go with &lt;a href=&quot;https://en.wikipedia.org/wiki/Attractor&quot;&gt;Attractors&lt;/a&gt; mapped to the surface of a sphere. You’ve likely seen these attractors before. The Lorenz attractor creates this famous butterfly-like curve.&lt;/p&gt;&lt;div name=&quot;Lorenz attractor by Dan Quinn&quot; link=&quot;https://en.wikipedia.org/wiki/Lorenz_system#/media/File:A_Trajectory_Through_Phase_Space_in_a_Lorenz_Attractor.gif&quot;&gt;&lt;div bg=&quot;#fff&quot; py=&quot;4&quot;&gt;&lt;div mb=&quot;0&quot; src=&quot;static/lorenz-attractor-d15ce48e9ee841cc5e49d41db4d440b9.gif&quot; alt=&quot;A sample trajectory through phase space is plotted near a Lorenz attractor&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; newPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;attractor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;currentPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; timeStep&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We’re not going to get into the math behind attractors. For our purposes, an attractor is simply a function that uses the current position and a time step value to calculate the next location for a point.&lt;/p&gt;&lt;p&gt;Notice how that ball moves along the attractor. We’ll use this effect to power our particle system by tracking multiple points on the attractor. Then connect those points to draw a line.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;We start with an initial, randomly generated, list of positions. Then use the attractor to calculate a new position on each frame. We then drop the last position in the list to advance the line and push this new position in. THREE.MeshLine has a handy &lt;code class=&quot;language-text&quot;&gt;advance&lt;/code&gt; function built in that does this for you.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;StormLine&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; simulation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; line &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Create the points&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;positions&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; currentPosition&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createAttractor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Move the points&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useFrame&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;line&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; nextPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;updateAttractor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
        currentPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        simulation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token number&quot;&gt;0.005&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      line&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;advance&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nextPosition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Draw the line&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;mesh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meshLine&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;line&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;attach&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;geometry&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;positions&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;meshLineMaterial&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;transparent&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;lineWidth&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;mesh&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are many &lt;a href=&quot;https://fusefactory.github.io/openfuse/strange%20attractors/particle%20system/Strange-Attractors-GPU/&quot;&gt;different attractors&lt;/a&gt;, and each produces a different kind of curve. The system randomly picks an attractor for each line of the Spark Storm, which adds a good amount of variation to the animation and makes for a pretty cool effect!&lt;/p&gt;&lt;p&gt;The other significant bit here is to map the positions to the surface of a sphere. With vectors, that’s as simple as normalizing and scaling the vector. Without this, the particles will fly all over the place, and I wanted to make it look like they were engulfing a planet.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; normalizedPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; currentPosition
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;clone&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multiplyScalar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;scale&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is probably my favourite technique because you can change the mathematical model to create totally different effects. For example, you could use a &lt;a href=&quot;https://www.youtube.com/watch?v=mhjuuHl6qHM&quot;&gt;flocking algorithm&lt;/a&gt; or &lt;a href=&quot;/noise&quot;&gt;noise&lt;/a&gt; instead of attractors.&lt;/p&gt;&lt;h2 id=&quot;wrapping-up&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#wrapping-up&quot; aria-label=&quot;wrapping up permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Wrapping up&lt;/h2&gt;&lt;p&gt;Thanks for following along. I hope breaking down these techniques will encourage you to make your own awesome particle systems. Do share them with me on Twitter &lt;a href=&quot;https://twitter.com/winkerVSbecks&quot;&gt;@winkerVSbecks&lt;/a&gt; — I love seeing what you all make!&lt;/p&gt;&lt;p&gt;The complete source code is available at &lt;a href=&quot;https://github.com/winkerVSbecks/3d-particle-effects-demo&quot;&gt;github.com/winkerVSbecks/3d-particle-effects-demo&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Want to dive deeper? Several particle effect examples are available on the &lt;a href=&quot;https://threejs.org/examples/?q=particles#webgl_points_billboards&quot;&gt;Three.js &lt;/a&gt; and &lt;a href=&quot;https://docs.pmnd.rs/react-three-fiber/getting-started/examples&quot;&gt;React Three Fiber&lt;/a&gt; sites. Also, Codrops has &lt;a href=&quot;https://tympanus.net/codrops/?s=particles&amp;amp;search-type=posts&quot;&gt;many excellent tutorials&lt;/a&gt; on this topic.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[How to build stunning 3D scenes with React Three Fiber]]></title><description><![CDATA[WebGL is the magic sauce behind  Solar Storm  , an audio-reactive music video that renders live in the browser. After fumbling around with…]]></description><link>https://varun.ca/modular-webgl/</link><guid isPermaLink="false">https://varun.ca/modular-webgl/</guid><pubDate>Mon, 15 Nov 2021 00:00:00 GMT</pubDate><content:encoded>&lt;div name=&quot;Solar Storm&quot; link=&quot;https://solarstorm.netlify.app/&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/solarstorm-0929ec760de458e231ebdddf5d526b4c.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;WebGL is the magic sauce behind &lt;a href=&quot;https://solarstorm.netlify.app/&quot;&gt;Solar Storm&lt;/a&gt; , an audio-reactive music video that renders live in the browser. After fumbling around with Three.js for many years, WebGL finally clicked for me thanks to &lt;a href=&quot;https://docs.pmnd.rs/react-three-fiber/getting-started/introduction&quot;&gt;React Three Fiber&lt;/a&gt;. That’s because I could use the familiar concepts—components, props, hooks and state—and transfer my app development skills to 3D graphics.&lt;/p&gt;&lt;p&gt;This article shows you how to create breathtaking 3D animations using React Three Fiber (R3F). We’ll walk through setting up a stage, creating geometry, adding lighting and enabling post-processing effects. What’s more, you’ll get to learn by recreating the animation below from scratch.&lt;/p&gt;&lt;div name=&quot;Visualization&quot; link=&quot;https://github.com/winkerVSbecks/storybook-blocks&quot;&gt;&lt;div width=&quot;100%&quot; height=&quot;700&quot; mb=&quot;0&quot; display=&quot;block&quot; src=&quot;https://main--60fff54833991c0039d51492.chromatic.com/iframe.html?id=app--default&amp;amp;args=&amp;amp;viewMode=story&amp;amp;singleStory=true&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;declarative-and-componentized-webgl&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#declarative-and-componentized-webgl&quot; aria-label=&quot;declarative and componentized webgl permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Declarative and Componentized WebGL&lt;/h2&gt;&lt;p&gt;Before we begin, it’s worth covering why building with components offers more benefits than just &lt;em&gt;familiarity&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Breaking up the UI into components makes it easier to reason through your code and build complex interfaces. The structure, styling and associated logic get encapsulated into one reusable module. You can test all its variants and work through its edge cases. The same is true for WebGL.&lt;/p&gt;&lt;p&gt;With Three.js, the code for creating the geometry &amp;amp; material, combining it into a mesh and animating is split across multiple parts of the file. R3F enables you to package all of that into a single component. That way, you can start by building basic meshes, then progressively combining them to create scenes and finally, layer on post-processing effects.&lt;/p&gt;&lt;h3 id=&quot;build-it-up-part-by-part&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#build-it-up-part-by-part&quot; aria-label=&quot;build it up part by part permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Build it up part by part&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;http://storybook.js.org&quot;&gt;Storybook&lt;/a&gt; is my go-to tool for building meshes in isolation. That allows you to finesse them without worrying about other scene elements. No constant repositioning or toggling global lighting &amp;amp; effects. You can focus on getting the look and feel just right.&lt;/p&gt;&lt;div name=&quot;Visualization Storybook&quot; link=&quot;https://main--60fff54833991c0039d51492.chromatic.com/&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/cdd-storybook-d560364c75b491033f9ad121dc44dd5d.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;To get started, you need a &lt;a href=&quot;https://github.com/winkerVSbecks/storybook-blocks/blob/main/.storybook/StoryStage.js&quot;&gt;minimal scene&lt;/a&gt; that’ll wrap each story using a decorator.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; StoryStage &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;../../.storybook/StoryStage&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; TetrisBlock &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./TetrisBlock&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  title&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Meshes/TetrisBlock&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  component&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; TetrisBlock&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  decorators&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;storyFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;StoryStage&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;storyFn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;StoryStage&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;your-first-scene&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#your-first-scene&quot; aria-label=&quot;your first scene permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Your first scene&lt;/h2&gt;&lt;p&gt;Web UIs are built using HTML &amp;amp; CSS. 3D scenes are similar, but the building blocks are geometry, material and lights. You start with a &lt;strong&gt;Geometry&lt;/strong&gt; that describes the shape of an object (think HTML). You can apply a &lt;strong&gt;Material&lt;/strong&gt; to this geometry that controls the look and feel (think CSS). Combined together, you get an &lt;strong&gt;Mesh&lt;/strong&gt;. You can place this mesh in a 3D space. Then add in some &lt;strong&gt;Lights&lt;/strong&gt; to be able to see your object. Finally, a &lt;strong&gt;Renderer&lt;/strong&gt; renders the whole thing as though you were looking at it through a &lt;strong&gt;Camera&lt;/strong&gt;.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;The above is a demo of an introductory 3D scene—a rotating box. Notice how everything is a component. The canvas, lights, geometry, material and mesh. The entire Three.js API is automatically available as components in R3F.&lt;/p&gt;&lt;h2 id=&quot;decomposing--building-the-scene&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#decomposing--building-the-scene&quot; aria-label=&quot;decomposing  building the scene permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Decomposing &amp;amp; building the scene&lt;/h2&gt;&lt;p&gt;Now that we have the basics down, let’s go back to the visualization we’re building. The high-level elements of this scene are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Components:&lt;/strong&gt; these have Tetris block shapes with translucent material.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Data &amp;amp; State:&lt;/strong&gt; these are flat planes with funky custom textures.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Label:&lt;/strong&gt; this is just a text overlay.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:50%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;200\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20200\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%20100v100h401V0H0v100m29-20v10l6%203%206%204-5%204c-8%204-8%204-1%208%205%203%206%203%205%205-1%201-1%201%201%201%203-1%207%201%206%203v1l2-1%206%203%202%201%204%202%203%202%204%202%203%202c2%200%205%203%204%204l1%201c2-1%206%201%2013%205l11%206%2010-5a1440%201440%200%200160-36c0-1-12-8-14-7-2%200-1%202%201%202%204%201%209%206%208%207s-3%200-6-2c-5-3-9-5-9-3l3%202c5%202%209%205%207%206l-4-1c-4-3-11-3-13%200-3%203-5%208-5%2011l-1%203c-1%201-3-4-2-8%200-3%200-4-1-2v12c-1%200-3-3-4-7s-2-4-2-2l2%206c4%208%200%206-4-2l-3-3%203%206c4%207%202%207-2%201l-5-5%203%206%204%205-4%202-5%203-12-2a214%20214%200%2001-31-5c-4%200-9-3-13-8-5-7-8-14-4-14l1%203c0%208%207%2013%2018%2013%207%200%208%200%2011%203%204%205%208%206%2019%207%2010%200%2011%200%2012-2%201-1%202-3%201-4%200-2-4-6-4-4l2%202c4%204%200%207-9%207-8%200-8%200-8-11v-10L65%2090%2030%2070l-1%2010m115%2030l-5%209c0%203%202%202%206-1%202-3%204-4%206-4l5-1c1-2%201-2-2-3-5-2-8-2-10%200m10%2073\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;The Scene consists of Label, State, Data and Components&quot; title=&quot;The Scene consists of Label, State, Data and Components&quot; src=&quot;/static/18717624e9250784c21e5aee68a5aff3/4ad3a/cdd-scene-breakdown.png&quot; srcSet=&quot;/static/18717624e9250784c21e5aee68a5aff3/477c9/cdd-scene-breakdown.png 288w,/static/18717624e9250784c21e5aee68a5aff3/533c1/cdd-scene-breakdown.png 576w,/static/18717624e9250784c21e5aee68a5aff3/4ad3a/cdd-scene-breakdown.png 1152w,/static/18717624e9250784c21e5aee68a5aff3/b8bf8/cdd-scene-breakdown.png 1728w,/static/18717624e9250784c21e5aee68a5aff3/cb93d/cdd-scene-breakdown.png 2304w,/static/18717624e9250784c21e5aee68a5aff3/dcef9/cdd-scene-breakdown.png 3200w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;h3 id=&quot;components-tetris-blocks&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#components-tetris-blocks&quot; aria-label=&quot;components tetris blocks permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Components (Tetris blocks)&lt;/h3&gt;&lt;p&gt;The &lt;em&gt;components&lt;/em&gt; in this visualization are represented by Tetris blocks. These shapes are constructed by drawing a 2D path and then extruding it along the Z-axis. We’ll use the &lt;a href=&quot;https://github.com/pmndrs/drei/#shapes&quot;&gt;Extrude&lt;/a&gt; utility from Drei, which offers a shortcut syntax to create such shapes.&lt;/p&gt;&lt;div&gt;&lt;a href=&quot;https://docs.pmnd.rs/drei/introduction&quot;&gt;Drei&lt;/a&gt; is a helper library that offers utilities for common Three.js tasks, e.g., adding audio or Orbit controls or creating a custom shader material.&lt;/div&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;The syntax for defining the shape is quite similar to &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths&quot;&gt;SVG Paths&lt;/a&gt;. You can control the extrude depth and bevelled edges using the &lt;code class=&quot;language-text&quot;&gt;extrudeSettings&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;That’s that for the geometry, but remember, a mesh consists of a geometry plus a material. We’ll use &lt;a href=&quot;https://threejs.org/docs/?q=meshPhysicalMaterial#api/en/materials/MeshPhysicalMaterial&quot;&gt;MeshPhysicalMaterial&lt;/a&gt; here. It allows you to replicate physical properties such as transparency, roughness and clearcoat. In this case, we’ve used it for a &lt;a href=&quot;https://uxdesign.cc/glassmorphism-in-user-interfaces-1f39bb1308c9&quot;&gt;Glassmorphism&lt;/a&gt; effect, which is a super popular aesthetic right now.&lt;/p&gt;&lt;h3 id=&quot;data--state&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#data--state&quot; aria-label=&quot;data  state permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Data &amp;amp; State&lt;/h3&gt;&lt;p&gt;Now that we know how to create meshes let’s focus on making custom materials. At its core, a material is a shader, and a shader is a program that takes a set of inputs and produces a texture. For Data and State, we’ll build custom shader materials using the &lt;a href=&quot;https://github.com/pmndrs/drei/#shadermaterial&quot;&gt;shaderMaterial&lt;/a&gt; utility from Drei.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;shaderMaterial&lt;/code&gt; takes in a set of uniforms plus the vertex and fragment shaders, and returns a material. We then use &lt;code class=&quot;language-text&quot;&gt;extend&lt;/code&gt; to add it to the R3F namespace and finally apply it to the &lt;a href=&quot;https://github.com/pmndrs/drei/#shapes&quot;&gt;Plane&lt;/a&gt;.&lt;/p&gt;&lt;div&gt;Not sure how to get started with shaders? Check out the &lt;a href=&quot;https://market.pmnd.rs/materials&quot;&gt;Poimandres marketplace&lt;/a&gt; for a bunch of ready-to-use materials.&lt;/div&gt;&lt;p&gt;The shader in this example is using &lt;a href=&quot;https://varun.ca/noise/#noise-material&quot;&gt;noise&lt;/a&gt; and is animated using the &lt;code class=&quot;language-text&quot;&gt;time&lt;/code&gt; uniform. You can use the &lt;code class=&quot;language-text&quot;&gt;useFrame&lt;/code&gt; hook to access the Three.js clock and update the time value.&lt;/p&gt;&lt;h3 id=&quot;label&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#label&quot; aria-label=&quot;label permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Label&lt;/h3&gt;&lt;p&gt;Rendering text in WebGL is &lt;a href=&quot;https://threejs.org/docs/index.html?q=text#manual/en/introduction/Creating-text&quot;&gt;&lt;em&gt;complicated&lt;/em&gt;&lt;/a&gt;. That complexity only ramps up if you want to use a custom font. That’s why if possible, use HTML and layer the text on top of your scene. That’s exactly what we’re doing here. The Label is absolutely positioned on top of the canvas.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styled &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-components&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Container &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  pointer-events: none;
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  width: 100%;
  height: 144px;
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Box &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Label&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Container&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Atomic components&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Container&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For more complex applications, I recommend the &lt;a href=&quot;https://github.com/pmndrs/drei/#html&quot;&gt;Html&lt;/a&gt; component, which controls size and positioning of your HTML content based on its location in the 3D space.&lt;/p&gt;&lt;h3 id=&quot;compose-the-scene-and-animate&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#compose-the-scene-and-animate&quot; aria-label=&quot;compose the scene and animate permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Compose the scene and animate!&lt;/h3&gt;&lt;p&gt;We have all the bits now; the next step is to animate them using &lt;a href=&quot;https://docs.pmnd.rs/react-spring/introduction&quot;&gt;React Spring&lt;/a&gt;. It uses a spring-physics-based model where the animated props are generated using the &lt;code class=&quot;language-text&quot;&gt;useSpring&lt;/code&gt; hook and applied to an &lt;code class=&quot;language-text&quot;&gt;animated&lt;/code&gt; component instance.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;The visualization has four states and the position, scale and colour of the meshes animate between each step. We can track all that info in an array and use component state for cycling between each step.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STEP_COUNT&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useCDDState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;step&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setStep&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setStep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STEP_COUNT&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token number&quot;&gt;3000&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;clearTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; step&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Then in the component:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// const step = useCDDState();&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// const spring = useSpring(STATES[step]);&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The embed below is interactive. Zoom out and rotate the scene to see how the animation is executed. Or check out the &lt;a href=&quot;https://github.com/winkerVSbecks/storybook-blocks/blob/main/src/cdd-scene/ComponentDriven.js&quot;&gt;source&lt;/a&gt; to see how each mesh is wired up to a spring.&lt;/p&gt;&lt;div name=&quot;storybook-blocks/src/cdd-scene/ComponentDriven.js&quot; link=&quot;https://github.com/winkerVSbecks/storybook-blocks/blob/main/src/cdd-scene/ComponentDriven.js&quot;&gt;&lt;div width=&quot;100%&quot; height=&quot;600&quot; mb=&quot;0&quot; display=&quot;block&quot; src=&quot;https://60fff54833991c0039d51492-nqnxmkzxja.chromatic.com/?path=/story/cdd-scene-componentdriven--default&amp;amp;full=1&amp;amp;shortcuts=false&amp;amp;singleStory=true&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;React Spring works with both Three.js objects and HTML, so we can also apply the same principles to animate the label. All animations are driven by the same state and therefore stay in sync.&lt;/p&gt;&lt;div name=&quot;storybook-blocks/src/cdd-scene/Label.js&quot; link=&quot;https://github.com/winkerVSbecks/storybook-blocks/blob/main/src/cdd-scene/Label.js&quot;&gt;&lt;div width=&quot;100%&quot; height=&quot;200&quot; mb=&quot;0&quot; display=&quot;block&quot; src=&quot;https://60fff54833991c0039d51492-nqnxmkzxja.chromatic.com/iframe.html?id=cdd-scene-label--default&amp;amp;args=&amp;amp;viewMode=story&amp;amp;singleStory=true&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;post-processing-effects&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#post-processing-effects&quot; aria-label=&quot;post processing effects permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Post processing effects&lt;/h3&gt;&lt;p&gt;Lastly, we’re going to add a glow effect to the scene. Post-processing effects are also shaders but applied to the entire rendered output instead of individual meshes.&lt;/p&gt;&lt;p&gt;This whole process is often referred to as a render pipeline. You start by rendering the scene as usual and pass that as the input into the first effect shader. Then give that output to the following effect and so on. The output of the final effect is rendered onto the screen.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;THREE&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;three&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useMemo &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Effects &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; EffectsComposer &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;@react-three/drei&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; extend&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; useThree &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;@react-three/fiber&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; UnrealBloomPass &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;three-stdlib&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;extend&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; UnrealBloomPass &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Effects&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; scene&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; camera &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useThree&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; aspect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useMemo&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Vector2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; size&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;size&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;EffectsComposer
      multisamping&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      renderIndex&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      disableGamma
      disableRenderPass
    &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;renderPass attachArray&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;passes&amp;quot;&lt;/span&gt; scene&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;scene&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; camera&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;camera&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;unrealBloomPass attachArray&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;passes&amp;quot;&lt;/span&gt; args&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;aspect&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;EffectsComposer&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In our case, we have just one effect, the &lt;code class=&quot;language-text&quot;&gt;unrealBloomPass&lt;/code&gt;, which adds that nice sci-fi glow.&lt;/p&gt;&lt;div name=&quot;storybook-blocks/src/cdd-scene/Effects.js&quot; link=&quot;https://github.com/winkerVSbecks/storybook-blocks/blob/main/src/cdd-scene/Effects.js&quot;&gt;&lt;div width=&quot;100%&quot; height=&quot;500&quot; mb=&quot;0&quot; display=&quot;block&quot; src=&quot;https://60fff54833991c0039d51492-nqnxmkzxja.chromatic.com/iframe.html?id=cdd-scene-effects--default&amp;amp;args=&amp;amp;viewMode=story&amp;amp;singleStory=true&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;wrapping-up&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#wrapping-up&quot; aria-label=&quot;wrapping up permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Wrapping up&lt;/h2&gt;&lt;p&gt;Success! We used React Three Fiber to create an animated 3D visualization. The whole thing is simply a component that you can drop into any React app, and it’ll work.&lt;/p&gt;&lt;p&gt;Solarstorm was built mainly using these techniques. The significant difference was that instead of animating with springs, I used JavaScript to analyze the audio and use that output to drive the animations. Now that you’re familiar with these concepts, jump into &lt;a href=&quot;https://github.com/winkerVSbecks/solarstorm/&quot;&gt;the source code&lt;/a&gt; or use that as a starting point for your own audio reactive scene.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Noise in Creative Coding]]></title><description><![CDATA[Noise is an indispensable tool for creative coding. We use it to generate all kinds of organic effects like clouds, landscapes and contours…]]></description><link>https://varun.ca/noise/</link><guid isPermaLink="false">https://varun.ca/noise/</guid><pubDate>Thu, 22 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot;&gt;&lt;source src=&quot;static/chromatic-noise-24340c49afbd7146f3b04f86ed5a0357.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;p&gt;Noise is an indispensable tool for creative coding. We use it to generate all kinds of organic effects like clouds, landscapes and contours. Or to move and distort objects with a more lifelike behaviour.&lt;/p&gt;&lt;p&gt;On the surface, noise appears to be simple to use but, there are so many layers to it. This post takes a deep dive into what noise is, its variants, how to use it on the web and its applications. And lot’s of examples. So many examples!&lt;/p&gt;&lt;h2 id=&quot;what-is-noise&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#what-is-noise&quot; aria-label=&quot;what is noise permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What is noise?&lt;/h2&gt;&lt;p&gt;Imagine you want to move an object around the screen. Animators will use keyframes and tweens to describe the exact motion. Generative artists instead rely on algorithms.&lt;/p&gt;&lt;p&gt;So what, something like &lt;code class=&quot;language-text&quot;&gt;math.random()&lt;/code&gt;?&lt;/p&gt;&lt;p&gt;Not exactly. Randomness is just too unnatural. Look at that pink ball, bouncing all over the place. It’s nauseating 🥴&lt;/p&gt;&lt;p&gt;What we need is a smoother, more &lt;em&gt;organic randomness&lt;/em&gt;. That is what the noise function generates (the yellow ball). Much more aesthetically pleasing!&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;This idea of &lt;em&gt;organic randomness&lt;/em&gt; appears again and again in creative coding. For example, when generating textures, moving objects or distorting them. We often reach for the noise function.&lt;/p&gt;&lt;h3 id=&quot;generating-noise-on-the-web&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#generating-noise-on-the-web&quot; aria-label=&quot;generating noise on the web permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Generating noise on the web&lt;/h3&gt;&lt;p&gt;There are two flavours of noise—Perlin and Simplex.&lt;/p&gt;&lt;p&gt;Ken Perlin developed the first while working on Tron in the early 1980s and won an &lt;a href=&quot;https://mrl.cs.nyu.edu/~perlin/doc/oscar.html&quot;&gt;Oscar&lt;/a&gt; 🏆 for those special effects. He then improved on it with Simplex noise and made it a bit faster. I’ll focus on the latter and use the &lt;a href=&quot;https://www.npmjs.com/package/simplex-noise&quot;&gt;simplex-noise&lt;/a&gt; library for my examples.&lt;/p&gt;&lt;p&gt;The noise function takes in a couple of inputs (which &lt;em&gt;drive&lt;/em&gt; the output) and returns a value between -1 and 1. The output is a mix of &lt;code class=&quot;language-text&quot;&gt;Math.sin()&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Math.random()&lt;/code&gt;. A random wave is how I would describe it.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; SimplexNoise &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;simplex-noise&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; simplex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;SimplexNoise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The underlying mechanics are similar to how waves work. You can control how quickly or how much it oscillates by adjusting frequency and amplitude.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;Umm, noise… 2D, what’s happening here?&lt;/p&gt;&lt;h2 id=&quot;noise-dimensions&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noise-dimensions&quot; aria-label=&quot;noise dimensions permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noise Dimensions&lt;/h2&gt;&lt;p&gt;The noise algorithm can be implemented for multiple dimensions. Think of these as the number of inputs into the noise generator—two for 2D, three for 3D and so on.&lt;/p&gt;&lt;p&gt;Which dimension you pick depends on what variables you want to drive the generator with. Let’s look at a few examples.&lt;/p&gt;&lt;div&gt;💡 Starting here, each example is embedded in a source card. With links to the actual source code and, in some cases, variables you can tweak.&lt;/div&gt;&lt;h3 id=&quot;noise-1d--wave-motion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noise-1d--wave-motion&quot; aria-label=&quot;noise 1d  wave motion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noise 1D — Wave Motion&lt;/h3&gt;&lt;p&gt;Technically there is no noise1D. You can get 1D noise by passing in zero as the second argument to simplex.noise2D. Let’s say you want to move a ball with an organic-looking oscillating motion. Increment its x coordinate and use it to generate the y value.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h3 id=&quot;noise2d--terrain-generator&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noise2d--terrain-generator&quot; aria-label=&quot;noise2d  terrain generator permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noise2D — Terrain Generator&lt;/h3&gt;&lt;p&gt;We can turn a flat 2D plane into hilly terrain by moving its vertices in the z-direction. Use the &lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;y&lt;/code&gt; coordinates to generate the &lt;code class=&quot;language-text&quot;&gt;z&lt;/code&gt; location.&lt;/p&gt;&lt;p&gt;And just like that, we have a terrain generator 🏔️&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;z &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h3 id=&quot;noise3d--vertex-displacement&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noise3d--vertex-displacement&quot; aria-label=&quot;noise3d  vertex displacement permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noise3D — Vertex Displacement&lt;/h3&gt;&lt;p&gt;You’ve probably seen these &lt;a href=&quot;https://tympanus.net/codrops/2021/01/26/twisted-colorful-spheres-with-three-js/&quot;&gt;distorted spheres&lt;/a&gt; in the wild. They are created by displacing the vertices of a sphere. Use the vertex coordinate &lt;code class=&quot;language-text&quot;&gt;(x, y, z)&lt;/code&gt; to generate the distortion amount. Then displace the vertex by it radially.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; distortion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise3D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; z &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

newPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multiplyScalar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;distortion&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h3 id=&quot;noise4d--animated-distortion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noise4d--animated-distortion&quot; aria-label=&quot;noise4d  animated distortion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noise4D — Animated Distortion&lt;/h3&gt;&lt;p&gt;We can animate the distorted sphere by using 4D noise. The inputs will be the vertex coordinate &lt;code class=&quot;language-text&quot;&gt;(x, y, z)&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;time&lt;/code&gt;. This technique is used to create &lt;a href=&quot;https://www.clicktorelease.com/blog/vertex-displacement-noise-3d-webgl-glsl-three-js/&quot;&gt;fireballs&lt;/a&gt;, amongst other things.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; distortion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise4D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    y &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    z &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    time &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

newPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; position&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;multiplyScalar&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;distortion&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;p&gt;Notice our use of amplitude in the above examples. It’s a handy way to scale the noise output to your application. You could also use &lt;a href=&quot;https://github.com/mattdesl/canvas-sketch-util/blob/master/docs/math.md#mapRange&quot;&gt;interpolation&lt;/a&gt; to map the noise output to a specified range of your choice.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/f395880281f813f30b62086fd3563803/mapping-noise.svg&quot; alt=&quot;mapping noise&quot;/&gt;&lt;/p&gt;&lt;p&gt;Now that we have the basics down let’s look at a few more applications of noise.&lt;/p&gt;&lt;h2 id=&quot;textures&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#textures&quot; aria-label=&quot;textures permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Textures&lt;/h2&gt;&lt;p&gt;The noise output for a 2D grid, with &lt;code class=&quot;language-text&quot;&gt;(x,y)&lt;/code&gt; coordinates, looks something like this:&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:800px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:50%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;200\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20200\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2024v23h21c18%200%2041-1%2033-2-5%200-3-2%203-2%205-1%206-2%206-3%200-2%201-2%204-2%202%200%203%200%203-2s1-2%203-2%203-1%203-2c0-2%201-3%204-3%202%200%203-1%203-2%200-2%201-2%206-2s6%200%206-2%201-2%2016-2%2016%200%2016%202%201%202%2011%202c15%200%2021%201%2021%203-1%201%200%201%204%201%208%200%2015%201%2015%203l6%202c5%200%206%201%206%202%200%202%201%202%203%202%203%200%204%200%204%202s1%203%203%203c3%200%203%201%203%203%200%206%201%209%203%208l2-2%201%203c1%204%201%204%204%204%202%200%203%200%203%202s1%202%203%202l4%202c0%201%201%202%206%203%205%200%206%201%206%202%200%202%201%202%207%202%205%200%206%200%206%202s1%202%204%202l14%202-2%201h-3l6%202c4%200%206%201%206%202l3%201c3%200%204%201%204%203%200%201%201%202%203%202s3%200%203%202-1%202-3%202l-4%202-6%203c-4%200-5%201-3%201%205%200%203%202-3%203-5%200-6%201-6%202%200%202-1%202-3%202-3%200-4%200-4%202s-1%202-3%202l-4%202c0%201-1%202-6%203-5%200-6%201-6%202%200%202-1%202-3%202s-3%201-3%202l-4%202c-2%200-3%200-3%202%200%201-1%202-6%202l-6%203-4%202c-2%200-3%200-3%202%200%201-1%202-3%202s-3%200-3%202-1%202-3%202c-3%200-3%200-1%201%202%200%203%201%204%204%200%203%201%203%203%203l4%202c0%202%204%203%204%200%201-1%201-1%201%201s1%202%204%202c2%200%203%200%203%202%200%201%201%202%206%202%205%201%206%201%206%203l4%202c2%200%203%200%203%202s1%202%203%202%203%201%203%202l3%202c3%200%203%200%203%204v4h-2c-3%200-3%201-3%203%200%201-1%202-4%202-2%200-3%201-3%202%200%202-1%202-3%202s-3%200-3%202-1%202-3%202c-3%200-4%200-4%202%200%201-1%202-6%203-5%200-6%201-6%202%200%202%202%202%2060%202%2059%200%2061%200%2061-2%200-1-1-2-7-2-5-1-6-1-6-3s-1-2-3-2c-3%200-4%200-4-2s-1-2-3-2c-3%200-4%200-4-2%200-1-1-2-6-3-5%200-6-1-6-2s0-2-3-2c-4%200-4-3%200-3l4-1h-4c-4%200-5-4%200-4%203%200%203-1%203-7l3-1%204-2c0-1%201-2%203-2s3-1%203-3%204-2%204%200h-1l-2%201%202%201%202-2c0-2%202-3%205-3l2-2%203-2c2%200%203-1%204-3%200-4%201-4%203-4%203%200%203%200%203-4%201-4%201-5%203-4%202%200%202%200%200%201-1%201-1%201%201%201s2%200%202-6v-6h-3c-3%200-3%200-3-4s0-4-3-4c-2%200-3-1-3-2%200-2-1-3-3-3s-3-1-3-2c0-2-1-2-3-2s-3%200-3-2-1-3-4-3l-3-1%203-1h4l-4-1-4-2c0-2-1-2-3-2s-3-1-3-3%200-2%203-2c2%200%203%200%203-2s1-3%204-3c2%200%203-1%203-2l3-1%204-2c0-1%201-2%206-3%205%200%206-1%206-2%200-2%201-2%204-2%202%200%203%200%203-2s0-2%201-1c0%202%204%203%204%201%200-1%201-2%204-2s3-1%203-2c0-2%206-3%2020-3%2012%200%2019%201%2019%203%200%201%2011%203%2012%202l1-34V0H0v24m83%2063c-1%202-2%202-7%202-6%200-7%200-7%202%200%203-4%203-4%200l-1-2v2c0%202-1%202-3%202-3%200-4%200-4%202%200%201-1%202-6%203l-4%201c5%200%203%202-3%203-5%200-6%201-6%202%200%202-1%202-3%202-3%200-4%200-4%202%200%201-1%202-6%203-4%200-6%201-6%202l-2%201c-3%200-5%201-5%203l-2%202H0v81h45c43%200%2044%200%2044-2s1-2%203-2c3%200%203%200%204-5%200-3%201-4%201-2l1%202%201-1v-2c0-1%201-1%201%201%201%202%201%202%201-1%200-7%201-9%204-9%202%200%203-1%203-3%200-1%201-2%203-2s3-1%203-2c0-2%201-3%203-3s3-1%203-2l4-2c2%200%203%200%203-2s1-2%203-2c3%200%204%200%204-2l3-2c2%200%203%200%203-2s4-2%204%200h-1l-2%201%202%201%202-2c0-2%201-2%204-2%202%200%203%200%203-2%200-1%201-2%203-2%203%200%204-1%204-3%200-1%201-2%203-2%203%200%203%200%203-4s0-4-3-4-3%200-3-2c0-3%200-3-3-3s-4-2-4-9c0-2%200-3-1-2%200%203-4%202-4%200l-1-8c0-6%200-6-3-6s-3%200-3-3v-4l-3-2c-2%200-3-1-3-2l-4-2c-2%200-3-1-3-2%200-2-1-2-10-2-16%200-16%200-15-2%200-3-19-3-19%200\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;raw noise output&quot; title=&quot;raw noise output&quot; src=&quot;/static/dba89966db3e40dc39c27443d4541be4/5a190/noise.png&quot; srcSet=&quot;/static/dba89966db3e40dc39c27443d4541be4/477c9/noise.png 288w,/static/dba89966db3e40dc39c27443d4541be4/533c1/noise.png 576w,/static/dba89966db3e40dc39c27443d4541be4/5a190/noise.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Generated using:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; gridSize&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; gridSize&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; x&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; n &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gridSize&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gridSize&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is going to be our starting point.&lt;/p&gt;&lt;p&gt;We can use the &lt;a href=&quot;https://thecodingtrain.com/challenges/coding-in-the-cabana/005-marching-squares.html&quot;&gt;Marching Squares algorithm&lt;/a&gt; to turn that 2D noise data into contours. Using Canavas, SVG, WebGL or whatever else you prefer. I recently used this technique with SVG to create generative profile cards. For a full tutorial on that, check out &lt;a href=&quot;https://storybook.js.org/blog/generative-image-service/&quot;&gt;creating a generative image service&lt;/a&gt; 📸&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:800px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:50%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;200\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20200\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2028v29h7a973%20973%200%200149%200c5-2%2016-8%2015-9l-6%203c-10%206-14%207-45%205-27-2-26-4%202-3%2028%200%2032-1%2050-13%2017-11%2020-11%2042-11%2015%200%2021%200%2034%202%2028%206%2039%2010%2046%2021%208%2013%2011%2015%2039%2024%2036%2012%2040%2015%2024%2025-17%2012-39%2022-65%2032-7%202-21%202-26%200-9-5-13-10-21-29-6-13-23-19-54-19-18-1-20%200-43%2011a410%20410%200%2001-47%2019l10-5c12-4%2027-11%2040-20%2018-10%2024-12%2039-10l28%203c29%204%2032%206%2035%2021%203%2013%2010%2020%2021%2024%2012%203%2035-3%2061-18%2010-6%206-4-6%202-38%2020-63%2020-71%200l-4-11c-4-14-7-15-42-20-38-5-40-4-60%208-22%2013-49%2024-51%2021-1-1-1%2015-1%2044v46h60l56-1h-5l2-6%207-12%204-5c-3%200-14%2017-14%2022l-5%201h-5l4-7c7-13%2012-18%2033-28%2029-14%2038-15%2059-8%2014%205%2029%2012%2034%2016%207%206%201%2013-22%2024-7%204-11%204-4%200l10-7-7%203-9%206-4%202h207V0H0v28m0%201l1%2025v-3h17c27%201%2036%200%2053-12l14-8c3-1%203-1%201-2s-1-1%202-1l13-1c11-1%2027%200%2047%203%2029%205%2039%2010%2047%2021%209%2013%2012%2015%2036%2023%2035%2011%2041%2015%2033%2024l-4%204h3l4-2c0-1%201-2%203-2%203%200%203-1%203-2s1-2%203-2c3%200%204-1%204-3v-3l-23-8c-43-14-47-17-55-29-7-12-20-17-59-23-30-5-56-5-60%201l-4%201-2%202-3%202-4%202c0%201-1%202-3%202l-3%202c0%201-1%202-3%202l-4%202c0%201-1%202-3%202l-10%201c-6%202-13%202-25%202H1V25a325%20325%200%2000-1%204m102%202c-6%201-15%204-18%207l8-2c13-6%2039-6%2065%201%2010%202%2015%202%207%200-19-6-48-8-62-6m255%2034l-2%201-2%201c-5%200-9%201-10%203%200%201-1%202-4%202l-6%202-8%203c-3%201-4%202-2%202%201%201%201%201-1%201-5%200-11%202-11%203s-1%202-3%202c-3%200-3%201-3%204%200%207%200%208%202%208%202%201%202%201%202-2-1-4%204-8%2016-15%2019-8%2029-11%2041-11%2019-1%2030%206%2032%2021%201%205%201%204%201-6V73l-3-2c-9-5-31-9-39-6m-5%207c-15%204-38%2015-40%2019s0%2011%204%2011l1%201c0%202%2010%2012%2012%2011l1%202%203%205c9%2010%205%2020-18%2034-24%2017-25%2021-7%2031%2016%209%2030%2011%2060%2011%2022%201%2031%200%2031-3h-4c-6%201-44%200-52-1-20-3-37-12-37-20%200-3%204-10%206-10l-1%203c-6%208-4%2012%209%2018%205%203%2013%206%2017%206%209%202%2045%204%2056%202l7-1v4a994%20994%200%2000-2-66l-1-21c0-19-1-21-3-25-5-11-24-16-42-11m-28%2019c-4%206-1%2012%2014%2027%2011%2012%2012%2013%203%2022l-4%206c1%200%2010-9%2011-12%201-4-1-8-9-17-11-11-15-16-15-21l1-5%201-2-2%202m-132%2044c-5%202-20%202-24%201-3-1-3-1-3%201s1%203%203%203l4%201h-4c-2%200-3%200-3%202s-1%202-3%202l-3%201%203%201h3l-6%201c-5%201-6%202-6%203l-4%202c-2%200-3%200-3%202s-1%202-3%202c-3%200-9%202-9%204l-2%201c-1-1-5%201-5%203l-3%201c-3%200-4%200-4%202%200%201%200%202-2%202-3%200-4%200-4%202%200%201-1%202-3%202s-3%200-3%202l-1%204c0%202%200%202%204-1%2012-12%2049-29%2064-29%2014%200%2052%2015%2058%2023%203%203%203%206-1%2010l-4%204h4c2%200%203%200%203-2s2-3%205-2l2-5c0-4%201-6%202-5h1l-16-9a206%20206%200%2001-32-18c0-1-1-2-5-2l-2-2%201-4c0-2%203-3%204-1l-1%201h-2l2%201%202-1%202-3c2-3-1-2-6%200m-25%2023c-12%202-28%208-38%2014-7%205-4%204%204%200%2017-10%2031-14%2047-13%2010%201%2015%202%2031%208l1-1a85%2085%200%2000-45-8m161%2024c7%206%2040%2010%2062%207h9c1%201%201%201%201-1l-1-2-13%202c-22%201-42-1-57-6h-1\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;noise contours&quot; title=&quot;noise contours&quot; src=&quot;/static/1d9b0f2d30e4a98ca9d259786c72f751/5a190/noise-rings.png&quot; srcSet=&quot;/static/1d9b0f2d30e4a98ca9d259786c72f751/477c9/noise-rings.png 288w,/static/1d9b0f2d30e4a98ca9d259786c72f751/533c1/noise-rings.png 576w,/static/1d9b0f2d30e4a98ca9d259786c72f751/5a190/noise-rings.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;The cool thing about noise is that you can go up one dimension, layer in time and animate your image.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise3D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gridSize&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gridSize&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.75&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div name=&quot;basic-noise.js&quot; link=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/basic-noise.js&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/animated-contours-707781879518914be04e673177d36c09.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;fields&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#fields&quot; aria-label=&quot;fields permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Fields&lt;/h2&gt;&lt;p&gt;Honestly, this 2D grid of noise data is super utilitarian. It’s my go-to for all kinds of stuff. One of which is noise fields—a particular favourite of mine.&lt;/p&gt;&lt;p&gt;Let’s go back to that initial grayscale output. Map that to a more interesting colour scale, and you get plasma 🤩&lt;/p&gt;&lt;div name=&quot;plasma.js&quot; link=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/plasma.js&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/plasma-a56ace001ec71cfb5ecc9e308a4ef9cb.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Or, start with a grid of rectangles. Then turn it into a vector field by using noise to control the colour and angle of rotation.&lt;/p&gt;&lt;div name=&quot;vector-field.js&quot; link=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/colour-field.js&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/vector-field-0522984ddbb5abbeab7d7e43fbc39005.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;noisy-particles&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noisy-particles&quot; aria-label=&quot;noisy particles permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noisy Particles&lt;/h2&gt;&lt;p&gt;Vector fields are cool, but &lt;a href=&quot;https://www.pinterest.ca/search/pins/?q=noise%20field&quot;&gt;flow fields&lt;/a&gt; are an even more exciting visualization. Here’s a plot I made last year.&lt;/p&gt;&lt;div name=&quot;flow-field-plot.js&quot; link=&quot;https://github.com/winkerVSbecks/penplot-sketches/blob/master/sketches/flow-field.js&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/flow-field-plotter-59e979d6644f9ea760599aa48b39e4e4.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice the path that the pen traces. Each one of those strokes is generated by dropping a particle onto the vector field. And then tracing its path. 💫&lt;/p&gt;&lt;p&gt;Alright, let’s break down this process.&lt;/p&gt;&lt;h3 id=&quot;creating-a-flow-field&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#creating-a-flow-field&quot; aria-label=&quot;creating a flow field permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Creating a Flow Field&lt;/h3&gt;&lt;p&gt;Step 1, create a vector field. Same as before. But this time, we’re &lt;em&gt;not&lt;/em&gt; going to animate the vector field.&lt;/p&gt;&lt;p&gt;Step 2, drop a bunch of particles onto the canvas. Their direction of movement is based on the underlying vector field. Take a step forward, get the new direction and repeat.&lt;/p&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot;&gt;&lt;source src=&quot;static/particle-movement-3c6414876beb96267efa9f6c4515d6fa.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;moveParticle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;particle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Calculate direction from noise&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
    simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;FREQUENCY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;FREQUENCY&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;AMPLITUDE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Update the velocity of the particle&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// based on the direction&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vx &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STEP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vy &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STEP&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Move the particle&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vx&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vy&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Use damping to slow down the particle (think friction)&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vx &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DAMPING&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vy &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;DAMPING&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;line&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Step 3, track the location of the particle to trace its path.&lt;/p&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot;&gt;&lt;source src=&quot;static/particle-path-26fe132d84145b3cbc1c41c8b09c572f.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;p&gt;Add in more particles and colour, and we get our flow field.&lt;/p&gt;&lt;div name=&quot;flow-field.js&quot; link=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/flow-field.js&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/flow-field-4ac7d44cf40ea2b2a6cca3652cd30ea2.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;particle-systems&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#particle-systems&quot; aria-label=&quot;particle systems permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Particle systems&lt;/h3&gt;&lt;p&gt;Speaking of particles, noise shows up in particle systems too. For effects like rain, snow or confetti, you’re looking to simulate a natural-looking motion. Imagine a confetti particle floating down to earth. The particles don’t move in straight lines. They float and wiggle due to air resistance. Noise is a really great tool for adding in that organic variability.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; wiggle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; simplex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; wiggle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; wiggle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For a deeper dive, check my post on &lt;a href=&quot;/confetti&quot;&gt;building a confetti cannon&lt;/a&gt; 🎉&lt;/p&gt;&lt;div name=&quot;carnival-nights&quot; link=&quot;https://github.com/winkerVSbecks/carnival-nights&quot; bg=&quot;#000&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;static/confetti-header-6d2c155f1a08237fa90d08b25f52cd83.gif&quot; width=&quot;100%&quot; maxWidth=&quot;400px&quot; mb=&quot;0&quot;/&gt;&lt;/div&gt;&lt;h2 id=&quot;shaders&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#shaders&quot; aria-label=&quot;shaders permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Shaders&lt;/h2&gt;&lt;p&gt;Let’s circle all the way back to those animated blobs. Manipulating and animating 3D geometries is a lot more efficient with shaders. But shaders are a whole different world unto themselves. For starters, there is a special WebGL version of noise, &lt;a href=&quot;https://www.npmjs.com/package/glsl-noise&quot;&gt;glsl-noise&lt;/a&gt;. We’ll need to import that into our shader using &lt;a href=&quot;https://github.com/glslify/glslify&quot;&gt;glslify&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;We’ll take it slow, starting with 2D first.&lt;/p&gt;&lt;div name=&quot;mars.js&quot; link=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/mars.js&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; width=&quot;50%&quot; mx=&quot;auto&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/mars-1e9bcfb5b9cdab7b91519b52d7633a2b.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The animation above is quite similar to the contours we looked at earlier. It’s implemented as a fragment shader. Which means we run the same program for each pixel of the canvas.&lt;/p&gt;&lt;p&gt;Notice the &lt;code class=&quot;language-text&quot;&gt;pragma&lt;/code&gt; line? That’s us importing webgl-noise. Then use it to generate noise data for each pixel position &lt;code class=&quot;language-text&quot;&gt;vUv&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;This part should look quite familiar by now.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;fragment.glsl&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; density&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt; vUv&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;token macro-name&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;&lt;span class=&quot;token number&quot;&gt;3.141592653589793&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; noise &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;glsl&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;noise&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;simplex&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;patternZebra&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; density&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; PI &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;smoothstep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;.1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; s &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fwidth&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token comment&quot;&gt;// Generate noise data&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; amplitude &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; frequency &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; noiseValue &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;noise&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vUv &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token comment&quot;&gt;// Convert noise data to rings&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;patternZebra&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;noiseValue&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mix&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1.&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.369&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.824&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.318&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.369&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Clip the rings to a circle&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; dist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;vUv &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; alpha &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;smoothstep&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.250&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2482&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dist&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  gl_FragColor &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; alpha&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Fragment shaders have this concept of &lt;a href=&quot;https://thebookofshaders.com/07/&quot;&gt;distance functions&lt;/a&gt; used for drawing shapes. &lt;code class=&quot;language-text&quot;&gt;patternZebra&lt;/code&gt; is one such example that converts noise data into rings. Essentially it returns either &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt;. Which we then use to pick a colour using &lt;code class=&quot;language-text&quot;&gt;mix&lt;/code&gt;. And finally, use another distance function to clip a circular boundary.&lt;/p&gt;&lt;p&gt;Seems quite basic?&lt;/p&gt;&lt;p&gt;Well, the amazing thing about shaders is that you can turn them into a material and apply it to more complex geometry.&lt;/p&gt;&lt;h3 id=&quot;noise-material&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#noise-material&quot; aria-label=&quot;noise material permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Noise Material&lt;/h3&gt;&lt;p&gt;We can take the same 2D mars shader from above. Convert it into a ThreeJS &lt;a href=&quot;https://threejs.org/docs/?q=shade#api/en/materials/ShaderMaterial&quot;&gt;shader material&lt;/a&gt;. Then use the vertex position &lt;code class=&quot;language-text&quot;&gt;vPosition&lt;/code&gt; to generate noise instead of &lt;code class=&quot;language-text&quot;&gt;vUv&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;And voilà, we have a 3D Mars!&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; material &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;THREE&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ShaderMaterial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  extensions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    derivatives&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  uniforms&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    time&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    density&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  vertexShader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;/*glsl*/&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    varying vec3 vPosition;
    void main () {
      vPosition = position;
      gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  fragmentShader&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;glslify&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* glsl */&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    precision highp float;
    varying vec3 vPosition;
    uniform float time;
    uniform float density;
    #pragma glslify: noise = require(glsl-noise/simplex/4d);
    #define PI 3.141592653589793
    float patternZebra(float v){
      float d = 1.0 / density;
      float s = -cos(v / d * PI * 2.);
      return smoothstep(.0, .1 * d, .1 * s / fwidth(s));
    }
    void main () {
      float frequency = .6;
      float amplitude = 1.5;
      float v = noise(vec4(vPosition * frequency, sin(PI * time))) * amplitude;
      float t = patternZebra(v);
      vec3 fragColor = mix(vec3(1.,0.4,0.369), vec3(0.824,0.318,0.369), t);
      gl_FragColor = vec4(fragColor, 1.);
    }
    &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div name=&quot;mars.js&quot; link=&quot;https://github.com/winkerVSbecks/3d-sketches/blob/master/sketches/mars.js&quot;&gt;&lt;div bg=&quot;#323132&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; width=&quot;50%&quot; mx=&quot;auto&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/mars-3d-fae61f39f3a67df8e18d4976c2eed51a.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This is honestly just a start. Shaders open up so many possibilities. Like the example below 👻&lt;/p&gt;&lt;p&gt;Not only is noise mapping to colours but, also alpha.&lt;/p&gt;&lt;div name=&quot;ghost-planets.js&quot; link=&quot;https://github.com/winkerVSbecks/3d-sketches/blob/master/sketches/ghost-planets.js&quot;&gt;&lt;div bg=&quot;#110488&quot;&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; width=&quot;50%&quot; mx=&quot;auto&quot; mb=&quot;0&quot;&gt;&lt;source src=&quot;static/ghost-planets-12120729a0c3317399a8d8eb119026c3.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;glossy-blobs&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#glossy-blobs&quot; aria-label=&quot;glossy blobs permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Glossy Blobs&lt;/h3&gt;&lt;p&gt;The idea behind vertex displacement is quite similar. Instead of a fragment shader, we write a vertex shader that transforms each vertex of the sphere. Again, applied using a &lt;a href=&quot;https://threejs.org/docs/?q=shade#api/en/materials/ShaderMaterial&quot;&gt;shader material&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;vertex.glsl&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;glsl&quot;&gt;&lt;pre class=&quot;language-glsl&quot;&gt;&lt;code class=&quot;language-glsl&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;precision&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;highp&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;varying&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; vNormal&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token macro property&quot;&gt;&lt;span class=&quot;token directive-hash&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token directive keyword&quot;&gt;pragma&lt;/span&gt; &lt;span class=&quot;token expression&quot;&gt;glslify&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; snoise4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;glsl&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;noise&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;simplex&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; u_time&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; u_amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;uniform&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; u_frequency&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;main&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  vNormal &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; normalMatrix &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;normalize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normal&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;float&lt;/span&gt; distortion &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;snoise4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normal &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; u_frequency&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; u_time&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; u_amplitude&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;vec3&lt;/span&gt; newPosition &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; position &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normal &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; distortion&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
  gl_Position &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; projectionMatrix &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; modelViewMatrix &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;vec4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;newPosition&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Oh, and throw on some &lt;a href=&quot;https://threejs.org/docs/#api/en/materials/MeshMatcapMaterial&quot;&gt;matcap&lt;/a&gt;, and you’ve got some glossy animated blobs.&lt;/p&gt;&lt;div&gt;Loading...&lt;/div&gt;&lt;h2 id=&quot;your-turn-to-make-some-noise&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#your-turn-to-make-some-noise&quot; aria-label=&quot;your turn to make some noise permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Your turn to make some noise&lt;/h2&gt;&lt;p&gt;That was quite a journey. Motion, textures, fields, particle systems and displacement—noise can do it all. It truly is the workhorse of the creative coding world.&lt;/p&gt;&lt;p&gt;So obviously, you want to play with noise 😁&lt;/p&gt;&lt;p&gt;I’ve put together a little starter CodePen for you. It spins up a grid of noise and maps it to an array of glyphs. Just start by modifying the array and see how far you can take it.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; glyphs &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;¤&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;✳&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;●&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;◔&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;○&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;◕&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;◐&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;◑&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;◒&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or if you’re looking for something more advanced, check out &lt;a href=&quot;https://noisedeck.app/&quot;&gt;noisedeck.app&lt;/a&gt;. It’s like a synthesizer but for visuals.&lt;/p&gt;&lt;p&gt;Either way, don’t forget to share your creations with me on &lt;a href=&quot;https://mobile.twitter.com/winkerVSbecks&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;&lt;div hash=&quot;YzNRaLP&quot; title=&quot;Noise Grid&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Let's Build a Confetti Cannon]]></title><description><![CDATA[Confetti cannons are fun! Both to play with and to build. Let's learn to make one. Along the way, we'll cover particle systems and a bit of…]]></description><link>https://varun.ca/confetti/</link><guid isPermaLink="false">https://varun.ca/confetti/</guid><pubDate>Sat, 19 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;img alt=&quot;&quot; src=&quot;static/confetti-header-6d2c155f1a08237fa90d08b25f52cd83.gif&quot; width=&quot;100%&quot; maxWidth=&quot;400px&quot;/&gt;&lt;p&gt;Confetti cannons are fun! Both to play with and to build. Let’s learn to make one. Along the way, we’ll cover particle systems and a bit of high school physics. I’ll also show you how to integrate a Canvas based animation into a larger application.&lt;/p&gt;&lt;h2 id=&quot;the-confetti-system-&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-confetti-system-&quot; aria-label=&quot;the confetti system  permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Confetti System 🎉&lt;/h2&gt;&lt;p&gt;Confetti is all about a quick pop, followed by a slow, wobbly tumble to the ground. In graphical terms, it can be modelled as a &lt;a href=&quot;https://natureofcode.com/book/chapter-4-particle-systems/&quot;&gt;particle system&lt;/a&gt;.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;“A particle system is a collection of many many minute particles that together represent a fuzzy object. Over a period of time, particles are generated into a system, move and change from within the system, and die from the system.”&lt;/p&gt;&lt;p&gt;— William Reeves, “Particle Systems—A Technique for Modeling a Class of Fuzzy Objects”&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;You’ve seen these before. They are used to model all sorts of natural phenomena: fire, smoke, waterfall, fog, grass, bubbles, a flock of birds, and so on.&lt;/p&gt;&lt;p&gt;We’re not just building any old particle system. We’re building one inspired by Laura Belém’s &lt;a href=&quot;https://www.artbasel.com/catalog/artwork/36465/Laura-Bel%C3%A9m-Carnival-Nights&quot;&gt;Carnival Nights&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&quot;but-why-a-particle-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#but-why-a-particle-system&quot; aria-label=&quot;but why a particle system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;But why a particle system?&lt;/h3&gt;&lt;p&gt;Confetti is made up of many small pieces of paper. Each piece of paper follows the same rules of physics. A particle allows us to encapsulate this behaviour in code. The system manages a collection of these particles. We don’t want to control each particle on its own. Instead, we give the system a few high-level parameters and let it drive the simulation.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 dsJevP&quot;&gt;&lt;figure display=&quot;none,none,block&quot; width=&quot;300&quot; class=&quot;sc-24qoga-0 sc-1lreduh-0 dzUXjn&quot;&gt;&lt;img alt=&quot;&quot; src=&quot;static/confetti-particle-c3495d9df83f93a9c7e33c8fb9f40e9b.svg&quot;/&gt;&lt;/figure&gt;&lt;div display=&quot;none,none,block&quot; class=&quot;sc-24qoga-0 sc-1lreduh-1 iDprnf&quot;&gt;&lt;h3 id=&quot;the-confetti-particle&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-confetti-particle&quot; aria-label=&quot;the confetti particle permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The confetti particle&lt;/h3&gt;&lt;img alt=&quot;&quot; src=&quot;static/confetti-particle-c3495d9df83f93a9c7e33c8fb9f40e9b.svg&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Each particle has a few attributes that define its state:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Start position&lt;/li&gt;&lt;li&gt;Angle: the direction of movement&lt;/li&gt;&lt;li&gt;Velocity: how fast it’s moving&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All combined, these tell us where the particle is, which direction it’s moving in, and how fast.&lt;/p&gt;&lt;h3 id=&quot;lets-move-it&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#lets-move-it&quot; aria-label=&quot;lets move it permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Let’s move it&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;We’ll use the &lt;a href=&quot;https://www.khanacademy.org/science/physics/two-dimensional-motion/two-dimensional-projectile-mot/a/what-are-velocity-components&quot;&gt;velocity components&lt;/a&gt; to move the particle.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This essentially describes the motion in terms of vectors.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;New position = Current Position + Velocity Vector&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Often graphics &amp;amp; physics libraries use an actual vector object. I’m keeping things simple and breaking up the motion into x and y directions.&lt;/p&gt;&lt;p&gt;This is the foundational movement we’ll build on top of. Right now, it lacks any natural characteristics. It is the equivalent of confetti being fired in space. On Earth, its motion is impacted by external forces: friction, air resistance and gravity.&lt;/p&gt;&lt;h3 id=&quot;decay&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#decay&quot; aria-label=&quot;decay permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Decay&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;decay&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;decay&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;decay&quot; name=&quot;decay&quot; value=&quot;0&quot; min=&quot;0.8&quot; max=&quot;1&quot; step=&quot;0.01&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Friction is the first of those forces. We model that as a decay multiplier.&lt;/p&gt;&lt;p&gt;The decay should be less than 1 to slow things down. In each frame, we multiply the velocity by decay. The smaller the value, the quicker it’ll slow down.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decay&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;gravity&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#gravity&quot; aria-label=&quot;gravity permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Gravity&lt;/h3&gt;&lt;p&gt;What goes up must come down, with a bit of gravity.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;gravity&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;gravity&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;gravity&quot; name=&quot;gravity&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;10&quot; step=&quot;1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The confetti’s net motion is a combination of three forces: the initial launch, the decay and the gravity.&lt;/p&gt;&lt;p&gt;It starts by launching upwards. The decay then starts slowing it down. Then eventually, the gravity overpowers it and starts pulling it downwards in the y-direction.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gravity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decay&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Too little gravity, and it’ll look like the confetti was fired on the Moon. And too much gravity will stop it from getting very far. You can tweak the value to find the right balance.&lt;/p&gt;&lt;h3 id=&quot;tilt&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tilt&quot; aria-label=&quot;tilt permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tilt&lt;/h3&gt;&lt;p&gt;The confetti also tilts as it moves. Sometimes rotating just one way and sometimes back and forth.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;Each particle will have a starting tilt angle. Chosen randomly at launch. Which is then animated using &lt;a href=&quot;https://github.com/jwagner/simplex-noise.js&quot;&gt;noise&lt;/a&gt;. Which gives it a more natural tumbling look.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tiltOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tiltAngle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tiltAngle &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; tiltOffset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Noise is a perfect tool for simulating organic motion. Think of it as a smoother form of randomness.&lt;/p&gt;&lt;div&gt;🚂  Not familiar with noise? Checkout this Coding Train episode for a primer: &lt;a href=&quot;https://www.youtube.com/watch?v=Qf4dIN99e2w&quot;&gt;Introduction - Perlin Noise and p5.js Tutorial&lt;/a&gt;&lt;/div&gt;&lt;h3 id=&quot;wobble&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#wobble&quot; aria-label=&quot;wobble permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Wobble&lt;/h3&gt;&lt;p&gt;In nature, things rarely move in straight lines. We’re going to add a bit of wobble. This will simulate the effect of confetti wafting through the air.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;We’ll once again use noise. This time, however, it will add an offset to the x-position of the particle.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Add wobble using 2D noise&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; xOffset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That’s much better. The movement feels a lot more natural now.&lt;/p&gt;&lt;h3 id=&quot;the-particle-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-particle-system&quot; aria-label=&quot;the particle system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The particle system&lt;/h3&gt;&lt;p&gt;Moving on to the particle system. Each particle is an object. This object tracks all its visual characteristics and those related to motion.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;We also need to track the lifetime of each particle. Notice how they fade out after a while? That’s their lifetime. We do this to track when the animation is complete and trigger another one. I chose to track the lifetime as ticks or frame count.&lt;/p&gt;&lt;p&gt;It will be responsible for four aspects:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Creating&lt;/strong&gt; the particles and seeding their initial attributes. For example, launch velocity, tilt and colour.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Updating&lt;/strong&gt; their motion at each tick or frame. And marking them as dead once their allotted tick count has been reached.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Drawing&lt;/strong&gt; the particle&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Resetting&lt;/strong&gt;  the particles once all of them are dead and triggering another pop&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now, some attributes are defined at the system level and passed down. For example, start position, gravity, decay and the size of the particle. While others, such as colour, are set for each particle.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// System Level Attributes&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  particleCount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  radiusRatio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.02&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animDelay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  noInteractionWait&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  velocityFactor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  decay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.94&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  gravity&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  colors&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some attributes are set at the system level but inform individual particles—for example, direction and velocity. We pick a direction of launch. Then each particle is launched in that direction ± a slight variance. The larger the variance, the wider the confetti will spread.&lt;/p&gt;&lt;h3 id=&quot;an-even-spread&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#an-even-spread&quot; aria-label=&quot;an even spread permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;An even spread&lt;/h3&gt;&lt;p&gt;At this point, we have a confetti system. The fun thing about particle systems is that you can tweak their behaviour in all kinds of exciting ways. I wanted to recreate an effect similar to the &lt;a href=&quot;https://www.artbasel.com/catalog/artwork/36465/Laura-Bel%C3%A9m-Carnival-Nights&quot;&gt;original image&lt;/a&gt;. Make the confetti pop from one location, but then get it to spread somewhat evenly across the canvas.&lt;/p&gt;&lt;img alt=&quot;&quot; src=&quot;static/confetti-spread-fffb73960e01575a6011ae0ae25ac995.svg&quot; width=&quot;100%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Instead of cascading the launch angle down to the particle, we’ll try something different. We start by picking a random start position. Based on the bounds, we calculate a random end position—a different one for each particle. Now we have a start point and an endpoint. With a bit of trigonometry, we can calculate the angle between them. And then calculate a launch velocity as a function of the distance between the two points.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setEndLocation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xBounds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; yBounds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;xBounds&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;yBounds&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;launchAngle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;atan2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;launchVelocity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;maxDist&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startVelocity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;startPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; maxDist&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startVelocity &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; startVelocity&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;integrating-it-into-an-app&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#integrating-it-into-an-app&quot; aria-label=&quot;integrating it into an app permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Integrating it into an app&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;I originally built this as a &lt;a href=&quot;https://carnival-nights.netlify.app&quot;&gt;digital greeting card&lt;/a&gt;. It sits inside a larger &lt;a href=&quot;https://github.com/winkerVSbecks/carnival-nights&quot;&gt;Svelte app&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Canvas is quite portable. You can render the DOM node using vanilla HTML or a SPA framework like React or Svelte. And once the DOM node mounts, initialize the animation. The animation then runs in its own loop. You can leave it unattached or trigger a refresh based on props.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;Canvas.svelte&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; onMount &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;svelte&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; initConfettiSystem &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./confetti-system&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; canvasEl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;onMount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;initConfettiSystem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;canvasEl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;canvas&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;carnival-nights&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;bind:&lt;/span&gt;this&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{canvasEl}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;canvas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div display=&quot;block,block,none&quot; class=&quot;sc-24qoga-0 rdEeX&quot;&gt;&lt;h3 id=&quot;the-confetti-particle&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-confetti-particle&quot; aria-label=&quot;the confetti particle permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The confetti particle&lt;/h3&gt;&lt;img alt=&quot;&quot; src=&quot;static/confetti-particle-c3495d9df83f93a9c7e33c8fb9f40e9b.svg&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Each particle has a few attributes that define its state:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Start position&lt;/li&gt;&lt;li&gt;Angle: the direction of movement&lt;/li&gt;&lt;li&gt;Velocity: how fast it’s moving&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;All combined, these tell us where the particle is, which direction it’s moving in, and how fast.&lt;/p&gt;&lt;h3 id=&quot;lets-move-it&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#lets-move-it&quot; aria-label=&quot;lets move it permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Let’s move it&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;We’ll use the &lt;a href=&quot;https://www.khanacademy.org/science/physics/two-dimensional-motion/two-dimensional-projectile-mot/a/what-are-velocity-components&quot;&gt;velocity components&lt;/a&gt; to move the particle.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This essentially describes the motion in terms of vectors.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;New position = Current Position + Velocity Vector&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Often graphics &amp;amp; physics libraries use an actual vector object. I’m keeping things simple and breaking up the motion into x and y directions.&lt;/p&gt;&lt;p&gt;This is the foundational movement we’ll build on top of. Right now, it lacks any natural characteristics. It is the equivalent of confetti being fired in space. On Earth, its motion is impacted by external forces: friction, air resistance and gravity.&lt;/p&gt;&lt;h3 id=&quot;decay&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#decay&quot; aria-label=&quot;decay permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Decay&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;decay&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;decay&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;decay&quot; name=&quot;decay&quot; value=&quot;0&quot; min=&quot;0.8&quot; max=&quot;1&quot; step=&quot;0.01&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Friction is the first of those forces. We model that as a decay multiplier.&lt;/p&gt;&lt;p&gt;The decay should be less than 1 to slow things down. In each frame, we multiply the velocity by decay. The smaller the value, the quicker it’ll slow down.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decay&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;gravity&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#gravity&quot; aria-label=&quot;gravity permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Gravity&lt;/h3&gt;&lt;p&gt;What goes up must come down, with a bit of gravity.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gYGPCf&quot;&gt;&lt;label for=&quot;gravity&quot; font-size=&quot;2&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gIbjSl&quot;&gt;gravity&lt;/label&gt;&lt;input type=&quot;range&quot; id=&quot;gravity&quot; name=&quot;gravity&quot; value=&quot;0&quot; min=&quot;0&quot; max=&quot;10&quot; step=&quot;1&quot; class=&quot;sc-24qoga-0 zSzeV&quot;/&gt;&lt;p font-size=&quot;2&quot; width=&quot;30&quot; font-family=&quot;systemSans&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eMdMHz&quot;&gt;0&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The confetti’s net motion is a combination of three forces: the initial launch, the decay and the gravity.&lt;/p&gt;&lt;p&gt;It starts by launching upwards. The decay then starts slowing it down. Then eventually, the gravity overpowers it and starts pulling it downwards in the y-direction.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;gravity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity &lt;span class=&quot;token operator&quot;&gt;*=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;decay&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Too little gravity, and it’ll look like the confetti was fired on the Moon. And too much gravity will stop it from getting very far. You can tweak the value to find the right balance.&lt;/p&gt;&lt;h3 id=&quot;tilt&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tilt&quot; aria-label=&quot;tilt permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tilt&lt;/h3&gt;&lt;p&gt;The confetti also tilts as it moves. Sometimes rotating just one way and sometimes back and forth.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;Each particle will have a starting tilt angle. Chosen randomly at launch. Which is then animated using &lt;a href=&quot;https://github.com/jwagner/simplex-noise.js&quot;&gt;noise&lt;/a&gt;. Which gives it a more natural tumbling look.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; tiltOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tiltAngle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;tiltAngle &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; tiltOffset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Noise is a perfect tool for simulating organic motion. Think of it as a smoother form of randomness.&lt;/p&gt;&lt;div&gt;🚂  Not familiar with noise? Checkout this Coding Train episode for a primer: &lt;a href=&quot;https://www.youtube.com/watch?v=Qf4dIN99e2w&quot;&gt;Introduction - Perlin Noise and p5.js Tutorial&lt;/a&gt;&lt;/div&gt;&lt;h3 id=&quot;wobble&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#wobble&quot; aria-label=&quot;wobble permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Wobble&lt;/h3&gt;&lt;p&gt;In nature, things rarely move in straight lines. We’re going to add a bit of wobble. This will simulate the effect of confetti wafting through the air.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;We’ll once again use noise. This time, however, it will add an offset to the x-position of the particle.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;angle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;velocity&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xOffset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;noise2D&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;random
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Add wobble using 2D noise&lt;/span&gt;
particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; particle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; xOffset&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That’s much better. The movement feels a lot more natural now.&lt;/p&gt;&lt;h3 id=&quot;the-particle-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-particle-system&quot; aria-label=&quot;the particle system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The particle system&lt;/h3&gt;&lt;p&gt;Moving on to the particle system. Each particle is an object. This object tracks all its visual characteristics and those related to motion.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;We also need to track the lifetime of each particle. Notice how they fade out after a while? That’s their lifetime. We do this to track when the animation is complete and trigger another one. I chose to track the lifetime as ticks or frame count.&lt;/p&gt;&lt;p&gt;It will be responsible for four aspects:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Creating&lt;/strong&gt; the particles and seeding their initial attributes. For example, launch velocity, tilt and colour.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Updating&lt;/strong&gt; their motion at each tick or frame. And marking them as dead once their allotted tick count has been reached.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Drawing&lt;/strong&gt; the particle&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Resetting&lt;/strong&gt;  the particles once all of them are dead and triggering another pop&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Now, some attributes are defined at the system level and passed down. For example, start position, gravity, decay and the size of the particle. While others, such as colour, are set for each particle.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// System Level Attributes&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  particleCount&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;90&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  radiusRatio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.02&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  animDelay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  noInteractionWait&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  velocityFactor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.15&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  decay&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.94&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  gravity&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  colors&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Some attributes are set at the system level but inform individual particles—for example, direction and velocity. We pick a direction of launch. Then each particle is launched in that direction ± a slight variance. The larger the variance, the wider the confetti will spread.&lt;/p&gt;&lt;h3 id=&quot;an-even-spread&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#an-even-spread&quot; aria-label=&quot;an even spread permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;An even spread&lt;/h3&gt;&lt;p&gt;At this point, we have a confetti system. The fun thing about particle systems is that you can tweak their behaviour in all kinds of exciting ways. I wanted to recreate an effect similar to the &lt;a href=&quot;https://www.artbasel.com/catalog/artwork/36465/Laura-Bel%C3%A9m-Carnival-Nights&quot;&gt;original image&lt;/a&gt;. Make the confetti pop from one location, but then get it to spread somewhat evenly across the canvas.&lt;/p&gt;&lt;img alt=&quot;&quot; src=&quot;static/confetti-spread-fffb73960e01575a6011ae0ae25ac995.svg&quot; width=&quot;100%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Instead of cascading the launch angle down to the particle, we’ll try something different. We start by picking a random start position. Based on the bounds, we calculate a random end position—a different one for each particle. Now we have a start point and an endpoint. With a bit of trigonometry, we can calculate the angle between them. And then calculate a launch velocity as a function of the distance between the two points.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setEndLocation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xBounds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; yBounds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;xBounds&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Random&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;yBounds&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;launchAngle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;atan2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;launchVelocity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;maxDist&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startVelocity&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;startPos&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; endPos&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; maxDist&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; startVelocity &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; startVelocity&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;integrating-it-into-an-app&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#integrating-it-into-an-app&quot; aria-label=&quot;integrating it into an app permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Integrating it into an app&lt;/h3&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 gRRpot visualization&quot;&gt;&lt;canvas display=&quot;block&quot; class=&quot;sc-24qoga-0 hWifkc&quot;&gt;&lt;/canvas&gt;&lt;/div&gt;&lt;p&gt;I originally built this as a &lt;a href=&quot;https://carnival-nights.netlify.app&quot;&gt;digital greeting card&lt;/a&gt;. It sits inside a larger &lt;a href=&quot;https://github.com/winkerVSbecks/carnival-nights&quot;&gt;Svelte app&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Canvas is quite portable. You can render the DOM node using vanilla HTML or a SPA framework like React or Svelte. And once the DOM node mounts, initialize the animation. The animation then runs in its own loop. You can leave it unattached or trigger a refresh based on props.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;Canvas.svelte&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; onMount &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;svelte&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; initConfettiSystem &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./confetti-system&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; canvasEl&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;onMount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setTimeout&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function&quot;&gt;initConfettiSystem&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;canvasEl&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;canvas&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;carnival-nights&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;bind:&lt;/span&gt;this&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{canvasEl}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;canvas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You now have a foundational particle system. You can simulate other effects just by tweaking the particle’s attributes and behaviours. Create snow, rain or fireworks. &lt;a href=&quot;https://www.kirilv.com/canvas-confetti/&quot;&gt;Canvas-confetti&lt;/a&gt; is another really great example for reference. Or check out the &lt;a href=&quot;https://github.com/winkerVSbecks/carnival-nights&quot;&gt;source code&lt;/a&gt; for my greeting card to see how I added interactivity.&lt;/p&gt;&lt;img src=&quot;static/flocking-13abca1c04e3b0e1d0fbed793161f8a3.gif&quot; alt=&quot;Flocking simulation&quot; width=&quot;100%&quot; maxWidth=&quot;400px&quot;/&gt;&lt;h3 id=&quot;taking-it-to-the-next-level&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#taking-it-to-the-next-level&quot; aria-label=&quot;taking it to the next level permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Taking It to the Next Level&lt;/h3&gt;&lt;p&gt;With confetti, each particle follows the same rules but runs independently. There are systems where particles interact with each other and influence behaviour. &lt;a href=&quot;https://www.youtube.com/watch?v=mhjuuHl6qHM&quot;&gt;Flocking&lt;/a&gt; is an excellent example of this. In my next post, I’ll cover one such system. Sign up for my newsletter to get an update.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Scrollytelling with React]]></title><description><![CDATA[Scrollytelling is a visual and interactive form of storytelling. It consists of a logical sequence of visualizations. They accompany a…]]></description><link>https://varun.ca/scrollytelling/</link><guid isPermaLink="false">https://varun.ca/scrollytelling/</guid><pubDate>Sat, 12 Dec 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Scrollytelling is a visual and interactive form of storytelling. It consists of a logical sequence of visualizations. They accompany a narrative and are driven by the user’s scrolling. In my &lt;a href=&quot;/torsions/&quot;&gt;last post&lt;/a&gt;, I used this technique to break down an animation. There are plenty of off-the-shelf &lt;a href=&quot;https://codehike.org/&quot;&gt;libraries&lt;/a&gt; that one can use. I wanted something minimal that fit my existing publishing setup and didn’t impact content portability.&lt;/p&gt;&lt;p&gt;Let’s talk about how I built my React and Intersection Observer based solution.&lt;/p&gt;&lt;h2 id=&quot;what-are-we-building&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#what-are-we-building&quot; aria-label=&quot;what are we building permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What Are We Building?&lt;/h2&gt;&lt;p&gt;The setup is largely inspired by &lt;a href=&quot;https://generativeartistry.com/tutorials/&quot;&gt;Generative Artistry&lt;/a&gt;. It is incredibly powerful to put words and updating visuals side by side. This approach works particularly well for incremental tutorials and code walkthroughs.&lt;/p&gt;&lt;div autoplay=&quot;&quot; loop=&quot;&quot; muted=&quot;&quot; playsinline=&quot;&quot; display=&quot;block&quot; mx=&quot;auto&quot; borderColor=&quot;brand.bright&quot; borderWidth=&quot;1px&quot; borderStyle=&quot;solid&quot; borderRadius=&quot;3&quot;&gt;&lt;source src=&quot;static/scrollytelling-791437e91a03c6bc65cc005c0043905a.webm&quot; type=&quot;video/webm&quot;/&gt;&lt;source src=&quot;static/scrollytelling-d138b6acf07a5a6a0900462f33eca3fc.mp4&quot; type=&quot;video/mp4&quot;/&gt;&lt;/div&gt;&lt;h3 id=&quot;whats-involved&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#whats-involved&quot; aria-label=&quot;whats involved permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What’s involved?&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;The actual page layout&lt;/li&gt;&lt;li&gt;A sticky container for the visualization&lt;/li&gt;&lt;li&gt;Tracking the user’s scrolling and updating the visuals accordingly&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;sectioning-content&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#sectioning-content&quot; aria-label=&quot;sectioning content permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Sectioning Content&lt;/h2&gt;&lt;p&gt;The post is broken into discrete steps and each step has a visualization associated with it. But how do you define those steps?&lt;/p&gt;&lt;p&gt;One option would be to define them as an array. That’s not a great authoring experience though. You have to breakdown freeform text into JavaScript. Makes writing and editing super annoying.&lt;/p&gt;&lt;p&gt;Instead, I decided to use &lt;code class=&quot;language-text&quot;&gt;&amp;lt;h3&amp;gt;&lt;/code&gt; elements (in markdown) to signify a step.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;post.mdx&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;md&quot;&gt;&lt;pre class=&quot;language-md&quot;&gt;&lt;code class=&quot;language-md&quot;&gt;&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Lorem ipsum dolor sit amet&lt;/span&gt;

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Pulvinar elementum integer enim neque volutpat ac tincidunt vitae. Ut venenatis tellus in metus. Nulla posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus.

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Mattis aliquam faucibus purus in&lt;/span&gt;

Metus aliquam eleifend mi in nulla posuere. Nunc id cursus metus aliquam eleifend mi. Venenatis cras sed felis eget velit aliquet. Sit amet cursus sit amet dictum sit amet. Orci eu lobortis elementum nibh tellus molestie nunc non blandit. Iaculis nunc sed augue lacus. Quis varius quam quisque id diam. Viverra ipsum nunc aliquet bibendum enim facilisis gravida.

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Nunc sed blandit libero volutpat sed cras ornare arcu dui&lt;/span&gt;

Id aliquet risus feugiat in ante. Mi eget mauris pharetra et ultrices. Sed arcu non odio euismod. Nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Auctor urna nunc id cursus metus aliquam eleifend. Condimentum mattis pellentesque id nibh tortor.

&lt;span class=&quot;token title important&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;##&lt;/span&gt; Et netus et malesuada fames ac&lt;/span&gt;

In est ante in nibh mauris. Aliquam malesuada bibendum arcu vitae elementum curabitur vitae nunc. Id nibh tortor id aliquet lectus proin nibh nisl. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo. Massa sapien faucibus et molestie ac feugiat sed lectus. Ipsum a arcu cursus vitae congue. Sociis natoque penatibus et magnis dis parturient montes. Interdum velit laoreet id donec ultrices.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Cool. So, each of those &lt;code class=&quot;language-text&quot;&gt;##&lt;/code&gt; headings mark the start of a section.&lt;/p&gt;&lt;p&gt;How do you attach visuals to this?&lt;/p&gt;&lt;p&gt;I write my posts in &lt;a href=&quot;https://github.com/mdx-js/mdx&quot;&gt;MDX&lt;/a&gt;. Which means we can use React components within the content. I created a &lt;code class=&quot;language-text&quot;&gt;Scroller&lt;/code&gt; component which can wrap all or a part of the post. And we can pass in a list of figures to this component.&lt;/p&gt;&lt;p&gt;It’s also going to be responsible for the layout and scroll tracking.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;post.mdx&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; figures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;image for section one&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;./img-1&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;image for section two&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;./img-2&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;img&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;alt&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;image for section three&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;./img-3&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
## Lorem ipsum dolor sit amet

Lorem ipsum dolor sit amet&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; consectetur adipiscing elit&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sed &lt;span class=&quot;token keyword&quot;&gt;do&lt;/span&gt; eiusmod tempor incididunt ut labore et dolore magna aliqua&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; Pulvinar elementum integer enim neque volutpat ac tincidunt vitae&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; Ut venenatis tellus &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; metus&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt; Nulla posuere sollicitudin aliquam ultrices sagittis orci a scelerisque purus&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Scroller&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;figures&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;figures&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;## Mattis aliquam faucibus purus in&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;Metus aliquam eleifend mi in nulla posuere. Nunc id cursus metus aliquam eleifend mi. Venenatis cras sed felis eget velit aliquet. Sit amet cursus sit amet dictum sit amet. Orci eu lobortis elementum nibh tellus molestie nunc non blandit. Iaculis nunc sed augue lacus. Quis varius quam quisque id diam. Viverra ipsum nunc aliquet bibendum enim facilisis gravida.&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;## Nunc sed blandit libero volutpat sed cras ornare arcu dui&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;Id aliquet risus feugiat in ante. Mi eget mauris pharetra et ultrices. Sed arcu non odio euismod. Nisl condimentum id venenatis a condimentum vitae sapien pellentesque. Auctor urna nunc id cursus metus aliquam eleifend. Condimentum mattis pellentesque id nibh tortor.&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;## Et netus et malesuada fames ac&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;token plain-text&quot;&gt;In est ante in nibh mauris. Aliquam malesuada bibendum arcu vitae elementum curabitur vitae nunc. Id nibh tortor id aliquet lectus proin nibh nisl. Adipiscing elit duis tristique sollicitudin nibh sit amet commodo. Massa sapien faucibus et molestie ac feugiat sed lectus. Ipsum a arcu cursus vitae congue. Sociis natoque penatibus et magnis dis parturient montes. Interdum velit laoreet id donec ultrices.&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;span class=&quot;token plain-text&quot;&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Scroller&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;layout&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#layout&quot; aria-label=&quot;layout permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Layout&lt;/h2&gt;&lt;p&gt;The layout is relatively straightforward. A flex container that puts the text and visuals side-by-side. The visuals container has a fixed width while the text expands to fill the remaining space.&lt;/p&gt;&lt;div justifyContent=&quot;center&quot;&gt;&lt;div&gt;+----------------------------------------------------------+
| Container                                                |
|                                                          |
| display: flex;                                           |
|                                                          |
| align-items: flex-start;                                 |
|                                                          |
|                                                          |
| +---------------+ +------------------------------------+ |
| |   visuals     | |                                    | |
| |               | |   Text Content                     | |
| |   flex:none   | |                                    | |
| +---------------+ |   flex: 1 1 auto;                  | |
|                   |                                    | |
|                   |                                    | |
|                   |                                    | |
|                   +------------------------------------+ |
+----------------------------------------------------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;Flex container&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;sticky-visuals&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#sticky-visuals&quot; aria-label=&quot;sticky visuals permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Sticky Visuals&lt;/h2&gt;&lt;p&gt;There are no restrictions to what the visuals can be: image, multiple images, video, code blocks, etc. Therefore, they are wrapped in a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;figure&amp;gt;&lt;/code&gt; element. Which in turn uses &lt;code class=&quot;language-text&quot;&gt;position: sticky&lt;/code&gt; for its &lt;em&gt;sticky&lt;/em&gt; behaviour.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;flex&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; none&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; sticky&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 64px&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;margin-left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;margin-top&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;track-scrolling-and-update-visuals&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#track-scrolling-and-update-visuals&quot; aria-label=&quot;track scrolling and update visuals permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Track scrolling and update visuals&lt;/h2&gt;&lt;p&gt;Each section starts with an &lt;code class=&quot;language-text&quot;&gt;&amp;lt;h3&amp;gt;&lt;/code&gt;. We can track to see which of those headings is near the top of the viewport and display the visual for that section.&lt;/p&gt;&lt;figure height=&quot;300&quot; overflow=&quot;hidden&quot; class=&quot;sc-24qoga-0 sc-24qoga-2 dfuYxT&quot;&gt;&lt;div width=&quot;4&quot; height=&quot;4&quot; class=&quot;sc-24qoga-0 sc-1clks1x-2 fqIrdJ&quot;&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 zSzeV&quot;&gt;&lt;div class=&quot;sc-24qoga-0 sc-1clks1x-0 cTKUiB content-placeholder&quot;&gt;&lt;div height=&quot;2&quot; width=&quot;60%&quot; offset=&quot;0&quot; class=&quot;sc-24qoga-0 sc-1clks1x-1 bXKEPn&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;40%&quot; class=&quot;sc-24qoga-0 dAxfSI&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 sc-1clks1x-0 cTKUiB content-placeholder&quot;&gt;&lt;div height=&quot;2&quot; width=&quot;60%&quot; offset=&quot;1&quot; class=&quot;sc-24qoga-0 sc-1clks1x-1 klcnGS&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;40%&quot; class=&quot;sc-24qoga-0 dAxfSI&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 sc-1clks1x-0 cTKUiB content-placeholder&quot;&gt;&lt;div height=&quot;2&quot; width=&quot;60%&quot; offset=&quot;2&quot; class=&quot;sc-24qoga-0 sc-1clks1x-1 dPidlr&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;40%&quot; class=&quot;sc-24qoga-0 dAxfSI&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 sc-1clks1x-0 cTKUiB content-placeholder&quot;&gt;&lt;div height=&quot;2&quot; width=&quot;60%&quot; offset=&quot;3&quot; class=&quot;sc-24qoga-0 sc-1clks1x-1 NqnkF&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;40%&quot; class=&quot;sc-24qoga-0 dAxfSI&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 sc-1clks1x-0 cTKUiB content-placeholder&quot;&gt;&lt;div height=&quot;2&quot; width=&quot;60%&quot; offset=&quot;4&quot; class=&quot;sc-24qoga-0 sc-1clks1x-1 iLsoRE&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;100%&quot; class=&quot;sc-24qoga-0 Hjojc&quot;&gt;&lt;/div&gt;&lt;div height=&quot;1&quot; width=&quot;40%&quot; class=&quot;sc-24qoga-0 dAxfSI&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API&quot;&gt;Intersection Observer&lt;/a&gt; is an efficient tool for this job. I wrote a custom hook that tracks all elements of a specific type, within a particular parent element. And then executes a callback when one of them enters the target area.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;useIntersection.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; useEffect &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;useIntersection&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;ref&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; selector&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; handler&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; observers &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; IntersectionObserver &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;function&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;handleIntersect&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;entries&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;handler&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;entries&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelectorAll&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;selector&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;node&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; observer &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;IntersectionObserver&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
          &lt;span class=&quot;token function&quot;&gt;handleIntersect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          options
        &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;observe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        observers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;observer&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        observers&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;observer&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          observer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;disconnect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;ref&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;current&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;threshold&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; options&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;rootMargin&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We’re going to use this hook in the Scroller component. It’s set up to track all &lt;code class=&quot;language-text&quot;&gt;&amp;lt;h3&amp;gt;&lt;/code&gt; elements within the flex container. Notice the &lt;code class=&quot;language-text&quot;&gt;rootMargin&lt;/code&gt;, that’s how I limit the target area to roughly the top of the viewport.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;scroller.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Scroller&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; figures &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; ScrollerContainerRef &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useRef&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;activeFigure&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setActiveFigure&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token function&quot;&gt;useIntersection&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    ScrollerContainerRef&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;h3&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;entry&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; idx&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;entry&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;intersectionRatio &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;        &lt;span class=&quot;token function&quot;&gt;setActiveFigure&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; threshold&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rootMargin&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;32px 0px -80% 0px&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; figure &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figures&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;activeFigure&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Flex ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ScrollerContainerRef&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; alignItems&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;flex-start&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;StickyFigure width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; mr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;figure&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;StickyFigure&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box maxWidth&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Flex&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now as the user scrolls, the &lt;code class=&quot;language-text&quot;&gt;IntersectionObserver&lt;/code&gt; tracks which heading is near the top. We then update &lt;code class=&quot;language-text&quot;&gt;activeFigure&lt;/code&gt; to that index. Which in turn is used to pick which figure to display.&lt;/p&gt;&lt;p&gt;That’s all there is to it!&lt;/p&gt;&lt;h2 id=&quot;where-can-you-take-this-next&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#where-can-you-take-this-next&quot; aria-label=&quot;where can you take this next permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Where can you take this next?&lt;/h2&gt;&lt;p&gt;One obvious scenario I ran into was mobile. There just isn’t enough space to show text and images side-by-side. So, I split behaviour based on viewport size:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Small viewports:&lt;/strong&gt; hide the sticky visual container and display the visuals inline instead&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Large viewports:&lt;/strong&gt; hide the inline visuals and make the sticky visual container visible&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The inline visuals are placed by the author in the main content body. Check out the &lt;a href=&quot;https://github.com/winkerVSbecks/varun.ca/blob/master/src/components/scroller.js&quot;&gt;source&lt;/a&gt; for this responsive version.&lt;/p&gt;&lt;p&gt;This was just a start. The basic concept is to leverage visuals to explain ideas. And drive those visuals via scrolling. You can use it to modify or highlight code snippets. Add transitions between the visuals. Or drive an animation timeline. The possibilities are endless.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Making things move]]></title><description><![CDATA[One of my favourite forms of creative coding is to add motion to static images. The process is always the same: pick an image, recreate it…]]></description><link>https://varun.ca/torsions/</link><guid isPermaLink="false">https://varun.ca/torsions/</guid><pubDate>Mon, 30 Nov 2020 00:00:00 GMT</pubDate><content:encoded>&lt;figure bg=&quot;#EFEDF5&quot; py=&quot;4&quot;&gt;
  &lt;img bg=&quot;#EFEDF5&quot; width=&quot;400&quot; height=&quot;300&quot; alt=&quot;torsions&quot; src=&quot;/612f931b41307378ccab2f3eccef7d7a/torsions.gif&quot; mb=&quot;0&quot;/&gt;&lt;/figure&gt;&lt;p&gt;One of my favourite forms of creative coding is to add motion to static images. The process is always the same: pick an image, recreate it with Canvas, SVG or WebGL and animate aspects of its geometry. The image above is a good example. It’s based on Walter Leblanc’s print &lt;a href=&quot;https://www.vintage-design-point.be/product/abstract-lithograph-torsie-vorming-in-6-phasen-by-walter-leblanc-1978-69-150/&quot;&gt;&lt;em&gt;Torsions&lt;/em&gt;&lt;/a&gt;. In this post I’m going to break down the process of creating this animation. And share 2D techniques that I often use in my work.&lt;/p&gt;&lt;h2 id=&quot;torsions&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#torsions&quot; aria-label=&quot;torsions permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Torsions&lt;/h2&gt;&lt;p&gt;My go-to tool for creative coding these days is &lt;a href=&quot;https://github.com/mattdesl/canvas-sketch&quot;&gt;canvas-sketch&lt;/a&gt;. It is both a dev enviornment and a framework for creating generative art. By default, it allows you to create pieces using the Canvas API. However, you can also pair it with other graphics libraries like ThreeJS, p5.js, d3, etc. And most importantly it allows you to export high-resolution PNGs, animated GIFs or even render videos.&lt;/p&gt;&lt;p&gt;I’ll do a detailed dive into canvas-sketch in a future post. However, for now all you need to know is overall structure of the program. The &lt;code class=&quot;language-text&quot;&gt;settings&lt;/code&gt; object controls the dimensions and other characteristics of the animation. The &lt;code class=&quot;language-text&quot;&gt;sketch&lt;/code&gt; function recieves the canvas &lt;code class=&quot;language-text&quot;&gt;context&lt;/code&gt; and other props such as canvas &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;playhead&lt;/code&gt;, etc. This is where you also define the actual draw loop. Most of your code will live inside that.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;hello.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Import the library&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; canvasSketch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;canvas-sketch&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Specify some output parameters&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; settings &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The [ width, height ] of the artwork in pixels&lt;/span&gt;
  dimensions&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Is it animated and the duration of the animation&lt;/span&gt;
  animate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  duration&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Start the sketch&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sketch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The draw loop&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Destructure what we need from props&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Now draw a white rectangle in the center&lt;/span&gt;
    context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;strokeStyle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;white&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;lineWidth &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    context&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;strokeRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Start the sketch with parameters&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;canvasSketch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;sketch&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; settings&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 dsJevP&quot;&gt;&lt;figure display=&quot;none,none,block&quot; width=&quot;300&quot; class=&quot;sc-24qoga-0 sc-1lreduh-0 dzUXjn&quot;&gt;&lt;img alt=&quot;Torsions by Walter Leblanc&quot; src=&quot;static/torsions-by-walter-leblanc-2-faa4f949376daf416970b343b6d9d7f3.jpg&quot;/&gt;&lt;/figure&gt;&lt;div display=&quot;none,none,block&quot; class=&quot;sc-24qoga-0 sc-1lreduh-1 iDprnf&quot;&gt;&lt;h3 id=&quot;1-getting-started&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#1-getting-started&quot; aria-label=&quot;1 getting started permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;1. Getting Started&lt;/h3&gt;&lt;p&gt;Our starting point in the original image. This is an ideal scenario. The image essentially gives you keyframes for what the animation should look like. Usually, we’re not that lucky. To figure out what to animate requires a bit more imagination.&lt;/p&gt;&lt;img alt=&quot;Torsions by Walter Leblanc&quot; src=&quot;static/torsions-by-walter-leblanc-2-faa4f949376daf416970b343b6d9d7f3.jpg&quot; maxWidth=&quot;400px&quot; width=&quot;100%&quot;/&gt;&lt;p&gt;So, what exactly is going on here? I see a block of some thickness. The top edge remains fixed while the bottom twists back and forth. As the block twists, the edge warps and creates the tapered look you see on the far right.&lt;/p&gt;&lt;p&gt;All in all, I see three parts: the beige front face, the blue back face and the front-facing edge.&lt;/p&gt;&lt;h3 id=&quot;2-simplified-case--no-thickness&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#2-simplified-case--no-thickness&quot; aria-label=&quot;2 simplified case  no thickness permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;2. Simplified Case — No Thickness&lt;/h3&gt;&lt;p&gt;Let’s reduce this down to the simplest scenario, a flat 2D rectangle that is twisting around. As with hand-drawing, learning to draw with code requires you to observe an object and describe it in terms of lines and curves.&lt;/p&gt;&lt;img alt=&quot;Edge curve animated&quot; src=&quot;static/edge-curve-animated-381dd358ba4bc0a6400466e9be4c0106.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;I see a rectangle with the bottom two vertices oscillating left and right. And the two vertical edges go from a straight line to a curve and then back again.&lt;/p&gt;&lt;p&gt;What is that curve?&lt;/p&gt;&lt;h3 id=&quot;3-edge-curve&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#3-edge-curve&quot; aria-label=&quot;3 edge curve permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;3. Edge Curve&lt;/h3&gt;&lt;p&gt;To me this looks a like a cosine wave. There is no cosine path API for Canvas, however, you can draw it using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo&quot;&gt;bezier path API&lt;/a&gt;.&lt;/p&gt;&lt;img alt=&quot;Edge curve&quot; src=&quot;static/edge-curve-aca82639b8c8c135d11b4cc034798e5b.png&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;A bezier curve requires four points: start, end and two control points. This should be quite familiar if you’ve ever worked with vector paths in Illustrator, Sketch or Figma. Now, we know the start and endpoints. They are two vertices of the rectangle.&lt;/p&gt;&lt;p&gt;So, what about the control points? A quick google took me to this Stackoverflow &lt;a href=&quot;https://stackoverflow.com/a/29214613&quot;&gt;answer&lt;/a&gt;. Here’s how you can calculate the two control points:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Where (x1, y1) is the start and (x2, y2) the end points&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I’ve actually used this technique in a previous post, &lt;a href=&quot;/chillwave/&quot;&gt;chillwave&lt;/a&gt;. Check it out for a full deep dive.&lt;/p&gt;&lt;h3 id=&quot;4-straight-edge-to-curve-and-back-again&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#4-straight-edge-to-curve-and-back-again&quot; aria-label=&quot;4 straight edge to curve and back again permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;4. Straight Edge to Curve and Back Again&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Edge curve control point&quot; src=&quot;static/edge-curve-bottom-animated-140b35537bc5086dca393d73b4b65365.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;Edge curve control point&quot; src=&quot;static/edge-curve-cp-animated-620d66b20e836b4a50abd4331b0b5009.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;The edge oscillates between a straight line and a curve. This requires two movements:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Horizontal movement of the bottom vertices&lt;/li&gt;&lt;li&gt;Vertical movement of the top vertex and the bottom control point&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The first movement controls the twist i.e., moves the bottom right vertex to the left and vice versa. The second collapses the curve into a straight line.&lt;/p&gt;&lt;h3 id=&quot;5-combining-the-movements&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#5-combining-the-movements&quot; aria-label=&quot;5 combining the movements permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;5. Combining the Movements&lt;/h3&gt;&lt;p&gt;By synchronizing the two movements we achieve the desired result. The curve appears as the bar twists, and straightens as the bar untwists.&lt;/p&gt;&lt;img alt=&quot;Edge curve combined motion&quot; src=&quot;static/edge-curve-animated-combined-1622a85e147b4e64535a3234d8824587.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;And then run the whole thing in reverse.&lt;/p&gt;&lt;p&gt;Here’s a handy little trick to get the animation to alternate its direction.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sketch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The draw loop&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pingPongPlayhead &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;playhead &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Canvas-sketch gives you a &lt;code class=&quot;language-text&quot;&gt;playhead&lt;/code&gt; property. It goes from 0 to 1. By passing it through the sine function, you can make it oscillate from 0 to 1 and back to 0 in the same time duration. Use this &lt;code class=&quot;language-text&quot;&gt;pingPongPlayhead&lt;/code&gt; value to drive the two movements above.&lt;/p&gt;&lt;p&gt;BTW I’m only describing the geometry of the left edge here. You can draw the right edge as a mirror image.&lt;/p&gt;&lt;h3 id=&quot;6-adding-a-thick-edge&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#6-adding-a-thick-edge&quot; aria-label=&quot;6 adding a thick edge permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;6. Adding a Thick Edge&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Double curve&quot; src=&quot;static/double-curve-87b82cf8249290016d45c2ac03d2837c.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;The double curves join to create a thick edge&quot; src=&quot;static/edge-thickness-7b79445bd7711b339720e1d0ae073549.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;Let’s go beyond that flat 2D rectangle. You can add the 3D perspective by making the edge appear thicker. To do so, draw it twice with a slight offset. The start point is same for both the curves. It’s only the end point that is different. Therefore, when you join the two curves you get this triangular-ish strip. The larger the offset the thicker the edge will appear.&lt;/p&gt;&lt;h3 id=&quot;7-combine-the-edge-and-faces&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#7-combine-the-edge-and-faces&quot; aria-label=&quot;7 combine the edge and faces permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;7. Combine the Edge and Faces&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Face and edge&quot; src=&quot;static/face-and-edge-aaad3dde7b203b5dbbd8f82463eb124d.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;The double curves join to create a thick edge&quot; src=&quot;static/edge-thickness-7b79445bd7711b339720e1d0ae073549.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;I broke down the animation into two layers: the flat faces and the edge. By combining the two we get this perception of a block of some thickness twisting around.&lt;/p&gt;&lt;p&gt;To be honest, I thought I was done, but there’s an issue. Observe the edge. At first, you don’t see the edge, then slowly, the edge appears and then it disappears again as the block twists entirely. That isn’t correct. The edge should remain visible in that fully twisted state. However, it does being to taper. Let’s fix that.&lt;/p&gt;&lt;h3 id=&quot;8-correcting-perspective&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#8-correcting-perspective&quot; aria-label=&quot;8 correcting perspective permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;8. Correcting Perspective&lt;/h3&gt;&lt;img alt=&quot;The double curves join to create a thick edge&quot; src=&quot;static/edge-thickness-7b79445bd7711b339720e1d0ae073549.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Let’s go back to that control point calculation. Notice the &lt;code class=&quot;language-text&quot;&gt;lerpFrames&lt;/code&gt; here. I added that back in step 4, to animate the bottom control point.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;edgeCurve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lerpFrames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, we’ll add a variation to this. When the perspective flag is enabled the control point will extend a bit further. Draw one curve with this variation and one without to get that tapered look.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;edgeCurve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; perspective&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; perspective
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lerpFrames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lerpFrames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;9-colouring-faces&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#9-colouring-faces&quot; aria-label=&quot;9 colouring faces permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;9. Colouring Faces&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Intersections&quot; src=&quot;static/intersections-d8f9502a13cc49322bf01df7f6bc1384.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;Edge curve split&quot; src=&quot;static/edge-curve-split-b5568df5395b8b90b08c0048e8e25ec5.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;Almost there. So far we’ve drawn the twisty rectangle and added an edge to it. The last bit is to render different colours for the front and back faces. Beidge for the front and blue for the back.&lt;/p&gt;&lt;p&gt;As the rectangle twists, the two sides intersect. The shape formed by the top two vertices and the point of intersection is the front-face. And the rest is the backface. First up, we need to find the point of intersection.&lt;/p&gt;&lt;p&gt;Remember the two sides are bezier curves. I used &lt;a href=&quot;https://twitter.com/TheRealPomax&quot;&gt;Pomax’s&lt;/a&gt; fantastic &lt;a href=&quot;http://pomax.github.io/bezierjs&quot;&gt;bezierjs&lt;/a&gt; library. It has an &lt;code class=&quot;language-text&quot;&gt;.intersects&lt;/code&gt; function built in. If the curves aren’t intersecting then simply draw the front face. Otherwise, render the two parts with the appropriate colour.&lt;/p&gt;&lt;h3 id=&quot;10-putting-it-all-together&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#10-putting-it-all-together&quot; aria-label=&quot;10 putting it all together permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;10. Putting It All Together&lt;/h3&gt;&lt;p&gt;In total there are three parts to the final image:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The twisty rectangle&lt;/li&gt;&lt;li&gt;Which gets replaced by the split faces&lt;/li&gt;&lt;li&gt;And finally the edge that layers on top at all times&lt;/li&gt;&lt;/ol&gt;&lt;img alt=&quot;Edge curve split&quot; src=&quot;static/final-ff2064576fefe9bad4071df86936ba66.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Combine them, and success!&lt;/p&gt;&lt;p&gt;I love creating these 2D drawings of 3D shapes. With 3D engines you define 3D geometry. The 2D approach is a lot like sketching. You create curves and then morph them as the image animates.&lt;/p&gt;&lt;p&gt;Checkout the &lt;a href=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/torsions.js&quot;&gt;full source&lt;/a&gt; on Github.&lt;/p&gt;&lt;/div&gt;&lt;div display=&quot;block,block,none&quot; class=&quot;sc-24qoga-0 rdEeX&quot;&gt;&lt;h3 id=&quot;1-getting-started&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#1-getting-started&quot; aria-label=&quot;1 getting started permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;1. Getting Started&lt;/h3&gt;&lt;p&gt;Our starting point in the original image. This is an ideal scenario. The image essentially gives you keyframes for what the animation should look like. Usually, we’re not that lucky. To figure out what to animate requires a bit more imagination.&lt;/p&gt;&lt;img alt=&quot;Torsions by Walter Leblanc&quot; src=&quot;static/torsions-by-walter-leblanc-2-faa4f949376daf416970b343b6d9d7f3.jpg&quot; maxWidth=&quot;400px&quot; width=&quot;100%&quot;/&gt;&lt;p&gt;So, what exactly is going on here? I see a block of some thickness. The top edge remains fixed while the bottom twists back and forth. As the block twists, the edge warps and creates the tapered look you see on the far right.&lt;/p&gt;&lt;p&gt;All in all, I see three parts: the beige front face, the blue back face and the front-facing edge.&lt;/p&gt;&lt;h3 id=&quot;2-simplified-case--no-thickness&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#2-simplified-case--no-thickness&quot; aria-label=&quot;2 simplified case  no thickness permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;2. Simplified Case — No Thickness&lt;/h3&gt;&lt;p&gt;Let’s reduce this down to the simplest scenario, a flat 2D rectangle that is twisting around. As with hand-drawing, learning to draw with code requires you to observe an object and describe it in terms of lines and curves.&lt;/p&gt;&lt;img alt=&quot;Edge curve animated&quot; src=&quot;static/edge-curve-animated-381dd358ba4bc0a6400466e9be4c0106.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;I see a rectangle with the bottom two vertices oscillating left and right. And the two vertical edges go from a straight line to a curve and then back again.&lt;/p&gt;&lt;p&gt;What is that curve?&lt;/p&gt;&lt;h3 id=&quot;3-edge-curve&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#3-edge-curve&quot; aria-label=&quot;3 edge curve permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;3. Edge Curve&lt;/h3&gt;&lt;p&gt;To me this looks a like a cosine wave. There is no cosine path API for Canvas, however, you can draw it using the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo&quot;&gt;bezier path API&lt;/a&gt;.&lt;/p&gt;&lt;img alt=&quot;Edge curve&quot; src=&quot;static/edge-curve-aca82639b8c8c135d11b4cc034798e5b.png&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;A bezier curve requires four points: start, end and two control points. This should be quite familiar if you’ve ever worked with vector paths in Illustrator, Sketch or Figma. Now, we know the start and endpoints. They are two vertices of the rectangle.&lt;/p&gt;&lt;p&gt;So, what about the control points? A quick google took me to this Stackoverflow &lt;a href=&quot;https://stackoverflow.com/a/29214613&quot;&gt;answer&lt;/a&gt;. Here’s how you can calculate the two control points:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Where (x1, y1) is the start and (x2, y2) the end points&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I’ve actually used this technique in a previous post, &lt;a href=&quot;/chillwave/&quot;&gt;chillwave&lt;/a&gt;. Check it out for a full deep dive.&lt;/p&gt;&lt;h3 id=&quot;4-straight-edge-to-curve-and-back-again&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#4-straight-edge-to-curve-and-back-again&quot; aria-label=&quot;4 straight edge to curve and back again permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;4. Straight Edge to Curve and Back Again&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Edge curve control point&quot; src=&quot;static/edge-curve-bottom-animated-140b35537bc5086dca393d73b4b65365.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;Edge curve control point&quot; src=&quot;static/edge-curve-cp-animated-620d66b20e836b4a50abd4331b0b5009.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;The edge oscillates between a straight line and a curve. This requires two movements:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Horizontal movement of the bottom vertices&lt;/li&gt;&lt;li&gt;Vertical movement of the top vertex and the bottom control point&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The first movement controls the twist i.e., moves the bottom right vertex to the left and vice versa. The second collapses the curve into a straight line.&lt;/p&gt;&lt;h3 id=&quot;5-combining-the-movements&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#5-combining-the-movements&quot; aria-label=&quot;5 combining the movements permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;5. Combining the Movements&lt;/h3&gt;&lt;p&gt;By synchronizing the two movements we achieve the desired result. The curve appears as the bar twists, and straightens as the bar untwists.&lt;/p&gt;&lt;img alt=&quot;Edge curve combined motion&quot; src=&quot;static/edge-curve-animated-combined-1622a85e147b4e64535a3234d8824587.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;And then run the whole thing in reverse.&lt;/p&gt;&lt;p&gt;Here’s a handy little trick to get the animation to alternate its direction.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;sketch&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// The draw loop&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; context&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pingPongPlayhead &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;playhead &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ...&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Canvas-sketch gives you a &lt;code class=&quot;language-text&quot;&gt;playhead&lt;/code&gt; property. It goes from 0 to 1. By passing it through the sine function, you can make it oscillate from 0 to 1 and back to 0 in the same time duration. Use this &lt;code class=&quot;language-text&quot;&gt;pingPongPlayhead&lt;/code&gt; value to drive the two movements above.&lt;/p&gt;&lt;p&gt;BTW I’m only describing the geometry of the left edge here. You can draw the right edge as a mirror image.&lt;/p&gt;&lt;h3 id=&quot;6-adding-a-thick-edge&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#6-adding-a-thick-edge&quot; aria-label=&quot;6 adding a thick edge permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;6. Adding a Thick Edge&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Double curve&quot; src=&quot;static/double-curve-87b82cf8249290016d45c2ac03d2837c.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;The double curves join to create a thick edge&quot; src=&quot;static/edge-thickness-7b79445bd7711b339720e1d0ae073549.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;Let’s go beyond that flat 2D rectangle. You can add the 3D perspective by making the edge appear thicker. To do so, draw it twice with a slight offset. The start point is same for both the curves. It’s only the end point that is different. Therefore, when you join the two curves you get this triangular-ish strip. The larger the offset the thicker the edge will appear.&lt;/p&gt;&lt;h3 id=&quot;7-combine-the-edge-and-faces&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#7-combine-the-edge-and-faces&quot; aria-label=&quot;7 combine the edge and faces permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;7. Combine the Edge and Faces&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Face and edge&quot; src=&quot;static/face-and-edge-aaad3dde7b203b5dbbd8f82463eb124d.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;The double curves join to create a thick edge&quot; src=&quot;static/edge-thickness-7b79445bd7711b339720e1d0ae073549.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;I broke down the animation into two layers: the flat faces and the edge. By combining the two we get this perception of a block of some thickness twisting around.&lt;/p&gt;&lt;p&gt;To be honest, I thought I was done, but there’s an issue. Observe the edge. At first, you don’t see the edge, then slowly, the edge appears and then it disappears again as the block twists entirely. That isn’t correct. The edge should remain visible in that fully twisted state. However, it does being to taper. Let’s fix that.&lt;/p&gt;&lt;h3 id=&quot;8-correcting-perspective&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#8-correcting-perspective&quot; aria-label=&quot;8 correcting perspective permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;8. Correcting Perspective&lt;/h3&gt;&lt;img alt=&quot;The double curves join to create a thick edge&quot; src=&quot;static/edge-thickness-7b79445bd7711b339720e1d0ae073549.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Let’s go back to that control point calculation. Notice the &lt;code class=&quot;language-text&quot;&gt;lerpFrames&lt;/code&gt; here. I added that back in step 4, to animate the bottom control point.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;edgeCurve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lerpFrames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, we’ll add a variation to this. When the perspective flag is enabled the control point will extend a bit further. Draw one curve with this variation and one without to get that tapered look.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;edgeCurve&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; perspective&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; perspective
    &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lerpFrames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;lerpFrames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.37&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; playhead&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cp2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;K2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;cp2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;9-colouring-faces&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#9-colouring-faces&quot; aria-label=&quot;9 colouring faces permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;9. Colouring Faces&lt;/h3&gt;&lt;div alignItems=&quot;center&quot;&gt;&lt;img alt=&quot;Intersections&quot; src=&quot;static/intersections-d8f9502a13cc49322bf01df7f6bc1384.gif&quot; mr=&quot;3&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;img alt=&quot;Edge curve split&quot; src=&quot;static/edge-curve-split-b5568df5395b8b90b08c0048e8e25ec5.gif&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; maxWidth=&quot;300px&quot;/&gt;&lt;/div&gt;&lt;p&gt;Almost there. So far we’ve drawn the twisty rectangle and added an edge to it. The last bit is to render different colours for the front and back faces. Beidge for the front and blue for the back.&lt;/p&gt;&lt;p&gt;As the rectangle twists, the two sides intersect. The shape formed by the top two vertices and the point of intersection is the front-face. And the rest is the backface. First up, we need to find the point of intersection.&lt;/p&gt;&lt;p&gt;Remember the two sides are bezier curves. I used &lt;a href=&quot;https://twitter.com/TheRealPomax&quot;&gt;Pomax’s&lt;/a&gt; fantastic &lt;a href=&quot;http://pomax.github.io/bezierjs&quot;&gt;bezierjs&lt;/a&gt; library. It has an &lt;code class=&quot;language-text&quot;&gt;.intersects&lt;/code&gt; function built in. If the curves aren’t intersecting then simply draw the front face. Otherwise, render the two parts with the appropriate colour.&lt;/p&gt;&lt;h3 id=&quot;10-putting-it-all-together&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#10-putting-it-all-together&quot; aria-label=&quot;10 putting it all together permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;10. Putting It All Together&lt;/h3&gt;&lt;p&gt;In total there are three parts to the final image:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The twisty rectangle&lt;/li&gt;&lt;li&gt;Which gets replaced by the split faces&lt;/li&gt;&lt;li&gt;And finally the edge that layers on top at all times&lt;/li&gt;&lt;/ol&gt;&lt;img alt=&quot;Edge curve split&quot; src=&quot;static/final-ff2064576fefe9bad4071df86936ba66.gif&quot; maxWidth=&quot;300px&quot;/&gt;&lt;p&gt;Combine them, and success!&lt;/p&gt;&lt;p&gt;I love creating these 2D drawings of 3D shapes. With 3D engines you define 3D geometry. The 2D approach is a lot like sketching. You create curves and then morph them as the image animates.&lt;/p&gt;&lt;p&gt;Checkout the &lt;a href=&quot;https://github.com/winkerVSbecks/sketchbook/blob/master/torsions.js&quot;&gt;full source&lt;/a&gt; on Github.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;now-your-turn&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#now-your-turn&quot; aria-label=&quot;now your turn permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Now, your turn&lt;/h2&gt;&lt;p&gt;Find an image and create an animation for yourself. Looking for inspiration? &lt;a href=&quot;https://www.pinterest.ca/winkervsbecks/_saved/&quot;&gt;Pinterest&lt;/a&gt;, &lt;a href=&quot;https://winkervsbecks.tumblr.com/&quot;&gt;Tumblr&lt;/a&gt;, &lt;a href=&quot;https://dribbble.com/winkerVSbecks/collections&quot;&gt;Dribbble&lt;/a&gt; and &lt;a href=&quot;https://www.artsy.net/&quot;&gt;Artsy&lt;/a&gt; are my go to places.&lt;/p&gt;&lt;p&gt;Also, I would highly recommend this MDN &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths&quot;&gt;guide&lt;/a&gt; on paths. Paths are going to be the foundation of any 2D piece. While this guide focuses on SVGs, the Canvas API is nearly identical.&lt;/p&gt;&lt;p&gt;And if you create something, I would love to see it. Give me a shout on &lt;a href=&quot;https://twitter.com/winkerVSbecks&quot;&gt;Twitter&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[React Icon System]]></title><description><![CDATA[Icons play a crucial role in interface design. They can certainly be used as visual embellishments, but they are quite often able to convey…]]></description><link>https://varun.ca/react-icon-system/</link><guid isPermaLink="false">https://varun.ca/react-icon-system/</guid><pubDate>Wed, 10 Jun 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Icons play a crucial role in interface design. They can certainly be used as visual embellishments, but they are quite often able to convey their meaning without additional text, making them a handy tool for designers &amp;amp; developers. There are &lt;a href=&quot;https://css-tricks.com/?s=icon%20system&quot;&gt;many&lt;/a&gt; different ways to build icon systems. In the past, I have &lt;a href=&quot;/icon-component&quot;&gt;written&lt;/a&gt; about a sprite based technique. Since then, tooling has matured and there are better approaches. This article will show you how to set up an icon system using &lt;a href=&quot;https://react-svgr.com&quot;&gt;SVGR&lt;/a&gt; — a tool for transforming SVGs into React components.&lt;/p&gt;&lt;h2 id=&quot;prepare-the-svg-files&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#prepare-the-svg-files&quot; aria-label=&quot;prepare the svg files permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Prepare the SVG Files&lt;/h2&gt;&lt;p&gt;Our starting point will be SVG files – one per icon. You will likely use design tools like Figma, Illustrator or Sketch to create these.&lt;/p&gt;&lt;p&gt;When designing these icons, consider using a consistent artboard size. This ensures that all icons follow the same layout rules and can be used interchangeably. You should also consider adding a bit of padding to your artboard to keep the icon content visually centred.&lt;/p&gt;&lt;figure px=&quot;4&quot;&gt;&lt;flex alignItems=&quot;center&quot;&gt;&lt;img mb=&quot;0&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; src=&quot;static/icon-frame-fe122f110f2cb96cb67b1f95fba67ee4.png&quot;/&gt;&lt;box width=&quot;1&quot;&gt;&lt;/box&gt;&lt;img mb=&quot;0&quot; width=&quot;50%&quot; flex=&quot;1 1 50%&quot; src=&quot;static/icon-live-area-ee8d3c9a978e44b92dc62741b19e55b1.png&quot;/&gt;&lt;/flex&gt;&lt;figcaption&gt;Artboard size, live area and padding&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id=&quot;generating-the-icon-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#generating-the-icon-components&quot; aria-label=&quot;generating the icon components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Generating the Icon Components&lt;/h2&gt;&lt;p&gt;SVGR converts SVG files into React components. It is available as a Node library, a CLI tool and a webpack plugin.&lt;/p&gt;&lt;p&gt;Create React App comes &lt;a href=&quot;https://create-react-app.dev/docs/adding-images-fonts-and-files/#adding-svgs&quot;&gt;pre-configured&lt;/a&gt; with SVGR. You can import an SVG file and use it as a component. This is a great start. It reduces the effort required to use SVGs with React.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ReactComponent &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Logo &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./logo.svg&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;/* Logo is an actual React component */&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Logo &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;By using the SVGR CLI, you can customize the component generation and improve your workflow further. You can provide a custom template for component generation and even transform the SVG itself. To start, install the CLI using:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ npm install @svgr/cli --save-dev&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To create an icon, run:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ npx svgr --icon --replace-attr-values &amp;quot;#000=currentColor&amp;quot; my-icon.svg&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice, the &lt;code class=&quot;language-text&quot;&gt;--icon&lt;/code&gt; flag. It performs a couple of important tasks for us:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;It sets the width and height values to &lt;code class=&quot;language-text&quot;&gt;1em&lt;/code&gt; to make the SVG scale with the inherited font-size.&lt;/li&gt;&lt;li&gt;It preserves &lt;code class=&quot;language-text&quot;&gt;viewBox&lt;/code&gt; to ensure that the SVG scales with the correct aspect ratio.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;--replace-attr-values &amp;quot;#000=currentColor&amp;quot;&lt;/code&gt; flag replaces the chosen color with &lt;code class=&quot;language-text&quot;&gt;currentColor&lt;/code&gt;, allowing you to control the icon color using the &lt;code class=&quot;language-text&quot;&gt;font-color&lt;/code&gt; CSS property.&lt;/p&gt;&lt;p&gt;Behind the scenes, SVGR also uses &lt;a href=&quot;https://github.com/svg/svgo&quot;&gt;SVGO&lt;/a&gt; to optimize the SVG file before converting it into a component. This is a sample of what you can expect the output to look like:&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;MyIcon.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;SvgMyIcon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;svg
      width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;1em&amp;quot;&lt;/span&gt;
      height&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;1em&amp;quot;&lt;/span&gt;
      viewBox&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;0 0 24 24&amp;quot;&lt;/span&gt;
      fill&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;none&amp;quot;&lt;/span&gt;
      stroke&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;currentColor&amp;quot;&lt;/span&gt;
      strokeWidth&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      strokeLinecap&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;round&amp;quot;&lt;/span&gt;
      strokeLinejoin&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;round&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;path d&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;M22 12h-4l-3 9L9 3l-3 9H2&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;svg&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; SvgMyIcon&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To transform an entire directory of icons, use:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;sh&quot;&gt;&lt;pre class=&quot;language-sh&quot;&gt;&lt;code class=&quot;language-sh&quot;&gt;$ npx svgr --icon --replace-attr-values &amp;quot;#000=currentColor&amp;quot; -d icons icons&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I generally treat these generated icon components as build artifacts. All the SVG files live in an &lt;code class=&quot;language-text&quot;&gt;icon&lt;/code&gt; directory, and the &lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt; files within that directory are ignored by git. Then use an npm task to generate the icon components at build time.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;package.json&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  ...
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;scripts&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&amp;quot;start&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;react-scripts start&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&amp;quot;build&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;react-scripts build&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token property&quot;&gt;&amp;quot;prebuild&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;npm run icons&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;    &lt;span class=&quot;token property&quot;&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;react-scripts test&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&amp;quot;eject&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;react-scripts eject&amp;quot;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token property&quot;&gt;&amp;quot;icons&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;svgr --icon --replace-attr-values &amp;#x27;#000=currentColor&amp;#x27; -d src/icons src/icons&amp;quot;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;customizing-the-icon-component&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#customizing-the-icon-component&quot; aria-label=&quot;customizing the icon component permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Customizing the Icon Component&lt;/h3&gt;&lt;p&gt;You can provide a custom template to modify the generated component code. The template below creates an icon component that leverages styled-components to control its styling.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;icon-template.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; template &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  opts&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; imports&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; componentName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; jsx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; exports &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; styledComponentName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Styled&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; componentName&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; template&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ast&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;imports&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    import styled from &amp;#x27;styled-components&amp;#x27;;

    const SVG = (&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;props&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;) =&amp;gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;jsx&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;

    const &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;componentName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; = styled(SVG)\`
      display: \${(props) =&amp;gt; (props.block ? &amp;#x27;block&amp;#x27; : &amp;#x27;inline-block&amp;#x27;)};
      font-size: \${(props) =&amp;gt; (props.fontSize ? props.fontSize : &amp;#x27;16px&amp;#x27;)};
      color: \${(props) =&amp;gt; (props.color ? props.color : &amp;#x27;#ccc&amp;#x27;)};
      vertical-align: middle;
      shape-rendering: inherit;
      transform: translate3d(0, 0, 0);
    \`;

    export default &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;componentName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; template&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For the Radius design system, we are using TypeScript, styled-components and styled-system. Our &lt;a href=&quot;https://github.com/rangle/radius/blob/master/packages/ds/icon-template.js&quot;&gt;custom template&lt;/a&gt; generated icons that are correctly typed and appropriately connected to our design tokens.&lt;/p&gt;&lt;h2 id=&quot;compound-icons-component&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#compound-icons-component&quot; aria-label=&quot;compound icons component permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Compound Icons Component&lt;/h2&gt;&lt;p&gt;We can further simplify the icons’ usage by combining all the generated icons into one compound Icons component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Icons &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;ds&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Icons&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Airplay aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;airplay the video&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Icons&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;AlertCircle aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;error&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SVGR allows us to specify a custom index template. This template is used to generate the &lt;code class=&quot;language-text&quot;&gt;index.js&lt;/code&gt; file when transforming a directory of SVGs. The following template generates a compound component.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;icon-index-template.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; path &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;path&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;indexTemplate&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;files&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; compoundExportEntries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; importEntries &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; files&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; componentName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;basename&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; path&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;extname&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;file&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    compoundExportEntries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;componentName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;import { default as &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;componentName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; } from &amp;#x27;./&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;componentName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;importEntries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;\n&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;

    export const Icons = {
      &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;compoundExportEntries&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;,\n  &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    };
  &lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

module&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;exports &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; indexTemplate&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It adds an import statement for all the components, generates a name for the component based on the file name and finally combines them all into the &lt;code class=&quot;language-text&quot;&gt;Icons&lt;/code&gt; object.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;src/icons/index.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Activity &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./Activity&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; Airplay &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./Airplay&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; AlertCircle &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./AlertCircle&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt; AlertOctagon &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./AlertOctagon&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Icons &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  Activity&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  Airplay&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  AlertCircle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  AlertOctagon&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here is the final version of the npm task:&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;package.json&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;scripts&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ...
    &lt;span class=&quot;token property&quot;&gt;&amp;quot;icons&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;svgr --icon --replace-attr-values &amp;#x27;#000=currentColor&amp;#x27; --template icon-template.js --index-template ./icon-index-template.js -d src/icons src/icons&amp;quot;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;SVGR is a fantastic tool. You can use it out of the box with Create React App. You can also customize it to better fit your workflow. The full code for this example is available &lt;a href=&quot;https://github.com/winkerVSbecks/react-icons-demo&quot;&gt;here&lt;/a&gt;. For a more complex example, I recommend checking out the Radius &lt;a href=&quot;https://github.com/rangle/radius/tree/master/packages/ds&quot;&gt;source-code&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Figma Plugins]]></title><description><![CDATA[Figma plugins extend the core product's functionality and allow designers to enhance and automate their workflow. Building a plugin is…]]></description><link>https://varun.ca/figma-plugins/</link><guid isPermaLink="false">https://varun.ca/figma-plugins/</guid><pubDate>Wed, 20 May 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Figma plugins extend the core product’s functionality and allow designers to enhance and automate their workflow. Building a plugin is relatively approachable. The shape of a plugin is quite similar to that of a website. However, it is a significant jump to go from making your first plugin to writing one that tackles a more sophisticated user problem. In this post, I’m going to break down the architecture of Figma plugins and describe how to use &lt;a href=&quot;https://rsms.me/figplug&quot;&gt;figplug&lt;/a&gt; to reduce some of the tooling complexity.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If you can code a webpage with basic HTML and JavaScript, you can build a Figma plugin.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;That’s the motto that the Figma team adopted when designing their plugin &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Glossary/API&quot;&gt;API&lt;/a&gt;. I’m focusing on designers here. Instead of relying on engineers, I want you to be able to build plugins for yourself. I’m going to assume familiarity with HTML, CSS and JavaScript. However, I will try my best to explain the modern JavaScript ecosystem and the various tools you are likely to encounter when writing plugins.&lt;/p&gt;&lt;p&gt;If you have never created a plugin, start with this &lt;a href=&quot;https://www.figma.com/plugin-docs/setup/&quot;&gt;tutorial&lt;/a&gt; first.&lt;/p&gt;&lt;h2 id=&quot;whats-in-a-plugin&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#whats-in-a-plugin&quot; aria-label=&quot;whats in a plugin permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What’s in a Plugin?&lt;/h2&gt;&lt;p&gt;A website is an HTML page that runs in the browser. You can use CSS to control the visual styling of the page and JavaScript to handle user interactions.&lt;/p&gt;&lt;p&gt;Similarly, a Figma plugin is a little website that runs inside Figma… kind of. The plugin has two parts:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Main Plugin Code —&lt;/strong&gt; JavaScript code that can interact with the Figma file, modify its contents or generate new content.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Optional UI —&lt;/strong&gt; an iframe that renders the UI associated with your plugin, inputs, sliders, buttons, etc.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The diagram below visualizes a Figma plugin, click to step through the explanation.&lt;/p&gt;&lt;div style=&quot;border:none&quot; width=&quot;100%&quot; height=&quot;550&quot; src=&quot;https://www.figma.com/embed?embed_host=share&amp;amp;url=https%3A%2F%2Fwww.figma.com%2Fproto%2FIlQnd9MJTFvzt1M67anyXo%2FFigma-Plugin-Architecture%3Fnode-id%3D65%253A0%26scaling%3Dscale-down-width&quot; allowfullscreen=&quot;&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;the-shape-of-a-plugin&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-shape-of-a-plugin&quot; aria-label=&quot;the shape of a plugin permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Shape of a Plugin&lt;/h2&gt;&lt;p&gt;Plugins fall into two categories:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Run Once —&lt;/strong&gt; doesn’t require the user to interact with the plugin after it runs once.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;With UI &amp;amp; browser APIs —&lt;/strong&gt; allows users to interact with your plugin and provides access to the full set of browser APIs like &lt;code class=&quot;language-text&quot;&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; and network.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;img src=&quot;/dbbf098b72c8c28d5ff32e300b3e5864/plugin-types.svg&quot; alt=&quot;Run once plugins require a manifest and plugin file, while With UI plugins require an additional ui.html file&quot;/&gt;&lt;/p&gt;&lt;p&gt;Where:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;manifest.json&lt;/code&gt; — metadata that describes your plugin. Its name, version of the plugin API you want to use, what file has the main plugin code and what file has the UI code.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;plugin.js&lt;/code&gt; — the main Javascript code of your plugin.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;ui.html&lt;/code&gt; (optional) — the UI associated with your plugin. You can write inline CSS and JavaScript or load it from other &lt;code class=&quot;language-text&quot;&gt;.css&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.js&lt;/code&gt; files.&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;example&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#example&quot; aria-label=&quot;example permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Example&lt;/h3&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:800px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:25%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;100\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20100\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M184%209c0%202%201%203%208%203l7-1%204-1%203-1-3-1-4-1-8-1h-7v3m120%2017l-8%201c-5%200-6%200-6%202%200%203%2031%201%2032-2%200-2-1-2-9-2l-9%201m-82%2038c1%203%204%204%2014%204%206%200%206%200%206-3v-2l-10-1c-10%200-10%200-10%202\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;sample output of the confetting plugin&quot; title=&quot;sample output of the confetting plugin&quot; src=&quot;/static/a9a1d305aafedd1d5a49e145135964d7/5a190/confetti-example.png&quot; srcSet=&quot;/static/a9a1d305aafedd1d5a49e145135964d7/477c9/confetti-example.png 288w,/static/a9a1d305aafedd1d5a49e145135964d7/533c1/confetti-example.png 576w,/static/a9a1d305aafedd1d5a49e145135964d7/5a190/confetti-example.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Throughout this post, I’ll build out the Confetti plugin. It draws a bunch of confetti in a selected frame. The manifest file looks something like this:&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;manifest.json&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Confetti&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;737805260747778092&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;api&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;plugin.js&amp;quot;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The ID property will be provided to you by Figma, through the &lt;em&gt;Create new Plugin&lt;/em&gt; feature.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;plugin.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Draw the confetti&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;createConfetti&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Make sure to close the plugin when you&amp;#x27;re done. Otherwise the plugin will&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// keep running, which shows the cancel button at the bottom of the screen.&lt;/span&gt;
figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closePlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createConfetti&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Make sure the user has only selected one node&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;error: select a frame to render into&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; frameNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selection&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Ensure that the selected node is a frame&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;FRAME&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;error: select a frame to render into&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; colors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.094&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.627&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.984&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.482&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.38&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.105&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.49&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.949&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.282&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.133&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.921&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;randomRange&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;low&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; low&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;randomColor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; index&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Create a rectangle&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createRectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Assign a random width and height to the rectangle&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Randomly position the rectangle within the frame&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Set a random color&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fills &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;SOLID&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Add the rectangle to the frame&lt;/span&gt;
    frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rect&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above plugin allows the user to select a frame and render 50 rectangles within it, with random size, location and colour. It picks from a list of six predefined colours. What if you wanted to allow the user to define a colour palette or control the number of rectangles? For that, we would need to add in the plugin UI.&lt;/p&gt;&lt;h3 id=&quot;creating-a-user-interface&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#creating-a-user-interface&quot; aria-label=&quot;creating a user interface permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Creating a User Interface&lt;/h3&gt;&lt;p&gt;Create an HTML file containing the markup for your UI and then modify the manifest file to add the UI property. Notice the &lt;code class=&quot;language-text&quot;&gt;postMessage&lt;/code&gt; here. When the user clicks on the button, we grab the rectangle count and send a message to the main plugin code.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;ui.html&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Number of rectangles:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;50&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;draw&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Draw Confetti&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;#draw&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onclick&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;#number&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;postMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; pluginMessage&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;create-confetti&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;*&amp;#x27;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;manifest.json&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Confetti&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;737805260747778092&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;api&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;plugin.js&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token property&quot;&gt;&amp;quot;ui&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;ui.html&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div style=&quot;border:none&quot; width=&quot;100%&quot; height=&quot;550&quot; src=&quot;https://www.figma.com/embed?embed_host=share&amp;amp;url=https%3A%2F%2Fwww.figma.com%2Fproto%2FIlQnd9MJTFvzt1M67anyXo%2FFigma-Plugin-Architecture%3Fnode-id%3D272%253A109%26scaling%3Dscale-down-width&quot; allowfullscreen=&quot;&quot;&gt;&lt;/div&gt;&lt;p&gt;We need to make a few modifications to the plugin code too. We start by telling Figma to show the UI. Then we register a listener for messages. This listener is going to receive all messages from the UI. If the right type of message comes along, then we draw the confetti and close the plugin.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;plugin.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;showUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__html__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ui&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onmessage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;create-confetti&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; msg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;number&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token function&quot;&gt;createConfetti&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Make sure to close the plugin when you&amp;#x27;re done. Otherwise the plugin will&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// keep running, which shows the cancel button at the bottom of the screen.&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closePlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createConfetti&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Make sure the user has only selected one node&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;error: select a frame to render into&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; frameNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selection&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Ensure that the selected node is a frame&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;FRAME&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;error: select a frame to render into&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; colors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.094&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.627&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.984&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.482&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.38&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.105&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.49&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.949&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.282&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.133&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.921&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;randomRange&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;low&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; low&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;randomColor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; index&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Create a rectangle&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createRectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Assign a random width and height to the rectangle&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Randomly position the rectangle within the frame&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Set a random color&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fills &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;SOLID&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Add the rectangle to the frame&lt;/span&gt;
    frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rect&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;displaying-errors&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#displaying-errors&quot; aria-label=&quot;displaying errors permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Displaying Errors&lt;/h3&gt;&lt;p&gt;So far, we have seen how to send messages from the iframe to the sandbox. This allows us to get information from the user or other sources (via network requests) and send that to our plugin. There are also going to be scenarios where you want to send information from the sandbox to the iframe. For example, to display errors encountered by the plugin.&lt;/p&gt;&lt;div style=&quot;border:none&quot; width=&quot;100%&quot; height=&quot;550&quot; src=&quot;https://www.figma.com/embed?embed_host=share&amp;amp;url=https%3A%2F%2Fwww.figma.com%2Fproto%2FIlQnd9MJTFvzt1M67anyXo%2FFigma-Plugin-Architecture%3Fnode-id%3D311%253A152%26scaling%3Dscale-down-width&quot; allowfullscreen=&quot;&quot;&gt;&lt;/div&gt;&lt;p&gt;In the plugin code, replace &lt;code class=&quot;language-text&quot;&gt;console.error&lt;/code&gt; with &lt;code class=&quot;language-text&quot;&gt;postMessage&lt;/code&gt; to dispatch errors to the UI.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;plugin.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;showUI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;__html__&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ui&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onmessage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; status&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;create-confetti&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;typeof&lt;/span&gt; msg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;number&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    status &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createConfetti&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;msg&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Make sure to close the plugin when you&amp;#x27;re done. Otherwise the plugin will&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// keep running, which shows the cancel button at the bottom of the screen.&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closePlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createConfetti&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Make sure the user has only selected one node&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selection&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ui&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;postMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;select a frame to render into&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; frameNode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;currentPage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selection&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Ensure that the selected node is a frame&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;!==&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;FRAME&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;ui&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;postMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      value&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;select a frame to render into&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; colors &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.094&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.627&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.984&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.482&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.38&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.105&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.49&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.949&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.282&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.133&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.921&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;randomRange&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;low&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; high&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; high&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; low&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;randomColor&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;floor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; colors&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; index &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; index&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Create a rectangle&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; rect &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createRectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Assign a random width and height to the rectangle&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.01&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.05&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Randomly position the rectangle within the frame&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Set a random color&lt;/span&gt;
    rect&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fills &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;SOLID&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;randomColor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Add the rectangle to the frame&lt;/span&gt;
    frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;rect&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;success&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the UI code, add a listener for the messages. The &lt;code class=&quot;language-text&quot;&gt;showError&lt;/code&gt; function then displays the error to the user.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;ui.html&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Number of rectangles:&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;label&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;input&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;50&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;b&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;errors&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;b&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;draw&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Draw Confetti&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;#draw&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onclick&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; count &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;#number&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    parent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;postMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; pluginMessage&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;create-confetti&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;Number&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;*&amp;#x27;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;errorMessage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;querySelector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;#errors&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;textContent &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error:&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; errorMessage&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onmessage&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;event&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; message &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pluginMessage&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;error&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token function&quot;&gt;showError&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;message&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;value&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;accelerate-the-development-process&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#accelerate-the-development-process&quot; aria-label=&quot;accelerate the development process permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Accelerate the Development Process&lt;/h2&gt;&lt;p&gt;At this point, the UI looks pretty raw, just default browser styling. Unfortunately, Figma doesn’t offer any out of the box solution. There is no official component library to make your plugin UI match that of Figma. There are however, some great open-source options like &lt;a href=&quot;https://github.com/thomas-lowry/figma-plugin-ds&quot;&gt;figma-plugin-ds&lt;/a&gt;, &lt;a href=&quot;https://github.com/thomas-lowry/figma-plugin-ds-svelte&quot;&gt;figma-plugin-ds-svelte&lt;/a&gt;, &lt;a href=&quot;https://github.com/lessmess-dev/figma-ui-components&quot;&gt;figma-ui-components&lt;/a&gt; and &lt;a href=&quot;https://github.com/yuanqing/create-figma-plugin&quot;&gt;create-figma-plugin&lt;/a&gt;.&lt;/p&gt;&lt;img alt=&quot;the plugin ui has default browser styling&quot; src=&quot;static/plugin-ui-0ad0853d02a683ee1c7a1c6cada9266f.png&quot; style=&quot;box-shadow:0 2px 14px rgba(0,0,0,.15), 0 0 0 0.5px rgba(0,0,0,.2);border-radius:4px;max-width:300px&quot;/&gt;&lt;p&gt;As soon as you introduce UI, the complexity level of building a plugin ramps up pretty quickly — forms, error handling and styling the UI. You could stick with vanilla HTML, CSS and JS. A lot of people prefer to use frameworks such as React, Vue or Svelte to make their life easier. For example, you probably don’t want to implement your own colour picker. You could use the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/color&quot;&gt;colour picker&lt;/a&gt; built into the browser or something fancier like &lt;a href=&quot;http://casesandberg.github.io/react-color&quot;&gt;react-color&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Figma also recommends using TypeScript to write your plugin. This is not mandatory. You can use vanilla JavaScript or any other language which can be translated to JavaScript. Using TypeScript does give you a better editing experience.&lt;/p&gt;&lt;p&gt;The modern front-end development ecosystem is built to handle such complexity. We use &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;NPM&lt;/a&gt; to install code written by others, code like chroma.js, Vue, figma-ui-components, react-color, etc. Tools like Webpack or Rollup package up your code and other’s code into one file. Even translate TypeScript code into JavaScript. It can be quite overwhelming to set up all these tools so, most frameworks offer tools to create a new application. You might have come across &lt;a href=&quot;https://reactjs.org/docs/create-a-new-react-app.html&quot;&gt;Create React App&lt;/a&gt; or the &lt;a href=&quot;https://cli.vuejs.org/&quot;&gt;Vue CLI&lt;/a&gt;. They generate boilerplate code for you. That way, you only need to focus on your code and the boilerplate handles the rest.&lt;/p&gt;&lt;h3 id=&quot;figplug&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#figplug&quot; aria-label=&quot;figplug permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;figplug&lt;/h3&gt;&lt;p&gt;For Figma plugins, I like to use &lt;a href=&quot;https://rsms.me/figplug&quot;&gt;figplug&lt;/a&gt;. It handles TypeScript, React/JSX, asset bundling, plugin manifest generation, etc. There are some other really great &lt;a href=&quot;https://github.com/thomas-lowry/figma-plugins-on-github#resources&quot;&gt;alternatives&lt;/a&gt; too. Fire up your terminal and use the following commands to install figplug and initialize your first plugin.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install figplug&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; -g figplug
&lt;span class=&quot;token comment&quot;&gt;# create a plugin&lt;/span&gt;
figplug init -ui confetti
&lt;span class=&quot;token comment&quot;&gt;# build a plugin&lt;/span&gt;
figplug build -w confetti
&lt;span class=&quot;token comment&quot;&gt;# Your plugin is now available in &amp;quot;confetti/build&amp;quot;.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# -w makes figbuild watch your source files for changes&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# and rebuild your plugin automatically.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here’s the full &lt;a href=&quot;https://github.com/winkerVSbecks/figma-plugin-example-confetti/tree/ui-html&quot;&gt;source-code&lt;/a&gt; for the confetti plugin, using figplug. You’ll notice a few modifications to account for TypeScript. Also, the UI code is split into an HTML file and a TS file. Figplug builds and packages it all up for you.&lt;/p&gt;&lt;p&gt;To use React, initialize the plugin with &lt;code class=&quot;language-text&quot;&gt;-react&lt;/code&gt; flag. Here’s the full &lt;a href=&quot;https://github.com/winkerVSbecks/figma-plugin-example-confetti&quot;&gt;source-code&lt;/a&gt; for the React &amp;amp; figma-plugin-ds version of the plugin. If you are new to React, I highly recommend &lt;a href=&quot;https://www.framer.com/blog/posts/react-for-web-designers&quot;&gt;React for Web Designers&lt;/a&gt;. The ID property will be assigned to you by Figma.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;bash&quot;&gt;&lt;pre class=&quot;language-bash&quot;&gt;&lt;code class=&quot;language-bash&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# Install figplug&lt;/span&gt;
&lt;span class=&quot;token function&quot;&gt;npm&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;install&lt;/span&gt; -g figplug
&lt;span class=&quot;token comment&quot;&gt;# create a plugin&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;figplug init -react confetti&lt;/span&gt;&lt;span class=&quot;token comment&quot;&gt;# build a plugin&lt;/span&gt;
figplug build -w confetti&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;multi-command-plugins&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#multi-command-plugins&quot; aria-label=&quot;multi command plugins permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Multi-Command Plugins&lt;/h2&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:944px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:50.34722222222222%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;202\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20202\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2023v22h10c15%200%2021%201%2021%203h-1c-1-1-1%201-1%206l-1%208%202%202c1%201-6%201-14%201H0v7h32v-6h168v18l-1-9-1-8v8l1%209-83%201-84%201v83h169v-56h84c92%200%2086%200%2086-5%200-2-2-2-85-2h-85V86h170V74l-1-14c-1-2-6-2-85-2l-84%201V39l-85-1H32V1L16%200H0v23\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;The context menu displays a list of all plugins, and their sub-commands as a nested menu&quot; title=&quot;The context menu displays a list of all plugins, and their sub-commands as a nested menu&quot; src=&quot;/static/baa61db7395d9c7d95126e17fb5588c5/966a0/figma-commands.png&quot; srcSet=&quot;/static/baa61db7395d9c7d95126e17fb5588c5/477c9/figma-commands.png 288w,/static/baa61db7395d9c7d95126e17fb5588c5/533c1/figma-commands.png 576w,/static/baa61db7395d9c7d95126e17fb5588c5/966a0/figma-commands.png 944w&quot; sizes=&quot;(max-width: 944px) 100vw, 944px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;You can break up various features of your plugin into multiple commands. These commands are available to the user via the context menu and defined in the manifest file.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;manifest.json&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;api&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Pack&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;843186203578433973&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;plugin.ts&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token property&quot;&gt;&amp;quot;menu&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Circle&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;circle&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Square&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;square&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let’s look at an example, Pack. It is a plugin that fills a frame using the &lt;a href=&quot;https://generativeartistry.com/tutorials/circle-packing&quot;&gt;Circle packing&lt;/a&gt; effect. The user can choose between two different fill shapes.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:52.77777777777778%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;211\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20211\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M238%2022c-5%201-7%207-4%2010%201%201%201%201-2%201-6%200-10%207-5%2011%206%206%2015-3%209-9-1-2-1-2%201-1%204%200%208-2%208-6s-3-7-7-6m43%200c-41%205-68%2051-53%2090%203%208%203%208-1%205-10-9-22%205-13%2014l3%203h-3c-3%201-4%205-1%206%203%202%205-1%205-4-1-2%200-2%203-2%205%200%2010-5%209-10v-5l3%205c3%205%204%205%201%204-1%200-4%202-4%204l-2%202c-3%200-6%205-3%208l-4%201c-12-1-14%2018-1%2021%2010%202%2016-15%207-20-1-1-1-1%201-1%204%200%206-5%203-8-1-1-1-1%201-1%203%201%205-1%204-3l7%205%2013%2010c6%204%206%204%203%204-5%201-5%208%201%208h2l-2%203c-8%2011%200%2024%2013%2024%2014%200%2020-20%207-28-3-1-2-2%2010-2%2019%200%2034-5%2045-16%203-2%203-2%203%200-1%202%201%205%204%204%202%200%202%200%201%204l-2%207c0%204%200%204-2%202-3-3-5-3-8%200s-3%204%200%208c4%203%208%202%2010-3l1-3v2c3%2010%2015%2015%2026%2011v1c-3%204%202%2010%206%207%204-2%202-8-3-8-2%200-2%200%201-3%2011-9%208-25-4-31l-4-2h3c3-1%206-5%206-8-2-5-8-7-11-3-2%201-2%201-2-2-1-3-4-5-7-3l-2%201%202-7c2-5%203-6%203-4%200%2014%2021%2015%2021%201%200-11-14-15-20-5l-1%203v-3c5-22-1-44-14-60-5-6-6-7-3-7l2%202c0%202%203%203%205%203%202-1%203-4%200-6h-3c-1%201-2%200-2-2s1-3%202-2c5%201%209-7%206-10-6-4-12%201-9%207v2c-2-1-5%201-5%203%200%203%200%203-7-2-14-9-30-13-47-11m85%200c-8%202-6%2014%202%2014%204%200%208-4%208-7%200-5-5-9-10-7M82%2029v18l1%2016h34V29l-17-1-18%201m272%209c-7%205-6%2015%202%2019s17-4%2015-14c-2-6-12-9-17-5M34%2039l-1%206v5h13V38h-6l-6%201m98%2030v23h48V45h-48v24m234-6c-2%202-3%203-3%206%200%207%208%2011%2014%206%207-8-3-18-11-12M23%2065v6l1%205h11V64h-6l-6%201m22%2019l1%2019h38V65H45v19m169-16c-7%205%200%2015%207%2010%204-3%204-7%200-10-3-3-4-3-7%200M103%2078v5h12V72h-12v6m263%2010c-5%204-3%2010%203%2010%204%200%206-2%206-6%200-5-5-7-9-4M91%20107l1%2012h24V95H91v12m36%2029v23h47v-47h-47v24m221-11l-7%208c-3%204-3%204-1%204%203-1%205%201%204%204%200%202%200%202%203%200%203-4%209-6%2014-6%203%200%203%200%201-2-1-1-2-2-2-5s0-3-1-2c-3%203-7%201-8-4%200-2-1-1-3%203M34%20141v16h33v-33H34v17m42-3v5h11v-10H76v5m159%202c-4%202-5%206-2%209%202%203%207%203%209%200%204-5-1-11-7-9m84%2015l-2%204c0%204%202%206%206%206%203%200%205-2%205-6%200-3-3-6-5-6l-4%202m-84%200c-3%202-5%206-4%209%201%206%207%209%2012%206%202-1%202-1%201%201-1%205%206%209%209%205%204-3%201-10-4-9-3%201-3%200-2-3%201-7-6-12-12-9m70%201c-4%202-3%209%201%2011%207%202%2012-6%207-10-2-2-6-3-8-1m-208%206v6h12v-12H97v6m79%201v5h11v-10h-11v5m-150%206v5h11v-10H26v5m191%200c-4%203-1%2010%204%2010%203%200%206-3%206-6%200-5-7-8-10-4m103%200v2c0%202-1%202-4%201-3%200-4%200-7%203s-3%203-3%201c0-3-2-5-5-5s-5%202-5%205c0%205%205%207%208%204%202-2%202-1%202%202%202%208%2014%2010%2017%203%200-2%200-2%201%201%202%205%208%204%208-2%200-2-5-4-6-2-1%201-2%200-2-2l-3-5c-1-2-1-2%201-2%203%201%205-2%204-4s-6-3-6%200m12%201c-1%203%201%206%204%205%202%200%202%200%201%203-3%206%203%2011%208%208%203-2%203-2%203%200%201%204%208%204%209%200s-6-7-8-3c-1%201-1%201-1-2%200-5-3-8-7-7-2%201-3%201-2-1%201-4-5-7-7-3m-268%208v8h16v-17H64v9m-20-2v6h13v-12H44v6m192-2c-5%203-3%2011%203%2011l3-2c1-1%202-1%203%201%201%204%206%204%207%201%203-4-4-8-7-4-1%201-1%201-1-2%200-4-4-7-8-5m-120%207v6h13v-13h-13v7m100%200v7c2%201%207%201%207-1l2%201c3%203%207%201%206-3-1-3-5-2-6%200h-1c0-4-5-6-8-4\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Circles and squares packed into a rectangle&quot; title=&quot;Circles and squares packed into a rectangle&quot; src=&quot;/static/f744831be06c1e33f78092d8651adbe0/4ad3a/pack-demo.png&quot; srcSet=&quot;/static/f744831be06c1e33f78092d8651adbe0/477c9/pack-demo.png 288w,/static/f744831be06c1e33f78092d8651adbe0/533c1/pack-demo.png 576w,/static/f744831be06c1e33f78092d8651adbe0/4ad3a/pack-demo.png 1152w,/static/f744831be06c1e33f78092d8651adbe0/b8bf8/pack-demo.png 1728w,/static/f744831be06c1e33f78092d8651adbe0/a88f6/pack-demo.png 1900w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;In the plugin code, use the &lt;code class=&quot;language-text&quot;&gt;figma.command&lt;/code&gt; property to determine which command the user selected. Check out the full source code on &lt;a href=&quot;https://github.com/winkerVSbecks/figma-plugin-examples/tree/circle-pack&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;plugin.ts&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; pack &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;pack-spheres&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;drawPack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;closePlugin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;drawPack&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; shapes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    circle&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; drawCircle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    square&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; drawSquare&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; circle &lt;span class=&quot;token keyword&quot;&gt;of&lt;/span&gt; circles&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; shapes&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;command&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;circle&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/span&gt;    frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;node&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;drawCircle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createEllipse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fills &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;SOLID&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;drawSquare&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;circle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; node &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; figma&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createRectangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;**&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; circle&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;position&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;resize&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  node&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;fills &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;SOLID&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; node&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;relaunch-buttons&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#relaunch-buttons&quot; aria-label=&quot;relaunch buttons permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Relaunch Buttons&lt;/h3&gt;&lt;p&gt;Let’s say the user is not happy with the result of the packing effect, and they want to regenerate it. They could delete the content of the frame and execute the plugin again. Alternatively, we can give them a shortcut using the &lt;a href=&quot;https://www.figma.com/plugin-docs/manifest/#relaunchbuttons&quot;&gt;Relaunch Button&lt;/a&gt; feature. You can specify these shortcut commands under the &lt;code class=&quot;language-text&quot;&gt;relaunchButtons&lt;/code&gt; property of the manifest.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;manifest.json&lt;/div&gt;&lt;div class=&quot;gatsby-highlight has-highlighted-lines&quot; data-language=&quot;json&quot;&gt;&lt;pre class=&quot;language-json&quot;&gt;&lt;code class=&quot;language-json&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;api&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;1.0.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Pack&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;843186203578433973&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;main&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;plugin.ts&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;&amp;quot;menu&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Circle&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;circle&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Square&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;square&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token property&quot;&gt;&amp;quot;relaunchButtons&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&amp;quot;command&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;regenerate&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;      &lt;span class=&quot;token property&quot;&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;quot;Regenerate&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;gatsby-highlight-code-line&quot;&gt;  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the plugin code, you can attach the command to any node of your document. For example, the following will attach the regenerate command to the selected frame. This relaunch command is available to the user under the plugins sections of the right sidebar.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;frameNode&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setRelaunchData&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; regenerate&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;regenerate the packing effect&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:67.0138888888889%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;268\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20268\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M20%2028v13h142a5404%205404%200%2001184%200h34V14H20v14m128%2064c-2%201-2%202-1%204l1%203%201%202v-2l2-1c2%200%202%200%201%203-3%203-2%205%201%205h2c1%201%200%202-1%202l-1%202c1%201%200%202-3%203l-3%203c-1%201%202%203%203%203h2l-3%203-2%201h2l1%205-1%205c-2%200-3%200-2%201l2%201%202%201h-1c-2%200-2%200-2%202l-1%203v2l2%201c0%201%201%202%203%202s3-1%203-2l3%201%206%204h2l-2%201h-3c-2-1-3-1-3%201l1%201v2c-3%206%201%2013%207%2013%203%200%208-3%208-6h3l-1%202c-2%200-1%203%201%203l1-1c0-1%201-2%202-1l2%201%201%202%201-2v-2l1%202%203%202c2-1%203-4%200-5-2%200-2-7%200-7v3c0%202%200%202%202%203l1%201c-1%203%205%206%207%204%201-2%206-1%207%200h2c0-2%201-2%203-1h5c1-2%201-2%203%200%201%202%202%202%203%202%203-1%204-4%202-6-2-1-2-3%200-5v-2h-5l-1%202h-2v-4c-1-1-3%200-3%201l-1%201c-2%201-2%201%200-3%202-3%204-3%206%200%201%202%205%201%205-2l-3-1-3-1-2-1c-2%201-2%200-2-2l-1-3%201-2%201%201c0%203%203%205%205%203h5c1-1%201-1-1-2-2%200-3-3%200-3v-2c-2-2-2-2%200-4%205-4-1-13-8-12h-1l3-1%201-1-2-1-1-1%201-1%201-2c-1-1-1-1%201-1l2%201v2l1%201v2l1%203c2%201%203-2%202-3v-3l-1-3c-2%200-1-5%201-6%202%200%201-3-1-3l-4-1c-2%200-2%200-2%202l-1%203v-3c0-4%202-5%205-3%201%201%204%200%204-2l-4-1c-3%200-3-1-3-3s-1-2-2-2l-2-2h-3c0%202-1%202-3%200-3-2-10-1-13%202-2%202-3%202-3%200l-3-1c-1%201-2%200-2-1l-1-1-1%202c0%203-2%202-2%200l-2-2v4c1%200%202%205%200%205-1%201-1%200-1-2%200-3-4-7-8-7l-6%202c-2%203-2%203-2%201s-1-3-3-2h-2c-2-1-2-1-3%201h-2c-2-3-3-2-5%200m44%2036v9l2-2%207-1%204-1%203-2v-1l2-7c2-2%202-2%200-2l-1%201-1%201-2-1c0-4-2-2-2%202%200%202%201%203%202%203l1%202-1%201-2-2h-1l-1%202-1%202-1-2-2-1-1%201c1%201-1%202-2%201v-1c1-1%200-2-1-4v-4l-1-2-1%208m-38%2020v2l-2%201c-4%200-7%204-5%208l1%202c-1%200-1%201%201%204%201%202%202%202%203%201h5c2-3%200-5-3-3-2%201-4%200-4-1l2-1c4%200%207-5%204-8-2-1-1-2%200-3l1-2h-3m209%2073c-5%203-5%208-2%2010%207%205%2014-4%208-9-3-2-4-2-6-1\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;The frame has a regenerate command attached to it&quot; title=&quot;The frame has a regenerate command attached to it&quot; src=&quot;/static/64c3a013d9949f01180f28f80b8fd92b/4ad3a/relaunch-data.png&quot; srcSet=&quot;/static/64c3a013d9949f01180f28f80b8fd92b/477c9/relaunch-data.png 288w,/static/64c3a013d9949f01180f28f80b8fd92b/533c1/relaunch-data.png 576w,/static/64c3a013d9949f01180f28f80b8fd92b/4ad3a/relaunch-data.png 1152w,/static/64c3a013d9949f01180f28f80b8fd92b/b8bf8/relaunch-data.png 1728w,/static/64c3a013d9949f01180f28f80b8fd92b/7e9b1/relaunch-data.png 2252w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;The execution is handled much like other commands. You can check the value of &lt;code class=&quot;language-text&quot;&gt;figma.command&lt;/code&gt; and perform the associated &lt;a href=&quot;https://github.com/winkerVSbecks/figma-plugin-examples/blob/circle-pack/plugin.ts#L59&quot;&gt;operation&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;One of my biggest challenges with learning a new skill is not having a mental model of how it works. It gets incredibly frustrating because you are not even sure what to search for. I know this was a lot of information. Hopefully, it has helped you develop your mental model of how Figma plugins work and what to search for when you are stuck.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Styled System Revisited]]></title><description><![CDATA[Much has changed in the world of Styled System since my last  post . There are fewer packages to deal with; it is much more performant and…]]></description><link>https://varun.ca/styled-system-revisited/</link><guid isPermaLink="false">https://varun.ca/styled-system-revisited/</guid><pubDate>Sun, 19 Apr 2020 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Much has changed in the world of Styled System since my last &lt;a href=&quot;https://varun.ca/styled-system&quot;&gt;post&lt;/a&gt;. There are fewer packages to deal with; it is much more performant and has a more straightforward and powerful API. I recently helped build Rangle’s open-source design system kit, &lt;a href=&quot;https://rangle.io/radius&quot;&gt;Radius&lt;/a&gt;. We used Styled System, and it was a great experience. It remains my preferred tool for building design systems. However, I did have to update my understanding of the tool and adopt newer architectural patterns.&lt;/p&gt;&lt;h2 id=&quot;the-design-graph&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-design-graph&quot; aria-label=&quot;the design graph permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Design Graph&lt;/h2&gt;&lt;p&gt;The foundation of the Styled System API is the &lt;a href=&quot;https://jxnblk.com/blog/design-graph&quot;&gt;Design Graph&lt;/a&gt; — a constraint-based system for organizing styles in UI design. It consists of four parts: scales, theme, variants and components.&lt;/p&gt;&lt;h3 id=&quot;scales&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#scales&quot; aria-label=&quot;scales permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Scales&lt;/h3&gt;&lt;p&gt;Design Tokens is a &lt;a href=&quot;https://www.youtube.com/watch?v=wDBEc3dJJV8&quot;&gt;familiar&lt;/a&gt; term by now. They define the visual characteristics of a brand or a product such as typography, colours, icons, and spacing. They make it easier to maintain a scalable, consistent system for UI development.&lt;/p&gt;&lt;p&gt;Design tokens can have a broad set of responsibilities. They span both design tools &amp;amp; code and can support multiple render targets such as the web, iOS, Android and even embedded devices. You can think of scales as a subset of design tokens that map to specific CSS style properties. For example, typography tokens can map to font-size, font-weight and line-height scales.&lt;/p&gt;&lt;h3 id=&quot;theme&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#theme&quot; aria-label=&quot;theme permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Theme&lt;/h3&gt;&lt;p&gt;The theme is a collection of all the scales and is maintained in a &lt;code class=&quot;language-text&quot;&gt;theme.ts&lt;/code&gt; file. The shape of this theme object conforms to the &lt;a href=&quot;https://system-ui.com/theme&quot;&gt;System UI Theme Specification&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;You might have multiple versions of the theme. For example, to switch between different brands or perhaps colour modes (dark &amp;amp; light). Radius is excellent real-world &lt;a href=&quot;https://github.com/rangle/radius/blob/d21532c3cfa05137dd71f0b0601f44e5d40d57d8/packages/ds/src/theme.ts&quot;&gt;example&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&quot;components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#components&quot; aria-label=&quot;components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Components&lt;/h3&gt;&lt;p&gt;Components allow you to split the UI into independent and reusable pieces. Styled System provides functions to connect component styles to the scales.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// styled-components is a CSS-in-JS Library&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styled &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-components&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// styled-system provides functions that add props to React components&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// which allow you to control styles based on design tokens.&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; layout&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-system&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// The Box component is now connected to Space and Color tokens&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Box &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, this component will have style props available to set foreground color, background color, margin and padding values.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * Color maps to theme.colors.textEditorial
 * background color maps to theme.colors.background[1]
 * Padding maps to theme.space[3]
 */&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;textEditorial&amp;quot;&lt;/span&gt; bg&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;bg.primary&amp;quot;&lt;/span&gt; p&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  Tomato
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;variants&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#variants&quot; aria-label=&quot;variants permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Variants&lt;/h3&gt;&lt;p&gt;There are situations where you might want to support slight stylistic variations of components. For example, a button might have primary, secondary and transparent variants.&lt;/p&gt;&lt;p&gt;Styled System variants allow you to apply a set of visual styles to a component using a single prop.&lt;/p&gt;&lt;p&gt;Let’s consider typography variants. In Figma, you define reusable typography as text styles. A text style has predefined values for font-family, size, weight and line-height.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:42.01388888888889%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;168\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20168\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%208v8h401V0H0v8m378%20138c-4%204-1%2012%205%2012%203%200%207-3%207-5%201-8-7-12-12-7\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;An example of text styles defined in Figma&quot; title=&quot;An example of text styles defined in Figma&quot; src=&quot;/static/cbfaed0404fcfd3717db4c0830513de2/4ad3a/text-styles-figma.png&quot; srcSet=&quot;/static/cbfaed0404fcfd3717db4c0830513de2/477c9/text-styles-figma.png 288w,/static/cbfaed0404fcfd3717db4c0830513de2/533c1/text-styles-figma.png 576w,/static/cbfaed0404fcfd3717db4c0830513de2/4ad3a/text-styles-figma.png 1152w,/static/cbfaed0404fcfd3717db4c0830513de2/b8bf8/text-styles-figma.png 1728w,/static/cbfaed0404fcfd3717db4c0830513de2/263f4/text-styles-figma.png 1996w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;In code, use the &lt;a href=&quot;https://styled-system.com/variants&quot;&gt;variant&lt;/a&gt; function to define typography variants.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;text.ts&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; textVariants &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  variants&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      fontFamily&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;body&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fontWeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;regular&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      lineHeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;copy&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    caption&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      fontFamily&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;body&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fontWeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;medium&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      lineHeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;copy&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    label&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      fontFamily&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;heading&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fontWeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;regular&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      lineHeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;p&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    typography
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;textVariants&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These variants map back to the scales.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;theme.ts&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  fonts&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    body&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;quot;Helvetica Neue&amp;quot;, sans-serif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    heading&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;quot;Roboto&amp;quot;, sans-serif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  fontWeights&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    regular&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    medium&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    bold&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lineHeights&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    solid&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    title&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    copy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  fontSizes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Text component can now use the &lt;code class=&quot;language-text&quot;&gt;variant&lt;/code&gt; prop to switch between lead, body and label styles.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text variant&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;body&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text variant&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;caption&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text variant&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;label&amp;quot;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;as&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;span&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;example&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#example&quot; aria-label=&quot;example permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Example&lt;/h2&gt;&lt;p&gt;Let’s look at a complete example. The Field component here is a composition of the Input, Label and Text components, which, in turn, use a composition of scales and variants. The Hint and Error texts are the Text component with the variant set to hint and different colour values.&lt;/p&gt;&lt;figure class=&quot;sc-24qoga-0 eKYvFn&quot;&gt;&lt;div height=&quot;70vh,90vh&quot; overflow=&quot;hidden&quot; class=&quot;sc-24qoga-0 sc-24qoga-2 kmkMoJ&quot;&gt;&lt;div transform=&quot;translate3d(-110%, -105%, 0)&quot; class=&quot;sc-24qoga-0 sc-1h2zccj-0 duxGXm&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; fill=&quot;none&quot; viewBox=&quot;0 0 368 405&quot;&gt;&lt;g&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 0H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#F1F1F1&quot; d=&quot;M0 0H368V36H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M30.35 20.816h3.873V22h-5.356v-8.531h1.483v7.347zM39.01 22c-.063-.121-.117-.318-.164-.592a2.216 2.216 0 01-1.664.71c-.637 0-1.157-.182-1.559-.546a1.744 1.744 0 01-.603-1.347c0-.676.25-1.194.75-1.553.503-.363 1.222-.545 2.156-.545h.873v-.416c0-.328-.092-.59-.276-.785-.183-.2-.463-.299-.838-.299-.324 0-.59.082-.796.246a.745.745 0 00-.31.615h-1.425c0-.347.115-.672.346-.972.23-.305.543-.543.938-.715a3.324 3.324 0 011.33-.258c.742 0 1.334.188 1.775.563.441.37.668.894.68 1.57v2.86c0 .57.08 1.024.24 1.364v.1H39.01zm-1.565-1.025c.282 0 .545-.069.791-.206.25-.136.438-.32.563-.55v-1.196h-.768c-.527 0-.924.092-1.19.276a.892.892 0 00-.398.78c0 .273.09.491.27.655.184.16.428.24.732.24zm9.832-2.08c0 .984-.22 1.767-.662 2.35-.437.581-1.04.872-1.81.872-.742 0-1.32-.267-1.735-.803L43 22h-1.29v-9h1.425v3.27c.41-.485.963-.727 1.658-.727.773 0 1.38.287 1.822.861.442.575.662 1.377.662 2.409v.082zm-1.424-.123c0-.688-.12-1.204-.363-1.547-.242-.344-.593-.516-1.055-.516-.617 0-1.05.27-1.3.809v2.613c.254.55.691.826 1.312.826.446 0 .79-.166 1.031-.498.243-.332.368-.834.375-1.506v-.181zm5.415 3.345c-.903 0-1.635-.283-2.198-.85-.558-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.364-1.693.246-.5.59-.889 1.031-1.166a2.718 2.718 0 011.476-.416c.864 0 1.53.275 1.999.826.472.55.709 1.33.709 2.338v.574h-4.143c.043.524.217.938.522 1.242.308.305.695.457 1.16.457.652 0 1.183-.263 1.593-.79l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.896.31-1.423.31zm-.17-5.431c-.391 0-.707.136-.95.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.37-.926-.37zM56.435 22h-1.423v-9h1.423v9zm11.192-2.777c-.086.91-.422 1.62-1.008 2.133-.586.507-1.365.761-2.338.761-.68 0-1.279-.16-1.799-.48-.515-.325-.914-.784-1.195-1.377-.281-.594-.428-1.283-.44-2.069v-.796c0-.805.143-1.514.428-2.127.285-.614.694-1.086 1.225-1.418.535-.332 1.152-.498 1.852-.498.941 0 1.699.255 2.273.767.574.512.908 1.235 1.002 2.168H66.15c-.07-.613-.25-1.055-.539-1.324-.285-.273-.705-.41-1.26-.41-.644 0-1.14.236-1.488.709-.343.468-.52 1.158-.527 2.068v.756c0 .922.164 1.625.492 2.11.332.484.816.726 1.453.726.582 0 1.02-.131 1.313-.393.293-.261.478-.697.556-1.306h1.477zm.926-.451c0-.622.123-1.18.369-1.676.246-.5.592-.883 1.037-1.149.445-.27.957-.404 1.535-.404.856 0 1.549.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.12 1.183-.363 1.675a2.639 2.639 0 01-1.031 1.143c-.446.27-.961.404-1.547.404-.895 0-1.612-.297-2.15-.89-.536-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.134 1.164.404 1.535.27.367.644.55 1.125.55.48 0 .853-.187 1.119-.562.27-.375.404-.924.404-1.646 0-.641-.138-1.149-.416-1.524a1.312 1.312 0 00-1.119-.563c-.465 0-.834.186-1.107.557-.274.367-.41.918-.41 1.652zm7.013-3.235l.041.662c.446-.52 1.055-.779 1.828-.779.848 0 1.428.324 1.74.973.462-.649 1.11-.973 1.946-.973.7 0 1.219.193 1.558.58.344.387.52.957.528 1.711V22h-1.424v-4.125c0-.402-.088-.697-.264-.885-.175-.187-.466-.281-.873-.281-.324 0-.59.088-.797.264a1.366 1.366 0 00-.427.68L80.852 22h-1.424v-4.172c-.02-.746-.4-1.119-1.143-1.119-.57 0-.974.232-1.213.697V22h-1.424v-6.34h1.342zm14.654 3.235c0 .98-.222 1.763-.667 2.35-.446.581-1.043.872-1.793.872-.696 0-1.252-.228-1.67-.685v3.006H86.09V15.66h1.312l.059.645c.418-.508.986-.762 1.705-.762.773 0 1.379.289 1.816.867.442.574.662 1.373.662 2.397v.088zm-1.417-.123c0-.633-.127-1.135-.381-1.506-.25-.371-.61-.557-1.078-.557-.582 0-1 .24-1.254.72v2.813c.258.492.68.738 1.265.738.453 0 .807-.181 1.06-.544.259-.368.388-.922.388-1.665zm2.36 0c0-.622.124-1.18.37-1.676.246-.5.592-.883 1.037-1.149.445-.27.957-.404 1.535-.404.856 0 1.55.275 2.08.826.535.55.825 1.281.868 2.192l.005.334c0 .625-.12 1.183-.363 1.675a2.639 2.639 0 01-1.031 1.143c-.445.27-.961.404-1.547.404-.894 0-1.611-.297-2.15-.89-.535-.598-.803-1.393-.803-2.385v-.07zm1.425.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.125.55s.853-.187 1.12-.562c.269-.375.403-.924.403-1.646 0-.641-.138-1.149-.416-1.524a1.311 1.311 0 00-1.119-.563c-.465 0-.834.186-1.107.557-.274.367-.41.918-.41 1.652zm6.996-3.235l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.015 2.268V22h-1.424v-4.107c0-.403-.088-.7-.263-.891-.172-.195-.455-.293-.85-.293-.574 0-1.002.26-1.283.78V22h-1.424v-6.34h1.342zm8.15 6.457c-.902 0-1.635-.283-2.197-.85-.559-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.363-1.693a2.8 2.8 0 011.032-1.166 2.715 2.715 0 011.476-.416c.863 0 1.529.275 1.998.826.473.55.709 1.33.709 2.338v.574h-4.142c.043.524.216.938.521 1.242.309.305.695.457 1.16.457.653 0 1.184-.263 1.594-.79l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.896.31-1.424.31zm-.17-5.431c-.39 0-.707.136-.949.41-.238.273-.391.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.381-1.078-.223-.246-.531-.37-.926-.37zm5.145-1.026l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.015 2.268V22h-1.424v-4.107c0-.403-.088-.7-.263-.891-.172-.195-.455-.293-.85-.293-.574 0-1.002.26-1.283.78V22h-1.424v-6.34h1.342zm7.142-1.54v1.54h1.12v1.055h-1.12v3.539c0 .242.047.418.141.527.098.106.27.159.516.159.164 0 .33-.02.498-.06v1.102c-.325.09-.637.135-.938.135-1.094 0-1.64-.603-1.64-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.423z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 164H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M70.64 243.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V249h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zm3.792 3.424v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.389-.005-.528-.016a.727.727 0 01-.304-.112.432.432 0 01-.16-.224 1.864 1.864 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm8.903 3.344h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm3.762-1.728L126.957 249h1.648l2.304-3.424 2.304 3.424h1.744l-3.2-4.464 2.848-3.808h-1.632l-2.064 2.896-1.985-2.896h-1.743l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm1.952 3.424v11.424h1.36v-4.256h.032c.149.245.33.453.544.624.224.16.458.288.704.384.245.096.49.165.736.208.256.043.485.064.688.064.629 0 1.178-.112 1.648-.336.48-.224.874-.528 1.184-.912.32-.395.554-.853.704-1.376.16-.523.24-1.077.24-1.664s-.08-1.141-.24-1.664c-.16-.523-.4-.981-.72-1.376a3.283 3.283 0 00-1.184-.96c-.47-.235-1.024-.352-1.664-.352-.576 0-1.104.107-1.584.32-.48.203-.832.533-1.056.992h-.032v-1.12h-1.36zm6.4 4.064c0 .405-.043.8-.128 1.184a3.15 3.15 0 01-.416 1.024 2.16 2.16 0 01-.768.72c-.31.181-.699.272-1.168.272-.47 0-.87-.085-1.2-.256a2.478 2.478 0 01-.816-.704 3.004 3.004 0 01-.448-.992 5.041 5.041 0 01-.016-2.32c.096-.373.245-.704.448-.992.202-.299.464-.539.784-.72.32-.181.709-.272 1.168-.272.437 0 .816.085 1.136.256.33.171.597.4.8.688.213.288.368.619.464.992.106.363.16.736.16 1.12zm2.988-4.064V249h1.36v-3.68c0-.533.053-1.003.16-1.408.107-.416.277-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm6.816-1.488v-1.664h-1.36v1.664h1.36zm-1.36 1.488V249h1.36v-8.272h-1.36zm3.467 0V249h1.36v-5.152c0-.16.037-.357.112-.592a2.52 2.52 0 01.384-.704c.181-.224.411-.416.688-.576.288-.16.629-.24 1.024-.24.309 0 .56.048.752.144.203.085.363.213.48.384.117.16.197.352.24.576.053.224.08.469.08.736V249h1.36v-5.152c0-.64.192-1.152.576-1.536.384-.384.912-.576 1.584-.576.331 0 .597.048.8.144.213.096.379.229.496.4.117.16.197.352.24.576.043.224.064.464.064.72V249h1.36v-6.064c0-.427-.069-.789-.208-1.088a1.82 1.82 0 00-.56-.752 2.176 2.176 0 00-.864-.416 4.019 4.019 0 00-1.12-.144c-.544 0-1.045.123-1.504.368a2.9 2.9 0 00-1.088 1.04c-.171-.512-.464-.875-.88-1.088a3.01 3.01 0 00-1.392-.32c-1.163 0-2.053.469-2.672 1.408h-.032v-1.216h-1.28zm20.969 8.24c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.322 3.322 0 01-1.312.976 4.354 4.354 0 01-1.6.288c-.374 0-.731-.043-1.072-.128a2.473 2.473 0 01-.864-.4 1.997 1.997 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.266-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.458-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.319 4.319 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.682-.384 1.088-.48a5.89 5.89 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.298.16.538.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.042.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288 17.81 17.81 0 01-.88.144 14.57 14.57 0 00-.912.128c-.31.043-.587.117-.832.224a1.541 1.541 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.394.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.202-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.426-4V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm8.624 9.376c-.16.405-.32.747-.48 1.024-.15.277-.32.501-.512.672-.182.181-.39.309-.624.384a2.207 2.207 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.26 2.26 0 01-.464-.112v-1.248c.117.053.25.096.4.128.16.043.293.064.4.064.277 0 .506-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;243&quot; r=&quot;10&quot; fill=&quot;#262626&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M70.64 287.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V293h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V293h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zm1.952.272V293h1.36v-1.104h.032c.149.245.331.453.544.624.224.16.459.288.704.384.245.096.491.165.736.208.256.043.485.064.688.064.629 0 1.179-.112 1.648-.336.48-.224.875-.528 1.184-.912a3.82 3.82 0 00.704-1.376c.16-.523.24-1.077.24-1.664s-.08-1.141-.24-1.664c-.16-.523-.4-.981-.72-1.376a3.275 3.275 0 00-1.184-.96c-.469-.235-1.024-.352-1.664-.352-.576 0-1.104.107-1.584.32-.48.203-.832.533-1.056.992h-.032v-4.272h-1.36zm6.4 7.216c0 .405-.043.8-.128 1.184A3.128 3.128 0 01120.1 291a2.16 2.16 0 01-.768.72c-.309.181-.699.272-1.168.272s-.869-.085-1.2-.256a2.478 2.478 0 01-.816-.704 3.004 3.004 0 01-.448-.992 4.865 4.865 0 01-.144-1.184 5.1 5.1 0 01.128-1.136c.096-.373.245-.704.448-.992.203-.299.464-.539.784-.72.32-.181.709-.272 1.168-.272.437 0 .816.085 1.136.256.331.171.597.4.8.688.213.288.368.619.464.992.107.363.16.736.16 1.12zm2.988-4.064V293h1.36v-3.68c0-.533.054-1.003.16-1.408.107-.416.278-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm12.704 8.24c-.234.139-.56.208-.976.208-.352 0-.634-.096-.848-.288-.202-.203-.304-.528-.304-.976-.373.448-.81.773-1.312.976a4.35 4.35 0 01-1.6.288c-.373 0-.73-.043-1.072-.128a2.49 2.49 0 01-.864-.4 2.018 2.018 0 01-.592-.704c-.138-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.267-.192.566-.336.896-.432.342-.096.688-.176 1.04-.24.374-.075.726-.128 1.056-.16.342-.043.64-.096.896-.16.256-.075.459-.176.608-.304.15-.139.224-.336.224-.592 0-.299-.058-.539-.176-.72a1.074 1.074 0 00-.432-.416 1.677 1.677 0 00-.592-.192 4.299 4.299 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.022-.512.128-.944.32-1.296.192-.352.448-.635.768-.848a3.14 3.14 0 011.088-.48 5.896 5.896 0 011.328-.144c.374 0 .742.027 1.104.08.374.053.71.165 1.008.336.299.16.539.389.72.688.182.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.043.149.171.224.384.224.118 0 .256-.027.416-.08v1.056zm-2.208-4.24c-.17.128-.394.224-.672.288-.277.053-.57.101-.88.144-.298.032-.602.075-.912.128a3.175 3.175 0 00-.832.224 1.549 1.549 0 00-.608.464c-.149.192-.224.459-.224.8 0 .224.043.416.128.576.096.149.214.272.352.368.15.096.32.165.512.208.192.043.395.064.608.064.448 0 .832-.059 1.152-.176.32-.128.582-.283.784-.464.203-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.474-4V293h1.36v-4.672c0-.373.048-.715.144-1.024.107-.32.261-.597.464-.832s.453-.416.752-.544a2.831 2.831 0 011.088-.192c.523 0 .933.149 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.243 2.243 0 00-.464-.96 2.227 2.227 0 00-.88-.624c-.363-.149-.816-.224-1.36-.224-1.227 0-2.123.501-2.688 1.504h-.032v-1.312h-1.28zm9.883 4.208c0-.405.042-.8.128-1.184.085-.384.224-.725.416-1.024a2.16 2.16 0 01.768-.72c.32-.181.709-.272 1.168-.272.469 0 .869.091 1.2.272.33.171.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304c-.086.373-.23.709-.432 1.008a2.375 2.375 0 01-.784.704c-.32.181-.71.272-1.168.272-.438 0-.822-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.27 3.27 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.054 2.054 0 00-.56-.608 2.64 2.64 0 00-.688-.4 3.248 3.248 0 00-.736-.224 4.004 4.004 0 00-.688-.064c-.63 0-1.184.117-1.664.352-.47.224-.864.533-1.184.928a4 4 0 00-.704 1.36 6.005 6.005 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.394.981.704 1.376.32.395.714.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V293h1.36zm5.516-11.696l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.736 9.088h-1.36c.022.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.854.144 1.312.144a6.22 6.22 0 001.248-.128 3.203 3.203 0 001.136-.416c.342-.203.614-.469.816-.8.214-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.882 1.882 0 00-.608-.656 2.988 2.988 0 00-.864-.432 9.622 9.622 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.337 2.337 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.054-.384.16-.512.107-.139.246-.245.416-.32a1.93 1.93 0 01.56-.176c.214-.032.422-.048.624-.048.224 0 .443.027.656.08.224.043.427.117.608.224.182.107.331.251.448.432.118.171.187.389.208.656h1.36c-.032-.501-.138-.917-.32-1.248a2.048 2.048 0 00-.736-.8 2.727 2.727 0 00-1.04-.416 6.15 6.15 0 00-1.296-.128c-.362 0-.73.048-1.104.144a3.157 3.157 0 00-.992.416 2.312 2.312 0 00-.72.72c-.181.299-.272.656-.272 1.072 0 .533.134.949.4 1.248.267.299.598.533.992.704.406.16.843.288 1.312.384.47.085.902.187 1.296.304.406.107.742.251 1.008.432.267.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.293.283-.496.368a2.36 2.36 0 01-.64.176 4.964 4.964 0 01-.672.048c-.277 0-.549-.027-.816-.08a2.524 2.524 0 01-.704-.256 1.576 1.576 0 01-.496-.496 1.58 1.58 0 01-.208-.768zm12.912-2.32h-4.752c.022-.32.091-.619.208-.896.118-.288.278-.539.48-.752.203-.213.443-.379.72-.496.288-.128.608-.192.96-.192.342 0 .651.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.349 2.349 0 01-.816-.592 2.43 2.43 0 01-.464-.864 3.374 3.374 0 01-.128-1.04h6.192a6.287 6.287 0 00-.144-1.584 4.349 4.349 0 00-.608-1.536 3.452 3.452 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32-.469.213-.88.512-1.232.896a4.208 4.208 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.171.533.422.992.752 1.376.331.384.736.683 1.216.896.491.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm7.154-2.992h1.408c-.053-.491-.181-.912-.384-1.264a2.774 2.774 0 00-.784-.896 3.015 3.015 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.651 0-1.221.117-1.712.352a3.377 3.377 0 00-1.232.944 4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.171.512.416.955.736 1.328a3.34 3.34 0 001.216.864c.491.203 1.051.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.189 2.189 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.894 4.894 0 01-.128-1.12c0-.416.043-.816.128-1.2a3.12 3.12 0 01.416-1.04 2.26 2.26 0 01.8-.72c.331-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992.234-.267.506-.469.816-.608.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.43 2.43 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.457 2.457 0 01-.816-.592 2.988 2.988 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.676 3.676 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.784 3.784 0 00-.768-1.376 3.577 3.577 0 00-1.264-.928c-.491-.224-1.067-.336-1.728-.336-.651 0-1.227.112-1.728.336a3.559 3.559 0 00-1.264.928 3.755 3.755 0 00-.768 1.376 5.426 5.426 0 00-.256 1.696zm9.635-4.144V293h1.36v-4.672c0-.373.048-.715.144-1.024.107-.32.262-.597.464-.832.203-.235.454-.416.752-.544.31-.128.672-.192 1.088-.192.523 0 .934.149 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.243 2.243 0 00-.464-.96 2.227 2.227 0 00-.88-.624c-.362-.149-.816-.224-1.36-.224-1.226 0-2.122.501-2.688 1.504h-.032v-1.312h-1.28zm9.883 4.208c0-.405.043-.8.128-1.184.085-.384.224-.725.416-1.024a2.16 2.16 0 01.768-.72c.32-.181.709-.272 1.168-.272.469 0 .869.091 1.2.272.331.171.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.375 2.375 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.295 3.295 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.04 2.04 0 00-.56-.608 2.624 2.624 0 00-.688-.4 3.233 3.233 0 00-.736-.224 3.995 3.995 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.373 3.373 0 00-1.184.928 4.018 4.018 0 00-.704 1.36 6.043 6.043 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V293h1.36zm9.42-.032c-.234.139-.56.208-.976.208-.352 0-.634-.096-.848-.288-.202-.203-.304-.528-.304-.976-.373.448-.81.773-1.312.976a4.35 4.35 0 01-1.6.288c-.373 0-.73-.043-1.072-.128a2.49 2.49 0 01-.864-.4 2.018 2.018 0 01-.592-.704c-.138-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.267-.192.566-.336.896-.432.342-.096.688-.176 1.04-.24.374-.075.726-.128 1.056-.16.342-.043.64-.096.896-.16.256-.075.459-.176.608-.304.15-.139.224-.336.224-.592 0-.299-.058-.539-.176-.72a1.074 1.074 0 00-.432-.416 1.677 1.677 0 00-.592-.192 4.299 4.299 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.022-.512.128-.944.32-1.296.192-.352.448-.635.768-.848a3.14 3.14 0 011.088-.48 5.896 5.896 0 011.328-.144c.374 0 .742.027 1.104.08.374.053.71.165 1.008.336.299.16.539.389.72.688.182.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.043.149.171.224.384.224.118 0 .256-.027.416-.08v1.056zm-2.208-4.24c-.17.128-.394.224-.672.288-.277.053-.57.101-.88.144-.298.032-.602.075-.912.128a3.175 3.175 0 00-.832.224 1.549 1.549 0 00-.608.464c-.149.192-.224.459-.224.8 0 .224.043.416.128.576.096.149.214.272.352.368.15.096.32.165.512.208.192.043.395.064.608.064.448 0 .832-.059 1.152-.176.32-.128.582-.283.784-.464.203-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.426-4V293h1.36v-3.68c0-.533.053-1.003.16-1.408.107-.416.277-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm8.624 9.376c-.16.405-.32.747-.48 1.024-.149.277-.32.501-.512.672a1.531 1.531 0 01-.624.384 2.203 2.203 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.26 2.26 0 01-.464-.112v-1.248c.117.053.251.096.4.128.16.043.293.064.4.064.277 0 .507-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;287&quot; r=&quot;10&quot; fill=&quot;#0064D9&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M67.84 194.856V205h1.52v-10.144h3.808v-1.28h-9.136v1.28h3.808zm10.334 5.216h-4.752c.022-.32.09-.619.208-.896.118-.288.278-.539.48-.752a2.12 2.12 0 01.72-.496c.288-.128.608-.192.96-.192.342 0 .65.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.336 2.336 0 01-.816-.592 2.423 2.423 0 01-.464-.864 3.353 3.353 0 01-.128-1.04h6.192a6.352 6.352 0 00-.144-1.584 4.37 4.37 0 00-.608-1.536A3.456 3.456 0 0077.694 197c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32a3.77 3.77 0 00-1.232.896 4.2 4.2 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.17.533.422.992.752 1.376.33.384.736.683 1.216.896.49.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm3.762-1.728L80.144 205h1.648l2.304-3.424L86.4 205h1.744l-3.2-4.464 2.848-3.808H86.16l-2.064 2.896-1.984-2.896h-1.744l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.038.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.39-.005-.528-.016a.725.725 0 01-.304-.112.434.434 0 01-.16-.224 1.836 1.836 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.128.272V205h7.568v-1.28h-6.048v-10.144h-1.52zm15.995 11.392c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.315 3.315 0 01-1.312.976 4.354 4.354 0 01-1.6.288 4.42 4.42 0 01-1.072-.128 2.473 2.473 0 01-.864-.4 2.008 2.008 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.267-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.459-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.309 4.309 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848a3.14 3.14 0 011.088-.48 5.896 5.896 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.299.16.539.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.043.149.171.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288c-.277.053-.571.101-.88.144a14.57 14.57 0 00-.912.128 3.165 3.165 0 00-.832.224 1.549 1.549 0 00-.608.464c-.149.192-.224.459-.224.8 0 .224.043.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.395.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.203-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.522-7.152V205h1.36v-1.104h.032c.149.245.33.453.544.624.224.16.458.288.704.384.245.096.49.165.736.208.256.043.485.064.688.064.629 0 1.178-.112 1.648-.336.48-.224.874-.528 1.184-.912.32-.395.554-.853.704-1.376.16-.523.24-1.077.24-1.664s-.08-1.141-.24-1.664c-.16-.523-.4-.981-.72-1.376a3.283 3.283 0 00-1.184-.96c-.47-.235-1.024-.352-1.664-.352-.576 0-1.104.107-1.584.32-.48.203-.832.533-1.056.992h-.032v-4.272h-1.36zm6.4 7.216c0 .405-.043.8-.128 1.184a3.15 3.15 0 01-.416 1.024 2.16 2.16 0 01-.768.72c-.31.181-.699.272-1.168.272-.47 0-.87-.085-1.2-.256a2.478 2.478 0 01-.816-.704 3.004 3.004 0 01-.448-.992 5.041 5.041 0 01-.016-2.32c.096-.373.245-.704.448-.992.202-.299.464-.539.784-.72.32-.181.709-.272 1.168-.272.437 0 .816.085 1.136.256.33.171.597.4.8.688.213.288.368.619.464.992.106.363.16.736.16 1.12zm8.78-.72h-4.752a2.75 2.75 0 01.208-.896c.117-.288.277-.539.48-.752.203-.213.443-.379.72-.496.288-.128.608-.192.96-.192.341 0 .651.064.928.192.288.117.533.283.736.496.213.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.43 2.43 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.367 4.367 0 00-.608-1.536 3.452 3.452 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32-.469.213-.88.512-1.232.896a4.208 4.208 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.171.533.421.992.752 1.376.331.384.736.683 1.216.896.491.213 1.067.32 1.728.32.939 0 1.717-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm1.618-8.8V205h1.36v-11.424h-1.36zM31.486 201.136l1.302-3.668h.028l1.26 3.668h-2.59zm.21-6.132L27.916 205h2.212l.784-2.226h3.738l.756 2.226h2.282l-3.738-9.996h-2.254zm10.018 8.288c-.308 0-.565-.065-.77-.196a1.631 1.631 0 01-.504-.504 2.33 2.33 0 01-.266-.686 4.448 4.448 0 01-.07-.784c0-.271.028-.527.084-.77.065-.252.163-.471.294-.658.14-.196.308-.35.504-.462.205-.112.448-.168.728-.168.327 0 .597.061.812.182.215.121.387.285.518.49.13.205.224.443.28.714a4 4 0 01.084.84c0 .261-.037.513-.112.756a1.894 1.894 0 01-.308.63c-.14.187-.317.336-.532.448a1.581 1.581 0 01-.742.168zm3.584 1.246v-6.776h-1.89v.966h-.028c-.243-.42-.546-.719-.91-.896-.355-.177-.77-.266-1.246-.266-.504 0-.952.098-1.344.294a2.86 2.86 0 00-.966.798 3.54 3.54 0 00-.602 1.148c-.13.429-.196.877-.196 1.344 0 .495.056.966.168 1.414.121.439.308.826.56 1.162.252.327.574.588.966.784.392.187.859.28 1.4.28.439 0 .854-.089 1.246-.266a2 2 0 00.924-.854h.028v.952c.01.513-.117.938-.378 1.274-.252.336-.658.504-1.218.504-.355 0-.667-.075-.938-.224-.27-.14-.453-.397-.546-.77h-1.974c.028.411.14.761.336 1.05.205.299.457.541.756.728.308.187.644.322 1.008.406.373.093.737.14 1.092.14.83 0 1.493-.112 1.988-.336.495-.224.873-.499 1.134-.826.261-.317.43-.663.504-1.036a4.59 4.59 0 00.126-.994z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 36H368V164H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M30.35 89.816h3.873V91h-5.356v-8.531h1.483v7.347zM39.01 91c-.063-.121-.117-.318-.164-.592a2.216 2.216 0 01-1.664.71c-.637 0-1.157-.182-1.559-.546a1.744 1.744 0 01-.603-1.347c0-.676.25-1.194.75-1.553.503-.363 1.222-.545 2.156-.545h.873v-.416c0-.328-.092-.59-.276-.785-.183-.2-.463-.299-.838-.299-.324 0-.59.082-.796.246a.745.745 0 00-.31.615h-1.425c0-.347.115-.672.346-.972.23-.305.543-.543.938-.715a3.324 3.324 0 011.33-.258c.742 0 1.334.188 1.775.563.441.37.668.894.68 1.57v2.86c0 .57.08 1.025.24 1.364v.1H39.01zm-1.565-1.025c.282 0 .545-.069.791-.206.25-.136.438-.32.563-.55v-1.196h-.768c-.527 0-.924.092-1.19.276a.892.892 0 00-.398.78c0 .273.09.491.27.655.184.16.428.24.732.24zm9.832-2.08c0 .984-.22 1.767-.662 2.35-.437.581-1.04.872-1.81.872-.742 0-1.32-.267-1.735-.803L43 91h-1.29v-9h1.425v3.27c.41-.485.963-.727 1.658-.727.773 0 1.38.287 1.822.861.442.575.662 1.377.662 2.409v.081zm-1.424-.123c0-.688-.12-1.204-.363-1.547-.242-.344-.593-.516-1.055-.516-.617 0-1.05.27-1.3.809v2.613c.254.55.691.826 1.312.826.446 0 .79-.166 1.031-.498.243-.332.368-.834.375-1.506v-.181zm5.415 3.345c-.903 0-1.635-.283-2.198-.85-.558-.57-.838-1.328-.838-2.273v-.176c0-.632.121-1.197.364-1.693.246-.5.59-.889 1.031-1.166a2.718 2.718 0 011.476-.416c.864 0 1.53.275 1.999.826.472.55.709 1.33.709 2.338v.574h-4.143c.043.524.217.938.522 1.242.308.305.695.458 1.16.458.652 0 1.183-.264 1.593-.791l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.896.31-1.423.31zm-.17-5.431c-.391 0-.707.136-.95.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.37-.926-.37zM56.435 91h-1.423v-9h1.423v9z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#0064D9&quot; d=&quot;M61.945 85.305l-1.787-.516.322-.99 1.77.685-.088-2.015h1.049l-.088 2.05 1.74-.673.317 1.007-1.817.516 1.172 1.559-.85.62-1.054-1.687-1.043 1.635-.856-.598 1.213-1.593z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#DEDEDE&quot; d=&quot;M0 164H368V165H0z&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div transform=&quot;translate3d(10%, -105%, 0)&quot; class=&quot;sc-24qoga-0 sc-1h2zccj-0 hLRwgE&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; fill=&quot;none&quot; viewBox=&quot;0 0 368 405&quot;&gt;&lt;g&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 0H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#F1F1F1&quot; d=&quot;M0 0H368V36H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M30.432 22h-1.477v-8.531h1.477V22zm3.006-6.34l.04.733c.47-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.85-.293-.574 0-1.001.26-1.282.78V22h-1.424v-6.34h1.342zm10.91 3.235c0 .98-.223 1.763-.668 2.35-.446.581-1.043.872-1.793.872-.696 0-1.252-.228-1.67-.685v3.006h-1.424V15.66h1.313l.058.645c.418-.508.986-.762 1.705-.762.774 0 1.379.289 1.816.867.442.574.663 1.373.663 2.397v.088zm-1.418-.123c0-.633-.127-1.135-.381-1.506-.25-.371-.61-.557-1.078-.557-.582 0-1 .24-1.254.72v2.813c.258.492.68.738 1.265.738.453 0 .807-.181 1.061-.544.258-.368.387-.922.387-1.665zm6.468 2.607c-.418.492-1.011.738-1.78.738-.688 0-1.21-.201-1.565-.603-.352-.403-.528-.985-.528-1.746V15.66h1.424v4.09c0 .805.334 1.207 1.002 1.207.692 0 1.158-.248 1.4-.744V15.66h1.424V22h-1.341l-.036-.621zm4.612-7.26v1.541h1.119v1.055h-1.12v3.539c0 .242.048.418.141.527.098.106.27.159.516.159.164 0 .33-.02.498-.06v1.102c-.324.09-.637.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424zm11.847 5.104c-.085.91-.421 1.62-1.007 2.133-.586.507-1.366.761-2.338.761-.68 0-1.28-.16-1.8-.48-.515-.325-.913-.784-1.194-1.377-.282-.594-.428-1.283-.44-2.069v-.796c0-.805.143-1.514.428-2.127.285-.614.693-1.086 1.224-1.418.536-.332 1.153-.498 1.852-.498.941 0 1.7.255 2.274.767.574.512.908 1.235 1.001 2.168h-1.476c-.07-.613-.25-1.055-.54-1.324-.284-.273-.704-.41-1.259-.41-.645 0-1.14.236-1.488.709-.344.468-.52 1.158-.528 2.068v.756c0 .922.164 1.625.493 2.11.332.484.816.726 1.453.726.582 0 1.02-.131 1.312-.393.293-.261.479-.697.557-1.306h1.476zm.926-.451c0-.622.123-1.18.37-1.676.245-.5.591-.883 1.036-1.149.446-.27.958-.404 1.536-.404.855 0 1.548.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.364 1.675a2.64 2.64 0 01-1.03 1.143c-.446.27-.962.404-1.548.404-.894 0-1.611-.297-2.15-.89-.535-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.125.55s.854-.187 1.12-.562c.269-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.312 1.312 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm7.014-3.235l.04.662c.446-.52 1.055-.779 1.829-.779.847 0 1.428.324 1.74.973.461-.649 1.11-.973 1.945-.973.7 0 1.22.193 1.559.58.344.387.52.957.527 1.711V22h-1.424v-4.125c0-.402-.087-.697-.263-.885-.176-.187-.467-.281-.873-.281-.324 0-.59.088-.797.264a1.366 1.366 0 00-.428.68L79.082 22h-1.424v-4.172c-.02-.746-.4-1.119-1.142-1.119-.57 0-.975.232-1.213.697V22h-1.424v-6.34h1.342zm14.654 3.235c0 .98-.223 1.763-.668 2.35-.445.581-1.043.872-1.793.872-.695 0-1.252-.228-1.67-.685v3.006H84.32V15.66h1.313l.058.645c.418-.508.987-.762 1.706-.762.773 0 1.378.289 1.816.867.441.574.662 1.373.662 2.397v.088zm-1.418-.123c0-.633-.127-1.135-.38-1.506-.25-.371-.61-.557-1.079-.557-.582 0-1 .24-1.254.72v2.813c.258.492.68.738 1.266.738.453 0 .806-.181 1.06-.544.258-.368.387-.922.387-1.665zm2.361 0c0-.622.123-1.18.37-1.676.246-.5.591-.883 1.037-1.149.445-.27.957-.404 1.535-.404.855 0 1.549.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.363 1.675a2.64 2.64 0 01-1.032 1.143c-.445.27-.96.404-1.546.404-.895 0-1.612-.297-2.15-.89-.536-.598-.804-1.393-.804-2.385v-.07zm1.424.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.126.55.48 0 .853-.187 1.119-.562.27-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.311 1.311 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm6.996-3.235l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.849-.293-.575 0-1.002.26-1.284.78V22h-1.423v-6.34h1.341zm8.151 6.457c-.903 0-1.635-.283-2.198-.85-.558-.57-.837-1.328-.837-2.273v-.176c0-.633.121-1.197.363-1.693.246-.5.59-.889 1.031-1.166a2.719 2.719 0 011.477-.416c.863 0 1.529.275 1.998.826.472.55.709 1.33.709 2.338v.574h-4.143c.043.524.217.938.522 1.242.308.305.695.457 1.16.457.652 0 1.183-.263 1.593-.79l.768.732a2.58 2.58 0 01-1.02.885c-.421.207-.896.31-1.423.31zm-.17-5.431c-.391 0-.707.136-.949.41-.239.273-.391.654-.458 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.37-.926-.37zm5.144-1.026l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.849-.293-.575 0-1.002.26-1.284.78V22h-1.424v-6.34h1.342zm7.143-1.54v1.54h1.119v1.055h-1.119v3.539c0 .242.047.418.14.527.098.106.27.159.516.159.164 0 .33-.02.498-.06v1.102c-.324.09-.637.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 164H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M67.84 194.856V205h1.52v-10.144h3.808v-1.28h-9.136v1.28h3.808zm10.334 5.216h-4.752c.022-.32.09-.619.208-.896.118-.288.278-.539.48-.752a2.12 2.12 0 01.72-.496c.288-.128.608-.192.96-.192.342 0 .65.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.336 2.336 0 01-.816-.592 2.423 2.423 0 01-.464-.864 3.353 3.353 0 01-.128-1.04h6.192a6.352 6.352 0 00-.144-1.584 4.37 4.37 0 00-.608-1.536A3.456 3.456 0 0077.694 197c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32a3.77 3.77 0 00-1.232.896 4.2 4.2 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.17.533.422.992.752 1.376.33.384.736.683 1.216.896.49.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm3.762-1.728L80.144 205h1.648l2.304-3.424L86.4 205h1.744l-3.2-4.464 2.848-3.808H86.16l-2.064 2.896-1.984-2.896h-1.744l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.038.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.39-.005-.528-.016a.725.725 0 01-.304-.112.434.434 0 01-.16-.224 1.836 1.836 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm3.648 5.184v-3.632h3.04c.331 0 .64.021.928.064.299.032.56.112.784.24.224.128.4.309.528.544.128.235.192.555.192.96 0 .608-.192 1.067-.576 1.376-.373.299-.992.448-1.856.448h-3.04zm-1.52-4.912V205h5.52c.566 0 1.062-.091 1.488-.272.438-.192.8-.437 1.088-.736.299-.309.523-.661.672-1.056.15-.395.224-.8.224-1.216 0-.704-.186-1.301-.56-1.792-.373-.491-.912-.811-1.616-.96v-.032c.544-.213.96-.539 1.248-.976.299-.448.448-.976.448-1.584 0-.576-.133-1.061-.4-1.456a2.891 2.891 0 00-.944-.928 1.926 1.926 0 00-.624-.24 5.282 5.282 0 00-.768-.112 7.389 7.389 0 00-.848-.048 19.76 19.76 0 00-.784-.016h-4.144zm1.52 10.144v-3.952h3.472c.32 0 .63.032.928.096.299.053.56.155.784.304.235.139.422.331.56.576.139.245.208.555.208.928 0 .64-.192 1.141-.576 1.504-.373.363-.896.544-1.568.544h-3.808zm10.201-2.848a4.2 4.2 0 01.192-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.598.341.832.608.235.267.416.597.544.992.139.384.208.827.208 1.328 0 .501-.069.949-.208 1.344a2.792 2.792 0 01-.544.976 2.421 2.421 0 01-.832.592 2.39 2.39 0 01-.992.208c-.352 0-.688-.069-1.008-.208a2.478 2.478 0 01-.816-.592 3.024 3.024 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.086 1.173.256 1.696.171.523.427.981.768 1.376.342.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.238-.107 1.728-.32a3.657 3.657 0 001.264-.912c.342-.395.598-.853.768-1.376a5.426 5.426 0 00.256-1.696c0-.608-.085-1.173-.256-1.696a3.755 3.755 0 00-.768-1.376 3.559 3.559 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.226.112-1.728.336a3.577 3.577 0 00-1.264.928 3.784 3.784 0 00-.768 1.376 5.455 5.455 0 00-.256 1.696zm10.628.064c0-.405.043-.8.128-1.184.085-.384.224-.725.416-1.024a2.16 2.16 0 01.768-.72c.32-.181.709-.272 1.168-.272.469 0 .869.091 1.2.272.331.171.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.375 2.375 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.295 3.295 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.04 2.04 0 00-.56-.608 2.624 2.624 0 00-.688-.4 3.233 3.233 0 00-.736-.224 3.995 3.995 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.373 3.373 0 00-1.184.928 4.018 4.018 0 00-.704 1.36 6.043 6.043 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V205h1.36zm5.34 1.104c-.16.405-.32.747-.48 1.024-.149.277-.32.501-.512.672a1.531 1.531 0 01-.624.384 2.203 2.203 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.276 2.276 0 01-.464-.112v-1.248c.118.053.251.096.4.128.16.043.294.064.4.064.278 0 .507-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376zM31.486 201.136l1.302-3.668h.028l1.26 3.668h-2.59zm.21-6.132L27.916 205h2.212l.784-2.226h3.738l.756 2.226h2.282l-3.738-9.996h-2.254zm10.018 8.288c-.308 0-.565-.065-.77-.196a1.631 1.631 0 01-.504-.504 2.33 2.33 0 01-.266-.686 4.448 4.448 0 01-.07-.784c0-.271.028-.527.084-.77.065-.252.163-.471.294-.658.14-.196.308-.35.504-.462.205-.112.448-.168.728-.168.327 0 .597.061.812.182.215.121.387.285.518.49.13.205.224.443.28.714a4 4 0 01.084.84c0 .261-.037.513-.112.756a1.894 1.894 0 01-.308.63c-.14.187-.317.336-.532.448a1.581 1.581 0 01-.742.168zm3.584 1.246v-6.776h-1.89v.966h-.028c-.243-.42-.546-.719-.91-.896-.355-.177-.77-.266-1.246-.266-.504 0-.952.098-1.344.294a2.86 2.86 0 00-.966.798 3.54 3.54 0 00-.602 1.148c-.13.429-.196.877-.196 1.344 0 .495.056.966.168 1.414.121.439.308.826.56 1.162.252.327.574.588.966.784.392.187.859.28 1.4.28.439 0 .854-.089 1.246-.266a2 2 0 00.924-.854h.028v.952c.01.513-.117.938-.378 1.274-.252.336-.658.504-1.218.504-.355 0-.667-.075-.938-.224-.27-.14-.453-.397-.546-.77h-1.974c.028.411.14.761.336 1.05.205.299.457.541.756.728.308.187.644.322 1.008.406.373.093.737.14 1.092.14.83 0 1.493-.112 1.988-.336.495-.224.873-.499 1.134-.826.261-.317.43-.663.504-1.036a4.59 4.59 0 00.126-.994zM70.64 291.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V297h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V297h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zM121.044 297v-8.272h-1.36v4.672c0 .373-.053.72-.16 1.04a2.256 2.256 0 01-.448.816 2.014 2.014 0 01-.768.544c-.299.128-.656.192-1.072.192-.523 0-.933-.149-1.232-.448-.299-.299-.448-.704-.448-1.216v-5.6h-1.36v5.44c0 .448.043.859.128 1.232a2.4 2.4 0 00.48.944c.224.267.517.475.88.624.363.139.816.208 1.36.208.608 0 1.136-.117 1.584-.352.448-.245.816-.624 1.104-1.136h.032V297h1.28zm3.483-9.76v-1.664h-1.36v1.664h1.36zm-1.36 1.488V297h1.36v-8.272h-1.36zm6.89-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.897 7.632c0-.405.042-.8.128-1.184.085-.384.224-.725.416-1.024a2.16 2.16 0 01.768-.72c.32-.181.709-.272 1.168-.272.469 0 .869.091 1.2.272.33.171.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304c-.086.373-.23.709-.432 1.008a2.375 2.375 0 01-.784.704c-.32.181-.71.272-1.168.272-.438 0-.822-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.27 3.27 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 7.216v-11.424h-1.36v1.104h-.032a2.054 2.054 0 00-.56-.608 2.64 2.64 0 00-.688-.4 3.248 3.248 0 00-.736-.224 4.004 4.004 0 00-.688-.064c-.63 0-1.184.117-1.664.352-.47.224-.864.533-1.184.928a4 4 0 00-.704 1.36 6.005 6.005 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.394.981.704 1.376.32.395.714.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032v4.272h1.36zm8.94-3.152v-8.272h-1.36v4.672c0 .373-.053.72-.16 1.04a2.256 2.256 0 01-.448.816 2.014 2.014 0 01-.768.544c-.299.128-.656.192-1.072.192-.523 0-.933-.149-1.232-.448-.299-.299-.448-.704-.448-1.216v-5.6h-1.36v5.44c0 .448.043.859.128 1.232a2.4 2.4 0 00.48.944c.224.267.517.475.88.624.363.139.816.208 1.36.208.608 0 1.136-.117 1.584-.352.448-.245.816-.624 1.104-1.136h.032V297h1.28zm9.371-.032c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.322 3.322 0 01-1.312.976 4.354 4.354 0 01-1.6.288c-.374 0-.731-.043-1.072-.128a2.473 2.473 0 01-.864-.4 1.997 1.997 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.266-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.458-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.319 4.319 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.682-.384 1.088-.48a5.89 5.89 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.298.16.538.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.042.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288 17.81 17.81 0 01-.88.144 14.57 14.57 0 00-.912.128c-.31.043-.587.117-.832.224a1.541 1.541 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.394.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.202-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm5.361-4v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.038.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.389-.005-.528-.016a.727.727 0 01-.304-.112.438.438 0 01-.16-.224 1.864 1.864 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm8.903 3.344h-4.752a2.75 2.75 0 01.208-.896c.117-.288.277-.539.48-.752.203-.213.443-.379.72-.496.288-.128.608-.192.96-.192.341 0 .651.064.928.192.288.117.533.283.736.496.213.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.43 2.43 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.367 4.367 0 00-.608-1.536 3.452 3.452 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32-.469.213-.88.512-1.232.896a4.208 4.208 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.171.533.421.992.752 1.376.331.384.736.683 1.216.896.491.213 1.067.32 1.728.32.939 0 1.717-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm1.49-5.648V297h1.36v-3.68c0-.533.053-1.003.16-1.408.107-.416.277-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm5.657 0V297h1.36v-4.672c0-.373.048-.715.144-1.024.107-.32.262-.597.464-.832.203-.235.454-.416.752-.544.31-.128.672-.192 1.088-.192.523 0 .934.149 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.243 2.243 0 00-.464-.96 2.227 2.227 0 00-.88-.624c-.362-.149-.816-.224-1.36-.224-1.226 0-2.122.501-2.688 1.504h-.032v-1.312h-1.28zm16.219 8.24c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.315 3.315 0 01-1.312.976 4.354 4.354 0 01-1.6.288 4.42 4.42 0 01-1.072-.128 2.473 2.473 0 01-.864-.4 2.008 2.008 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.267-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.459-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.309 4.309 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848a3.14 3.14 0 011.088-.48 5.896 5.896 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.299.16.539.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.043.149.171.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288c-.277.053-.571.101-.88.144a14.57 14.57 0 00-.912.128 3.165 3.165 0 00-.832.224 1.549 1.549 0 00-.608.464c-.149.192-.224.459-.224.8 0 .224.043.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.395.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.203-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.426-4V297h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm8.624 9.376c-.16.405-.32.747-.48 1.024-.15.277-.32.501-.512.672-.182.181-.39.309-.624.384a2.207 2.207 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.26 2.26 0 01-.464-.112v-1.248c.117.053.25.096.4.128.16.043.293.064.4.064.277 0 .506-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;291.018&quot; r=&quot;10.5&quot; fill=&quot;#fff&quot; stroke=&quot;#F1F1F1&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M70.64 245.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V251h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V251h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zm3.792 3.424v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.389-.005-.528-.016a.727.727 0 01-.304-.112.432.432 0 01-.16-.224 1.864 1.864 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm8.903 3.344h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm3.762-1.728L126.957 251h1.648l2.304-3.424 2.304 3.424h1.744l-3.2-4.464 2.848-3.808h-1.632l-2.064 2.896-1.985-2.896h-1.743l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.736 9.088h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm12.912-2.32h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm7.154-2.992h1.408c-.054-.491-.182-.912-.384-1.264a2.774 2.774 0 00-.784-.896 3.023 3.023 0 00-1.088-.512 4.718 4.718 0 00-1.312-.176c-.651 0-1.222.117-1.712.352a3.369 3.369 0 00-1.232.944 4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.618-.555 1.002-1.344 1.152-2.368h-1.392c-.086.64-.32 1.136-.704 1.488-.374.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.18 2.18 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.84 4.84 0 01-.128-1.12c0-.416.042-.816.128-1.2a3.12 3.12 0 01.416-1.04c.202-.299.469-.539.8-.72.33-.181.741-.272 1.232-.272.576 0 1.034.144 1.376.432.341.288.565.693.672 1.216zm3.969 1.488a4.2 4.2 0 01.192-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.598.341.832.608.235.267.416.597.544.992.139.384.208.827.208 1.328 0 .501-.069.949-.208 1.344a2.792 2.792 0 01-.544.976 2.421 2.421 0 01-.832.592 2.39 2.39 0 01-.992.208c-.352 0-.688-.069-1.008-.208a2.478 2.478 0 01-.816-.592 3.024 3.024 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.086 1.173.256 1.696.171.523.427.981.768 1.376.342.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.238-.107 1.728-.32a3.657 3.657 0 001.264-.912c.342-.395.598-.853.768-1.376a5.426 5.426 0 00.256-1.696c0-.608-.085-1.173-.256-1.696a3.755 3.755 0 00-.768-1.376 3.559 3.559 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.226.112-1.728.336a3.577 3.577 0 00-1.264.928 3.784 3.784 0 00-.768 1.376 5.455 5.455 0 00-.256 1.696zm9.636-4.144V251h1.36v-4.672c0-.373.048-.715.144-1.024.106-.32.261-.597.464-.832.202-.235.453-.416.752-.544a2.831 2.831 0 011.088-.192c.522 0 .933.149 1.232.448.298.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.255 2.255 0 00-.464-.96 2.234 2.234 0 00-.88-.624c-.363-.149-.816-.224-1.36-.224-1.227 0-2.123.501-2.688 1.504h-.032v-1.312h-1.28zm9.882 4.208c0-.405.043-.8.128-1.184a3.15 3.15 0 01.416-1.024 2.16 2.16 0 01.768-.72c.32-.181.71-.272 1.168-.272.47 0 .87.091 1.2.272.331.171.598.4.8.688.214.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.365 2.365 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.586-.4-.8-.688a3.32 3.32 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.04 2.04 0 00-.56-.608 2.608 2.608 0 00-.688-.4 3.218 3.218 0 00-.736-.224 3.986 3.986 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.373 3.373 0 00-1.184.928 4.018 4.018 0 00-.704 1.36 6.043 6.043 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V251h1.36zm9.421-.032c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.322 3.322 0 01-1.312.976 4.354 4.354 0 01-1.6.288c-.374 0-.731-.043-1.072-.128a2.473 2.473 0 01-.864-.4 1.997 1.997 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.266-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.458-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.319 4.319 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.682-.384 1.088-.48a5.89 5.89 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.298.16.538.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.042.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288 17.81 17.81 0 01-.88.144 14.57 14.57 0 00-.912.128c-.31.043-.587.117-.832.224a1.541 1.541 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.394.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.202-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.426-4V251h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm8.624 9.376c-.16.405-.32.747-.48 1.024-.15.277-.32.501-.512.672-.182.181-.39.309-.624.384a2.207 2.207 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.26 2.26 0 01-.464-.112v-1.248c.117.053.25.096.4.128.16.043.293.064.4.064.277 0 .506-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;245.009&quot; r=&quot;10.5&quot; fill=&quot;#757575&quot; stroke=&quot;#F1F1F1&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M70.64 337.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V343h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V343h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zM121.044 343v-8.272h-1.36v4.672c0 .373-.053.72-.16 1.04a2.256 2.256 0 01-.448.816 2.014 2.014 0 01-.768.544c-.299.128-.656.192-1.072.192-.523 0-.933-.149-1.232-.448-.299-.299-.448-.704-.448-1.216v-5.6h-1.36v5.44c0 .448.043.859.128 1.232a2.4 2.4 0 00.48.944c.224.267.517.475.88.624.363.139.816.208 1.36.208.608 0 1.136-.117 1.584-.352.448-.245.816-.624 1.104-1.136h.032V343h1.28zm3.483-9.76v-1.664h-1.36v1.664h1.36zm-1.36 1.488V343h1.36v-8.272h-1.36zm6.89-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.737 9.088h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.344 2.344 0 01-.641-.384.804.804 0 01-.24-.592c0-.213.054-.384.161-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm12.912-2.32h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.311 2.304h-1.343c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.199-2.096zm7.154-2.992h1.408c-.053-.491-.181-.912-.384-1.264a2.762 2.762 0 00-.784-.896 3.015 3.015 0 00-1.088-.512 4.708 4.708 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.171.512.416.955.736 1.328a3.34 3.34 0 001.216.864c.491.203 1.051.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.426 0-.794-.085-1.104-.256a2.189 2.189 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.894 4.894 0 01-.128-1.12c0-.416.043-.816.128-1.2.086-.395.224-.741.416-1.04.203-.299.47-.539.8-.72.331-.181.742-.272 1.232-.272.576 0 1.035.144 1.376.432.342.288.566.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.139-.395.325-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992.139.384.208.827.208 1.328 0 .501-.069.949-.208 1.344a2.792 2.792 0 01-.544.976 2.43 2.43 0 01-.832.592 2.39 2.39 0 01-.992.208c-.352 0-.688-.069-1.008-.208a2.478 2.478 0 01-.816-.592 3.006 3.006 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.171.523.427.981.768 1.376.341.384.763.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.666 3.666 0 001.264-.912c.341-.395.597-.853.768-1.376a5.426 5.426 0 00.256-1.696c0-.608-.085-1.173-.256-1.696a3.784 3.784 0 00-.768-1.376 3.568 3.568 0 00-1.264-.928c-.491-.224-1.067-.336-1.728-.336-.651 0-1.227.112-1.728.336a3.568 3.568 0 00-1.264.928 3.784 3.784 0 00-.768 1.376 5.426 5.426 0 00-.256 1.696zm9.636-4.144V343h1.36v-4.672c0-.373.048-.715.144-1.024.106-.32.261-.597.464-.832.202-.235.453-.416.752-.544a2.831 2.831 0 011.088-.192c.522 0 .933.149 1.232.448.298.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.255 2.255 0 00-.464-.96 2.234 2.234 0 00-.88-.624c-.363-.149-.816-.224-1.36-.224-1.227 0-2.123.501-2.688 1.504h-.032v-1.312h-1.28zm9.882 4.208c0-.405.043-.8.128-1.184.085-.384.224-.725.416-1.024a2.16 2.16 0 01.768-.72c.32-.181.709-.272 1.168-.272.469 0 .869.091 1.2.272.331.171.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.375 2.375 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.295 3.295 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.04 2.04 0 00-.56-.608 2.624 2.624 0 00-.688-.4 3.233 3.233 0 00-.736-.224 3.995 3.995 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.373 3.373 0 00-1.184.928 4.018 4.018 0 00-.704 1.36 6.043 6.043 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V343h1.36zm9.421-.032c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.322 3.322 0 01-1.312.976 4.354 4.354 0 01-1.6.288c-.374 0-.731-.043-1.072-.128a2.473 2.473 0 01-.864-.4 1.997 1.997 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.266-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.458-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.319 4.319 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.682-.384 1.088-.48a5.89 5.89 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.298.16.538.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.042.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288 17.81 17.81 0 01-.88.144 14.57 14.57 0 00-.912.128c-.31.043-.587.117-.832.224a1.541 1.541 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.394.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.202-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.425-4V343h1.36v-3.68c0-.533.054-1.003.16-1.408.107-.416.278-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm8.624 9.376c-.16.405-.32.747-.48 1.024-.149.277-.32.501-.512.672a1.531 1.531 0 01-.624.384 2.203 2.203 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.276 2.276 0 01-.464-.112v-1.248c.118.053.251.096.4.128.16.043.294.064.4.064.278 0 .507-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;337.027&quot; r=&quot;10.5&quot; fill=&quot;#757575&quot; stroke=&quot;#F1F1F1&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 36H368V164H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M28.5 79.5H296.5V120.5H28.5z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#757575&quot; d=&quot;M39.768 100.048v-4.192h2.976c.864 0 1.493.181 1.888.544.405.352.608.87.608 1.552 0 .683-.203 1.205-.608 1.568-.395.363-1.024.539-1.888.528h-2.976zm-1.52-5.472V106h1.52v-4.672h3.488c1.152.011 2.021-.283 2.608-.88.597-.597.896-1.43.896-2.496 0-1.067-.299-1.893-.896-2.48-.587-.597-1.456-.896-2.608-.896h-5.008zm10.231 0V106h1.36V94.576h-1.36zm10.795 11.392c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976-.373.448-.81.773-1.312.976a4.353 4.353 0 01-1.6.288 4.42 4.42 0 01-1.072-.128 2.478 2.478 0 01-.864-.4 2.006 2.006 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.267-.192.565-.336.896-.432.341-.096.688-.176 1.04-.24.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.459-.176.608-.304.15-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.08 1.08 0 00-.432-.416 1.682 1.682 0 00-.592-.192 4.31 4.31 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.683-.384 1.088-.48a5.893 5.893 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.71.165 1.008.336.299.16.538.39.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.043.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24c-.17.128-.395.224-.672.288-.277.053-.57.101-.88.144-.299.032-.603.075-.912.128-.31.043-.587.117-.832.224a1.546 1.546 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.15.096.32.165.512.208.192.043.395.064.608.064.448 0 .832-.059 1.152-.176.32-.128.581-.283.784-.464.203-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm9.09-1.344h1.408c-.054-.49-.182-.912-.384-1.264a2.769 2.769 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.701 4.701 0 00-1.312-.176c-.651 0-1.222.117-1.712.352-.491.224-.902.539-1.232.944-.32.395-.56.864-.72 1.408a5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.618-.555 1.002-1.344 1.152-2.368H66.22c-.086.64-.32 1.136-.704 1.488-.374.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.042-.816.128-1.2.085-.395.224-.741.416-1.04.202-.299.469-.539.8-.72.33-.181.741-.272 1.232-.272.576 0 1.034.144 1.376.432.341.288.565.693.672 1.216zm8.721.688h-4.752c.022-.32.091-.619.208-.896.118-.288.278-.539.48-.752a2.12 2.12 0 01.72-.496c.288-.128.608-.192.96-.192.342 0 .651.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.336 2.336 0 01-.816-.592 2.423 2.423 0 01-.464-.864 3.353 3.353 0 01-.128-1.04h6.192a6.352 6.352 0 00-.144-1.584 4.372 4.372 0 00-.608-1.536A3.45 3.45 0 0074.397 98c-.48-.31-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32-.469.213-.88.512-1.232.896a4.204 4.204 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.171.533.422.992.752 1.376.331.384.736.683 1.216.896.491.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm1.538-8.8V106h1.36v-4.672c0-.373.048-.715.144-1.024.107-.32.262-.597.464-.832a2.04 2.04 0 01.752-.544c.31-.128.672-.192 1.088-.192.523 0 .934.15 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.243 2.243 0 00-.464-.96 2.235 2.235 0 00-.88-.624c-.362-.15-.816-.224-1.36-.224a3.92 3.92 0 00-.768.08 3.298 3.298 0 00-.752.256c-.234.107-.448.25-.64.432-.192.17-.341.384-.448.64h-.032v-4.368h-1.36zm9.883 7.296a4.2 4.2 0 01.192-1.328 2.97 2.97 0 01.56-.992 2.37 2.37 0 01.816-.608 2.508 2.508 0 012 0c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.773 3.773 0 00-.768-1.376 3.572 3.572 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.57 3.57 0 00-1.264.928 3.77 3.77 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V106h1.36V94.576h-1.36zm4.459 7.36c0-.405.043-.8.128-1.184.085-.384.224-.725.416-1.024.192-.299.448-.539.768-.72.32-.181.709-.272 1.168-.272.469 0 .869.09 1.2.272.331.17.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.375 2.375 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.295 3.295 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064V94.576h-1.36v4.256h-.032a2.037 2.037 0 00-.56-.608 2.632 2.632 0 00-.688-.4 3.233 3.233 0 00-.736-.224 4.025 4.025 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.375 3.375 0 00-1.184.928c-.31.384-.544.837-.704 1.36a6.031 6.031 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V106h1.36zm7.837-4.928h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496a2.1 2.1 0 01.496.736c.128.288.202.592.224.912zm1.311 2.304h-1.343c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.389 4.389 0 00-.608-1.536A3.456 3.456 0 00114.101 98c-.48-.31-1.088-.464-1.824-.464-.566 0-1.088.107-1.568.32-.47.213-.88.512-1.232.896a4.193 4.193 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.199-2.096zm1.49-5.648V106h1.36v-3.68c0-.533.054-1.003.16-1.408.107-.416.278-.768.512-1.056.235-.288.544-.507.928-.656.384-.15.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm12.646-1.872V106h1.52V95.856h3.808v-1.28h-9.136v1.28h3.808zm10.334 5.216h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496a2.1 2.1 0 01.496.736c.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.389 4.389 0 00-.608-1.536A3.456 3.456 0 00139.882 98c-.48-.31-1.088-.464-1.824-.464-.566 0-1.088.107-1.568.32-.47.213-.88.512-1.232.896a4.193 4.193 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm3.762-1.728L142.332 106h1.648l2.304-3.424 2.304 3.424h1.744l-3.2-4.464 2.848-3.808h-1.632l-2.064 2.896-1.985-2.896h-1.743l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#757575&quot; d=&quot;M28.5 79.5H296.5V120.5H28.5z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#DEDEDE&quot; d=&quot;M0 164H368V165H0z&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div transform=&quot;translate3d(-110%, 5%, 0)&quot; class=&quot;sc-24qoga-0 sc-1h2zccj-0 eXecsn&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; fill=&quot;none&quot; viewBox=&quot;0 0 368 405&quot;&gt;&lt;g&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 0H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#F1F1F1&quot; d=&quot;M0 0H368V36H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M35.031 14.664h-2.66V22h-1.47v-7.336h-2.637V13.47h6.767v1.195zm3.252 7.453c-.902 0-1.635-.283-2.197-.85-.559-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.363-1.693.246-.5.59-.889 1.032-1.166a2.718 2.718 0 011.476-.416c.863 0 1.53.275 1.998.826.473.55.71 1.33.71 2.338v.574h-4.143c.043.524.216.938.521 1.242.309.305.695.457 1.16.457.653 0 1.184-.263 1.594-.79l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.897.31-1.424.31zm-.17-5.431c-.39 0-.707.136-.949.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.224-.246-.532-.37-.927-.37zm6.1 1.06l1.207-2.086h1.582l-1.94 3.123L47.066 22h-1.57l-1.266-2.168L42.97 22H41.39l2.004-3.217-1.934-3.123h1.57l1.184 2.086zm5.543-3.627v1.541h1.119v1.055h-1.12v3.539c0 .242.048.418.142.527.097.106.269.159.515.159.164 0 .33-.02.498-.06v1.102c-.324.09-.637.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424zm11.847 5.104c-.085.91-.421 1.62-1.007 2.133-.586.507-1.365.761-2.338.761-.68 0-1.28-.16-1.799-.48-.516-.325-.914-.784-1.195-1.377-.282-.594-.428-1.283-.44-2.069v-.796c0-.805.143-1.514.428-2.127.285-.614.693-1.086 1.225-1.418.535-.332 1.152-.498 1.851-.498.941 0 1.7.255 2.274.767.574.512.908 1.235 1.002 2.168h-1.477c-.07-.613-.25-1.055-.54-1.324-.284-.273-.704-.41-1.259-.41-.644 0-1.14.236-1.488.709-.344.468-.52 1.158-.528 2.068v.756c0 .922.165 1.625.493 2.11.332.484.816.726 1.453.726.582 0 1.02-.131 1.312-.393.293-.261.479-.697.557-1.306h1.476zm.926-.451c0-.622.123-1.18.37-1.676.245-.5.591-.883 1.036-1.149.446-.27.958-.404 1.536-.404.855 0 1.548.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.364 1.675a2.639 2.639 0 01-1.03 1.143c-.446.27-.962.404-1.548.404-.894 0-1.61-.297-2.15-.89-.535-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.125.55s.854-.187 1.12-.562c.27-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.311 1.311 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm7.014-3.235l.04.662c.446-.52 1.055-.779 1.829-.779.848 0 1.428.324 1.74.973.461-.649 1.11-.973 1.946-.973.699 0 1.218.193 1.558.58.344.387.52.957.527 1.711V22h-1.423v-4.125c0-.402-.088-.697-.264-.885-.176-.187-.467-.281-.873-.281-.324 0-.59.088-.797.264a1.366 1.366 0 00-.428.68L74.828 22h-1.424v-4.172c-.02-.746-.4-1.119-1.142-1.119-.57 0-.975.232-1.213.697V22h-1.424v-6.34h1.342zm14.654 3.235c0 .98-.223 1.763-.668 2.35-.445.581-1.043.872-1.793.872-.695 0-1.252-.228-1.67-.685v3.006h-1.424V15.66h1.313l.058.645c.419-.508.987-.762 1.706-.762.773 0 1.379.289 1.816.867.441.574.662 1.373.662 2.397v.088zm-1.418-.123c0-.633-.127-1.135-.38-1.506-.25-.371-.61-.557-1.079-.557-.582 0-1 .24-1.254.72v2.813c.258.492.68.738 1.266.738.453 0 .806-.181 1.06-.544.258-.368.387-.922.387-1.665zm2.361 0c0-.622.124-1.18.37-1.676.246-.5.591-.883 1.037-1.149.445-.27.957-.404 1.535-.404.855 0 1.549.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.363 1.675a2.64 2.64 0 01-1.032 1.143c-.445.27-.96.404-1.546.404-.895 0-1.612-.297-2.15-.89-.536-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.405 1.535.27.367.644.55 1.125.55.48 0 .853-.187 1.119-.562.27-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.311 1.311 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm6.996-3.235l.041.733c.47-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.85-.293-.574 0-1.001.26-1.283.78V22h-1.423v-6.34h1.341zm8.151 6.457c-.903 0-1.635-.283-2.197-.85-.559-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.363-1.693.246-.5.59-.889 1.031-1.166a2.72 2.72 0 011.477-.416c.863 0 1.529.275 1.998.826.472.55.709 1.33.709 2.338v.574h-4.143c.043.524.217.938.522 1.242.308.305.695.457 1.16.457.652 0 1.183-.263 1.594-.79l.767.732a2.585 2.585 0 01-1.019.885 3.19 3.19 0 01-1.424.31zm-.17-5.431c-.391 0-.707.136-.949.41-.239.273-.391.654-.457 1.142h2.712v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.37-.926-.37zm5.144-1.026l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.849-.293-.575 0-1.002.26-1.284.78V22h-1.423v-6.34h1.341zm7.143-1.54v1.54h1.119v1.055h-1.119v3.539c0 .242.047.418.141.527.097.106.269.159.515.159.164 0 .33-.02.498-.06v1.102c-.324.09-.636.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424zm13.184 4.241h-7.957v-1.148h7.957v1.148zM139.633 22h-1.477v-3.791h-3.814V22h-1.483v-8.531h1.483v3.55h3.814v-3.55h1.477V22zm3.135 0h-1.424v-6.34h1.424V22zm-1.512-7.986c0-.22.068-.4.205-.545.141-.145.34-.217.598-.217.257 0 .457.072.597.217a.748.748 0 01.211.545.74.74 0 01-.211.539c-.14.14-.34.21-.597.21-.258 0-.457-.07-.598-.21a.753.753 0 01-.205-.54zm4.389 1.646l.041.733c.468-.567 1.084-.85 1.845-.85 1.321 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.171-.195-.455-.293-.849-.293-.574 0-1.002.26-1.283.78V22h-1.424v-6.34h1.342zm7.142-1.54v1.54h1.119v1.055h-1.119v3.539c0 .242.047.418.141.527.097.106.269.159.515.159.164 0 .33-.02.498-.06v1.102c-.324.09-.636.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 164H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M67.84 194.856V205h1.52v-10.144h3.808v-1.28h-9.136v1.28h3.808zm10.334 5.216h-4.752c.022-.32.09-.619.208-.896.118-.288.278-.539.48-.752a2.12 2.12 0 01.72-.496c.288-.128.608-.192.96-.192.342 0 .65.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.336 2.336 0 01-.816-.592 2.423 2.423 0 01-.464-.864 3.353 3.353 0 01-.128-1.04h6.192a6.352 6.352 0 00-.144-1.584 4.37 4.37 0 00-.608-1.536A3.456 3.456 0 0077.694 197c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32a3.77 3.77 0 00-1.232.896 4.2 4.2 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.17.533.422.992.752 1.376.33.384.736.683 1.216.896.49.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm3.762-1.728L80.144 205h1.648l2.304-3.424L86.4 205h1.744l-3.2-4.464 2.848-3.808H86.16l-2.064 2.896-1.984-2.896h-1.744l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.038.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.39-.005-.528-.016a.725.725 0 01-.304-.112.434.434 0 01-.16-.224 1.836 1.836 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.128.272V205h1.52v-5.232h6.016V205h1.52v-11.424h-1.52v4.912h-6.016v-4.912h-1.52zm12.763 1.664v-1.664h-1.36v1.664h1.36zm-1.36 1.488V205h1.36v-8.272h-1.36zm3.467 0V205h1.36v-4.672c0-.373.048-.715.144-1.024.107-.32.261-.597.464-.832s.453-.416.752-.544a2.831 2.831 0 011.088-.192c.523 0 .933.149 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.243 2.243 0 00-.464-.96 2.227 2.227 0 00-.88-.624c-.363-.149-.816-.224-1.36-.224-1.227 0-2.123.501-2.688 1.504h-.032v-1.312h-1.28zm10.779 0v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zM31.486 201.136l1.302-3.668h.028l1.26 3.668h-2.59zm.21-6.132L27.916 205h2.212l.784-2.226h3.738l.756 2.226h2.282l-3.738-9.996h-2.254zm10.018 8.288c-.308 0-.565-.065-.77-.196a1.631 1.631 0 01-.504-.504 2.33 2.33 0 01-.266-.686 4.448 4.448 0 01-.07-.784c0-.271.028-.527.084-.77.065-.252.163-.471.294-.658.14-.196.308-.35.504-.462.205-.112.448-.168.728-.168.327 0 .597.061.812.182.215.121.387.285.518.49.13.205.224.443.28.714a4 4 0 01.084.84c0 .261-.037.513-.112.756a1.894 1.894 0 01-.308.63c-.14.187-.317.336-.532.448a1.581 1.581 0 01-.742.168zm3.584 1.246v-6.776h-1.89v.966h-.028c-.243-.42-.546-.719-.91-.896-.355-.177-.77-.266-1.246-.266-.504 0-.952.098-1.344.294a2.86 2.86 0 00-.966.798 3.54 3.54 0 00-.602 1.148c-.13.429-.196.877-.196 1.344 0 .495.056.966.168 1.414.121.439.308.826.56 1.162.252.327.574.588.966.784.392.187.859.28 1.4.28.439 0 .854-.089 1.246-.266a2 2 0 00.924-.854h.028v.952c.01.513-.117.938-.378 1.274-.252.336-.658.504-1.218.504-.355 0-.667-.075-.938-.224-.27-.14-.453-.397-.546-.77h-1.974c.028.411.14.761.336 1.05.205.299.457.541.756.728.308.187.644.322 1.008.406.373.093.737.14 1.092.14.83 0 1.493-.112 1.988-.336.495-.224.873-.499 1.134-.826.261-.317.43-.663.504-1.036a4.59 4.59 0 00.126-.994zM70.64 243.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V249h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zm3.792 3.424v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.389-.005-.528-.016a.727.727 0 01-.304-.112.432.432 0 01-.16-.224 1.864 1.864 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm8.903 3.344h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm3.762-1.728L126.957 249h1.648l2.304-3.424 2.304 3.424h1.744l-3.2-4.464 2.848-3.808h-1.632l-2.064 2.896-1.985-2.896h-1.743l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm2.736 9.088h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm12.912-2.32h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm7.154-2.992h1.408c-.054-.491-.182-.912-.384-1.264a2.774 2.774 0 00-.784-.896 3.023 3.023 0 00-1.088-.512 4.718 4.718 0 00-1.312-.176c-.651 0-1.222.117-1.712.352a3.369 3.369 0 00-1.232.944 4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.618-.555 1.002-1.344 1.152-2.368h-1.392c-.086.64-.32 1.136-.704 1.488-.374.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.18 2.18 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.84 4.84 0 01-.128-1.12c0-.416.042-.816.128-1.2a3.12 3.12 0 01.416-1.04c.202-.299.469-.539.8-.72.33-.181.741-.272 1.232-.272.576 0 1.034.144 1.376.432.341.288.565.693.672 1.216zm3.969 1.488a4.2 4.2 0 01.192-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.598.341.832.608.235.267.416.597.544.992.139.384.208.827.208 1.328 0 .501-.069.949-.208 1.344a2.792 2.792 0 01-.544.976 2.421 2.421 0 01-.832.592 2.39 2.39 0 01-.992.208c-.352 0-.688-.069-1.008-.208a2.478 2.478 0 01-.816-.592 3.024 3.024 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.086 1.173.256 1.696.171.523.427.981.768 1.376.342.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.238-.107 1.728-.32a3.657 3.657 0 001.264-.912c.342-.395.598-.853.768-1.376a5.426 5.426 0 00.256-1.696c0-.608-.085-1.173-.256-1.696a3.755 3.755 0 00-.768-1.376 3.559 3.559 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.226.112-1.728.336a3.577 3.577 0 00-1.264.928 3.784 3.784 0 00-.768 1.376 5.455 5.455 0 00-.256 1.696zm9.636-4.144V249h1.36v-4.672c0-.373.048-.715.144-1.024.106-.32.261-.597.464-.832.202-.235.453-.416.752-.544a2.831 2.831 0 011.088-.192c.522 0 .933.149 1.232.448.298.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.255 2.255 0 00-.464-.96 2.234 2.234 0 00-.88-.624c-.363-.149-.816-.224-1.36-.224-1.227 0-2.123.501-2.688 1.504h-.032v-1.312h-1.28zm9.882 4.208c0-.405.043-.8.128-1.184a3.15 3.15 0 01.416-1.024 2.16 2.16 0 01.768-.72c.32-.181.71-.272 1.168-.272.47 0 .87.091 1.2.272.331.171.598.4.8.688.214.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.365 2.365 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.586-.4-.8-.688a3.32 3.32 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.04 2.04 0 00-.56-.608 2.608 2.608 0 00-.688-.4 3.218 3.218 0 00-.736-.224 3.986 3.986 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.373 3.373 0 00-1.184.928 4.018 4.018 0 00-.704 1.36 6.043 6.043 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V249h1.36zm9.421-.032c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976a3.322 3.322 0 01-1.312.976 4.354 4.354 0 01-1.6.288c-.374 0-.731-.043-1.072-.128a2.473 2.473 0 01-.864-.4 1.997 1.997 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.266-.192.565-.336.896-.432a11.29 11.29 0 011.04-.24c.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.458-.176.608-.304.149-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.086 1.086 0 00-.432-.416 1.684 1.684 0 00-.592-.192 4.319 4.319 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.682-.384 1.088-.48a5.89 5.89 0 011.328-.144c.373 0 .741.027 1.104.08.373.053.709.165 1.008.336.298.16.538.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.042.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24a1.78 1.78 0 01-.672.288 17.81 17.81 0 01-.88.144 14.57 14.57 0 00-.912.128c-.31.043-.587.117-.832.224a1.541 1.541 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.149.096.32.165.512.208.192.043.394.064.608.064.448 0 .832-.059 1.152-.176a2.64 2.64 0 00.784-.464c.202-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm3.426-4V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm8.624 9.376c-.16.405-.32.747-.48 1.024-.15.277-.32.501-.512.672-.182.181-.39.309-.624.384a2.207 2.207 0 01-.784.128c-.16 0-.32-.011-.48-.032a2.26 2.26 0 01-.464-.112v-1.248c.117.053.25.096.4.128.16.043.293.064.4.064.277 0 .506-.069.688-.208.192-.128.336-.315.432-.56l.56-1.392-3.28-8.224h1.536l2.416 6.768h.032l2.32-6.768h1.44l-3.6 9.376z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;243&quot; r=&quot;10&quot; fill=&quot;#757575&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 36H368V164H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#757575&quot; d=&quot;M28.78 96.86V104h.95v-3.27h3.76V104h.95v-7.14h-.95v3.07h-3.76v-3.07h-.95zm7.977 1.04v-1.04h-.85v1.04h.85zm-.85.93V104h.85v-5.17h-.85zm2.167 0V104h.85v-2.92c0-.233.03-.447.09-.64.066-.2.163-.373.29-.52.126-.147.283-.26.47-.34.193-.08.42-.12.68-.12.326 0 .583.093.77.28.186.187.28.44.28.76v3.5h.85v-3.4c0-.28-.03-.533-.09-.76a1.402 1.402 0 00-.29-.6 1.397 1.397 0 00-.55-.39c-.227-.093-.51-.14-.85-.14-.767 0-1.327.313-1.68.94h-.02v-.82h-.8zm6.736 0v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.024.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.271.271 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03zm5.938 0v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.023.433.07.58.046.147.116.26.21.34.1.08.226.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.134 0-.244-.003-.33-.01a.453.453 0 01-.19-.07.271.271 0 01-.1-.14c-.014-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03zm5.564 2.09h-2.97c.013-.2.057-.387.13-.56a1.49 1.49 0 01.3-.47c.127-.133.277-.237.45-.31.18-.08.38-.12.6-.12.213 0 .407.04.58.12.18.073.333.177.46.31.133.127.237.28.31.46.08.18.127.37.14.57zm.82 1.44h-.84c-.073.34-.227.593-.46.76-.227.167-.52.25-.88.25-.28 0-.523-.047-.73-.14a1.461 1.461 0 01-.51-.37c-.133-.16-.23-.34-.29-.54a2.098 2.098 0 01-.08-.65h3.87a3.963 3.963 0 00-.09-.99 2.726 2.726 0 00-.38-.96 2.156 2.156 0 00-.73-.72c-.3-.193-.68-.29-1.14-.29-.353 0-.68.067-.98.2a2.36 2.36 0 00-.77.56c-.213.24-.38.523-.5.85-.12.327-.18.687-.18 1.08.013.393.07.757.17 1.09.107.333.263.62.47.86.207.24.46.427.76.56.307.133.667.2 1.08.2.587 0 1.073-.147 1.46-.44.387-.293.637-.73.75-1.31zm2.351-1.08l-1.94 2.72h1.03l1.44-2.14 1.44 2.14h1.09l-2-2.79 1.78-2.38h-1.02l-1.29 1.81-1.24-1.81h-1.09l1.8 2.45zm4.966-2.45v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.023.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.27.27 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#DEDEDE&quot; d=&quot;M0 164H368V165H0z&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div transform=&quot;translate3d(10%, 5%, 0)&quot; class=&quot;sc-24qoga-0 sc-1h2zccj-0 bFEiZ&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; fill=&quot;none&quot; viewBox=&quot;0 0 368 405&quot;&gt;&lt;g&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 0H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#F1F1F1&quot; d=&quot;M0 0H368V36H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M35.031 14.664h-2.66V22h-1.47v-7.336h-2.637V13.47h6.767v1.195zm3.252 7.453c-.902 0-1.635-.283-2.197-.85-.559-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.363-1.693.246-.5.59-.889 1.032-1.166a2.718 2.718 0 011.476-.416c.863 0 1.53.275 1.998.826.473.55.71 1.33.71 2.338v.574h-4.143c.043.524.216.938.521 1.242.309.305.695.457 1.16.457.653 0 1.184-.263 1.594-.79l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.897.31-1.424.31zm-.17-5.431c-.39 0-.707.136-.949.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.224-.246-.532-.37-.927-.37zm6.1 1.06l1.207-2.086h1.582l-1.94 3.123L47.066 22h-1.57l-1.266-2.168L42.97 22H41.39l2.004-3.217-1.934-3.123h1.57l1.184 2.086zm5.543-3.627v1.541h1.119v1.055h-1.12v3.539c0 .242.048.418.142.527.097.106.269.159.515.159.164 0 .33-.02.498-.06v1.102c-.324.09-.637.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424zm11.847 5.104c-.085.91-.421 1.62-1.007 2.133-.586.507-1.365.761-2.338.761-.68 0-1.28-.16-1.799-.48-.516-.325-.914-.784-1.195-1.377-.282-.594-.428-1.283-.44-2.069v-.796c0-.805.143-1.514.428-2.127.285-.614.693-1.086 1.225-1.418.535-.332 1.152-.498 1.851-.498.941 0 1.7.255 2.274.767.574.512.908 1.235 1.002 2.168h-1.477c-.07-.613-.25-1.055-.54-1.324-.284-.273-.704-.41-1.259-.41-.644 0-1.14.236-1.488.709-.344.468-.52 1.158-.528 2.068v.756c0 .922.165 1.625.493 2.11.332.484.816.726 1.453.726.582 0 1.02-.131 1.312-.393.293-.261.479-.697.557-1.306h1.476zm.926-.451c0-.622.123-1.18.37-1.676.245-.5.591-.883 1.036-1.149.446-.27.958-.404 1.536-.404.855 0 1.548.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.364 1.675a2.639 2.639 0 01-1.03 1.143c-.446.27-.962.404-1.548.404-.894 0-1.61-.297-2.15-.89-.535-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.125.55s.854-.187 1.12-.562c.27-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.311 1.311 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm7.014-3.235l.04.662c.446-.52 1.055-.779 1.829-.779.848 0 1.428.324 1.74.973.461-.649 1.11-.973 1.946-.973.699 0 1.218.193 1.558.58.344.387.52.957.527 1.711V22h-1.423v-4.125c0-.402-.088-.697-.264-.885-.176-.187-.467-.281-.873-.281-.324 0-.59.088-.797.264a1.366 1.366 0 00-.428.68L74.828 22h-1.424v-4.172c-.02-.746-.4-1.119-1.142-1.119-.57 0-.975.232-1.213.697V22h-1.424v-6.34h1.342zm14.654 3.235c0 .98-.223 1.763-.668 2.35-.445.581-1.043.872-1.793.872-.695 0-1.252-.228-1.67-.685v3.006h-1.424V15.66h1.313l.058.645c.419-.508.987-.762 1.706-.762.773 0 1.379.289 1.816.867.441.574.662 1.373.662 2.397v.088zm-1.418-.123c0-.633-.127-1.135-.38-1.506-.25-.371-.61-.557-1.079-.557-.582 0-1 .24-1.254.72v2.813c.258.492.68.738 1.266.738.453 0 .806-.181 1.06-.544.258-.368.387-.922.387-1.665zm2.361 0c0-.622.124-1.18.37-1.676.246-.5.591-.883 1.037-1.149.445-.27.957-.404 1.535-.404.855 0 1.549.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.363 1.675a2.64 2.64 0 01-1.032 1.143c-.445.27-.96.404-1.546.404-.895 0-1.612-.297-2.15-.89-.536-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.405 1.535.27.367.644.55 1.125.55.48 0 .853-.187 1.119-.562.27-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.311 1.311 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm6.996-3.235l.041.733c.47-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.85-.293-.574 0-1.001.26-1.283.78V22h-1.423v-6.34h1.341zm8.151 6.457c-.903 0-1.635-.283-2.197-.85-.559-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.363-1.693.246-.5.59-.889 1.031-1.166a2.72 2.72 0 011.477-.416c.863 0 1.529.275 1.998.826.472.55.709 1.33.709 2.338v.574h-4.143c.043.524.217.938.522 1.242.308.305.695.457 1.16.457.652 0 1.183-.263 1.594-.79l.767.732a2.585 2.585 0 01-1.019.885 3.19 3.19 0 01-1.424.31zm-.17-5.431c-.391 0-.707.136-.949.41-.239.273-.391.654-.457 1.142h2.712v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.37-.926-.37zm5.144-1.026l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.016 2.268V22h-1.424v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.849-.293-.575 0-1.002.26-1.284.78V22h-1.423v-6.34h1.341zm7.143-1.54v1.54h1.119v1.055h-1.119v3.539c0 .242.047.418.141.527.097.106.269.159.515.159.164 0 .33-.02.498-.06v1.102c-.324.09-.636.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424zm13.184 4.241h-7.957v-1.148h7.957v1.148zm9.41-.17h-3.504v2.625h4.096V22h-5.579v-8.531h5.537v1.195h-4.054v2.356h3.504v1.171zm4.98-1.23a3.525 3.525 0 00-.58-.047c-.652 0-1.092.25-1.318.75V22h-1.424v-6.34h1.359l.035.71c.344-.552.821-.827 1.43-.827.203 0 .371.027.504.082l-.006 1.336zm4.219 0a3.534 3.534 0 00-.58-.047c-.653 0-1.092.25-1.319.75V22h-1.423v-6.34h1.359l.035.71c.344-.552.821-.827 1.43-.827.203 0 .371.027.504.082l-.006 1.336zm.422 1.81c0-.62.123-1.18.369-1.675.246-.5.592-.883 1.037-1.149.445-.27.957-.404 1.535-.404.856 0 1.549.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.363 1.675a2.638 2.638 0 01-1.031 1.143c-.446.27-.961.404-1.547.404-.895 0-1.611-.297-2.15-.89-.536-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .653.134 1.165.404 1.536.269.367.644.55 1.125.55.48 0 .853-.187 1.119-.562.27-.375.404-.924.404-1.646 0-.641-.138-1.149-.416-1.524-.273-.375-.646-.563-1.119-.563-.465 0-.834.186-1.107.557-.274.367-.41.918-.41 1.652zm8.994-1.933a3.534 3.534 0 00-.58-.047c-.653 0-1.092.25-1.319.75V22h-1.424v-6.34h1.36l.035.71c.344-.552.82-.827 1.43-.827.203 0 .371.027.504.082l-.006 1.336z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 164H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M67.84 194.856V205h1.52v-10.144h3.808v-1.28h-9.136v1.28h3.808zm10.334 5.216h-4.752c.022-.32.09-.619.208-.896.118-.288.278-.539.48-.752a2.12 2.12 0 01.72-.496c.288-.128.608-.192.96-.192.342 0 .65.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.336 2.336 0 01-.816-.592 2.423 2.423 0 01-.464-.864 3.353 3.353 0 01-.128-1.04h6.192a6.352 6.352 0 00-.144-1.584 4.37 4.37 0 00-.608-1.536A3.456 3.456 0 0077.694 197c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32a3.77 3.77 0 00-1.232.896 4.2 4.2 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.17.533.422.992.752 1.376.33.384.736.683 1.216.896.49.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm3.762-1.728L80.144 205h1.648l2.304-3.424L86.4 205h1.744l-3.2-4.464 2.848-3.808H86.16l-2.064 2.896-1.984-2.896h-1.744l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.038.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.39-.005-.528-.016a.725.725 0 01-.304-.112.434.434 0 01-.16-.224 1.836 1.836 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm1.904.272V205h1.36v-4.672c0-.373.048-.715.144-1.024.107-.32.262-.597.464-.832.203-.235.454-.416.752-.544.31-.128.672-.192 1.088-.192.523 0 .934.149 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.243 2.243 0 00-.464-.96 2.227 2.227 0 00-.88-.624c-.362-.149-.816-.224-1.36-.224-.245 0-.501.027-.768.08a3.308 3.308 0 00-.752.256 2.359 2.359 0 00-.64.432 1.74 1.74 0 00-.448.64h-.032v-4.368h-1.36zm10.331 1.664v-1.664h-1.36v1.664h1.36zm-1.36 1.488V205h1.36v-8.272h-1.36zm3.467 0V205h1.36v-4.672c0-.373.048-.715.144-1.024.106-.32.261-.597.464-.832.202-.235.453-.416.752-.544a2.831 2.831 0 011.088-.192c.522 0 .933.149 1.232.448.298.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.255 2.255 0 00-.464-.96 2.234 2.234 0 00-.88-.624c-.363-.149-.816-.224-1.36-.224-1.227 0-2.123.501-2.688 1.504h-.032v-1.312h-1.28zm10.778 0v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.038.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.389-.005-.528-.016a.727.727 0 01-.304-.112.438.438 0 01-.16-.224 1.864 1.864 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zM31.486 201.136l1.302-3.668h.028l1.26 3.668h-2.59zm.21-6.132L27.916 205h2.212l.784-2.226h3.738l.756 2.226h2.282l-3.738-9.996h-2.254zm10.018 8.288c-.308 0-.565-.065-.77-.196a1.631 1.631 0 01-.504-.504 2.33 2.33 0 01-.266-.686 4.448 4.448 0 01-.07-.784c0-.271.028-.527.084-.77.065-.252.163-.471.294-.658.14-.196.308-.35.504-.462.205-.112.448-.168.728-.168.327 0 .597.061.812.182.215.121.387.285.518.49.13.205.224.443.28.714a4 4 0 01.084.84c0 .261-.037.513-.112.756a1.894 1.894 0 01-.308.63c-.14.187-.317.336-.532.448a1.581 1.581 0 01-.742.168zm3.584 1.246v-6.776h-1.89v.966h-.028c-.243-.42-.546-.719-.91-.896-.355-.177-.77-.266-1.246-.266-.504 0-.952.098-1.344.294a2.86 2.86 0 00-.966.798 3.54 3.54 0 00-.602 1.148c-.13.429-.196.877-.196 1.344 0 .495.056.966.168 1.414.121.439.308.826.56 1.162.252.327.574.588.966.784.392.187.859.28 1.4.28.439 0 .854-.089 1.246-.266a2 2 0 00.924-.854h.028v.952c.01.513-.117.938-.378 1.274-.252.336-.658.504-1.218.504-.355 0-.667-.075-.938-.224-.27-.14-.453-.397-.546-.77h-1.974c.028.411.14.761.336 1.05.205.299.457.541.756.728.308.187.644.322 1.008.406.373.093.737.14 1.092.14.83 0 1.493-.112 1.988-.336.495-.224.873-.499 1.134-.826.261-.317.43-.663.504-1.036a4.59 4.59 0 00.126-.994zM70.64 243.384h1.408c-.053-.491-.181-.912-.384-1.264a2.77 2.77 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.713 4.713 0 00-1.312-.176c-.65 0-1.221.117-1.712.352-.49.224-.901.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.619-.555 1.003-1.344 1.152-2.368h-1.392c-.085.64-.32 1.136-.704 1.488-.373.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.043-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.035.144 1.376.432.341.288.565.693.672 1.216zm3.97 1.488a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V249h1.36v-11.424h-1.36zm4.46 7.296a4.2 4.2 0 01.191-1.328c.139-.395.326-.725.56-.992.235-.267.507-.469.816-.608.32-.139.656-.208 1.008-.208s.683.069.992.208c.32.139.597.341.832.608.235.267.416.597.544.992a3.9 3.9 0 01.208 1.328c0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.427 2.427 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.472 2.472 0 01-.816-.592 3.007 3.007 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.255 1.696.17.523.427.981.768 1.376.341.384.763.688 1.264.912.502.213 1.078.32 1.728.32.662 0 1.237-.107 1.728-.32a3.665 3.665 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.085-1.173-.256-1.696a3.772 3.772 0 00-.768-1.376 3.567 3.567 0 00-1.264-.928c-.49-.224-1.066-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.569 3.569 0 00-1.264.928 3.775 3.775 0 00-.768 1.376 5.437 5.437 0 00-.256 1.696zm9.587-4.144V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.208 5.664h-1.36c.021.512.128.949.32 1.312.192.352.448.64.768.864.32.213.688.368 1.104.464.416.096.853.144 1.312.144a6.22 6.22 0 001.248-.128 3.218 3.218 0 001.136-.416 2.35 2.35 0 00.816-.8c.213-.331.32-.747.32-1.248 0-.395-.08-.725-.24-.992a1.892 1.892 0 00-.608-.656 3.014 3.014 0 00-.864-.432 9.691 9.691 0 00-.992-.272c-.32-.075-.64-.144-.96-.208a7.056 7.056 0 01-.864-.256 2.322 2.322 0 01-.64-.384.804.804 0 01-.24-.592c0-.213.053-.384.16-.512.106-.139.245-.245.416-.32a1.91 1.91 0 01.56-.176c.213-.032.421-.048.624-.048.224 0 .442.027.656.08.224.043.426.117.608.224a1.337 1.337 0 01.656 1.088h1.36c-.032-.501-.139-.917-.32-1.248a2.063 2.063 0 00-.736-.8 2.74 2.74 0 00-1.04-.416 6.163 6.163 0 00-1.296-.128c-.363 0-.731.048-1.104.144a3.138 3.138 0 00-.992.416 2.312 2.312 0 00-.72.72c-.182.299-.272.656-.272 1.072 0 .533.133.949.4 1.248.266.299.597.533.992.704.405.16.842.288 1.312.384.469.085.901.187 1.296.304.405.107.741.251 1.008.432.266.181.4.448.4.8 0 .256-.064.469-.192.64-.128.16-.294.283-.496.368a2.37 2.37 0 01-.64.176 4.987 4.987 0 01-.672.048c-.278 0-.55-.027-.816-.08a2.512 2.512 0 01-.704-.256 1.566 1.566 0 01-.496-.496 1.57 1.57 0 01-.208-.768zm10.592-9.088l-4.72 11.952h1.152l4.736-11.952h-1.168zm3.792 3.424v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.075.235.187.416.336.544.16.128.363.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.213 0-.389-.005-.528-.016a.727.727 0 01-.304-.112.432.432 0 01-.16-.224 1.864 1.864 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm8.903 3.344h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm3.762-1.728L126.957 249h1.648l2.304-3.424 2.304 3.424h1.744l-3.2-4.464 2.848-3.808h-1.632l-2.064 2.896-1.985-2.896h-1.743l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648zm6.583-3.424l-4.72 11.952h1.152l4.736-11.952h-1.168zm7.648 6.768h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm1.49-5.648V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm5.328 0V249h1.36v-3.68c0-.533.053-1.003.16-1.408.106-.416.277-.768.512-1.056.234-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.886.816-1.216 1.488h-.032v-1.744h-1.28zm6.087 4.144a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992.234-.267.506-.469.816-.608.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.43 2.43 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.457 2.457 0 01-.816-.592 2.988 2.988 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.676 3.676 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.784 3.784 0 00-.768-1.376 3.577 3.577 0 00-1.264-.928c-.491-.224-1.067-.336-1.728-.336-.651 0-1.227.112-1.728.336a3.559 3.559 0 00-1.264.928 3.755 3.755 0 00-.768 1.376 5.426 5.426 0 00-.256 1.696zm9.587-4.144V249h1.36v-3.68c0-.533.053-1.003.16-1.408.107-.416.277-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28z&quot;&gt;&lt;/path&gt;&lt;circle cx=&quot;38&quot; cy=&quot;243&quot; r=&quot;10&quot; fill=&quot;#D0421B&quot;&gt;&lt;/circle&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 36H368V164H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#D0421B&quot; d=&quot;M28.78 96.86V104h4.96v-.8h-4.01v-2.47h3.71v-.8h-3.71v-2.27h3.98v-.8h-4.93zm5.943 1.97V104h.85v-2.3c0-.333.034-.627.1-.88.067-.26.174-.48.32-.66.147-.18.34-.317.58-.41.24-.093.53-.14.87-.14v-.9c-.46-.013-.84.08-1.14.28-.3.2-.553.51-.76.93h-.02v-1.09h-.8zm3.33 0V104h.85v-2.3c0-.333.034-.627.1-.88.067-.26.174-.48.32-.66.147-.18.34-.317.58-.41.24-.093.53-.14.87-.14v-.9c-.46-.013-.84.08-1.14.28-.3.2-.553.51-.76.93h-.02v-1.09h-.8zm3.805 2.59c0-.313.04-.59.12-.83.086-.247.203-.453.35-.62a1.48 1.48 0 011.14-.51c.22 0 .426.043.62.13.2.087.373.213.52.38.146.167.26.373.34.62.086.24.13.517.13.83 0 .313-.044.593-.13.84a1.75 1.75 0 01-.34.61 1.52 1.52 0 01-.52.37 1.562 1.562 0 01-1.25 0 1.545 1.545 0 01-.51-.37 1.878 1.878 0 01-.35-.61 2.721 2.721 0 01-.12-.84zm-.9 0c0 .38.053.733.16 1.06.106.327.266.613.48.86.213.24.476.43.79.57.313.133.673.2 1.08.2.413 0 .773-.067 1.08-.2.313-.14.576-.33.79-.57.213-.247.373-.533.48-.86a3.4 3.4 0 00.16-1.06 3.4 3.4 0 00-.16-1.06 2.36 2.36 0 00-.48-.86 2.233 2.233 0 00-.79-.58 2.58 2.58 0 00-1.08-.21c-.407 0-.767.07-1.08.21-.314.14-.577.333-.79.58-.214.24-.374.527-.48.86-.107.327-.16.68-.16 1.06zm5.992-2.59V104h.85v-2.3c0-.333.033-.627.1-.88.067-.26.173-.48.32-.66.147-.18.34-.317.58-.41.24-.093.53-.14.87-.14v-.9c-.46-.013-.84.08-1.14.28-.3.2-.553.51-.76.93h-.02v-1.09h-.8zm7.323 0v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.023.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.271.271 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03zm5.564 2.09h-2.97c.014-.2.057-.387.13-.56a1.49 1.49 0 01.3-.47c.127-.133.277-.237.45-.31.18-.08.38-.12.6-.12.214 0 .407.04.58.12.18.073.334.177.46.31.134.127.237.28.31.46.08.18.127.37.14.57zm.82 1.44h-.84c-.073.34-.226.593-.46.76-.226.167-.52.25-.88.25-.28 0-.523-.047-.73-.14a1.461 1.461 0 01-.51-.37c-.133-.16-.23-.34-.29-.54a2.098 2.098 0 01-.08-.65h3.87a3.963 3.963 0 00-.09-.99 2.726 2.726 0 00-.38-.96 2.156 2.156 0 00-.73-.72c-.3-.193-.68-.29-1.14-.29-.353 0-.68.067-.98.2a2.36 2.36 0 00-.77.56c-.213.24-.38.523-.5.85-.12.327-.18.687-.18 1.08.014.393.07.757.17 1.09.107.333.264.62.47.86.207.24.46.427.76.56.307.133.667.2 1.08.2.587 0 1.074-.147 1.46-.44.387-.293.637-.73.75-1.31zm2.352-1.08l-1.94 2.72h1.03l1.44-2.14 1.44 2.14h1.09l-2-2.79 1.78-2.38h-1.02l-1.29 1.81-1.24-1.81h-1.09l1.8 2.45zm4.965-2.45v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.024.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.27.27 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#DEDEDE&quot; d=&quot;M0 164H368V165H0z&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div transform=&quot;translate3d(-50%, -50%, 0)&quot; class=&quot;sc-24qoga-0 sc-1h2zccj-1 iukEJm&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; fill=&quot;none&quot; viewBox=&quot;0 0 368 405&quot;&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 0H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#F1F1F1&quot; d=&quot;M0 0H368V36H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M33.783 18.385H30.35V22h-1.483v-8.531h5.42v1.195H30.35v2.537h3.433v1.184zM36.842 22h-1.424v-6.34h1.424V22zm-1.512-7.986c0-.22.068-.4.205-.545.14-.145.34-.217.598-.217.258 0 .457.072.597.217a.75.75 0 01.211.545c0 .215-.07.394-.21.539-.141.14-.34.21-.598.21-.258 0-.457-.07-.598-.21a.754.754 0 01-.205-.54zm5.86 8.103c-.903 0-1.635-.283-2.198-.85-.558-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.364-1.693.246-.5.59-.889 1.03-1.166a2.718 2.718 0 011.477-.416c.864 0 1.53.275 1.998.826.473.55.71 1.33.71 2.338v.574H39.59c.043.524.217.938.521 1.242.309.305.696.457 1.16.457.653 0 1.184-.263 1.594-.79l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.896.31-1.423.31zm-.17-5.431c-.391 0-.708.136-.95.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.37-.926-.37zM46.356 22h-1.423v-9h1.423v9zm1.29-3.217c0-.976.226-1.76.68-2.35.452-.593 1.06-.89 1.821-.89.672 0 1.215.234 1.63.703V13H53.2v9h-1.289l-.07-.656c-.426.515-.994.773-1.705.773-.742 0-1.344-.299-1.805-.896-.457-.598-.685-1.41-.685-2.438zm1.423.123c0 .645.123 1.149.37 1.512.25.36.603.539 1.06.539.582 0 1.008-.26 1.277-.78v-2.706c-.261-.508-.683-.762-1.265-.762-.461 0-.817.184-1.067.55-.25.364-.375.913-.375 1.647zm15.252.317c-.086.91-.422 1.62-1.008 2.133-.586.507-1.365.761-2.337.761-.68 0-1.28-.16-1.8-.48-.515-.325-.913-.784-1.195-1.377-.28-.594-.427-1.283-.439-2.069v-.796c0-.805.142-1.514.428-2.127.285-.614.693-1.086 1.224-1.418.535-.332 1.153-.498 1.852-.498.941 0 1.7.255 2.273.767.575.512.908 1.235 1.002 2.168h-1.476c-.07-.613-.25-1.055-.54-1.324-.284-.273-.704-.41-1.26-.41-.644 0-1.14.236-1.487.709-.344.468-.52 1.158-.528 2.068v.756c0 .922.164 1.625.492 2.11.332.484.817.726 1.454.726.582 0 1.02-.131 1.312-.393.293-.261.479-.697.557-1.306h1.476zm.926-.451c0-.622.123-1.18.37-1.676.245-.5.591-.883 1.036-1.149.446-.27.957-.404 1.535-.404.856 0 1.55.275 2.08.826.536.55.825 1.281.868 2.192l.006.334c0 .625-.121 1.183-.364 1.675a2.639 2.639 0 01-1.031 1.143c-.445.27-.96.404-1.547.404-.894 0-1.611-.297-2.15-.89-.535-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.125.55s.854-.187 1.12-.562c.269-.375.404-.924.404-1.646 0-.641-.14-1.149-.416-1.524a1.311 1.311 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm7.014-3.235l.04.662c.446-.52 1.055-.779 1.829-.779.847 0 1.427.324 1.74.973.46-.649 1.11-.973 1.945-.973.7 0 1.219.193 1.559.58.344.387.52.957.527 1.711V22h-1.424v-4.125c0-.402-.088-.697-.263-.885-.176-.187-.467-.281-.873-.281-.325 0-.59.088-.797.264a1.366 1.366 0 00-.428.68L77.547 22h-1.424v-4.172c-.02-.746-.4-1.119-1.142-1.119-.57 0-.975.232-1.213.697V22h-1.424v-6.34h1.342zm14.654 3.235c0 .98-.223 1.763-.668 2.35-.445.581-1.043.872-1.793.872-.695 0-1.252-.228-1.67-.685v3.006h-1.424V15.66h1.313l.058.645c.418-.508.987-.762 1.705-.762.774 0 1.38.289 1.817.867.441.574.662 1.373.662 2.397v.088zm-1.418-.123c0-.633-.127-1.135-.381-1.506-.25-.371-.61-.557-1.078-.557-.582 0-1 .24-1.254.72v2.813c.258.492.68.738 1.266.738.453 0 .806-.181 1.06-.544.258-.368.387-.922.387-1.665zm2.361 0c0-.622.123-1.18.37-1.676.245-.5.591-.883 1.036-1.149.446-.27.958-.404 1.536-.404.855 0 1.548.275 2.08.826.535.55.824 1.281.867 2.192l.006.334c0 .625-.121 1.183-.364 1.675a2.64 2.64 0 01-1.03 1.143c-.446.27-.962.404-1.548.404-.894 0-1.611-.297-2.15-.89-.535-.598-.803-1.393-.803-2.385v-.07zm1.424.123c0 .652.135 1.164.404 1.535.27.367.645.55 1.125.55s.854-.187 1.12-.562c.269-.375.404-.924.404-1.646 0-.641-.139-1.149-.416-1.524a1.312 1.312 0 00-1.12-.563c-.464 0-.833.186-1.107.557-.273.367-.41.918-.41 1.652zm6.996-3.235l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.015 2.268V22h-1.423v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.85-.293-.574 0-1.002.26-1.283.78V22h-1.424v-6.34h1.342zm8.151 6.457c-.903 0-1.635-.283-2.198-.85-.558-.57-.838-1.328-.838-2.273v-.176c0-.633.121-1.197.364-1.693.246-.5.589-.889 1.031-1.166a2.715 2.715 0 011.476-.416c.864 0 1.53.275 1.999.826.472.55.708 1.33.708 2.338v.574h-4.142c.043.524.217.938.521 1.242.309.305.696.457 1.161.457.652 0 1.183-.263 1.593-.79l.768.732a2.58 2.58 0 01-1.02.885c-.422.207-.896.31-1.423.31zm-.17-5.431c-.391 0-.707.136-.95.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.381-1.078-.222-.246-.531-.37-.925-.37zm5.144-1.026l.041.733c.469-.567 1.084-.85 1.846-.85 1.32 0 1.992.756 2.015 2.268V22h-1.423v-4.107c0-.403-.088-.7-.264-.891-.172-.195-.455-.293-.85-.293-.574 0-1.002.26-1.283.78V22h-1.424v-6.34h1.342zm7.143-1.54v1.54h1.119v1.055h-1.119v3.539c0 .242.047.418.14.527.098.106.27.159.516.159.164 0 .33-.02.498-.06v1.102c-.324.09-.637.135-.937.135-1.094 0-1.641-.603-1.641-1.81v-3.592h-1.043V15.66h1.043v-1.54h1.424z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M0 36H368V405H0z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#262626&quot; d=&quot;M30.35 165.816h3.873V167h-5.356v-8.531h1.483v7.347zM39.01 167c-.063-.121-.117-.318-.164-.592a2.215 2.215 0 01-1.664.709c-.637 0-1.157-.181-1.559-.545a1.742 1.742 0 01-.603-1.347c0-.676.25-1.194.75-1.553.503-.363 1.222-.545 2.156-.545h.873v-.416c0-.328-.092-.59-.276-.785-.183-.199-.463-.299-.838-.299-.324 0-.59.082-.796.246a.744.744 0 00-.31.615h-1.425c0-.347.115-.672.346-.972.23-.305.543-.543.938-.715a3.322 3.322 0 011.33-.258c.742 0 1.334.187 1.775.562.441.372.668.895.68 1.571v2.859c0 .57.08 1.026.24 1.365v.1H39.01zm-1.565-1.025c.282 0 .545-.069.791-.205.25-.137.438-.321.563-.551v-1.196h-.768c-.527 0-.924.092-1.19.276a.89.89 0 00-.398.779c0 .274.09.492.27.656.184.161.428.241.732.241zm9.832-2.08c0 .984-.22 1.767-.662 2.349-.437.582-1.04.873-1.81.873-.742 0-1.32-.267-1.735-.803L43 167h-1.29v-9h1.425v3.27c.41-.485.963-.727 1.658-.727.773 0 1.38.287 1.822.861.442.575.662 1.377.662 2.408v.083zm-1.424-.124c0-.687-.12-1.203-.363-1.546-.242-.344-.593-.516-1.055-.516-.617 0-1.05.27-1.3.809v2.613c.254.551.691.826 1.312.826.446 0 .79-.166 1.031-.498.243-.332.368-.834.375-1.506v-.182zm5.415 3.346c-.903 0-1.635-.283-2.198-.849-.558-.571-.838-1.329-.838-2.274v-.176c0-.632.121-1.197.364-1.693a2.8 2.8 0 011.031-1.166 2.721 2.721 0 011.476-.416c.864 0 1.53.275 1.999.826.472.551.709 1.33.709 2.338v.574h-4.143c.043.524.217.938.522 1.242.308.305.695.457 1.16.457.652 0 1.183-.263 1.593-.791l.768.733a2.58 2.58 0 01-1.02.885 3.19 3.19 0 01-1.423.31zm-.17-5.431c-.391 0-.707.136-.95.41-.238.273-.39.654-.457 1.142h2.713v-.105c-.031-.477-.158-.836-.38-1.078-.223-.246-.532-.369-.926-.369zM56.435 167h-1.423v-9h1.423v9z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#0064D9&quot; d=&quot;M61.945 161.305l-1.787-.516.322-.99 1.77.685-.088-2.015h1.049l-.088 2.051 1.74-.674.317 1.008-1.817.515 1.172 1.559-.85.621-1.054-1.688-1.043 1.635-.856-.598 1.213-1.593z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M28.5 174.5H296.5V215.5H28.5z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#757575&quot; d=&quot;M39.768 195.048v-4.192h2.976c.864 0 1.493.181 1.888.544.405.352.608.869.608 1.552s-.203 1.205-.608 1.568c-.395.363-1.024.539-1.888.528h-2.976zm-1.52-5.472V201h1.52v-4.672h3.488c1.152.011 2.021-.283 2.608-.88.597-.597.896-1.429.896-2.496s-.299-1.893-.896-2.48c-.587-.597-1.456-.896-2.608-.896h-5.008zm10.231 0V201h1.36v-11.424h-1.36zm10.795 11.392c-.235.139-.56.208-.976.208-.352 0-.635-.096-.848-.288-.203-.203-.304-.528-.304-.976-.373.448-.81.773-1.312.976a4.353 4.353 0 01-1.6.288 4.42 4.42 0 01-1.072-.128 2.478 2.478 0 01-.864-.4 2.006 2.006 0 01-.592-.704c-.139-.299-.208-.656-.208-1.072 0-.469.08-.853.24-1.152.16-.299.368-.539.624-.72.267-.192.565-.336.896-.432.341-.096.688-.176 1.04-.24.373-.075.725-.128 1.056-.16.341-.043.64-.096.896-.16.256-.075.459-.176.608-.304.15-.139.224-.336.224-.592 0-.299-.059-.539-.176-.72a1.082 1.082 0 00-.432-.416 1.682 1.682 0 00-.592-.192 4.31 4.31 0 00-.64-.048c-.576 0-1.056.112-1.44.336-.384.213-.592.624-.624 1.232h-1.36c.021-.512.128-.944.32-1.296.192-.352.448-.635.768-.848.32-.224.683-.384 1.088-.48a5.893 5.893 0 011.328-.144c.373 0 .741.027 1.104.08a2.8 2.8 0 011.008.336c.299.16.538.389.72.688.181.299.272.688.272 1.168v4.256c0 .32.016.555.048.704.043.149.17.224.384.224.117 0 .256-.027.416-.08v1.056zm-2.208-4.24c-.17.128-.395.224-.672.288-.277.053-.57.101-.88.144-.299.032-.603.075-.912.128-.31.043-.587.117-.832.224a1.546 1.546 0 00-.608.464c-.15.192-.224.459-.224.8 0 .224.042.416.128.576.096.149.213.272.352.368.15.096.32.165.512.208.192.043.395.064.608.064.448 0 .832-.059 1.152-.176.32-.128.581-.283.784-.464.203-.192.352-.395.448-.608.096-.224.144-.432.144-.624v-1.392zm9.09-1.344h1.408c-.054-.491-.182-.912-.384-1.264a2.769 2.769 0 00-.784-.896 3.017 3.017 0 00-1.088-.512 4.712 4.712 0 00-1.312-.176c-.651 0-1.222.117-1.712.352-.491.224-.902.539-1.232.944a4 4 0 00-.72 1.408 5.985 5.985 0 00-.24 1.728c0 .619.08 1.189.24 1.712.17.512.416.955.736 1.328.33.373.736.661 1.216.864.49.203 1.05.304 1.68.304 1.056 0 1.888-.277 2.496-.832.618-.555 1.002-1.344 1.152-2.368H66.22c-.086.64-.32 1.136-.704 1.488-.374.352-.896.528-1.568.528-.427 0-.795-.085-1.104-.256a2.186 2.186 0 01-.752-.672 3.235 3.235 0 01-.432-.976 4.878 4.878 0 01-.128-1.12c0-.416.042-.816.128-1.2.085-.395.224-.741.416-1.04a2.26 2.26 0 01.8-.72c.33-.181.741-.272 1.232-.272.576 0 1.034.144 1.376.432.341.288.565.693.672 1.216zm8.721.688h-4.752c.022-.32.091-.619.208-.896.118-.288.278-.539.48-.752a2.12 2.12 0 01.72-.496c.288-.128.608-.192.96-.192.342 0 .651.064.928.192.288.117.534.283.736.496.214.203.379.448.496.736.128.288.203.592.224.912zm1.312 2.304h-1.344c-.117.544-.362.949-.736 1.216-.362.267-.832.4-1.408.4-.448 0-.837-.075-1.168-.224a2.336 2.336 0 01-.816-.592 2.423 2.423 0 01-.464-.864 3.353 3.353 0 01-.128-1.04h6.192a6.352 6.352 0 00-.144-1.584 4.37 4.37 0 00-.608-1.536A3.456 3.456 0 0074.397 193c-.48-.309-1.088-.464-1.824-.464-.565 0-1.088.107-1.568.32a3.77 3.77 0 00-1.232.896 4.2 4.2 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.022.629.112 1.211.272 1.744.171.533.422.992.752 1.376.331.384.736.683 1.216.896.491.213 1.067.32 1.728.32.939 0 1.718-.235 2.336-.704.619-.469 1.019-1.168 1.2-2.096zm1.538-8.8V201h1.36v-4.672c0-.373.048-.715.144-1.024a2.44 2.44 0 01.464-.832c.203-.235.454-.416.752-.544.31-.128.672-.192 1.088-.192.523 0 .934.149 1.232.448.299.299.448.704.448 1.216v5.6h1.36v-5.44c0-.448-.048-.853-.144-1.216a2.247 2.247 0 00-.464-.96 2.23 2.23 0 00-.88-.624c-.362-.149-.816-.224-1.36-.224-.245 0-.501.027-.768.08a3.298 3.298 0 00-.752.256 2.35 2.35 0 00-.64.432 1.737 1.737 0 00-.448.64h-.032v-4.368h-1.36zm9.883 7.296a4.2 4.2 0 01.192-1.328c.138-.395.325-.725.56-.992a2.37 2.37 0 01.816-.608c.32-.139.656-.208 1.008-.208s.682.069.992.208c.32.139.597.341.832.608.234.267.416.597.544.992.138.384.208.827.208 1.328 0 .501-.07.949-.208 1.344-.128.384-.31.709-.544.976a2.428 2.428 0 01-.832.592c-.31.139-.64.208-.992.208s-.688-.069-1.008-.208a2.47 2.47 0 01-.816-.592 3.004 3.004 0 01-.56-.976 4.353 4.353 0 01-.192-1.344zm-1.44 0c0 .608.085 1.173.256 1.696.17.523.426.981.768 1.376.341.384.762.688 1.264.912.501.213 1.077.32 1.728.32.661 0 1.237-.107 1.728-.32a3.667 3.667 0 001.264-.912c.341-.395.597-.853.768-1.376.17-.523.256-1.088.256-1.696 0-.608-.086-1.173-.256-1.696a3.775 3.775 0 00-.768-1.376 3.569 3.569 0 00-1.264-.928c-.49-.224-1.067-.336-1.728-.336-.65 0-1.227.112-1.728.336a3.567 3.567 0 00-1.264.928 3.772 3.772 0 00-.768 1.376 5.434 5.434 0 00-.256 1.696zm9.715-7.296V201h1.36v-11.424h-1.36zm4.459 7.36c0-.405.043-.8.128-1.184.085-.384.224-.725.416-1.024a2.16 2.16 0 01.768-.72c.32-.181.709-.272 1.168-.272.469 0 .869.091 1.2.272.331.171.597.4.8.688.213.288.368.624.464 1.008a4.672 4.672 0 010 2.304 2.938 2.938 0 01-.432 1.008 2.375 2.375 0 01-.784.704c-.32.181-.709.272-1.168.272-.437 0-.821-.085-1.152-.256-.32-.171-.587-.4-.8-.688a3.295 3.295 0 01-.464-.976 4.542 4.542 0 01-.144-1.136zm6.4 4.064v-11.424h-1.36v4.256h-.032a2.04 2.04 0 00-.56-.608 2.624 2.624 0 00-.688-.4 3.233 3.233 0 00-.736-.224 3.995 3.995 0 00-.688-.064c-.629 0-1.184.117-1.664.352a3.372 3.372 0 00-1.184.928c-.31.384-.544.837-.704 1.36a6.031 6.031 0 00-.224 1.664c0 .587.08 1.141.24 1.664.16.523.395.981.704 1.376.32.395.715.709 1.184.944.48.235 1.04.352 1.68.352.576 0 1.104-.101 1.584-.304.48-.203.832-.533 1.056-.992h.032V201h1.36zm7.837-4.928h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.311 2.304h-1.343c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.199-2.096zm1.49-5.648V201h1.36v-3.68c0-.533.054-1.003.16-1.408.107-.416.278-.768.512-1.056.235-.288.544-.507.928-.656.384-.149.848-.224 1.392-.224v-1.44c-.736-.021-1.344.128-1.824.448s-.885.816-1.216 1.488h-.032v-1.744h-1.28zm12.646-1.872V201h1.52v-10.144h3.808v-1.28h-9.136v1.28h3.808zm10.334 5.216h-4.752c.021-.32.09-.619.208-.896.117-.288.277-.539.48-.752.202-.213.442-.379.72-.496.288-.128.608-.192.96-.192.341 0 .65.064.928.192.288.117.533.283.736.496.213.203.378.448.496.736.128.288.202.592.224.912zm1.312 2.304h-1.344c-.118.544-.363.949-.736 1.216-.363.267-.832.4-1.408.4-.448 0-.838-.075-1.168-.224a2.33 2.33 0 01-.816-.592 2.413 2.413 0 01-.464-.864 3.344 3.344 0 01-.128-1.04h6.192a6.38 6.38 0 00-.144-1.584 4.386 4.386 0 00-.608-1.536 3.461 3.461 0 00-1.168-1.152c-.48-.309-1.088-.464-1.824-.464a3.82 3.82 0 00-1.568.32c-.47.213-.88.512-1.232.896a4.19 4.19 0 00-.8 1.36 4.98 4.98 0 00-.288 1.728c.021.629.112 1.211.272 1.744.17.533.421.992.752 1.376.33.384.736.683 1.216.896.49.213 1.066.32 1.728.32.938 0 1.717-.235 2.336-.704.618-.469 1.018-1.168 1.2-2.096zm3.762-1.728L142.332 201h1.648l2.304-3.424 2.304 3.424h1.744l-3.2-4.464 2.848-3.808h-1.632l-2.064 2.896-1.985-2.896h-1.743l2.88 3.92zm7.945-3.92v-2.48h-1.36v2.48h-1.408v1.2h1.408v5.264c0 .384.037.693.112.928.074.235.186.416.336.544.16.128.362.219.608.272.256.043.56.064.912.064h1.04v-1.2h-.624c-.214 0-.39-.005-.528-.016a.722.722 0 01-.304-.112.432.432 0 01-.16-.224 1.796 1.796 0 01-.032-.384v-5.136h1.648v-1.2h-1.648z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#757575&quot; d=&quot;M28.5 174.5H296.5V215.5H28.5z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#757575&quot; d=&quot;M28.78 222.86V230h.95v-3.27h3.76V230h.95v-7.14h-.95v3.07h-3.76v-3.07h-.95zm7.977 1.04v-1.04h-.85v1.04h.85zm-.85.93V230h.85v-5.17h-.85zm2.167 0V230h.85v-2.92c0-.233.03-.447.09-.64.066-.2.163-.373.29-.52a1.27 1.27 0 01.47-.34c.193-.08.42-.12.68-.12.326 0 .583.093.77.28.186.187.28.44.28.76v3.5h.85v-3.4c0-.28-.03-.533-.09-.76a1.406 1.406 0 00-.29-.6 1.39 1.39 0 00-.55-.39c-.227-.093-.51-.14-.85-.14-.767 0-1.327.313-1.68.94h-.02v-.82h-.8zm6.736 0v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.024.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.271.271 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03zm5.938 0v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.023.433.07.58.046.147.116.26.21.34.1.08.226.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.134 0-.244-.003-.33-.01a.453.453 0 01-.19-.07.271.271 0 01-.1-.14c-.014-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03zm5.564 2.09h-2.97c.013-.2.057-.387.13-.56a1.49 1.49 0 01.3-.47c.127-.133.277-.237.45-.31.18-.08.38-.12.6-.12.213 0 .407.04.58.12.18.073.333.177.46.31.133.127.237.28.31.46.08.18.127.37.14.57zm.82 1.44h-.84c-.073.34-.227.593-.46.76-.227.167-.52.25-.88.25-.28 0-.523-.047-.73-.14a1.461 1.461 0 01-.51-.37c-.133-.16-.23-.34-.29-.54a2.098 2.098 0 01-.08-.65h3.87a3.963 3.963 0 00-.09-.99 2.726 2.726 0 00-.38-.96 2.162 2.162 0 00-.73-.72c-.3-.193-.68-.29-1.14-.29-.353 0-.68.067-.98.2-.293.133-.55.32-.77.56-.213.24-.38.523-.5.85-.12.327-.18.687-.18 1.08.013.393.07.757.17 1.09.107.333.263.62.47.86.207.24.46.427.76.56.307.133.667.2 1.08.2.587 0 1.073-.147 1.46-.44.387-.293.637-.73.75-1.31zm2.351-1.08l-1.94 2.72h1.03l1.44-2.14 1.44 2.14h1.09l-2-2.79 1.78-2.38h-1.02l-1.29 1.81-1.24-1.81h-1.09l1.8 2.45zm4.966-2.45v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.023.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.27.27 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#D0421B&quot; d=&quot;M28.78 239.86V247h4.96v-.8h-4.01v-2.47h3.71v-.8h-3.71v-2.27h3.98v-.8h-4.93zm5.943 1.97V247h.85v-2.3c0-.333.034-.627.1-.88.067-.26.174-.48.32-.66.147-.18.34-.317.58-.41.24-.093.53-.14.87-.14v-.9c-.46-.013-.84.08-1.14.28-.3.2-.553.51-.76.93h-.02v-1.09h-.8zm3.33 0V247h.85v-2.3c0-.333.034-.627.1-.88.067-.26.174-.48.32-.66.147-.18.34-.317.58-.41.24-.093.53-.14.87-.14v-.9c-.46-.013-.84.08-1.14.28-.3.2-.553.51-.76.93h-.02v-1.09h-.8zm3.805 2.59c0-.313.04-.59.12-.83.086-.247.203-.453.35-.62a1.48 1.48 0 011.14-.51c.22 0 .426.043.62.13.2.087.373.213.52.38.146.167.26.373.34.62.086.24.13.517.13.83 0 .313-.044.593-.13.84a1.75 1.75 0 01-.34.61 1.52 1.52 0 01-.52.37 1.562 1.562 0 01-1.25 0 1.545 1.545 0 01-.51-.37 1.878 1.878 0 01-.35-.61 2.721 2.721 0 01-.12-.84zm-.9 0c0 .38.053.733.16 1.06.106.327.266.613.48.86.213.24.476.43.79.57.313.133.673.2 1.08.2.413 0 .773-.067 1.08-.2.313-.14.576-.33.79-.57.213-.247.373-.533.48-.86a3.4 3.4 0 00.16-1.06 3.4 3.4 0 00-.16-1.06 2.36 2.36 0 00-.48-.86 2.23 2.23 0 00-.79-.58 2.58 2.58 0 00-1.08-.21c-.407 0-.767.07-1.08.21-.314.14-.577.333-.79.58-.214.24-.374.527-.48.86-.107.327-.16.68-.16 1.06zm5.992-2.59V247h.85v-2.3c0-.333.033-.627.1-.88.067-.26.173-.48.32-.66.147-.18.34-.317.58-.41.24-.093.53-.14.87-.14v-.9c-.46-.013-.84.08-1.14.28-.3.2-.553.51-.76.93h-.02v-1.09h-.8zm7.323 0v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.023.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.271.271 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03zm5.564 2.09h-2.97c.014-.2.057-.387.13-.56a1.49 1.49 0 01.3-.47c.127-.133.277-.237.45-.31.18-.08.38-.12.6-.12.214 0 .407.04.58.12.18.073.334.177.46.31.134.127.237.28.31.46.08.18.127.37.14.57zm.82 1.44h-.84c-.073.34-.226.593-.46.76-.226.167-.52.25-.88.25-.28 0-.523-.047-.73-.14a1.461 1.461 0 01-.51-.37c-.133-.16-.23-.34-.29-.54a2.098 2.098 0 01-.08-.65h3.87a3.963 3.963 0 00-.09-.99 2.726 2.726 0 00-.38-.96 2.162 2.162 0 00-.73-.72c-.3-.193-.68-.29-1.14-.29-.353 0-.68.067-.98.2-.293.133-.55.32-.77.56-.213.24-.38.523-.5.85-.12.327-.18.687-.18 1.08.014.393.07.757.17 1.09.107.333.264.62.47.86.207.24.46.427.76.56.307.133.667.2 1.08.2.587 0 1.074-.147 1.46-.44.387-.293.637-.73.75-1.31zm2.352-1.08l-1.94 2.72h1.03l1.44-2.14 1.44 2.14h1.09l-2-2.79 1.78-2.38h-1.02l-1.29 1.81-1.24-1.81h-1.09l1.8 2.45zm4.965-2.45v-1.55h-.85v1.55h-.88v.75h.88v3.29c0 .24.024.433.07.58.047.147.117.26.21.34.1.08.227.137.38.17.16.027.35.04.57.04h.65v-.75h-.39c-.133 0-.243-.003-.33-.01a.453.453 0 01-.19-.07.27.27 0 01-.1-.14c-.013-.06-.02-.14-.02-.24v-3.21h1.03v-.75h-1.03z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;&lt;/div&gt;&lt;/figure&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Field&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Label htmlFor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;my-input&amp;quot;&lt;/span&gt; required&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      Label text
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Label&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Input
      placeholder&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;Placeholder Text&amp;quot;&lt;/span&gt;
      id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;my-input&amp;quot;&lt;/span&gt;
      aria&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;describedby&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;helper-text error-text&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text variant&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;hint&amp;quot;&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;text.secondary&amp;quot;&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;helper-text&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      Hint text
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text variant&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;hint&amp;quot;&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;text.error&amp;quot;&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;error-text&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      Error text
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;component-hierarchy&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#component-hierarchy&quot; aria-label=&quot;component hierarchy permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Component Hierarchy&lt;/h2&gt;&lt;p&gt;Not all components are built the same way. A component might be created using styled-components or a combination of styled-components and Styled System or as a composition of other components. I recommend using the following hierarchy to reason as to what technique to use for creating components.&lt;/p&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;100%&quot; height=&quot;238&quot; fill=&quot;none&quot; viewBox=&quot;0 0 957 238&quot;&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M804 17h136v168H804V17z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M814 82h115v92H814V82z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.2&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M857 162.5h30&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.1&quot; fill-rule=&quot;evenodd&quot; d=&quot;M16 38h136v131H16V38z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.7&quot; d=&quot;M71.308 73c.77 0 1.424.215 1.962.644.538.428.855 1.014.95 1.757h-1.44a1.294 1.294 0 00-.523-.847 1.518 1.518 0 00-.95-.33c-.58 0-1.033.21-1.36.628-.317.419-.475.978-.475 1.68 0 .659.158 1.197.475 1.616.327.408.78.612 1.36.612.433 0 .782-.13 1.045-.392.264-.262.428-.628.491-1.099h1.44c-.084.848-.395 1.517-.933 2.009-.539.481-1.22.722-2.042.722-.644 0-1.219-.147-1.725-.44a2.964 2.964 0 01-1.171-1.24A3.918 3.918 0 0168 76.532c0-1.035.3-1.883.902-2.542.612-.66 1.414-.989 2.406-.989zm7.003 0c1.003 0 1.805.335 2.406 1.004.612.66.918 1.502.918 2.527 0 .994-.306 1.821-.918 2.48-.601.66-1.403.989-2.406.989-.643 0-1.218-.147-1.725-.44a2.966 2.966 0 01-1.171-1.24 3.918 3.918 0 01-.412-1.789c0-1.035.301-1.883.903-2.542.612-.66 1.413-.989 2.405-.989zm-1.836 3.531c0 .66.159 1.198.475 1.617.327.408.781.612 1.361.612s1.03-.204 1.346-.612c.327-.408.49-.947.49-1.617 0-.711-.163-1.27-.49-1.679-.317-.419-.765-.628-1.346-.628-.58 0-1.034.21-1.36.628-.317.419-.476.978-.476 1.68zm7.65-3.374v5.446h3.293v1.24h-4.78v-6.686h1.488zm6.74-.157c1.002 0 1.804.335 2.406 1.004.612.66.918 1.502.918 2.527 0 .994-.306 1.821-.918 2.48-.602.66-1.404.989-2.406.989-.644 0-1.219-.147-1.725-.44a2.966 2.966 0 01-1.171-1.24 3.918 3.918 0 01-.412-1.789c0-1.035.3-1.883.902-2.542.612-.66 1.414-.989 2.406-.989zm-1.836 3.531c0 .66.158 1.198.475 1.617.327.408.78.612 1.36.612.581 0 1.03-.204 1.346-.612.327-.408.49-.947.49-1.617 0-.711-.163-1.27-.49-1.679-.316-.419-.765-.628-1.345-.628s-1.034.21-1.361.628c-.317.419-.475.978-.475 1.68zm9.834-3.374c.549 0 1.008.173 1.377.518.38.345.57.79.57 1.334 0 .418-.09.769-.269 1.052-.179.272-.448.476-.807.612v.015c.316.084.559.272.728.565.169.293.264.743.285 1.35.01.607.095 1.02.253 1.24h-1.472c-.095-.22-.158-.57-.19-1.052-.042-.659-.153-1.082-.332-1.27-.169-.19-.438-.283-.807-.283h-1.52v2.605h-1.487v-6.686h3.671zm-.522 3.03c.306 0 .544-.074.712-.22.18-.158.27-.403.27-.738 0-.325-.085-.56-.254-.707-.169-.146-.411-.22-.728-.22H96.68v1.884h1.662zM57.46 86.157v1.24h-2.003v5.446h-1.455v-5.446H52v-1.24h5.46zm1.694 0l1.564 2.637 1.549-2.637h1.627l-2.472 4.112v2.574h-1.455v-2.605l-2.456-4.081h1.642zm8.357 0c.699 0 1.251.199 1.658.596.407.388.61.905.61 1.554 0 .638-.203 1.156-.61 1.554-.407.387-.96.58-1.658.58h-1.58v2.402H64.46v-6.686h3.05zm-.407 3.139c.428 0 .74-.079.939-.236.208-.156.313-.407.313-.753 0-.345-.1-.596-.298-.753-.198-.168-.51-.251-.938-.251h-1.19v1.993h1.174zM73.678 86c.99 0 1.783.335 2.378 1.004.605.66.907 1.502.907 2.527 0 .994-.302 1.821-.907 2.48-.595.66-1.388.989-2.378.989-.636 0-1.205-.147-1.706-.44a2.951 2.951 0 01-1.157-1.24 3.956 3.956 0 01-.407-1.789c0-1.035.297-1.883.892-2.542.605-.66 1.397-.989 2.378-.989zm-1.815 3.531c0 .66.156 1.198.47 1.617.323.408.771.612 1.345.612.573 0 1.017-.204 1.33-.612.323-.408.484-.947.484-1.617 0-.711-.161-1.27-.485-1.679-.312-.419-.756-.628-1.33-.628-.573 0-1.021.21-1.345.628-.313.419-.47.978-.47 1.68zM80.943 86c.72 0 1.345.21 1.877.628.542.418.855.994.939 1.726H82.35c-.093-.376-.265-.659-.516-.847-.24-.189-.537-.283-.892-.283-.573 0-1.022.215-1.345.644-.313.418-.47.973-.47 1.663 0 .65.157 1.183.47 1.601.313.419.761.628 1.345.628.47 0 .84-.12 1.111-.36.271-.242.433-.603.485-1.084h-1.486v-1.099h2.816v3.626h-.939l-.156-.753c-.24.303-.511.533-.814.69-.302.147-.641.22-1.017.22-.636 0-1.204-.147-1.705-.44a2.951 2.951 0 01-1.157-1.24 3.954 3.954 0 01-.407-1.789c0-1.035.297-1.883.891-2.542.605-.66 1.398-.989 2.378-.989zm7.728.157c.542 0 .996.173 1.36.518.376.345.564.79.564 1.334 0 .418-.089.769-.266 1.052-.177.272-.443.476-.798.612v.015c.313.084.553.272.72.565.167.293.26.743.281 1.35.01.607.094 1.02.25 1.24h-1.454c-.094-.22-.157-.57-.188-1.052-.042-.659-.151-1.082-.328-1.27-.167-.19-.433-.283-.798-.283h-1.502v2.605h-1.47v-6.686h3.629zm-.517 3.03c.303 0 .538-.074.705-.22.177-.158.266-.403.266-.738 0-.325-.084-.56-.25-.707-.168-.146-.408-.22-.72-.22h-1.643v1.884h1.642zm6.964-3.03l2.488 6.686h-1.518l-.5-1.491h-2.503l-.517 1.491h-1.486l2.535-6.686h1.501zm-.782 1.648l-.86 2.448h1.72l-.828-2.448h-.032zm6.899-1.648c.699 0 1.252.199 1.658.596.407.388.611.905.611 1.554 0 .638-.204 1.156-.611 1.554-.406.387-.959.58-1.658.58h-1.58v2.402h-1.47v-6.686h3.05zm-.407 3.139c.428 0 .741-.079.939-.236.209-.156.313-.407.313-.753 0-.345-.099-.596-.297-.753-.199-.168-.511-.251-.939-.251h-1.189v1.993h1.173zm5.057-3.139v2.558h2.706v-2.558h1.455v6.686h-1.455v-2.888h-2.706v2.888h-1.471v-6.686h1.471zm6.375 0l1.564 2.637 1.549-2.637H117l-2.472 4.112v2.574h-1.455v-2.605l-2.456-4.081h1.643zM66.733 99c.806 0 1.455.188 1.947.565.492.366.738.895.738 1.585H67.99c-.02-.335-.136-.586-.345-.753-.21-.178-.534-.267-.974-.267-.293 0-.54.068-.738.204a.658.658 0 00-.283.565c0 .168.037.293.11.377.084.083.246.172.487.267.251.083.79.225 1.618.423.555.126.99.351 1.303.675.314.325.471.727.471 1.209 0 .649-.246 1.172-.738 1.569-.481.387-1.162.581-2.041.581-.849 0-1.54-.204-2.074-.612-.523-.419-.785-.994-.785-1.727v-.031h1.43c0 .408.135.717.408.926.272.199.628.298 1.068.298.397 0 .712-.068.942-.204a.695.695 0 00.361-.628c0-.209-.094-.381-.282-.518-.178-.146-.467-.272-.864-.376a20.863 20.863 0 01-1.398-.361 2.278 2.278 0 01-1.037-.628c-.272-.293-.408-.67-.408-1.13 0-.596.24-1.078.722-1.444.482-.377 1.079-.565 1.79-.565zm6.838.157c.702 0 1.257.199 1.665.596.408.388.613.905.613 1.554 0 .638-.205 1.156-.613 1.554-.408.387-.963.581-1.665.581h-1.586v2.401h-1.476v-6.686h3.062zm-.408 3.139c.43 0 .743-.079.942-.235.21-.157.314-.409.314-.754 0-.345-.1-.596-.298-.753-.199-.168-.513-.251-.942-.251h-1.194v1.993h1.178zm6.327-3.139l2.497 6.686h-1.524l-.502-1.491h-2.513l-.518 1.491h-1.493l2.545-6.686h1.508zm-.786 1.648l-.863 2.448h1.727l-.832-2.448h-.032zM85.398 99c.764 0 1.413.215 1.948.644.533.428.848 1.014.942 1.757h-1.43a1.295 1.295 0 00-.518-.847 1.498 1.498 0 00-.942-.33c-.576 0-1.026.209-1.35.628-.315.419-.472.978-.472 1.679 0 .66.157 1.198.471 1.617.325.408.775.612 1.35.612.43 0 .776-.131 1.037-.392.262-.262.425-.628.487-1.099h1.43c-.084.848-.393 1.517-.927 2.009-.534.481-1.21.722-2.026.722-.639 0-1.21-.146-1.712-.439a2.96 2.96 0 01-1.162-1.24 3.943 3.943 0 01-.409-1.79c0-1.035.299-1.883.896-2.542.607-.66 1.403-.989 2.387-.989zm5.426.157v6.686h-1.476v-6.686h1.476zm2.75 0l2.796 4.489h.015v-4.489h1.382v6.686h-1.46l-2.796-4.473h-.016v4.473h-1.382v-6.686h1.46zm8.489-.157c.722 0 1.351.21 1.885.628.544.418.858.994.942 1.726h-1.413c-.095-.376-.267-.659-.519-.847-.241-.189-.539-.283-.895-.283-.576 0-1.026.215-1.351.644-.314.418-.471.973-.471 1.663 0 .649.157 1.183.471 1.601.314.419.765.628 1.351.628.471 0 .843-.12 1.115-.361s.435-.602.487-1.083h-1.492v-1.099H105v3.626h-.942l-.157-.753a2.53 2.53 0 01-.817.69c-.304.147-.644.22-1.021.22-.639 0-1.209-.146-1.712-.439a2.961 2.961 0 01-1.162-1.24 3.945 3.945 0 01-.408-1.79c0-1.035.298-1.883.895-2.542.607-.66 1.403-.989 2.387-.989zM76.301 112c.727 0 1.358.209 1.895.628.548.418.864.994.948 1.726h-1.421c-.095-.376-.269-.659-.522-.847-.242-.189-.542-.283-.9-.283-.58 0-1.032.215-1.358.644-.316.418-.474.973-.474 1.663 0 .649.158 1.183.474 1.601.316.419.768.628 1.358.628.474 0 .848-.12 1.121-.361.274-.241.437-.602.49-1.083h-1.5v-1.099h2.843v3.626h-.948l-.158-.753a2.542 2.542 0 01-.821.69c-.306.147-.648.22-1.027.22-.642 0-1.216-.146-1.722-.439a2.966 2.966 0 01-1.168-1.24 3.925 3.925 0 01-.411-1.79c0-1.035.3-1.883.9-2.542.611-.659 1.411-.989 2.401-.989zm7.802.157c.548 0 1.006.173 1.375.518.379.345.568.79.568 1.334 0 .419-.09.769-.268 1.052-.18.272-.448.476-.806.612v.015c.316.084.558.272.727.565.168.293.263.743.284 1.35.01.607.095 1.02.253 1.24h-1.47c-.094-.22-.157-.57-.189-1.052-.042-.659-.152-1.082-.331-1.271-.169-.188-.437-.282-.806-.282h-1.516v2.605h-1.485v-6.686h3.665zm-.52 3.029c.305 0 .542-.073.71-.22.179-.157.269-.402.269-.737 0-.325-.085-.56-.253-.707-.169-.146-.41-.219-.727-.219h-1.658v1.883h1.658zm5.15-3.029v6.686H87.25v-6.686h1.484zm4.25 0c.895 0 1.622.293 2.18.879.558.575.837 1.386.837 2.433 0 1.035-.274 1.857-.821 2.464-.548.607-1.28.91-2.196.91H90.03v-6.686h2.953zm-.11 5.446c.474 0 .863-.167 1.168-.502.316-.335.474-.837.474-1.507 0-.774-.163-1.334-.49-1.679-.326-.345-.8-.518-1.42-.518h-1.09v4.206h1.358zM71.468 125.157v6.686H70v-6.686h1.468zM75.73 125c.76 0 1.405.215 1.936.644.53.428.843 1.014.937 1.757h-1.421a1.297 1.297 0 00-.515-.847 1.483 1.483 0 00-.937-.33c-.572 0-1.02.209-1.343.628-.312.419-.468.978-.468 1.679 0 .66.156 1.198.468 1.617.323.408.77.612 1.343.612.427 0 .77-.131 1.03-.392.26-.262.422-.628.484-1.099h1.421c-.083.848-.39 1.517-.92 2.009-.532.481-1.203.722-2.015.722-.635 0-1.202-.146-1.702-.439a2.954 2.954 0 01-1.155-1.24 3.964 3.964 0 01-.406-1.79c0-1.035.296-1.883.89-2.542.603-.659 1.395-.989 2.373-.989zm6.909 0c.989 0 1.78.335 2.373 1.004.604.66.905 1.502.905 2.527 0 .994-.301 1.821-.905 2.48-.593.659-1.384.989-2.373.989-.635 0-1.203-.146-1.702-.439a2.953 2.953 0 01-1.155-1.24 3.964 3.964 0 01-.406-1.79c0-1.035.296-1.883.89-2.542.603-.659 1.394-.989 2.373-.989zm-1.811 3.531c0 .66.156 1.198.468 1.617.323.408.77.612 1.343.612.572 0 1.015-.204 1.327-.612.323-.408.484-.947.484-1.617 0-.711-.161-1.271-.484-1.679-.312-.419-.755-.628-1.327-.628-.573 0-1.02.209-1.343.628-.312.419-.468.978-.468 1.679zm7.53-3.374l2.78 4.489h.016v-4.489h1.373v6.686h-1.452l-2.779-4.473h-.015v4.473h-1.374v-6.686h1.452zm7.753-.157c.801 0 1.446.188 1.936.565.489.366.733.895.733 1.585h-1.42c-.021-.335-.136-.586-.344-.753-.208-.178-.53-.267-.968-.267-.291 0-.536.068-.734.204a.659.659 0 00-.28.565c0 .168.036.293.109.377.083.083.244.172.484.267.25.083.785.225 1.608.423.551.126.983.351 1.296.675.312.325.468.727.468 1.209 0 .649-.245 1.172-.734 1.569-.479.387-1.155.581-2.03.581-.843 0-1.53-.204-2.06-.612-.52-.419-.781-.994-.781-1.727v-.031h1.42c0 .408.136.717.407.926.27.199.624.298 1.061.298.396 0 .708-.068.937-.204a.696.696 0 00.36-.628c0-.209-.094-.381-.282-.518-.177-.146-.463-.272-.859-.376a20.65 20.65 0 01-1.39-.361 2.262 2.262 0 01-1.03-.628c-.27-.293-.405-.67-.405-1.13 0-.596.239-1.078.718-1.444.479-.377 1.072-.565 1.78-.565z&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M804 17h136v23H804V17z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M814 50h115v23H814V50z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.2&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M892 62.5h30&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M824 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M824 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M829 110h21v16h-21v-16zM829 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M824 93.5h95&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M855 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M855 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M861 110h21v16h-21v-16zM861 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M887 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M887 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M892 110h21v16h-21v-16zM892 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M607 82h115v92H607V82z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.2&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M650 162.5h30&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M617 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M617 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M622 110h21v16h-21v-16zM622 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M618 93.5h95&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M649 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M649 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M654 110h21v16h-21v-16zM654 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M681 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M681 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M686 110h21v16h-21v-16zM686 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M409 93.5h95&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.5&quot; fill-rule=&quot;evenodd&quot; d=&quot;M409 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-linejoin=&quot;round&quot; d=&quot;M409 105h32v46h-32v-46z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M414 110h21v16h-21v-16zM414 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.2&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; d=&quot;M211 162.5h30&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.3&quot; fill-rule=&quot;evenodd&quot; d=&quot;M211 131h21v16h-21v-16z&quot; clip-rule=&quot;evenodd&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;neutral.3&quot; stroke-dasharray=&quot;2 6&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M172 50.5h607M172 91.5h222M520 91.5h73M172 138.5h22M248 138.5h146M451 138.5h146M172 163.5h22M253 163.5h334M732 130.5h56&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;neutral.0&quot; d=&quot;M60.46 208.969c.032 1.484 1.04 3.234 4.134 3.234 2.57 0 4.226-1.25 4.226-3.344 0-1.906-1.289-2.664-2.867-3.007l-1.656-.383c-.961-.211-1.461-.649-1.461-1.289 0-.868.727-1.407 1.86-1.407 1.28 0 1.913.711 1.984 1.508h1.984c-.031-1.914-1.672-3.164-3.96-3.164-2.196 0-3.977 1.149-3.977 3.227 0 1.789 1.242 2.617 2.703 2.945l1.648.383c1.102.25 1.64.633 1.64 1.383 0 .883-.71 1.476-2.007 1.476-1.398 0-2.14-.734-2.211-1.562h-2.04zm9.665-.813c0 2.414 1.39 3.992 3.68 3.992 1.96 0 3.289-.984 3.46-2.836h-1.898c-.094.633-.539 1.188-1.453 1.188-1.062 0-1.727-.891-1.727-2.352v-.656c0-1.414.649-2.289 1.72-2.289.765 0 1.312.594 1.421 1.281h1.899c-.047-1.593-1.32-2.922-3.415-2.922-2.312 0-3.687 1.61-3.687 3.907v.687zm13.242 2.836h.086V212h1.945v-5.602c0-1.929-1.453-2.82-3.359-2.82-2.39 0-3.281 1.281-3.344 2.664h1.922c.055-.664.54-1.109 1.383-1.109.867 0 1.367.461 1.367 1.289v.75h-2.023c-1.922 0-2.953.953-2.953 2.437 0 1.563 1.109 2.516 2.726 2.516 1.219 0 1.922-.523 2.25-1.133zm-1.586-.367c-.687 0-1.344-.375-1.344-1.148 0-.633.446-1.071 1.352-1.071h1.578v.875c0 .805-.703 1.344-1.586 1.344zm5.64 1.375h2.063v-11.227h-2.062V212zm7.587.148c2.219 0 3.297-1.32 3.492-2.648h-1.906c-.172.672-.75 1.078-1.57 1.078-1.047 0-1.758-.797-1.758-2.055v-.226h5.312v-.813c0-2.382-1.398-3.922-3.656-3.922-2.18 0-3.672 1.438-3.672 3.868v.758c0 2.539 1.484 3.96 3.758 3.96zm-1.742-5.156v-.015c0-1.063.664-1.883 1.671-1.883 1 0 1.649.812 1.649 1.883v.015h-3.32zm6.726-.82c0 1.531 1.203 2.086 2.696 2.398 1.062.211 2.054.328 2.054 1.133 0 .539-.453 1-1.422 1-.882 0-1.414-.422-1.5-1.031h-1.992c0 1.476 1.242 2.476 3.375 2.476 2.195 0 3.531-1.007 3.531-2.71 0-1.532-1.117-2.055-2.64-2.329-.946-.171-2.141-.312-2.141-1.132 0-.61.516-.985 1.32-.985 1 0 1.336.578 1.391 1.102h1.82c0-1.539-1.195-2.532-3.172-2.532-1.742 0-3.32.766-3.32 2.61zM251.067 210.273h-4.773v-2.859h4.484v-1.617h-4.484v-2.735h4.773v-1.726H244.2V212h6.867v-1.727zm1.891 1.727h2.062v-11.227h-2.062V212zm7.586.148c2.218 0 3.296-1.32 3.492-2.648h-1.906c-.172.672-.75 1.078-1.571 1.078-1.047 0-1.758-.797-1.758-2.055v-.226h5.313v-.813c0-2.382-1.399-3.922-3.656-3.922-2.18 0-3.672 1.438-3.672 3.868v.758c0 2.539 1.484 3.96 3.758 3.96zm-1.743-5.156v-.015c0-1.063.664-1.883 1.672-1.883 1 0 1.649.812 1.649 1.883v.015h-3.321zm7.008 5.008h2.047v-5.031c0-1.149.656-1.672 1.461-1.672.836 0 1.453.492 1.453 1.687V212h1.985v-5.016c0-1.062.554-1.687 1.468-1.687.875 0 1.446.555 1.446 1.609V212h2.054v-5.664c0-1.656-.992-2.758-2.703-2.758-1.39 0-2.25.719-2.523 1.422h-.086c-.281-.852-1.047-1.422-2.321-1.422-1.242 0-1.945.719-2.171 1.32h-.11v-1.187h-2V212zm17.344.148c2.219 0 3.297-1.32 3.492-2.648h-1.906c-.172.672-.75 1.078-1.57 1.078-1.047 0-1.758-.797-1.758-2.055v-.226h5.312v-.813c0-2.382-1.398-3.922-3.656-3.922-2.18 0-3.672 1.438-3.672 3.868v.758c0 2.539 1.485 3.96 3.758 3.96zm-1.742-5.156v-.015c0-1.063.664-1.883 1.672-1.883 1 0 1.648.812 1.648 1.883v.015h-3.32zm7.008 5.008h2.046v-4.859c0-1.047.579-1.813 1.641-1.813.883 0 1.617.508 1.617 1.781V212h2.055v-5.336c0-2.031-1.18-3.086-2.867-3.086-1.383 0-2.141.774-2.406 1.344h-.086v-1.211h-2V212zm9.929-8.289h-1.211v1.594h1.172v4.351c0 1.696.68 2.391 2.742 2.391.414 0 .782-.039.938-.07v-1.524a5.804 5.804 0 01-.438.016c-.851 0-1.203-.25-1.203-1.078v-4.086h1.61v-1.594h-1.61v-1.984h-2v1.984zm5.024 2.461c0 1.531 1.203 2.086 2.695 2.398 1.063.211 2.055.328 2.055 1.133 0 .539-.453 1-1.422 1-.883 0-1.414-.422-1.5-1.031h-1.992c0 1.476 1.242 2.476 3.375 2.476 2.195 0 3.531-1.007 3.531-2.71 0-1.532-1.117-2.055-2.641-2.329-.945-.171-2.14-.312-2.14-1.132 0-.61.515-.985 1.32-.985 1 0 1.336.578 1.391 1.102h1.82c0-1.539-1.195-2.532-3.172-2.532-1.742 0-3.32.766-3.32 2.61zM425.958 201.336V212h2.109v-3.578h2.133c2.297 0 3.625-1.5 3.625-3.531 0-2-1.313-3.555-3.602-3.555h-4.265zm2.101 1.68h1.758c1.164 0 1.859.679 1.859 1.875 0 1.445-.882 1.875-2.351 1.875h-1.266v-3.75zm11.664 7.976h.086V212h1.946v-5.602c0-1.929-1.454-2.82-3.36-2.82-2.39 0-3.281 1.281-3.344 2.664h1.922c.055-.664.539-1.109 1.383-1.109.867 0 1.367.461 1.367 1.289v.75H437.7c-1.922 0-2.953.953-2.953 2.437 0 1.563 1.109 2.516 2.726 2.516 1.219 0 1.922-.523 2.25-1.133zm-1.586-.367c-.687 0-1.343-.375-1.343-1.148 0-.633.445-1.071 1.351-1.071h1.578v.875c0 .805-.703 1.344-1.586 1.344zm6.203-6.914h-1.21v1.594h1.171v4.351c0 1.696.68 2.391 2.743 2.391.414 0 .781-.039.937-.07v-1.524a5.796 5.796 0 01-.437.016c-.852 0-1.204-.25-1.204-1.078v-4.086h1.61v-1.594h-1.61v-1.984h-2v1.984zm6.094 0h-1.211v1.594h1.172v4.351c0 1.696.68 2.391 2.742 2.391.414 0 .782-.039.938-.07v-1.524a5.804 5.804 0 01-.438.016c-.851 0-1.203-.25-1.203-1.078v-4.086h1.61v-1.594h-1.61v-1.984h-2v1.984zm8.696 8.437c2.218 0 3.296-1.32 3.492-2.648h-1.907c-.171.672-.75 1.078-1.57 1.078-1.047 0-1.758-.797-1.758-2.055v-.226h5.313v-.813c0-2.382-1.399-3.922-3.656-3.922-2.18 0-3.672 1.438-3.672 3.868v.758c0 2.539 1.484 3.96 3.758 3.96zm-1.743-5.156v-.015c0-1.063.664-1.883 1.672-1.883 1 0 1.649.812 1.649 1.883v.015h-3.321zm7.008 5.008h2.102v-4.727c0-1.109.468-1.921 1.82-1.921.32 0 .648.023.813.07v-1.781a3.429 3.429 0 00-.657-.055c-1.133 0-1.75.734-1.937 1.266h-.086v-1.141h-2.055V212zm6.203 0h2.047v-4.859c0-1.047.578-1.813 1.641-1.813.883 0 1.617.508 1.617 1.781V212h2.055v-5.336c0-2.031-1.18-3.086-2.868-3.086-1.382 0-2.14.774-2.406 1.344h-.086v-1.211h-2V212zm9.032-5.828c0 1.531 1.203 2.086 2.695 2.398 1.062.211 2.055.328 2.055 1.133 0 .539-.454 1-1.422 1-.883 0-1.414-.422-1.5-1.031h-1.993c0 1.476 1.243 2.476 3.375 2.476 2.196 0 3.532-1.007 3.532-2.71 0-1.532-1.117-2.055-2.641-2.329-.945-.171-2.141-.312-2.141-1.132 0-.61.516-.985 1.321-.985 1 0 1.336.578 1.39 1.102h1.821c0-1.539-1.196-2.532-3.172-2.532-1.742 0-3.32.766-3.32 2.61zM634.856 212v-4.242h4.281v-1.703h-4.281v-2.977h4.688v-1.742h-6.797V212h2.109zm9.563.148c2.218 0 3.296-1.32 3.492-2.648h-1.906c-.172.672-.75 1.078-1.571 1.078-1.047 0-1.758-.797-1.758-2.055v-.226h5.313v-.813c0-2.382-1.399-3.922-3.656-3.922-2.18 0-3.672 1.438-3.672 3.868v.758c0 2.539 1.484 3.96 3.758 3.96zm-1.743-5.156v-.015c0-1.063.664-1.883 1.672-1.883 1 0 1.649.812 1.649 1.883v.015h-3.321zm11.555 4h.086V212h1.945v-5.602c0-1.929-1.453-2.82-3.359-2.82-2.391 0-3.281 1.281-3.344 2.664h1.922c.055-.664.539-1.109 1.383-1.109.867 0 1.367.461 1.367 1.289v.75h-2.023c-1.922 0-2.953.953-2.953 2.437 0 1.563 1.109 2.516 2.726 2.516 1.219 0 1.922-.523 2.25-1.133zm-1.586-.367c-.687 0-1.344-.375-1.344-1.148 0-.633.446-1.071 1.352-1.071h1.578v.875c0 .805-.703 1.344-1.586 1.344zm6.203-6.914h-1.211v1.594h1.172v4.351c0 1.696.68 2.391 2.742 2.391.414 0 .782-.039.938-.07v-1.524a5.804 5.804 0 01-.438.016c-.851 0-1.203-.25-1.203-1.078v-4.086h1.61v-1.594h-1.61v-1.984h-2v1.984zm12.539 0h-2.062v4.906c0 1.164-.703 1.766-1.625 1.766-.813 0-1.586-.375-1.586-1.742v-4.93h-2.055v5.477c0 1.953 1.141 2.937 2.836 2.937 1.367 0 2.133-.687 2.391-1.336h.094V212h2.007v-8.289zm2.047 8.289h2.102v-4.727c0-1.109.469-1.921 1.82-1.921.32 0 .649.023.813.07v-1.781a3.42 3.42 0 00-.657-.055c-1.132 0-1.75.734-1.937 1.266h-.086v-1.141h-2.055V212zm9.406.148c2.219 0 3.297-1.32 3.493-2.648h-1.907c-.171.672-.75 1.078-1.57 1.078-1.047 0-1.758-.797-1.758-2.055v-.226h5.313v-.813c0-2.382-1.399-3.922-3.656-3.922-2.18 0-3.672 1.438-3.672 3.868v.758c0 2.539 1.484 3.96 3.757 3.96zm-1.742-5.156v-.015c0-1.063.664-1.883 1.672-1.883 1 0 1.649.812 1.649 1.883v.015h-3.321zm6.727-.82c0 1.531 1.203 2.086 2.695 2.398 1.063.211 2.055.328 2.055 1.133 0 .539-.453 1-1.422 1-.883 0-1.414-.422-1.5-1.031h-1.992c0 1.476 1.242 2.476 3.375 2.476 2.195 0 3.531-1.007 3.531-2.71 0-1.532-1.117-2.055-2.641-2.329-.945-.171-2.14-.312-2.14-1.132 0-.61.515-.985 1.32-.985 1 0 1.336.578 1.391 1.102h1.82c0-1.539-1.195-2.532-3.172-2.532-1.742 0-3.32.766-3.32 2.61zM850.823 210.203h-4.524v-8.867h-2.109V212h6.633v-1.797zm5.773.789h.086V212h1.946v-5.602c0-1.929-1.454-2.82-3.36-2.82-2.39 0-3.281 1.281-3.344 2.664h1.922c.055-.664.539-1.109 1.383-1.109.867 0 1.367.461 1.367 1.289v.75h-2.023c-1.922 0-2.953.953-2.953 2.437 0 1.563 1.109 2.516 2.726 2.516 1.219 0 1.922-.523 2.25-1.133zm-1.586-.367c-.687 0-1.343-.375-1.343-1.148 0-.633.445-1.071 1.351-1.071h1.578v.875c0 .805-.703 1.344-1.586 1.344zm12.649-6.914h-2.18l-1.805 6.43h-.078l-1.765-6.43h-2.274l2.875 8.305-.078.296c-.148.766-.578 1.071-1.516 1.071a4.76 4.76 0 01-.671-.047v1.484c.25.055.695.086 1.046.086 1.797 0 2.797-.664 3.516-2.57l.211-.57c.016-.047 2.141-6.18 2.719-8.055zm4.398-.149c-2.445 0-3.797 1.68-3.797 3.969v.61c0 2.406 1.352 4.007 3.797 4.007 2.446 0 3.789-1.601 3.789-4.015v-.61c0-2.289-1.351-3.961-3.789-3.961zm0 1.594c1.188 0 1.711 1.016 1.711 2.367v.641c0 1.313-.515 2.383-1.711 2.383-1.203 0-1.719-1.078-1.719-2.383v-.641c0-1.343.532-2.367 1.719-2.367zm12.742-1.445h-2.062v4.906c0 1.164-.703 1.766-1.625 1.766-.813 0-1.586-.375-1.586-1.742v-4.93h-2.055v5.477c0 1.953 1.141 2.937 2.836 2.937 1.367 0 2.133-.687 2.391-1.336h.094V212h2.007v-8.289zm2.696 0h-1.211v1.594h1.172v4.351c0 1.696.679 2.391 2.742 2.391.414 0 .781-.039.937-.07v-1.524a5.751 5.751 0 01-.437.016c-.852 0-1.203-.25-1.203-1.078v-4.086h1.609v-1.594h-1.609v-1.984h-2v1.984zm5.023 2.461c0 1.531 1.203 2.086 2.695 2.398 1.063.211 2.055.328 2.055 1.133 0 .539-.453 1-1.422 1-.883 0-1.414-.422-1.5-1.031h-1.992c0 1.476 1.242 2.476 3.375 2.476 2.195 0 3.531-1.007 3.531-2.71 0-1.532-1.117-2.055-2.64-2.329-.946-.171-2.141-.312-2.141-1.132 0-.61.516-.985 1.32-.985 1 0 1.336.578 1.391 1.102h1.82c0-1.539-1.195-2.532-3.172-2.532-1.742 0-3.32.766-3.32 2.61z&quot; class=&quot;sc-10hkxpq-0 jqhDWa&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Elements&lt;/strong&gt; are basic reusable building blocks of the system.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Patterns&lt;/strong&gt; are reusable building blocks made up of elements or other patterns.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Features&lt;/strong&gt; are a set of patterns, elements, &amp;amp; styles that come together to support a specific user task. Sometimes referred to as container components.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Layouts&lt;/strong&gt; are how features come together to form a page.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The design system would generally be limited to Elements and Patterns. Ideally, you should define Features and Layouts in the application. There are some scenarios in which you might want to include &lt;em&gt;recipes&lt;/em&gt; to demonstrate how one might build a particular Feature — for example, the &lt;a href=&quot;https://radius-ds.netlify.com/?path=/docs/components-formcontrol-recipes--validation&quot;&gt;form control recipes&lt;/a&gt; in Radius.&lt;/p&gt;&lt;p&gt;Note, this is a framework for guiding architectural choices. I &lt;em&gt;do not&lt;/em&gt; recommend categorizing components in code. A component might start as an Element and evolve into a Pattern. Category based folder structure leads to unnecessary overhead and can hinder this natural evolution.&lt;/p&gt;&lt;h3 id=&quot;forwarding-refs&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#forwarding-refs&quot; aria-label=&quot;forwarding refs permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Forwarding Refs&lt;/h3&gt;&lt;p&gt;Each component should return a single HTML element that accepts all HTML props, including &lt;code class=&quot;language-text&quot;&gt;className&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;style&lt;/code&gt; and accessibility attributes. Which means you need to consider ref forwarding.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Encapsulation is desirable for application-level components (Features), it can be inconvenient for highly reusable “leaf” components like FancyButton or MyTextInput. These components tend to be used throughout the application in a similar manner as a regular DOM button and input, and accessing their DOM nodes may be unavoidable for managing focus, selection, or animations.&lt;/p&gt;&lt;p&gt;Ref forwarding is an opt-in feature that lets some components take a ref they receive, and pass it further down (in other words, “forward” it) to a child.&lt;/p&gt;&lt;p&gt;— &lt;a href=&quot;https://reactjs.org/docs/forwarding-refs.html&quot;&gt;Forwarding Refs&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3 id=&quot;elements&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#elements&quot; aria-label=&quot;elements permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Elements&lt;/h3&gt;&lt;p&gt;An element is a styled-component that uses functions from Styled System. Styled-components handles ref forwarding here. These are polymorphic components, i.e., keeping the styling same they allow you to render a different HTML tag or a different custom component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; textVariants &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;variant&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  variants&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    big&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      lineHeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;heading&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    small&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      lineHeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;body&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;p&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  textVariants&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    layout&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    flexbox&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    border&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    position&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    typography
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;patterns&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#patterns&quot; aria-label=&quot;patterns permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Patterns&lt;/h3&gt;&lt;p&gt;Patterns are comprised of elements. Therefore, we have to pick which component ref to forward.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; StyledComponentProps &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-components&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

type AspectRatioProps &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; StyledComponentProps&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;div&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  any&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;/** The aspect ratio to apply */&lt;/span&gt;
    ratio&lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; number&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt; BoxProps&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  never
&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; AspectRatio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; forwardRef&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;HTMLDivElement&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; AspectRatioProps&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ratio &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ref&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box ref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ref&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;relative&amp;quot;&lt;/span&gt; overflow&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;hidden&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;100%&amp;quot;&lt;/span&gt; height&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; pb&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; ratio &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;%&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt; top&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; right&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; bottom&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; left&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here &lt;code class=&quot;language-text&quot;&gt;StyledComponentProps&lt;/code&gt; is a utility to create types for a styled component. It merges the typings for style function props and the typings of the HTML element being forwarded.&lt;/p&gt;&lt;p&gt;Constraint-based Style Props has been a revolutionary idea. It allows us to truly reason about our UI as a system. For more real-world examples of components, check out the &lt;a href=&quot;https://github.com/rangle/radius/tree/master/packages/ds/src/components&quot;&gt;Radius source code&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Side-Loading a Design System]]></title><description><![CDATA[As you go from a smaller to a medium-sized team, the need to share knowledge becomes crucial. It is the perfect time to invest in a design…]]></description><link>https://varun.ca/side-loading-design-system/</link><guid isPermaLink="false">https://varun.ca/side-loading-design-system/</guid><pubDate>Thu, 12 Dec 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:56.25%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;225\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20225\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M114%2029v28h62V0h-62v29m93-15l15%2015-15%2014-14%2014h44V0h-44l14%2014m50%203l-3%204h22l4-3%203-4h-23l-3%203m66%2030v3h27l-13%2014-14%2014%204%203%203%203%2014-14%2014-13v28h7V43h-42v4M0%20141v84h100V114H89l-22-1H57V57H0v84m237-56v29h-18l-18%201-1%2055v55h53V114h46V57h-62v28m-88-16c-8%206-4%2016%205%2016%208%200%2011-13%204-17-4-2-6-1-9%201m-19%2019c-5%204-3%2013%204%2015%209%202%2015-12%206-17-4-2-6-1-10%202m157%2057c0%2019%200%2019%207%2016%2014-5%2014-26%200-32-7-3-7-3-7%2016m75%2012l-18%2031c0%202%202%202%2018%202h18v-62l-18%2029m-155-17c0%202%201%202%2018%202s18%200%2018-2c0-1-2-2-18-2-17%200-18%200-18%202m-67%205c-4%201-9%206-16%2013l-11%2011%209%2010c13%2014%2019%2018%2029%2018%209%200%2020-8%2033-24l3-4-7-8c-17-18-27-23-40-16m67%204l18%201%2018-1c0-2-3-2-18-2s-18%200-18%202m-62%203c-16%205-18%2027-3%2034%207%204%2018%202%2023-5%2011-14-3-34-20-29m62%205l18%201%2018-1c0-2-3-2-18-2s-18%200-18%202m0%208c0%202%201%202%2018%202%2016%200%2018-1%2018-2%200-2-1-2-18-2s-18%200-18%202m64%2012v7h64v-14h-64v7m0%2028v7l1-7v-6h109v6l1%207v-14H271v7\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;side loading design system&quot; title=&quot;side loading design system&quot; src=&quot;/static/ac00b167eeb1d4970f600f721085802c/4ad3a/side-loading-design-system.png&quot; srcSet=&quot;/static/ac00b167eeb1d4970f600f721085802c/477c9/side-loading-design-system.png 288w,/static/ac00b167eeb1d4970f600f721085802c/533c1/side-loading-design-system.png 576w,/static/ac00b167eeb1d4970f600f721085802c/4ad3a/side-loading-design-system.png 1152w,/static/ac00b167eeb1d4970f600f721085802c/b8bf8/side-loading-design-system.png 1728w,/static/ac00b167eeb1d4970f600f721085802c/cb93d/side-loading-design-system.png 2304w,/static/ac00b167eeb1d4970f600f721085802c/0e909/side-loading-design-system.png 3008w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;As you go from a smaller to a medium-sized team, the need to share knowledge becomes crucial. It is the perfect time to invest in a design system. However, you are also likely under delivery pressure. You are hoping to meet deadlines and roll out new features to ensure that your product is successful. In this blog post, I will share a few practices that will allow you to establish a design system that facilitates knowledge sharing without sacrificing delivery speed.&lt;/p&gt;&lt;h2 id=&quot;small-team&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#small-team&quot; aria-label=&quot;small team permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Small Team&lt;/h2&gt;&lt;p&gt;Small teams tend to be highly aligned. They work together on a day-to-day basis. They have a clear sense of the product’s surface area. Everyone is aware of the architecture, what components are available, where to find them, and how to use them. Because the team works so closely, knowledge sharing happens organically.&lt;/p&gt;&lt;h2 id=&quot;mid-sized-team&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#mid-sized-team&quot; aria-label=&quot;mid sized team permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Mid-sized Team&lt;/h2&gt;&lt;p&gt;As the team grows, it becomes challenging to maintain a shared context. Domains begin to develop within the product and the codebase. Not everyone is aware of all the UI components or architectural decisions or even who made them. It leads to sub-teams branching off and deviating from brand standards or the established interaction model. The code complexity ramps up, and ultimately it introduces too much entropy into your development process.&lt;/p&gt;&lt;h2 id=&quot;organically-introducing-a-design-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#organically-introducing-a-design-system&quot; aria-label=&quot;organically introducing a design system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Organically Introducing a Design System&lt;/h2&gt;&lt;p&gt;Design systems are an excellent tool to scale shared understanding and control those deviations from occurring. The challenge is that you likely don’t have the time and resources to stop and build out a design system.&lt;/p&gt;&lt;p&gt;The chances are that you are using a JavaScript UI framework such as React, Angular or Vue to build your product. These frameworks predominantly use a component-based architecture, which means that you already design and build UI as isolated extensible slices. That is one major step towards having your design system. There are a few more steps you can take, which leverages this component-based approach to creating a design system organically:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Storybook driven development&lt;/li&gt;&lt;li&gt;Implement Design Tokens&lt;/li&gt;&lt;li&gt;Start formalizing this knowledge with light-weight documentation&lt;/li&gt;&lt;/ol&gt;&lt;h3 id=&quot;storybook-driven-development&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#storybook-driven-development&quot; aria-label=&quot;storybook driven development permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Storybook Driven Development&lt;/h3&gt;&lt;p&gt;Storybook is a tool for developing self-contained components and document use cases as stories. Stories are a combination of visual, interaction and structural testing. It supports most JS frameworks and integrates well with existing codebases.&lt;/p&gt;&lt;p&gt;By enabling Storybook, your team gets a quick way to surface all the components within their codebase. Storybook becomes the place where they go to find components and figure out how to use them. It also makes it easier for them to see the impact of their changes. You can also integrate it into your automated QA pipeline.&lt;/p&gt;&lt;h3 id=&quot;design-tokens&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#design-tokens&quot; aria-label=&quot;design tokens permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Design Tokens&lt;/h3&gt;&lt;p&gt;Design tokens capture low-level visual characteristics of your product. As projects scale, you find that teams start hard-coding values directly into CSS — hex codes or pixel values. By using design tokens, you can move those values up into a centralized theme. Making it easier to maintain a scalable and consistent visual system.&lt;/p&gt;&lt;p&gt;Most teams have a theming infrastructure already set up, using Sass or CSS custom properties or CSS-in-JS solutions. Design tokens leverage that theming support to connect low-level design decisions to components. Colours, typography and spacing are must-haves for design tokens. You can extend them to all kinds of visual attributes such as widths, heights, border styles, elevations and even structural and motion attributes.&lt;/p&gt;&lt;figure px=&quot;4&quot;&gt;
  &lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:32.98611111111111%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;133\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20133\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M341%2084c-3%203-3%207%200%2010%204%203%2030%203%2033%200s3-7%200-10c-2-2-3-2-16-2-14%200-15%200-17%202\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Example of a set of design tokens for a component&quot; title=&quot;Example of a set of design tokens for a component&quot; src=&quot;/static/46d08d8dd02cb9e081de6d387c8f326b/4ad3a/set-of-design-tokens.png&quot; srcSet=&quot;/static/46d08d8dd02cb9e081de6d387c8f326b/477c9/set-of-design-tokens.png 288w,/static/46d08d8dd02cb9e081de6d387c8f326b/533c1/set-of-design-tokens.png 576w,/static/46d08d8dd02cb9e081de6d387c8f326b/4ad3a/set-of-design-tokens.png 1152w,/static/46d08d8dd02cb9e081de6d387c8f326b/29007/set-of-design-tokens.png 1600w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;
  &lt;figcaption&gt;
    Read more about
    &lt;a href=&quot;https://badootech.badoo.com/design-tokens-beyond-colors-typography-and-spacing-ad7c98f4f228&quot;&gt;
      Design Tokens beyond colors, typography, and spacing.
    &lt;/a&gt;
  &lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id=&quot;light-weight-documentation&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#light-weight-documentation&quot; aria-label=&quot;light weight documentation permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Light-Weight Documentation&lt;/h3&gt;&lt;p&gt;The most significant impact of a design system is that it allows your team to focus on solving differentiating challenges instead of continually reinventing the wheel. To be able to figure out what problems you have solved already, you need to start documenting those challenges and solutions.&lt;/p&gt;&lt;p&gt;Design systems you see in the wild tend to have polished websites with thorough documentation. That can feel quite intimidating. It would be best if you recognized that that is the end state after many months and years of iteration. Light-weight tools make it easy for you to start documenting this information. Tools such as InVision DSM and Zero Height provide a highly approachable authoring experience. They support version control and allow you to plug in Storybook for live code examples. In effect, seeding your DesignOps practice and slowly implementing a governance model.&lt;/p&gt;&lt;div position=&quot;relative&quot; paddingBottom=&quot;50.19%&quot; height=&quot;0&quot; overflow=&quot;hidden&quot; maxWidth=&quot;100%&quot; mb=&quot;4&quot;&gt;&lt;div position=&quot;absolute&quot; top=&quot;0&quot; left=&quot;0&quot; width=&quot;100%&quot; height=&quot;100%&quot; src=&quot;https://www.youtube.com/embed/gu9aaA8X8Qk&quot; frameBorder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The net impact of adopting these practices is that your teams have visibility to design decisions and how they flow into the code. They have an easily searchable directory of components and a development environment where they can test them in isolation. And finally, a platform to connect to designers and developers and build shared understanding asynchronously.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Dark Mode]]></title><description><![CDATA[After several years of using Jekyll, I switched over my website to Gatsby. Jekyll worked great for most things. The part that I struggled…]]></description><link>https://varun.ca/dark-mode/</link><guid isPermaLink="false">https://varun.ca/dark-mode/</guid><pubDate>Tue, 12 Nov 2019 00:00:00 GMT</pubDate><content:encoded>&lt;div width=&quot;60&quot; height=&quot;60&quot; ml=&quot;auto&quot; mr=&quot;auto&quot; mb=&quot;6&quot; overflow=&quot;hidden&quot;&gt;&lt;svg display=&quot;block&quot; width=&quot;7080&quot; height=&quot;60&quot; viewBox=&quot;0 0 2832 24&quot; color=&quot;neutral.0&quot; fill=&quot;currentcolor&quot; class=&quot;sc-24qoga-1 sc-2tyoko-0 gvbZgW&quot;&gt;&lt;path d=&quot;M12 2A10.003 10.003 0 002 12a10.003 10.003 0 0010 10 10.003 10.003 0 0010-10A10.003 10.003 0 0012 2m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10A10.003 10.003 0 0036 2m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10A10.003 10.003 0 0060 2m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10A10.003 10.003 0 0084 2m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10 10.003 10.003 0 00-10-10m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10 10.003 10.003 0 00-10-10m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10 10.003 10.003 0 00-10-10m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10 10.003 10.003 0 00-10-10m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10 10.003 10.003 0 00-10-10m24 0a10.003 10.003 0 00-10 10 10.003 10.003 0 0010 10 10.003 10.003 0 0010-10 10.003 10.003 0 00-10-10m23.934 0a9.965 9.965 0 00-7.003 2.877c-1.715 1.87-2.669 4.437-2.669 7.123s.954 5.253 2.669 7.123A9.965 9.965 0 00251.934 22a9.999 9.999 0 0010-10 9.706 9.706 0 00-3.16-7.167A9.678 9.678 0 00251.934 2m23.716 0a9.801 9.801 0 00-6.709 2.652c-1.022 1.85-1.54 4.513-1.54 7.348s.518 5.498 1.54 7.348A9.801 9.801 0 00275.65 22a10.001 10.001 0 0010-10c0-3.154-1.655-6.038-4.168-7.584A8.252 8.252 0 00275.65 2m23.435 0a9.579 9.579 0 00-6.124 2.207c.35 1.808.697 4.662.697 7.793 0 3.131-.347 5.985-.697 7.793A9.579 9.579 0 00299.085 22a9.989 9.989 0 007.071-2.929A9.99 9.99 0 00309.085 12c0-3.963-2.62-7.393-6.162-8.41A5.427 5.427 0 00299.085 2m23.525 0a9.56 9.56 0 00-5.632 1.831c1.508 1.774 2.584 4.789 2.584 8.169 0 3.38-1.076 6.395-2.584 8.169A9.56 9.56 0 00322.61 22a9.98 9.98 0 007.07-2.93 9.977 9.977 0 002.93-7.07c0-4.646-3.436-8.536-7.845-9.107A3.047 3.047 0 00322.61 2m23.716 0c-1.956 0-3.802.59-5.338 1.607 2.198 1.754 3.709 4.864 3.709 8.393 0 3.529-1.511 6.639-3.709 8.393A9.664 9.664 0 00346.326 22a9.974 9.974 0 007.07-2.93 9.976 9.976 0 002.93-7.07c0-5.053-3.922-9.218-8.849-9.523A1.628 1.628 0 00346.326 2m23.832 0a9.796 9.796 0 00-5.164 1.475c2.605 1.742 4.372 4.908 4.372 8.525s-1.767 6.783-4.372 8.525A9.796 9.796 0 00370.158 22a9.975 9.975 0 007.071-2.93 9.972 9.972 0 002.929-7.07c0-5.293-4.208-9.619-9.439-9.768a.797.797 0 00-.561-.232m23.904 0a9.89 9.89 0 00-5.064 1.399c2.838 1.735 4.752 4.934 4.752 8.601 0 3.667-1.914 6.866-4.752 8.601A9.89 9.89 0 00394.062 22a9.97 9.97 0 007.07-2.93 9.97 9.97 0 002.93-7.07c0-5.43-4.373-9.85-9.779-9.909a.313.313 0 00-.221-.091m23.952 0a9.958 9.958 0 00-5.015 1.361A9.991 9.991 0 01417.944 12a9.991 9.991 0 01-4.945 8.639 9.97 9.97 0 0012.085-1.569 9.966 9.966 0 002.93-7.07c0-5.5-4.456-9.966-9.95-9.979a.067.067 0 00-.05-.021M442 2c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00452 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00476 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00500 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00524 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00548 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00572 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00596 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00620 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65a9.973 9.973 0 0012.07-1.58A9.969 9.969 0 00644 12c0-5.52-4.48-10-10-10m24 0c-1.82 0-3.53.5-5 1.35 2.99 1.73 5 4.95 5 8.65s-2.01 6.92-5 8.65c1.47.85 3.18 1.35 5 1.35 5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.967 0a9.912 9.912 0 00-4.934 1.321c3.025 1.715 5.065 4.953 5.065 8.679s-2.04 6.964-5.065 8.679A9.912 9.912 0 00681.967 22c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.858 0c-1.685 0-3.271.44-4.65 1.194A9.91 9.91 0 01706.526 12a9.91 9.91 0 01-5.351 8.806 9.676 9.676 0 004.65 1.194c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.718 0a9.336 9.336 0 00-4.086.943c3.48 1.52 5.915 5 5.915 9.057s-2.435 7.537-5.915 9.057a9.336 9.336 0 004.086.943c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.762 0a9.27 9.27 0 00-3.61.731c3.734 1.41 6.391 5.027 6.391 9.269s-2.657 7.859-6.391 9.269a9.27 9.27 0 003.61.731c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.858 0a9.39 9.39 0 00-3.326.605c3.886 1.345 6.674 5.042 6.674 9.395s-2.788 8.05-6.674 9.395a9.39 9.39 0 003.326.605c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.916 0a9.584 9.584 0 00-3.158.531A9.962 9.962 0 01804.762 12a9.962 9.962 0 01-6.841 9.469 9.584 9.584 0 003.158.531c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.952 0a9.77 9.77 0 00-3.062.488c4.026 1.284 6.937 5.056 6.937 9.512s-2.911 8.228-6.937 9.512a9.77 9.77 0 003.062.488c5.52 0 10-4.48 10-10s-4.48-10-10-10zm23.976 0c-1.055 0-2.06.162-3.014.466A9.99 9.99 0 01852.979 12a9.99 9.99 0 01-6.986 9.534 9.873 9.873 0 003.014.466c5.52 0 10-4.48 10-10s-4.48-10-10-10zM873 2c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46 4.06 1.27 7 5.06 7 9.54 0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46 5.52 0 10-4.48 10-10s-4.48-10-10-10zm24 0c-1.05 0-2.05.16-3 .46a9.968 9.968 0 013.619 2.042A9.97 9.97 0 011093 12c0 4.48-2.94 8.27-7 9.54.95.3 1.95.46 3 .46a9.93 9.93 0 006.253-2.198 10.04 10.04 0 003.483-5.51c.173-.736.264-1.503.264-2.292 0-1.84-.498-3.564-1.366-5.046a10.063 10.063 0 00-3.588-3.588A9.952 9.952 0 001089 2M1112.99 2.066c-1.067 0-2.085.154-3.056.445a9.984 9.984 0 013.501 2.129 9.818 9.818 0 012.279 3.315 10.24 10.24 0 01.991 4.154 9.856 9.856 0 01-6.771 9.38c.971.291 1.989.445 3.056.445.799.037 1.577-.016 2.325-.147a10.839 10.839 0 002.144-.836 10.98 10.98 0 001.95-1.142 10.843 10.843 0 001.498-1.652c.48-.589.9-1.227 1.251-1.905.279-.678.488-1.396.619-2.144a9.698 9.698 0 00.256-2.217c0-1.83-.482-3.55-1.321-5.034a10.152 10.152 0 00-3.625-3.47 10.109 10.109 0 00-4.989-1.43l-.108.109m5.73 9.466a.205.205 0 01-.082-.018.197.197 0 000-.358.197.197 0 11.082.376m18.226-9.182c-1.14 0-2.239.132-3.296.38a10.664 10.664 0 012.985 2.506 9.599 9.599 0 011.456 3.314 11.72 11.72 0 011.332 4.03c0 3.969-2.425 7.369-5.773 8.69 1.057.248 2.156.38 3.296.38.843.193 1.67.311 2.47.362.8-.336 1.575-.739 2.316-1.201a16.68 16.68 0 002.353-.974c.471-.652.899-1.354 1.277-2.099a17.098 17.098 0 001.554-2.112c.075-.74.092-1.515.041-2.315.143-.607.218-1.24.218-1.891 0-1.791-.41-3.488-1.126-4.983a10.955 10.955 0 00-3.782-2.96 11.084 11.084 0 00-4.741-1.706l-.58.579m5.374 10.134a1.05 1.05 0 01-.438-.096c.361-.167.613-.531.613-.955 0-.424-.252-.788-.613-.955a1.05 1.05 0 11.438 2.006m18.538-9.569c-1.284 0-2.542.086-3.773.249a16.917 16.917 0 011.965 3.253 15.72 15.72 0 01-.174 3.313 18.232 18.232 0 012.009 3.784c0 3.146-1.596 5.918-3.8 7.322 1.231.163 2.489.249 3.773.249.933.505 1.854.96 2.758 1.371a39.86 39.86 0 002.655-1.922 43.397 43.397 0 003.153-.641c.31-.964.592-1.961.84-2.986a41.386 41.386 0 002.155-2.521 45.02 45.02 0 00-1.105-2.656c.094-.399.143-.816.143-1.244 0-1.713-.27-3.364-.741-4.883a15.498 15.498 0 00-4.092-1.947 15.324 15.324 0 00-4.252-2.255l-1.514 1.514m4.668 11.455c-.406 0-.795-.091-1.143-.251a2.748 2.748 0 001.601-2.492 2.745 2.745 0 00-1.601-2.492 2.737 2.737 0 013.887 2.492 2.746 2.746 0 01-2.744 2.743m19.258-10.98a62.56 62.56 0 00-4.174.141 40.741 40.741 0 011.103 3.883 56.822 56.822 0 01-1.549 3.311 35.331 35.331 0 012.579 3.576c0 2.452-.896 4.694-2.133 6.168a62.56 62.56 0 004.174.141c1.008.767 2.009 1.506 3 2.22.992-.82 1.974-1.664 2.943-2.53 1.289-.1 2.565-.221 3.826-.36.174-1.227.333-2.472.472-3.733.907-.941 1.795-1.898 2.662-2.867a177.162 177.162 0 00-2.072-2.943c.052-.224.08-.458.08-.698 0-1.648-.151-3.26-.416-4.799a29.664 29.664 0 00-4.354-1.093 26.459 26.459 0 00-3.839-2.718l-2.302 2.301m4.073 12.572c-.619 0-1.21-.139-1.738-.382a4.177 4.177 0 002.433-3.79 4.176 4.176 0 00-2.433-3.789 4.156 4.156 0 011.738-.382 4.175 4.175 0 014.172 4.171 4.175 4.175 0 01-4.172 4.172m19.883-12.288c-1.479 0-2.951.026-4.414.075.22 1.378.42 2.801.589 4.259a215.604 215.604 0 01-2.369 3.311 71.16 71.16 0 012.92 3.452c0 2.038-.479 3.964-1.14 5.48 1.463.049 2.935.075 4.414.075 1.053.923 2.101 1.832 3.145 2.728a227.417 227.417 0 003.113-2.894c1.417-.053 2.827-.118 4.229-.192.093-1.384.178-2.777.252-4.179a225.453 225.453 0 002.963-3.073c-.87-1.032-1.752-2.07-2.648-3.114.028-.119.043-.244.043-.373 0-1.608-.081-3.198-.222-4.748a61.58 61.58 0 00-4.511-.584 49.934 49.934 0 00-3.593-2.994l-2.771 2.771m3.718 13.237a5.002 5.002 0 01-2.093-.461 5.025 5.025 0 002.93-4.562 5.025 5.025 0 00-2.93-4.562 5.002 5.002 0 012.093-.461c2.771 0 5.023 2.252 5.023 5.023s-2.252 5.023-5.023 5.023m20.257-13.069c-1.523 0-3.042.012-4.557.036.108 1.473.205 2.968.287 4.48a772.036 772.036 0 01-2.852 3.311 153.258 153.258 0 013.12 3.379c0 1.794-.233 3.534-.555 5.074 1.515.024 3.034.036 4.557.036a873.172 873.172 0 003.229 3.027 492.8 492.8 0 003.214-3.107c1.492-.026 2.981-.057 4.466-.094.045-1.475.086-2.956.123-4.441a525.242 525.242 0 003.141-3.195c-.99-1.068-1.986-2.14-2.988-3.214a.781.781 0 00.021-.182c0-1.585-.04-3.161-.108-4.718a139.38 139.38 0 00-4.603-.284 103.349 103.349 0 00-3.448-3.156l-3.047 3.048m3.508 13.628c-.82 0-1.602-.184-2.302-.506a5.53 5.53 0 003.223-5.018 5.53 5.53 0 00-3.223-5.019 5.505 5.505 0 012.302-.506 5.528 5.528 0 015.524 5.525 5.528 5.528 0 01-5.524 5.524M1256.7 3.938c-1.548 0-3.093.005-4.638.014.043 1.528.081 3.064.113 4.607a2092.974 2092.974 0 01-3.129 3.31 404.697 404.697 0 013.235 3.338c0 1.654-.092 3.287-.219 4.841 1.545.009 3.09.014 4.638.014 1.093 1.069 2.186 2.135 3.278 3.199a1243.64 1243.64 0 003.272-3.23c1.536-.01 3.069-.023 4.602-.037.018-1.529.034-3.06.048-4.592a1425.94 1425.94 0 003.244-3.265l-3.183-3.272a.338.338 0 00.008-.072c0-1.572-.016-3.14-.043-4.701a371.55 371.55 0 00-4.655-.112 269.476 269.476 0 00-3.365-3.249l-3.206 3.207m3.388 13.853a5.774 5.774 0 01-2.422-.533 5.816 5.816 0 003.391-5.279 5.817 5.817 0 00-3.391-5.28 5.79 5.79 0 012.422-.533 5.818 5.818 0 015.813 5.813 5.818 5.818 0 01-5.813 5.812m20.604-13.805c-1.56 0-3.119.001-4.678.003.01 1.555.018 3.113.026 4.672l-3.27 3.31c1.1 1.104 2.198 2.21 3.293 3.316 0 1.584-.02 3.163-.049 4.724 1.559.002 3.118.003 4.678.003l3.303 3.285 3.302-3.292 4.67-.008.01-4.668 3.296-3.3-3.282-3.302.002-.016c0-1.565-.004-3.129-.01-4.692-1.558-.011-3.119-.019-4.682-.025a1288.394 1288.394 0 00-3.322-3.297l-3.287 3.287m3.328 13.967a5.944 5.944 0 01-2.483-.546c2.046-.944 3.476-3.009 3.476-5.412s-1.43-4.468-3.476-5.411a5.93 5.93 0 012.483-.547 5.963 5.963 0 015.958 5.958 5.963 5.963 0 01-5.958 5.958M1304.69 4H1300v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1308 .69 1304.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1324v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1332 .69 1328.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1348v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1356 .69 1352.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1372v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1380 .69 1376.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1396v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1404 .69 1400.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1420v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1428 .69 1424.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1444v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1452 .69 1448.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1468v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1476 .69 1472.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1492v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1500 .69 1496.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1516v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31V4h-4.69L1524 .69 1520.69 4m3.31 14c-.89 0-1.74-.2-2.5-.55 2.06-.95 3.5-3.03 3.5-5.45 0-2.42-1.44-4.5-3.5-5.45.76-.35 1.61-.55 2.5-.55 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1540v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-3.256-3.256-.054-.054V4h-4.69L1548 .69 1544.69 4m3.31 14a5.957 5.957 0 01-2.517-.559 5.857 5.857 0 003.314-5.342 6.014 6.014 0 00-3.412-5.37A5.067 5.067 0 011548 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1564v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-3.02-3.02-.29-.29V4h-4.69L1572 .69 1568.69 4m3.31 14c-.927 0-1.81-.217-2.592-.597 1.543-.875 2.601-2.721 2.509-4.873-.091-2.152-1.331-4.048-3.03-5.025.627-.869 1.799-1.505 3.113-1.505 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1588v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-2.553-2.553-.757-.757V4h-4.69L1596 .69 1592.69 4m3.31 14a5.908 5.908 0 01-2.741-.673c.712-.754 1.153-2.223.915-3.943-.238-1.72-1.156-3.322-2.274-4.342.412-1.703 2.103-3.042 4.1-3.042 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1612v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-2.159-2.159L1628 8.69V4h-4.69L1620 .69 1616.69 4m3.31 14a5.916 5.916 0 01-2.866-.738c.01-.652-.068-1.802-.431-3.158-.362-1.355-1.009-2.708-1.636-3.765C1615.298 7.931 1617.428 6 1620 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1636v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-1.925-1.925L1652 8.69V4h-4.69L1644 .69 1640.69 4m3.31 14a5.938 5.938 0 01-2.941-.776c-.408-.591-.796-1.552-1.232-2.69-.437-1.139-.921-2.343-1.257-3.422.124-2.828 2.514-5.112 5.43-5.112 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1660v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-1.786-1.786L1676 8.69V4h-4.69L1668 .69 1664.69 4m3.31 14a5.949 5.949 0 01-2.985-.799c-.655-.555-1.226-1.404-1.705-2.414-.48-1.01-.87-2.128-1.033-3.219.06-3.075 2.605-5.568 5.723-5.568 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1684v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.707-1.707L1700 8.69V4h-4.69L1692 .69 1688.69 4m3.31 14a5.956 5.956 0 01-3.01-.812c-.797-.534-1.472-1.319-1.977-2.256a7.527 7.527 0 01-.904-3.102c.024-3.218 2.657-5.83 5.891-5.83 3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1708v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.667-1.667L1724 8.69V4h-4.69L1716 .69 1712.69 4m3.31 14a5.963 5.963 0 01-3.023-.818 6.079 6.079 0 01-2.114-2.177 6.262 6.262 0 01-.838-3.043A5.978 5.978 0 011716 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m20.69-14H1732v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1748 8.69V4h-4.69L1740 .69 1736.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011734 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1756v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1772 8.69V4h-4.69L1764 .69 1760.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011758 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1780v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1796 8.69V4h-4.69L1788 .69 1784.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011782 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1804v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1820 8.69V4h-4.69L1812 .69 1808.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011806 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1828v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1844 8.69V4h-4.69L1836 .69 1832.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011830 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1852v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1868 8.69V4h-4.69L1860 .69 1856.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011854 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1876v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1892 8.69V4h-4.69L1884 .69 1880.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011878 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1900v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1916 8.69V4h-4.69L1908 .69 1904.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011902 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m20.69-14H1924v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L1940 8.69V4h-4.69L1932 .69 1928.69 4m3.31 14a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011926 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L1964 8.69V4h-4.69L1956 .69 1952.69 4H1948v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69a5.97 5.97 0 01-3.027-.82 6.035 6.035 0 01-2.153-2.153A5.97 5.97 0 011950 12c0-3.31 2.69-6 6-6s6 2.69 6 6-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L1988 8.69V4h-4.69L1980 .69 1976.69 4H1972v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69a5.858 5.858 0 01-2.928-.892 6.143 6.143 0 01-2.875-5.206c0-3.235 2.602-5.869 5.803-5.902 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2012 8.69V4h-4.69L2004 .69 2000.69 4H1996v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69a5.606 5.606 0 01-2.497-1.202 6.705 6.705 0 01-1.776-2.301 7.081 7.081 0 01-.676-3.023c0-2.905 2.219-5.299 4.949-5.474 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2036 8.69V4h-4.69L2028 .69 2024.69 4H2020v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69c-.599-.457-1.16-1.077-1.643-1.817a9.864 9.864 0 01-1.168-2.54 10.48 10.48 0 01-.445-3.015c0-2.254 1.46-4.171 3.256-4.628 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2060 8.69V4h-4.69L2052 .69 2048.69 4H2044v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69a17.688 17.688 0 01-.923-2.336 19.772 19.772 0 01-.656-2.741 18.69 18.69 0 01-.25-3.009c0-1.704.82-3.219 1.829-3.914 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2084 8.69V4h-4.69L2076 .69 2072.69 4H2068v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69a48.265 48.265 0 01-.493-2.645 41.457 41.457 0 01-.351-2.862 34.889 34.889 0 01-.133-3.004c0-1.377.438-2.652.977-3.489 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2108 8.69V4h-4.69L2100 .69 2096.69 4H2092v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69c-.087-.921-.169-1.865-.24-2.827a93.935 93.935 0 01-.17-2.933 70.96 70.96 0 01-.065-3.002c0-1.183.213-2.317.475-3.238 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2132 8.69V4h-4.69L2124 .69 2120.69 4H2116v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69c-.034-.969-.067-1.947-.094-2.932-.028-.985-.051-1.977-.068-2.974a186.84 186.84 0 01-.025-3c0-1.072.084-2.125.187-3.094 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2156 8.69V4h-4.69L2148 .69 2144.69 4H2140v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69a1464.54 1464.54 0 01-.036-5.979c-.004-.999-.006-1.999-.006-3 0-1.016.019-2.028.042-3.021 3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2180 8.69V4h-4.69L2172 .69 2168.69 4H2164v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2204 8.69V4h-4.69L2196 .69 2192.69 4H2188v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2228 8.69V4h-4.69L2220 .69 2216.69 4H2212v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2252 8.69V4h-4.69L2244 .69 2240.69 4H2236v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2276 8.69V4h-4.69L2268 .69 2264.69 4H2260v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2300 8.69V4h-4.69L2292 .69 2288.69 4H2284v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2324 8.69V4h-4.69L2316 .69 2312.69 4H2308v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2348 8.69V4h-4.69L2340 .69 2336.69 4H2332v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-2.69l3.31-3.31-1.655-1.655L2372 8.69V4h-4.69L2364 .69 2360.69 4H2356v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69m-8 2.69V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-9.31V4h-4.69L2388 .69 2384.69 4H2380v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.655-1.655L2396 8.69m-8 9.31V6c3.31 0 6 2.69 6 6s-2.69 6-6 6m32-9.31V4h-4.69L2412 .69 2408.69 4H2404v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-1.709-1.709L2420 8.69m-8 9.31a148.7 148.7 0 01-.139-2.959c-.036-1.003-.058-2.02-.058-3.041s.022-2.038.058-3.041A148.7 148.7 0 012412 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-6.131c.072 0 .131.059.131.131a.131.131 0 01-.131.131.131.131 0 01-.131-.131c0-.072.059-.131.131-.131m32-3.179V4h-4.69L2436 .69 2432.69 4H2428v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-1.945-1.945L2444 8.69m-8 9.31a18.953 18.953 0 01-.743-2.783 17.555 17.555 0 01-.308-3.217c0-1.115.118-2.202.308-3.217.19-1.016.453-1.958.743-2.783 3.31 0 6 2.69 6 6s-2.69 6-6 6m0-6.701a.701.701 0 110 1.402.701.701 0 010-1.402m32-2.609V4h-4.69L2460 .69 2456.69 4H2452v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-2.412-2.412-.898-.898m-8 9.31c-.757-.543-1.443-1.393-1.939-2.432-.497-1.04-.805-2.269-.805-3.568s.308-2.528.805-3.568c.496-1.039 1.182-1.889 1.939-2.432 3.31 0 6 2.69 6 6s-2.69 6-6 6m0-7.829a1.828 1.828 0 110 3.658 1.828 1.828 0 110-3.658m32-1.481V4h-4.69L2484 .69 2480.69 4H2476v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-2.806-2.806-.504-.504m-8 9.31c-1.151-.305-2.193-1.077-2.949-2.137-.755-1.06-1.222-2.408-1.222-3.863s.467-2.803 1.222-3.863c.756-1.06 1.798-1.832 2.949-2.137 3.31 0 6 2.69 6 6s-2.69 6-6 6m0-8.781a2.78 2.78 0 110 5.562 2.78 2.78 0 010-5.562m32-.529V4h-4.69L2508 .69 2504.69 4H2500v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-3.04-3.04-.27-.27m-8 9.31c-1.385-.163-2.641-.889-3.55-1.961a6.24 6.24 0 01-1.473-4.039 6.24 6.24 0 011.473-4.039c.909-1.072 2.165-1.798 3.55-1.961 3.31 0 6 2.69 6 6s-2.69 6-6 6m0-9.349a3.348 3.348 0 11.001 6.697 3.348 3.348 0 01-.001-6.697m32 .039V4h-4.69L2532 .69 2528.69 4H2524v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-3.179-3.179-.131-.131m-8 9.31c-1.524-.079-2.905-.778-3.905-1.857-1-1.08-1.62-2.54-1.62-4.143 0-1.603.62-3.063 1.62-4.143 1-1.079 2.381-1.778 3.905-1.857 3.31 0 6 2.69 6 6s-2.69 6-6 6m0-9.683c2.035 0 3.683 1.648 3.683 3.683s-1.648 3.683-3.683 3.683-3.683-1.648-3.683-3.683 1.648-3.683 3.683-3.683m32 .373V4h-4.69L2556 .69 2552.69 4H2548v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-3.258-3.258-.052-.052m-8 9.31a5.88 5.88 0 01-4.109-1.797 6.02 6.02 0 01-1.704-4.203 6.02 6.02 0 011.704-4.203A5.88 5.88 0 012556 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-9.875c2.141 0 3.875 1.734 3.875 3.875s-1.734 3.875-3.875 3.875-3.875-1.734-3.875-3.875 1.734-3.875 3.875-3.875m32 .565V4h-4.69L2580 .69 2576.69 4H2572v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69V15.31l3.31-3.31-3.298-3.298-.012-.012m-8 9.31a5.958 5.958 0 01-4.211-1.767 5.99 5.99 0 01-1.747-4.233 5.99 5.99 0 011.747-4.233A5.958 5.958 0 012580 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-9.972a3.972 3.972 0 110 7.943 3.972 3.972 0 010-7.943m32 .662V4h-4.69L2604 .69 2600.69 4H2596v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012598 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012604 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2628 .69 2624.69 4H2620v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012622 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012628 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2652 .69 2648.69 4H2644v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012646 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012652 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2676 .69 2672.69 4H2668v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012670 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012676 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2700 .69 2696.69 4H2692v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012694 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012700 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2724 .69 2720.69 4H2716v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012718 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012724 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2748 .69 2744.69 4H2740v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012742 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012748 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2772 .69 2768.69 4H2764v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012766 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012772 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2796 .69 2792.69 4H2788v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012790 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012796 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4m32 .69V4h-4.69L2820 .69 2816.69 4H2812v4.69l-3.31 3.31 3.31 3.31V20h4.69l3.31 3.31 3.31-3.31h4.69v-4.69l3.31-3.31-3.31-3.31m-8 9.31a5.977 5.977 0 01-4.241-1.759A5.982 5.982 0 012814 12c0-1.655.673-3.155 1.759-4.241A5.982 5.982 0 012820 6c3.31 0 6 2.69 6 6s-2.69 6-6 6m0-10c2.21 0 4 1.79 4 4s-1.79 4-4 4-4-1.79-4-4 1.79-4 4-4&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;&lt;p&gt;After several years of using Jekyll, I switched over my website to Gatsby. Jekyll worked great for most things. The part that I struggled with most was adding interactivity. The best I could do was embed CodePen blocks in markdown. Gatsby gives you all the benefits of static rendering and craft amazing interactive experiences with React. Josh Comeau’s &lt;a href=&quot;https://www.joshwcomeau.com/posts/dynamic-bezier-curves/&quot;&gt;Dynamic Bézier Curves post&lt;/a&gt; or Rodrigo Pombo’s &lt;a href=&quot;https://twitter.com/pomber/status/1191784048152195075?s=20&quot;&gt;scrollycoding&lt;/a&gt; are good examples of this.&lt;/p&gt;&lt;p&gt;There is much out there about &lt;a href=&quot;https://julesforrest.com/moving-to-gatsby&quot;&gt;migrating to Gatsby&lt;/a&gt;, the benefits and the trade-offs. I want to focus on one particular challenge of my migration — dark mode. Dark themes are certainly a bit of a trend, but it also happens to be a feature many users rely on on a day-to-day basis. Most devices support it at the OS level. The user preference even cascades down to the browser and can be captured in CSS via the &lt;code class=&quot;language-text&quot;&gt;prefers-color-scheme&lt;/code&gt; media query.&lt;/p&gt;&lt;h2 id=&quot;colour-palette&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#colour-palette&quot; aria-label=&quot;colour palette permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Colour Palette&lt;/h2&gt;&lt;p&gt;The first step was to pick a colour palette. Inverting shades using &lt;code class=&quot;language-text&quot;&gt;filter: invert(100%)&lt;/code&gt; is a quick and somewhat hacky way to get to dark mode. You can follow &lt;a href=&quot;https://mobile.twitter.com/_dte&quot;&gt;Daniel Eden’s&lt;/a&gt; advice and pair it with &lt;code class=&quot;language-text&quot;&gt;hue-rotate(180deg)&lt;/code&gt; for a better result. It compensates for the hue inversion. However, there is a lot more to it. Inverting hues can lead to unintended consequences such as poor contrast or shifting visual importance of UI elements. We need to be a lot more intentional about the colour palette.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:32.63888888888889%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;131\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20131\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2066v65h200V0H0v66\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Call-out, unintentionally, ends up with higher visual importance in dark mode&quot; title=&quot;Call-out, unintentionally, ends up with higher visual importance in dark mode&quot; src=&quot;/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/4ad3a/shifting-importance.png&quot; srcSet=&quot;/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/477c9/shifting-importance.png 288w,/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/533c1/shifting-importance.png 576w,/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/4ad3a/shifting-importance.png 1152w,/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/b8bf8/shifting-importance.png 1728w,/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/cb93d/shifting-importance.png 2304w,/static/fe61a4e1a198b90c7dafbf4d7d36bdbb/91945/shifting-importance.png 2944w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Teresa Man shared extremely valuable advice in her post, &lt;a href=&quot;https://blog.superhuman.com/how-to-design-delightful-dark-themes-7b3da644ff1f&quot;&gt;How to design delightful dark themes&lt;/a&gt;. Here are some of the key learnings that I applied to my website:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Avoid pure black or white. It can lead to eye fatigue and causes &lt;a href=&quot;https://twitter.com/marcedwards/status/1053519077958803456&quot;&gt;black smearing&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Darken distant surfaces.&lt;/li&gt;&lt;li&gt;Reduce large blocks of bright colour.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There are two categories in the colour palette: neutral scale, used for most things such as text and surface colours, and brand colours, used only used for highlights and accents.&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 ctAwpW&quot;&gt;&lt;div class=&quot;sc-24qoga-0 gWWSSE&quot;&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(19, 18, 23)&quot; class=&quot;lcfnd1-0 kgLfnN&quot;&gt;neutral.0 - rgb(217, 215, 224)&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(19, 18, 23)&quot; class=&quot;lcfnd1-0 lLtow&quot;&gt;neutral.1 - #ccc&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(19, 18, 23)&quot; class=&quot;lcfnd1-0 rQuhI&quot;&gt;neutral.2 - #aaa&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(19, 18, 23)&quot; class=&quot;lcfnd1-0 dxquCx&quot;&gt;neutral.3 - #777&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(217, 215, 224)&quot; class=&quot;lcfnd1-0 bLQMVv&quot;&gt;neutral.4 - #555&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(217, 215, 224)&quot; class=&quot;lcfnd1-0 kSpzGq&quot;&gt;neutral.5 - #333&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(217, 215, 224)&quot; class=&quot;lcfnd1-0 fmxnjv&quot;&gt;neutral.6 - #1b191f&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(217, 215, 224)&quot; class=&quot;lcfnd1-0 eOuDfK&quot;&gt;neutral.7 - rgb(19, 18, 23)&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 jYLWR&quot;&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(19, 18, 23)&quot; display=&quot;flex&quot; class=&quot;lcfnd1-0 iARYxU&quot;&gt;brand.main&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(19, 18, 23)&quot; display=&quot;flex&quot; class=&quot;lcfnd1-0 jbOid&quot;&gt;brand.bright&lt;/p&gt;&lt;p font-family=&quot;code&quot; font-size=&quot;1&quot; color=&quot;rgb(217, 215, 224)&quot; display=&quot;flex&quot; class=&quot;lcfnd1-0 jqowRU&quot;&gt;brand.faded&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Taking Teresa’s advice, the extreme ends of the neutral scale are a blue-ish black and a light gray. The background is set to &lt;code class=&quot;language-text&quot;&gt;neutral.7&lt;/code&gt;, and other surfaces such as code-blocks all are set to a lighter &lt;code class=&quot;language-text&quot;&gt;neutral.6&lt;/code&gt;.&lt;/p&gt;&lt;h2 id=&quot;implementation&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#implementation&quot; aria-label=&quot;implementation permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Implementation&lt;/h2&gt;&lt;p&gt;I was going for an end experience where my site supports two modes — dark and light. On the first load it defaults to the light mode. It then checks to see if the user prefers dark mode using &lt;code class=&quot;language-text&quot;&gt;prefers-color-scheme: dark&lt;/code&gt; media query. If yes, then switch to dark mode. There is also a button that the user can click to toggle modes. On subsequent loads the site needs to track their choice, default to it.&lt;/p&gt;&lt;p&gt;On the surface this seems like a failry straightforward feature set. However, I soon discovered that there was a lot of hidden complexity I wasn’t accounting for. I’ll go through those challenges in a bit but first, I want to give a major shout out to the &lt;a href=&quot;https://theme-ui.com/&quot;&gt;Theme UI&lt;/a&gt; team. My solution is largely based on how Theme UI handles &lt;a href=&quot;https://theme-ui.com/color-modes#setting-the-color-mode&quot;&gt;colour mode&lt;/a&gt; switching. This blog post could easily have been titled “How Theme UI handles colour mode switching with Gatsby”.&lt;/p&gt;&lt;h3 id=&quot;theme-variants&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#theme-variants&quot; aria-label=&quot;theme variants permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Theme Variants&lt;/h3&gt;&lt;p&gt;I’m using &lt;a href=&quot;https://styled-system.com/&quot;&gt;Styled System&lt;/a&gt; paired with &lt;a href=&quot;https://www.styled-components.com&quot;&gt;styled-components&lt;/a&gt; for the UI. styled-components provides theming support through its &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ThemeProvider&amp;gt;&lt;/code&gt; component. I created the dark and light variants and choose the appropriate theme based on the active mode.&lt;/p&gt;&lt;img width=&quot;400px&quot; src=&quot;/0b57a50d9a953f262f4fabb39fb9feca/color-mode.gif&quot; alt=&quot;user toggling the colour mode&quot;/&gt;&lt;h3 id=&quot;tracking-user-choice&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tracking-user-choice&quot; aria-label=&quot;tracking user choice permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tracking User choice&lt;/h3&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;useColorMode&lt;/code&gt; hook allows us to track the active colour mode. On the first load it checks to see if the user’s choice is stored in local storage or if the user has enabled dark mode at their OS level. When updating the selected mode there a couple of side-effects that need to happen:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Set a class on the &lt;code class=&quot;language-text&quot;&gt;body&lt;/code&gt; element reflecting the active mode, for example, &lt;code class=&quot;language-text&quot;&gt;varun-ca-dark&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Save the active mode in local-storage&lt;/li&gt;&lt;li&gt;Update state&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;use-color-mode.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;useColorMode&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setMode&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;light&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;useEffect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; stored &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; dark &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getMediaQuery&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;stored &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; dark&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;setModeWithSideEffects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;dark&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;!&lt;/span&gt;stored &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; stored &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; mode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setModeWithSideEffects&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stored&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;setModeWithSideEffects&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;setMode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; nextMode &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; state &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;light&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;dark&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;light&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;classList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;remove&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;varun-ca-&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; state&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      document&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;classList&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;varun-ca-&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; nextMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      storage&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;nextMode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

      &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; nextMode&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setModeWithSideEffects&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Check out &lt;a href=&quot;https://github.com/winkerVSbecks/varun.ca/blob/master/src/use-color-mode.js&quot;&gt;use-color-mode.js&lt;/a&gt; for more context.&lt;/p&gt;&lt;p&gt;My site has a base layout that I use for all pages, the &lt;code class=&quot;language-text&quot;&gt;layout.js&lt;/code&gt; file. It essentially acts at the root of the application and the themeing set up is done there. The active &lt;code class=&quot;language-text&quot;&gt;mode&lt;/code&gt; is used to generate the appropriate theme object and passed into the &lt;code class=&quot;language-text&quot;&gt;ThemeProvider&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;To allow the user to select the colour-mode manually, we need to connect the &lt;code class=&quot;language-text&quot;&gt;mode&lt;/code&gt; state and updater to the toggle button. React’s context API works perfectly for this. The &lt;code class=&quot;language-text&quot;&gt;ColorModeContext&lt;/code&gt; provides &lt;code class=&quot;language-text&quot;&gt;{ mode, setColorMode }&lt;/code&gt; which is then used by the &lt;a href=&quot;https://github.com/winkerVSbecks/varun.ca/blob/master/src/components/cycle-mode.js&quot;&gt;CycleMode&lt;/a&gt; button.&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;layout.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Layout&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; description&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;mode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setColorMode&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;useColorMode&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeProvider theme&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createColorStyles&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mode&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ColorModeContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Provider value&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; mode&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; setColorMode &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;SEO&lt;/span&gt; title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; description&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;description&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; image&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;InitializeColorMode &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;GlobalStyle &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;MDXProvider components&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dsToMdx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;MDXProvider&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ColorModeContext&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Provider&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ThemeProvider&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;avoiding-flash&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#avoiding-flash&quot; aria-label=&quot;avoiding flash permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Avoiding Flash&lt;/h3&gt;&lt;p&gt;Gatsby, at build time, uses a React server-side rendering to compile the site into files that can be delivered to a web browser. The output is HTML and a JavaScript runtime that takes over in the browser once the initial HTML has loaded.&lt;/p&gt;&lt;img width=&quot;400px&quot; src=&quot;/6625dd0479c4b2b453f101b2b0e2d461/color-mode-flash.gif&quot; alt=&quot;the site colours flash once the JavaScript is loaded&quot;/&gt;&lt;p&gt;The generated HTML and CSS use the default colour mode. When the user loads the page, it renders with that default colour mode. Once the JS loads, it updates the CSS to match the user’s preferred choice. This switch causes the page to flash between the two styles. Not a great user experience!&lt;/p&gt;&lt;p&gt;The best way to avoid &lt;em&gt;the flash&lt;/em&gt; is to rely on CSS rather than JavaScript. The challenge here is that styled-components is a CSS-in-JS library and relies on the JS bundle to load and parse before the CSS can be appropriately updated. The Theme UI team came up with an innovative solution.&lt;/p&gt;&lt;p&gt;First, convert the colour modes from hard-coded hex values to CSS Custom Properties. Then generate global CSS that controls the value of these CSS Custom Properties using scoped class names, for example: &lt;code class=&quot;language-text&quot;&gt;.varun-ca-dark&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;.varun-ca-light&lt;/code&gt; (&lt;a href=&quot;https://github.com/winkerVSbecks/varun.ca/blob/master/src/theme/color-mode-styles.js&quot;&gt;color-mode-styles.js&lt;/a&gt;).&lt;/p&gt;&lt;figure class=&quot;sc-24qoga-0 sc-24qoga-2 jEZlit&quot;&gt;&lt;pre overflow=&quot;auto&quot; font-size=&quot;0&quot; font-family=&quot;code&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 iLypcE&quot;&gt;&lt;code&gt;{
  light: {
    brand: {
      main: &amp;#x27;#4e4bec&amp;#x27;,
      bright: &amp;#x27;#dedefb&amp;#x27;,
      faded: &amp;#x27;#ececfd&amp;#x27;,
      selection: &amp;#x27;#ececfd&amp;#x27;,
    },
    neutral: {
      0: &amp;#x27;#333&amp;#x27;,
      1: &amp;#x27;#555&amp;#x27;,
      ...
    },
  }
  dark: { ... },
}&lt;/code&gt;&lt;/pre&gt;&lt;pre overflow=&quot;auto&quot; font-size=&quot;2&quot; font-family=&quot;code&quot; display=&quot;none,block&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 fwrVCU&quot;&gt;⭢&lt;/pre&gt;&lt;pre overflow=&quot;auto&quot; font-size=&quot;2&quot; font-family=&quot;code&quot; display=&quot;block,none&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 gskTJl&quot;&gt;⭣&lt;/pre&gt;&lt;div class=&quot;sc-24qoga-0 kqXbxK&quot;&gt;&lt;pre overflow=&quot;auto&quot; font-size=&quot;0&quot; font-family=&quot;code&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 eYbZEp&quot;&gt;{
  light: {
    brand: {
      main: &amp;quot;var(--varun-ca-colors-brand-main, #4e4bec)&amp;quot;,
      bright: &amp;quot;var(--varun-ca-colors-brand-bright, #dedefb)&amp;quot;,
      faded: &amp;quot;var(--varun-ca-colors-brand-faded, #ececfd)&amp;quot;,
      selection: &amp;quot;var(--varun-ca-colors-brand-selection, #ececfd)&amp;quot;
    },
    neutral: {
      0: &amp;quot;var(--varun-ca-colors-neutral-0, #333)&amp;quot;,
      1: &amp;quot;var(--varun-ca-colors-neutral-1, #555)&amp;quot;,
      ...
    },
  }
  dark: { ... },
}&lt;/pre&gt;&lt;pre font-size=&quot;0&quot; font-family=&quot;code&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 cNWknj&quot;&gt;{
  &amp;quot;&amp;amp;.varun-ca-light&amp;quot;: {
    &amp;quot;--varun-ca-colors-brand-main&amp;quot;: &amp;quot;#4e4bec&amp;quot;,
    &amp;quot;--varun-ca-colors-brand-bright&amp;quot;: &amp;quot;#dedefb&amp;quot;,
    &amp;quot;--varun-ca-colors-brand-faded&amp;quot;: &amp;quot;#ececfd&amp;quot;,
    &amp;quot;--varun-ca-colors-brand-selection&amp;quot;: &amp;quot;#ececfd&amp;quot;,
    &amp;quot;--varun-ca-colors-neutral-0&amp;quot;: &amp;quot;#333&amp;quot;,
    &amp;quot;--varun-ca-colors-neutral-1&amp;quot;: &amp;quot;#555&amp;quot;,
    ...
  }
  &amp;quot;&amp;amp;.varun-ca-dark&amp;quot;: { ... },
}&lt;/pre&gt;&lt;/div&gt;&lt;figcaption class=&quot;sc-24qoga-6 khMaOS&quot;&gt;Theme object is modified to use CSS custom properties and a set of global CSS is extracted to control the value of those custom properties&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Lastly, inject a tiny script in your HTML to check local-storage for the user’s preference and set the appropriate class name to the body tag (&lt;a href=&quot;https://github.com/winkerVSbecks/varun.ca/blob/master/src/use-color-mode.js&quot;&gt;use-color-mode.js&lt;/a&gt;).&lt;/p&gt;&lt;div class=&quot;gatsby-code-title&quot;&gt;use-color-mode.js&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;STORAGE_KEY&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;varun-ca-color-mode&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;InitializeColorMode&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;script
    key&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;varun-ca-no-flash&amp;quot;&lt;/span&gt;
    dangerouslySetInnerHTML&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      __html&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;(function() { try {
        var mode = localStorage.getItem(&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;STORAGE_KEY&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;);
        if (!mode) return
        document.body.classList.add(&amp;#x27;varun-ca-&amp;#x27; + mode);
      } catch (e) {} })();&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We are still using Styled-Components for theming. However, the values point to CSS custom properties, and we can switch the theme by changing the class on the &lt;code class=&quot;language-text&quot;&gt;body&lt;/code&gt; element. Since all the variable values are in global CSS, and the above script runs as soon as the page loads, the user no longer sees a flash. The only time the user sees a flash is the first time they visit your site, and if they have enabled dark mode on their OS.&lt;/p&gt;&lt;p&gt;Gatsby does a tremendous amount of work to ensure that your site is performant. One of those things is to use React SSR to generate a static website. It, unfortunately, means that we have to do a bit more work to implement dark mode, but the trade-off was worth it, and I got to learn a lot. That said, if you use &lt;a href=&quot;https://theme-ui.com/&quot;&gt;Theme UI&lt;/a&gt;, then you get all of this for free.&lt;/p&gt;&lt;p&gt;The one key takeaway from this whole process is that implementing dark-mode means that you are creating more work for your future self. Each feature you add to your site will have to support it.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Why Not Both?]]></title><description><![CDATA[The web is defined by the interplay of various components: back-end technologies such as servers and databases to support the website itself…]]></description><link>https://varun.ca/why-not-both/</link><guid isPermaLink="false">https://varun.ca/why-not-both/</guid><pubDate>Sat, 11 May 2019 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The web is defined by the interplay of various components: back-end technologies such as servers and databases to support the website itself, client-side technologies to present content and provide interactivity, and the network to deliver the website to the user.&lt;/p&gt;&lt;p&gt;While there are a lot of layers to this medium I want to focus on the presentation layer — HTML, CSS &amp;amp; JS. In this article I am going to be using the shorthand &lt;em&gt;web&lt;/em&gt; to refer to this presentational layer. (I realize that is inaccurate but, I don’t have a better word for it.)&lt;/p&gt;&lt;h2 id=&quot;the-medium-of-the-web&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-medium-of-the-web&quot; aria-label=&quot;the medium of the web permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Medium of the Web&lt;/h2&gt;&lt;p&gt;Bret Victor in his talk &lt;a href=&quot;https://vimeo.com/64895205&quot;&gt;Stop Drawing Dead Fish&lt;/a&gt; differentiates computers from other mediums such as drawing, photography or animation. In his opinion, what makes computers different from all these other mediums is the fact that you can create simulations and add interactivity. It is not just a drawing of a fish or an animated fish but, an interactive simulation.&lt;/p&gt;&lt;div style=&quot;padding:56.25% 0 0 0;position:relative;margin-bottom:2em&quot;&gt;&lt;iframe src=&quot;https://player.vimeo.com/video/64895205&quot; style=&quot;position:absolute;top:0;left:0;width:100%;height:100%&quot; frameBorder=&quot;0&quot; webkitallowfullscreen=&quot;true&quot; mozallowfullscreen=&quot;true&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;script src=&quot;https://player.vimeo.com/api/player.js&quot;&gt;&lt;/script&gt;&lt;p&gt;Frank Chimero explored the medium of the web in his article &lt;a href=&quot;https://frankchimero.com/writing/the-webs-grain/&quot;&gt;The Web’s Grain&lt;/a&gt;. What makes the web truly different from anything else. What are its intrinsic properties? He summarizes it as “an edgeless surface of unknown proportions, comprised of small, individual, and variable elements from multiple vantages assembled into a readable whole that documents a moment.”&lt;/p&gt;&lt;p&gt;For me, the intrinsic qualities of the web are fluidity, responsiveness and dynamism. Or as Jen Simmons puts it much more eloquently:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Mix fluid with fixed&lt;/li&gt;&lt;li&gt;Four stages of squishiness&lt;/li&gt;&lt;li&gt;Truly two-dimensional layouts&lt;/li&gt;&lt;li&gt;Nested contexts&lt;/li&gt;&lt;li&gt;Ways to contract and expand content&lt;/li&gt;&lt;li&gt;Media queries, as needed&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;design-in-the-medium&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#design-in-the-medium&quot; aria-label=&quot;design in the medium permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Design in the Medium&lt;/h2&gt;&lt;p&gt;In the past couple of years, we’ve gone from being excited about CSS Grid Layout to using it in production. However, it seems that there is a bit of inertia when it comes to designers adopting it.&lt;/p&gt;&lt;p&gt;Jen Simmons often speaks about how everything about web design just changed. We are no longer limited to fixed or fluid column-based layouts. Instead, we can design truly two-dimensional layouts. But, do we actually have any tools that allow us to design that way?&lt;/p&gt;&lt;div width=&quot;100%&quot; height=&quot;0&quot; style=&quot;left:0;position:relative&quot; pb=&quot;56.1972%&quot; mb=&quot;4&quot;&gt;&lt;iframe src=&quot;//speakerdeck.com/player/492fb00803b144aba89a2d9dfeeca2fc?slide=53&quot; style=&quot;border:0;top:0;left:0;width:100%;height:100%;position:absolute&quot; allowfullscreen=&quot;&quot; scrolling=&quot;no&quot; allow=&quot;encrypted-media&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;When we design in Sketch or Figma, we are designing a snapshot in time and space. You have to create multiple &lt;em&gt;snapshots&lt;/em&gt; to describe the responsive behaviour of one screen. Now imagine designing responsive two-dimensional layouts with multiple states and variants: quite tedious.&lt;/p&gt;&lt;p&gt;So what is the answer? Design in the medium. You need to be able to code to design in the medium. Arguably, this barrier to entry is too high. What if you could design in the browser without needing to code?&lt;/p&gt;&lt;p&gt;Tools like &lt;a href=&quot;https://www.framer.com/features/react/&quot;&gt;Framer&lt;/a&gt;, &lt;a href=&quot;https://www.modulz.app/&quot;&gt;Modulz&lt;/a&gt;, &lt;a href=&quot;https://meetalva.io/&quot;&gt;Alva&lt;/a&gt; and &lt;a href=&quot;https://github.com/seek-oss/playroom&quot;&gt;Playroom&lt;/a&gt; are bridging this divide. Framer in particular is quite exciting. It allows you to import code components and mix them with design components. You can extend design components with code or even build a custom UI to interact with them.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Designers are equipped with tools that focus on communicating design aesthetic, and developer tools are more geared toward controlling behaviour and functionality.&lt;/p&gt;&lt;cite&gt;— Alan B Smith, &lt;a href=&quot;https://medium.com/@_alanbsmith/component-based-design-168811e0c4ab&quot;&gt;Component-Based Design&lt;/a&gt;&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;Fundamentally these are still design tools. They are visual code editors with the purpose of building living prototypes not the actual application itself. They don’t allow you to define behaviour and functionality. They are not meant to replace any development tools.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/58c847531e8ae3c5c45474f244291824/why-not-both.gif&quot; alt=&quot;Why not both?&quot;/&gt;&lt;/p&gt;&lt;p&gt;My hope is that we will get something like &lt;a href=&quot;https://unity.com/&quot;&gt;Unity&lt;/a&gt; for the web. Something that both developers and designers can use. A tool that allows us to define both aesthetic and functionality with an intuitive interface. That interface is going to be some combination of GUI and code editor.&lt;/p&gt;&lt;h2 id=&quot;generative-design&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#generative-design&quot; aria-label=&quot;generative design permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Generative Design&lt;/h2&gt;&lt;p&gt;The convergence of design and development tools will allow us to discover new and more innovative ways of working. Code is not the most expressive or performative of platforms. In my opinion, describing visual characteristics in code is tedious and not-intuitive. For example, designing an animation with the After Effects timeline panel is a much better experience than doing the same with CSS or a JS library. You can visualize the timeline, adjust curves and iterate much faster.&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;http://compositor.io/&quot;&gt;Compositor&lt;/a&gt; team has been working on some truly interesting tools. Modifying the UI directly or dragging components to create layouts is again a much better developer experience. It also allows you to explore and iterate with very little friction.&lt;/p&gt;&lt;div flexWrap=&quot;wrap,nowrap&quot; alignItems=&quot;center&quot; mb=&quot;4&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot;&gt;&lt;p lang=&quot;und&quot; dir=&quot;ltr&quot;&gt;🙀 &lt;a href=&quot;https://t.co/q0BqSsTRHi&quot;&gt;pic.twitter.com/q0BqSsTRHi&lt;/a&gt;&lt;/p&gt;— Compositor (@getcompositor) &lt;a href=&quot;https://twitter.com/getcompositor/status/931592802697469953?ref_src=twsrc%5Etfw&quot;&gt;November 17, 2017&lt;/a&gt;&lt;/blockquote&gt;&lt;div mr=&quot;0,3&quot;&gt;&lt;/div&gt;&lt;blockquote class=&quot;twitter-tweet&quot; data-conversation=&quot;none&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Making progress &lt;a href=&quot;https://t.co/IGrZWzqqbT&quot;&gt;pic.twitter.com/IGrZWzqqbT&lt;/a&gt;&lt;/p&gt;— Compositor (@getcompositor) &lt;a href=&quot;https://twitter.com/getcompositor/status/929689837971623936?ref_src=twsrc%5Etfw&quot;&gt;November 12, 2017&lt;/a&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&quot;https://medium.com/project-phoebe&quot;&gt;Project Phoebe&lt;/a&gt; was a brief attempt at using mutative design for UI and Adobe seems to be &lt;a href=&quot;https://www.fastcompany.com/3068884/adobe-is-building-an-ai-to-automate-web-design-should-you-worry&quot;&gt;exploring&lt;/a&gt; this space too. But, we are just scratching the surface. What would the UI design equivalent of &lt;a href=&quot;https://www.frustum.com/&quot;&gt;Real Time Topology Optimization&lt;/a&gt; look like? Can we define a set of constraints, allow the UI to morph around it and iterate?&lt;/p&gt;&lt;p&gt;With generative design you can start leveraging the power of the medium. You don’t have to manually create all the possible layouts. You have the ingredients. You can define a recipe and explore all the possible permutations.&lt;/p&gt;&lt;blockquote style=&quot;margin-bottom:2em&quot;&gt;&lt;p&gt;Generative design mimics nature’s evolutionary approach to design. Designers or engineers input design goals into generative design software, along with parameters such as materials, manufacturing methods, and cost constraints. The software explores all the possible permutations of a solution, quickly generating design alternatives. It tests and learns from each iteration what works and what doesn’t.&lt;/p&gt;&lt;cite&gt;—&lt;a href=&quot;https://www.autodesk.com/solutions/generative-design&quot;&gt;Autodesk Generative Design&lt;/a&gt;&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;Let’s focus on one category — layout. Much of web design is stuck in the mindset of fixed or fluid columns where content shifts around at breakpoints, almost completely ignoring the two-dimensional nature with the possibility of overlapping content.&lt;/p&gt;&lt;p&gt;Frank describes web design as “creating assemblages of elements, then associating them with the appropriate space”. I did an experiment very much inspired by that statement. Start by defining a high level fluid grid, say 6x4. Take a document and slice up the different sections into components, give them random grid sizing and drop them into the layout. The user can then lock items and continue regenerating the grid until they find a satisfying layout. You can try it yourself in this &lt;a href=&quot;https://codesandbox.io/s/8r6k4j9k2&quot;&gt;CodeSandbox&lt;/a&gt;.&lt;/p&gt;&lt;div flexWrap=&quot;wrap,nowrap&quot; alignItems=&quot;center&quot; mb=&quot;4&quot;&gt;&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Playing with the idea of procedurally generated layout grids.&lt;a href=&quot;https://t.co/yAsPbkpDZJ&quot;&gt;https://t.co/yAsPbkpDZJ&lt;/a&gt; &lt;a href=&quot;https://t.co/bHQIvlF9nC&quot;&gt;pic.twitter.com/bHQIvlF9nC&lt;/a&gt;&lt;/p&gt;— Varun Vachhar (@winkerVSbecks) &lt;a href=&quot;https://twitter.com/winkerVSbecks/status/1095479837534441474?ref_src=twsrc%5Etfw&quot;&gt;February 13, 2019&lt;/a&gt;&lt;/blockquote&gt;&lt;div mr=&quot;0,3&quot;&gt;&lt;/div&gt;&lt;blockquote class=&quot;twitter-tweet&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Continuing with generative grid experiments. Took one of the &lt;a href=&quot;https://twitter.com/tachyons_css?ref_src=twsrc%5Etfw&quot;&gt;@tachyons_css&lt;/a&gt; examples, sliced up the different sections into components and randomly sizing them in the container. You can then lock items and continue regenerating the grid until you find an interesting layout. &lt;a href=&quot;https://t.co/1cUSnz9VRN&quot;&gt;pic.twitter.com/1cUSnz9VRN&lt;/a&gt;&lt;/p&gt;— Varun Vachhar (@winkerVSbecks) &lt;a href=&quot;https://twitter.com/winkerVSbecks/status/1101502912675627014?ref_src=twsrc%5Etfw&quot;&gt;March 1, 2019&lt;/a&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;p&gt;The results were a lot better than I expected. It has been hard to break out of the twelve column mindset for me. This helped.&lt;/p&gt;&lt;p&gt;These are just a first steps. We could get people to rate these layouts on a scale of 1-10 and use that data to train a machine learning model which could then in-turn generate layouts for us. There is a lot more to explore in the world of generative design. I’m excited to see what else the web design and development community comes up with. Perhaps generative design will be the bridge between design and code?&lt;/p&gt;</content:encoded></item><item><title><![CDATA[What is a Design System?]]></title><description><![CDATA[Defining what a Design System is and what it means for an organization can be tricky. In this post, we'll take the conversation of Design…]]></description><link>https://varun.ca/what-is-a-design-system/</link><guid isPermaLink="false">https://varun.ca/what-is-a-design-system/</guid><pubDate>Thu, 18 Apr 2019 00:00:00 GMT</pubDate><content:encoded>&lt;div&gt;This post was co-authored with &lt;a to=&quot;http://www.catherinemaritan.com&quot;&gt;Catherine Maritan&lt;/a&gt; and originally published on the &lt;a to=&quot;https://rangle.io/blog/what-is-a-design-system&quot;&gt;Rangle.io Blog&lt;/a&gt;.&lt;/div&gt;&lt;p&gt;Defining what a Design System is and what it means for an organization can be tricky. In this post, we’ll take the conversation of Design Systems past style guides and component libraries and get into breaking down silos between development and design.&lt;/p&gt;&lt;h2 id=&quot;the-hand-off-problem&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-hand-off-problem&quot; aria-label=&quot;the hand off problem permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Hand-Off Problem&lt;/h2&gt;&lt;p&gt;From our experience, most organizations treat websites as a collection of pages. Pages provide a holistic view of the design problem — what content are we displaying, what is its purpose, how are we going to display this content and how is the user going to interact with it. This ideology is what drives the design and development process. Designers create designs for each page, followed by a hand-off to developers who then work with a product manager to divide the mock-ups into tickets for developers.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:51.041666666666664%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;205\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20205\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M55%2018v4l1-2c0-2%201-2%20114-2h115v2c1%202%201%202%201%200v-3H171L55%2018m67%2013v4h21v-8h-21v4m138%2027l1%203c2%202%201%204-2%204-6%201-6%203-1%202%205%200%205%200%206%202%200%204-1%2011-3%2010l-1%203%201%201%201%202c1%203-1%204-3%203v-1c2-2%201-3-1-2-3%202-3%204%200%204l-1%202%203-1c2%200%204%203%202%204-2%202-1%203%201%202l1-2c0-1%202-2%205-2%204-1%2011-4%2010-5l-4%201c-3%202-10%203-10%201l2-2v-2l-2%201c-1%203-3-4-1-7l1-7c0-4%200-4%202-3%202%202%204%207%204%2011v2c3-1%200-11-4-15l-4-4c-1-2%200-3%203-4%208-3%2015-1%2019%205%202%203%202%2012%200%2015l-2%204c2%201%204-6%205-10%201-13-9-20-22-15-4%201-4%201-6-1v1m-19%204l4%205c4%204%205%204%204%207l-2%202v7c0%207-1%209-3%208-2-2-1-13%202-17%202-3%203-5%200-3-2%202-4%207-4%2012v6l-2-3-1-8c0-4%200-4%203-5l1-1h-4c-4%202-2%2015%203%2019%202%201%202%202%201%203l1%201c2%201%202%200%202-1h1c2%200%2010-4%209-5l-3%201-5%202c-2%200-2%200%200-4l1-8v-2c1%202%201%202%201-1l2-6%201-3-2%201h-1l-9-7m-139%205c0%203-8%203-8%200h-1l-2%202v1c2%200%202%201%202%204s0%204-2%204v1c2%200%202%202%202%2017l1%2018V79h8v17c0%2016%200%2017%201%207l1-11h3c3%200%204%201%204%202%200%202%201%202%209%202h9v-9h-9c-7%200-9%200-9%202l-1%201h-1l-2%201-2-1h-1l-1-5v-6h22l22-1h-44v-8h22l22-1h-22c-22%200-22%200-22-2l-1-2v2m-81%209v7h36V70H21v6m262%2011l-2%202%203-1c3-2%205-2%205%201%200%204%202%204%2012%203%209-2%2010-2%2023%200l24%203h11l-13-1-22-3c-12-2-16-2-25%200-7%201-9%201-9-3-1-3-4-4-7-1M20%2088v16l1%2014h9V88l-5-1-5%201m14%201c0%202%201%203%2011%203s11-1%2011-2c0-2-1-3-11-3-11%200-11%200-11%202m320%2026c0%202%200%202%202%201h9l4%201%205-1h1l6%201%206-1h2c-1-2-1-2-16-2l-16-1-1-1c-1%200-2%201-2%203m-93%201c-1%203%202%205%203%203h3c1%202%202%202%203%201h5l3-1h27c0-2-1-2-4-2l-3-1h-37m-240%208c0%202%201%202%2018%202%2016%200%2017%200%2017-2s-1-2-17-2c-17%200-18%200-18%202m70%2055c0%203%203%204%203%201h1l2%201%203%201h8l5-1h2c0-2%200-2%201-1l3%202%203-2h1c0%202%206%202%206%200s-1-2-11-2h-14c0%202-1%202-1%201l-3-1h-6c-3-1-3-1-3%201\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;A lot of chaos is introduced when changes are made during the design &amp;amp; development process&quot; title=&quot;A lot of chaos is introduced when changes are made during the design &amp;amp; development process&quot; src=&quot;/static/9ddb2bc90a89896cb46b684e62361891/4ad3a/catherine-process-image.png&quot; srcSet=&quot;/static/9ddb2bc90a89896cb46b684e62361891/477c9/catherine-process-image.png 288w,/static/9ddb2bc90a89896cb46b684e62361891/533c1/catherine-process-image.png 576w,/static/9ddb2bc90a89896cb46b684e62361891/4ad3a/catherine-process-image.png 1152w,/static/9ddb2bc90a89896cb46b684e62361891/8fdfc/catherine-process-image.png 1725w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;The page-based approach, while popular, poses a lot of challenges. Applications are highly dynamic. The interface has to account for many different application states and responsive variants. It’s tedious to describe all of these states in static mock-ups. Also, as the development process begins the requirements often change. You discover new states which were previously not considered or there might be implementation challenges. Meanwhile, the designs continue to iterate. Due to the siloed nature of this approach, it makes it hard to resolve pressures coming from either side. Over time, the team starts to experience a number of symptoms:&lt;/p&gt;&lt;h3 id=&quot;developers-become-blocked-by-designers&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#developers-become-blocked-by-designers&quot; aria-label=&quot;developers become blocked by designers permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Developers Become Blocked By Designers&lt;/h3&gt;&lt;p&gt;As requirements change and we uncover new design considerations, designers will inevitably need to update the pages that they had previously designed. This leads to two scenarios: the developers are constantly blocked having to wait for design iterations or the development team forges ahead without designs and delivers inconsistent or off-brand user experiences.&lt;/p&gt;&lt;h3 id=&quot;poor-product-decisions-are-made&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#poor-product-decisions-are-made&quot; aria-label=&quot;poor product decisions are made permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Poor Product Decisions Are Made&lt;/h3&gt;&lt;p&gt;Traditionally, designers have only been responsible for thinking about the holistic experience, leaving developers to break down that design into small, implementable chunks.&lt;/p&gt;&lt;p&gt;How the developer breaks-down that design has implications for how the design can be changed at a later date, or how new types of content can fit into what has already been built. A developer may or may not have the context necessary to make informed decisions about this structure, and the resulting product implementation may not be flexible enough for all business scenarios.&lt;/p&gt;&lt;p&gt;Similarly, if a designer is not aware of how a developer has implemented a design, they may make design decisions that cause huge headaches for developers, potentially causing a lot of unnecessary rework.&lt;/p&gt;&lt;h3 id=&quot;the-design-of-the-site-becomes-inconsistent&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-design-of-the-site-becomes-inconsistent&quot; aria-label=&quot;the design of the site becomes inconsistent permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Design Of The Site Becomes Inconsistent&lt;/h3&gt;&lt;p&gt;We’ve all seen those websites that include 36 different button styles, and asked ourselves “how could anyone let this happen?”&lt;/p&gt;&lt;p&gt;It can happen quicker than you may think. When we are creating and iterating on products one page at the time, it is likely that the same UI element will be designed and implemented more than once. Not only does this mean that there might be inconsistencies from the get-go, but it also increases the chances that an instance of a button is missed when updates are made in the future.&lt;/p&gt;&lt;p&gt;There is a lot of wasted time re-solving the same problems
Whenever there is a new request, a designer (oftentimes) will open a new file and starts the design process from scratch. For all the time solving the holistic problem at-hand, there is also just as much time defining all the nitty-gritty design details. What does this dropdown look like on hover? How about this button? These are time-consuming tasks.&lt;/p&gt;&lt;p&gt;Now, these detailed-design nitty-gritty questions are important but aren’t unique problems. Most likely, another designer on the team has already thought about it, or maybe it’s something that has already been designed on another page. Once that dropdown hover state has been defined once, the designer shouldn’t have to think about it or document it again.&lt;/p&gt;&lt;h3 id=&quot;maintenance-becomes-a-nightmare&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#maintenance-becomes-a-nightmare&quot; aria-label=&quot;maintenance becomes a nightmare permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Maintenance Becomes A Nightmare&lt;/h3&gt;&lt;p&gt;Documenting a product one page-at-a-time isn’t exactly maintainable. This approach doesn’t allow designers to easily revisit previous design decisions. Suddenly, even the smallest change in design direction requires a designer to update in 12 design files, 6 hand-off documents, and 22 places in code. Inevitably, someone will forget to update a document, and these inconsistencies will leave developers scratching their head and asking for the “source of truth”.&lt;/p&gt;&lt;p&gt;As time goes on, and a product (and its documentation!) gets larger, the cost for feature changes gets larger, too. The design and tech debt accrue. Fast forward 3 years down the road, and now nobody wants to touch the product.&lt;/p&gt;&lt;h2 id=&quot;component-based-design--development&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#component-based-design--development&quot; aria-label=&quot;component based design  development permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Component-based Design &amp;amp; Development&lt;/h2&gt;&lt;p&gt;There was clearly the need for a better approach. Both designers and developers were looking for techniques to improve and optimize their workflow.&lt;/p&gt;&lt;p&gt;As a result, designers started adopting style guides — a set of standards for designing the product often. These would include typographic scales, color palette, and UI patterns, and was published as a static document. Design tools evolved into a symbol based model. This made it easier to maintain states and compose more complex interfaces.&lt;/p&gt;&lt;p&gt;Meanwhile, JavaScript UI frameworks adopted a component-based architecture. This allowed developers create component libraries — a collection of reusable UI elements that can be used to build the application.&lt;/p&gt;&lt;p&gt;This was exciting. For the first time, both designers and developers were working off the same mental model. User interfaces are both designed and built as isolated extensible slices that are composed to create entire pages. Brad Frost’s &lt;a href=&quot;http://bradfrost.com/blog/post/atomic-web-design&quot;&gt;Atomic Design&lt;/a&gt; pattern provided a good model for how to approach component-based design and extend those practices to development.&lt;/p&gt;&lt;p&gt;By focusing on isolated, extensible and reusable components we can surface implementation challenges much sooner in the process. It allowed for greater collaboration between designers and developers, and previously-siloed teams began to speak the same language. Design or development iterations could be more targeted and isolated. It was easier to see what UI components already exist which reduced a lot of duplicated effort.&lt;/p&gt;&lt;h2 id=&quot;what-is-a-design-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#what-is-a-design-system&quot; aria-label=&quot;what is a design system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What is a Design System?&lt;/h2&gt;&lt;p&gt;The component-based model was a massive step in the right direction. There was a reduced need for hand-off, however, there were now multiple sources of truth — in design tools, in code and sometimes in documentation. There were reusable components, but usually no governance model of how to iterate. Which again lead to inconsistent UI or a need for constant design oversight.&lt;/p&gt;&lt;p&gt;There’s a common misconception that a Design System is just a Style Guide or a Component Library, terms people often use interchangeably. However, in our opinion, those are both sub-components of a Design System.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/f0237c7ab47ac48df3c13091c9f89a1e/design-system.svg&quot; alt=&quot;A design system includes design language, design kit, component library, developer sandbox and a documentation site&quot;/&gt;&lt;/p&gt;&lt;p&gt;A Design System is a systematic approach to product development — complete with guidelines, principles, philosophies, and code. It shines a spotlight on &lt;em&gt;how&lt;/em&gt; a team designs, making it a fantastic tool for scaling your design practice, reducing the need for hand-off and promoting more collaboration. As &lt;a href=&quot;https://medium.com/eightshapes-llc/a-design-system-isn-t-a-project-it-s-a-product-serving-products-74dcfffef935&quot;&gt;Nathan Curtis&lt;/a&gt; says, a “Design System isn’t a project, it’s a product serving products”. Our approach to a Design System includes:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design Language:&lt;/strong&gt; The overall visual design of a digital product. This foundation defines characteristics such as typography, colors, icons, spacing and information architecture. The essence of your brand in a digital context. It is maintained as &lt;a href=&quot;https://medium.com/eightshapes-llc/tokens-in-design-systems-25dd82d58421&quot;&gt;Design Tokens&lt;/a&gt; in code.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Design Kit:&lt;/strong&gt; A library of shared styles, symbols or components that can be used by product teams to design or prototype new experiences. These symbols mirror the JavaScript components from the component library and are updated to be always kept in sync.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Component Library:&lt;/strong&gt; A set of JavaScript components that are version controlled and are composed to build one or more products.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sandbox:&lt;/strong&gt; A tool for developing components in isolation, document use cases and write structural or visual tests. This is for the Design System developers.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentation:&lt;/strong&gt; Tying everything together it has guidelines on how to consume the Design System, design and dev considerations and detailed documentation for each component. The documentation site often includes a &lt;a href=&quot;https://react-live.kitten.sh/&quot;&gt;live playground&lt;/a&gt; which is aimed at the consumers to try out the Design System in the browser.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;A Governance model&lt;/strong&gt; for how we can continue to evolve the Design System and how others can contribute to it.
A Design System enables your product teams to share learnings across silos, avoid duplicate work and focus more on user experience problems rather than UI problems.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;A Design System enables your product teams to share learnings across silos, avoid duplicate work and focus more on user experience problems rather than UI problems.&lt;/p&gt;&lt;h2 id=&quot;what-does-a-design-system-look-like-in-practice&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#what-does-a-design-system-look-like-in-practice&quot; aria-label=&quot;what does a design system look like in practice permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What does a Design System Look like in Practice?&lt;/h2&gt;&lt;p&gt;Though we believe that each Design System should include the six pillars described above, the exact details or structure of every Design System will be slightly different. What is the structure of your team or organization? Will your Design System service multiple brands, products, or regions? Will there be a dedicated team available to govern the system? All of these questions will inform how a Design System will best support your goals.&lt;/p&gt;&lt;p&gt;Regardless of the exact implementation, we’ve seen that the impact of a Design System is relatively universal.&lt;/p&gt;&lt;h3 id=&quot;team-members-from-different-disciplines-establish-a-shared-understanding&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#team-members-from-different-disciplines-establish-a-shared-understanding&quot; aria-label=&quot;team members from different disciplines establish a shared understanding permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Team Members From Different Disciplines Establish A Shared Understanding&lt;/h3&gt;&lt;p&gt;In a Design System, the same set of components is shared by both designers and developers. The governance process ensures that both disciplines agree upon the exact requirements of a component and ensure it meets the needs of all parties, without those assumptions it can lead to painful rework later on. The capabilities and usage guidelines of these components are then documented in a centralized place so that everyone has a shared source of truth.&lt;/p&gt;&lt;p&gt;Suddenly, everyone is speaking the same language. When a designer is creating a page, they can now make use of these existing building blocks by grabbing from the UI kit, and can confidently point to those existing building blocks when implementation begins. There are no lengthy hand-off documents needed. The developer can then grab those same components from the component library. No more surprises or broken telephone.&lt;/p&gt;&lt;h3 id=&quot;teams-can-iterate-faster&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#teams-can-iterate-faster&quot; aria-label=&quot;teams can iterate faster permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Teams Can Iterate Faster&lt;/h3&gt;&lt;p&gt;By implementing a Design System, you unlock the ability to release new designs in smaller chunks and shorter feedback loops, with fewer resources. It’s like if you already have the lego blocks manufactured for you, it takes a lot less time to build that castle, compared to if you had to spec and build blocks from scratch.&lt;/p&gt;&lt;h3 id=&quot;multiple-teams-can-start-leveraging-each-others-work&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#multiple-teams-can-start-leveraging-each-others-work&quot; aria-label=&quot;multiple teams can start leveraging each others work permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Multiple Teams Can Start Leveraging Each Others’ Work&lt;/h3&gt;&lt;p&gt;Because Design Systems can be shared across multiple teams, efficiencies can be extended between multiple teams or multiple products. When one team has spent time and effort to solve a design problem, then why shouldn’t another team in your company also benefit from this work? Multiple teams, locales, or even separate brands can now make use of each other’s innovations and avoid reinventing the wheel.&lt;/p&gt;&lt;h3 id=&quot;the-role-of-a-designer-changes&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-role-of-a-designer-changes&quot; aria-label=&quot;the role of a designer changes permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Role Of A Designer Changes&lt;/h3&gt;&lt;p&gt;When a Design System is built, a designer’s role will change in one of two ways:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;For designers building or contributing to the Design System, designing UI becomes a more technical job. It is their responsibility to ensure that they are designing things in a reusable and systematic way to ensure that their designs mimic the world of development.
Components and design decisions (like spacing, colors, typography) don’t happen in a vacuum, and every decision has cascading effects. Because of this, designers are required to have an extra level of discipline to build and adhere to the system.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Designers using the system, however, are alleviated from thinking about these nitty-gritty UI interactions and instead get to focus on the holistic experience, the user flows, and the content. Because the nuances are already defined by the Design System, the creativity shifts from “How should I design this button” to “How do I create the most impactful experience?“. Now, the real innovation can begin.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 id=&quot;evolution-of-the-design-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#evolution-of-the-design-system&quot; aria-label=&quot;evolution of the design system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Evolution of the Design System&lt;/h2&gt;&lt;p&gt;It’s important to keep in mind that a Design System is never really “done”; it will grow and evolve just like any other product. As a website or product changes over time, there will be needs for new UI patterns to be created. By ensuring that the right governance processes are in place, teams can understand when and how to best introduce new elements into the system.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Reuleaux Polygons]]></title><description><![CDATA[I have always been fascinated by the Reuleaux triangle. It is a shape formed by the intersection of three circles. Sort of like a ballooned…]]></description><link>https://varun.ca/reuleaux-polygons/</link><guid isPermaLink="false">https://varun.ca/reuleaux-polygons/</guid><pubDate>Thu, 09 Aug 2018 00:00:00 GMT</pubDate><content:encoded>&lt;figure height=&quot;12.5rem&quot; class=&quot;sc-24qoga-0 sc-24qoga-2 bPzEBI&quot;&gt;&lt;div&gt;&lt;svg fill=&quot;none&quot; stroke=&quot;#2F3030&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; display=&quot;block&quot; width=&quot;4&quot; height=&quot;4&quot; viewBox=&quot;0 0 400 400&quot; class=&quot;sc-24qoga-1 fbOyEI&quot;&gt;&lt;path fill=&quot;#fff&quot; stroke=&quot;none&quot; d=&quot;M298.2 363.179A327.358 327.358 0 0114.7 199.5 327.358 327.358 0 01298.2 35.821a327.358 327.358 0 010 327.358z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M290 355.885A311.77 311.77 0 0120 200 311.77 311.77 0 01290 44.115a311.77 311.77 0 010 311.77z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 hwtwsg&quot;&gt;&lt;svg fill=&quot;none&quot; stroke=&quot;#2F3030&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; width=&quot;4&quot; height=&quot;4&quot; viewBox=&quot;0 0 400 400&quot; class=&quot;sc-24qoga-1 btxlQr&quot;&gt;&lt;path fill=&quot;#ED705C&quot; stroke=&quot;none&quot; d=&quot;M356.604 310.591a359.499 359.499 0 01-211.308 68.659A359.499 359.499 0 0114.7 199.5 359.499 359.499 0 01145.296 19.75 359.499 359.499 0 01356.604 88.41a359.499 359.499 0 010 222.182z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M345.623 305.801a342.38 342.38 0 01-201.246 65.39A342.38 342.38 0 0120 200 342.38 342.38 0 01144.377 28.81a342.38 342.38 0 01201.246 65.389 342.38 342.38 0 010 211.602z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;svg fill=&quot;none&quot; stroke=&quot;#2F3030&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;8&quot; width=&quot;4&quot; height=&quot;4&quot; viewBox=&quot;0 0 400 400&quot; class=&quot;sc-24qoga-1 btxlQr&quot;&gt;&lt;path fill=&quot;#337EED&quot; stroke=&quot;none&quot; d=&quot;M367.683 285.704a295.533 295.533 0 01-128.227 102.257A295.533 295.533 0 0179.56 351.466 295.533 295.533 0 018.4 203.7 295.533 295.533 0 0179.56 55.934a295.533 295.533 0 01159.896-36.495 295.533 295.533 0 01128.227 102.257 295.533 295.533 0 010 164.008z&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M362.174 278.1a281.46 281.46 0 01-122.12 97.387A281.46 281.46 0 0187.772 340.73 281.46 281.46 0 0120 200 281.46 281.46 0 0187.772 59.27a281.46 281.46 0 01152.282-34.757 281.46 281.46 0 01122.12 97.388 281.46 281.46 0 010 156.198z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/div&gt;&lt;/div&gt;&lt;figcaption class=&quot;sc-24qoga-6 khMaOS&quot;&gt;Reuleaux triangle, pentagon and hexagon.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;I have always been fascinated by the Reuleaux triangle. It is a shape formed by the intersection of three circles. Sort of like a ballooned up equilateral triangle.&lt;/p&gt;&lt;p&gt;Reuleaux polygons are a generalization of the Reuleaux triangle. They are a curvilinear polygons i.e., made up of circular arcs and have an odd number of sides.&lt;/p&gt;&lt;h2 id=&quot;construction&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#construction&quot; aria-label=&quot;construction permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Construction&lt;/h2&gt;&lt;p&gt;The Reuleaux triangle is constructed by drawing circles from each vertex of an equilateral triangle. Where the radius of these circles equals the side length of the triangle.&lt;/p&gt;&lt;div hash=&quot;vrLmPq&quot; title=&quot;Reuleaux Polygon Construction&quot; height=&quot;650&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;Reuleaux polygons are constructed using a similar process. Group three consecutive vertices to form a triangle. Then draw a circle from each vertex. The radius of this circle is the distance between the first and the third vertex. Then move onto the next three vertices and so on. Try changing the &lt;strong&gt;side count&lt;/strong&gt; slider, in the demo above, to see this visualized.&lt;/p&gt;&lt;h3 id=&quot;svg-arc-command&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#svg-arc-command&quot; aria-label=&quot;svg arc command permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;SVG Arc Command&lt;/h3&gt;&lt;p&gt;To draw these circular arcs in SVG we can use the arc command.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A rx ry x-axis-rotation large-arc-flag sweep-flag x y&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where &lt;code class=&quot;language-text&quot;&gt;rx&lt;/code&gt; is the x-radius of the ellipse and &lt;code class=&quot;language-text&quot;&gt;ry&lt;/code&gt; is the y-radius. Keep &lt;code class=&quot;language-text&quot;&gt;rx&lt;/code&gt; equal to &lt;code class=&quot;language-text&quot;&gt;ry&lt;/code&gt; to create circular arcs.&lt;/p&gt;&lt;p&gt;Given these radii, there are two ellipses that can connect any two points. On those ellipses there are two possible paths to connect the points. In total, there are four possible arcs connecting any two points.&lt;/p&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;large-arc-flag&lt;/code&gt; allows you to pick an arc greater than or less than 180 degrees. The &lt;code class=&quot;language-text&quot;&gt;sweep-flag&lt;/code&gt; controls if the arc should move clockwise or anti-clockwise.&lt;/p&gt;&lt;div hash=&quot;QxyKVX&quot; title=&quot;SVG Arc Command&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;reuleaux-polygons-with-svg&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#reuleaux-polygons-with-svg&quot; aria-label=&quot;reuleaux polygons with svg permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Reuleaux Polygons With SVG&lt;/h3&gt;&lt;p&gt;The first step is to get the location of each vertex of the polygon. In a previous blog post, I &lt;a href=&quot;/polar-coords/#polygon-generator&quot;&gt;explained&lt;/a&gt; how you can use polar coordinates to generate the vertices of a regular polygon. You can follow the same process to get the vertices of a Reuleaux polygon. The only difference is that instead of connecting those vertices with a line you need to connect them with arcs.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Compute the vertices of the polygon using the &lt;a href=&quot;/polar-coords/#polygon-generator&quot;&gt;polygon generator&lt;/a&gt;.&lt;pre class=&quot;mt3&quot;&gt;&lt;code&gt;const pts = polygon([cx, cy], sideCount, radius);&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;The radius of the arcs will be the distance between the first and the third vertex.&lt;pre class=&quot;mt3&quot;&gt;&lt;code&gt;const r = dist(pts[0], pts[2]);&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;Draw the path. For Reuleaux polygons we need the arc to be less than 180 degrees and the &lt;code&gt;sweep-flag&lt;/code&gt; direction should match the direction you define your points in (clockwise or anti-clockwise).&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;reuleauxPolygonConstruction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cy&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sideCount&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;polygon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cy&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; sideCount&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pts&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;head&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;tail&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pts&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// move to the first vertex&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; head&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; head&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Connect adjacent vertices with an arc&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;tail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;p&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;A &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;r&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;r&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; 0 0 1 &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Connect the last and the first vertices with an arc&lt;/span&gt;
  &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;A &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;r&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;r&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; 0 0 1 &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;head&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt; &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;head&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Close the shape&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Z&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;curve-of-constant-width&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#curve-of-constant-width&quot; aria-label=&quot;curve of constant width permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Curve Of Constant Width&lt;/h2&gt;&lt;p&gt;Although it is possible to construct curvilinear polygons with even number of sides. Reuleaux polygons always have an odd number of sides because they are constant-width shapes. Therefore, every vertex must be able to associate an opposite arc. This is possible only if we have an odd number of arcs.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;A curve of constant width is a convex planar shape whose width (defined as the perpendicular distance between two distinct parallel lines each having at least one point in common with the shape’s boundary but none with the shape’s interior) is the same regardless of the orientation of the curve.&lt;/p&gt;&lt;p&gt;— &lt;cite&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Curve_of_constant_width&quot;&gt;wikipedia&lt;/a&gt;&lt;/cite&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Any curve of constant width can rotate within a square while staying within it at all times. Notice, how as it rotates, its axis does not stay fixed at a single point. It follows a curve around the center of the square.&lt;/p&gt;&lt;div hash=&quot;wXMbzb&quot; title=&quot;Reuleaux Triangle Rotating in a Square&quot; height=&quot;420&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;This property of being able to rotate within a square is leveraged to create &lt;a href=&quot;https://youtu.be/L5AzbDJ7KYI&quot;&gt;bits that drill a nearly square hole&lt;/a&gt;. The drill bit itself is a Reuleaux triangle and is mounted in a chuck that allows for the bit to rotate without having a fixed centre of rotation.&lt;/p&gt;&lt;h2 id=&quot;morphing&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#morphing&quot; aria-label=&quot;morphing permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Morphing&lt;/h2&gt;&lt;p&gt;Lastly, just for fun, here are some polygons morphing between their regular form and Reuleaux form using &lt;a href=&quot;https://github.com/veltman/flubber&quot;&gt;flubber&lt;/a&gt;.&lt;/p&gt;&lt;div hash=&quot;oyLOvr&quot; title=&quot;Morphing Reuleaux Polygons&quot; height=&quot;400&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h4 id=&quot;references&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#references&quot; aria-label=&quot;references permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;References&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.wikiwand.com/en/Reuleaux_triangle&quot;&gt;Wikiwand&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mathworld.wolfram.com/ReuleauxTriangle.html&quot;&gt;Wolfram MathWorld&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://whistleralley.com/reuleaux/reuleaux.htm&quot;&gt;Whistler Alley Mathematics&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Component Based Design System With Styled-System]]></title><description><![CDATA[Component-based design system is the practice of splitting the UI into small, isolated and more manageable parts; backed by a set of design…]]></description><link>https://varun.ca/styled-system/</link><guid isPermaLink="false">https://varun.ca/styled-system/</guid><pubDate>Fri, 11 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Component-based design system is the practice of splitting the UI into small, isolated and more manageable parts; backed by a set of design constraints. It builds upon ideas such as &lt;a href=&quot;http://bradfrost.com/blog/post/atomic-web-design&quot;&gt;Atomic Design&lt;/a&gt;, &lt;a href=&quot;http://alistapart.com/article/creating-style-guides&quot;&gt;Style Guides&lt;/a&gt; and &lt;a href=&quot;https://medium.com/@dan.shapiro1210/understanding-component-based-architecture-3ff48ec0c238&quot;&gt;Component-Based Architecture&lt;/a&gt;. In my &lt;a href=&quot;/tachyons-components&quot;&gt;previous&lt;/a&gt;, post I introduced some foundational concepts of component-based design systems and shared my approach to building one with Tachyons and React. I now want to focus on a different tool called Styled-System which uses a Tachyons like API while giving you a lot more control over the design system implementation.&lt;/p&gt;&lt;h2 id=&quot;styled-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#styled-system&quot; aria-label=&quot;styled system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Styled System&lt;/h2&gt;&lt;p&gt;Styled-System provides you with a set of utilities that map props to your design system. It uses the concept of &lt;a href=&quot;https://github.com/jxnblk/styled-system#how-it-works&quot;&gt;style functions&lt;/a&gt;. Each style function exposes its own set of props that style elements based on values defined in your design system theme. It has a rich &lt;a href=&quot;https://github.com/jxnblk/styled-system#api&quot;&gt;API&lt;/a&gt; with functions for most CSS properties.&lt;/p&gt;&lt;p&gt;You need to pair the style functions with a CSS-in-JS library to build a component. It works with most CSS-in-JS libraries and even supports &lt;a href=&quot;https://github.com/c8r/vue-styled-system&quot;&gt;Vue&lt;/a&gt;. I will be using &lt;a href=&quot;https://www.styled-components.com&quot;&gt;styled-components&lt;/a&gt; for all the examples in this blog post.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; space&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; fontSize&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; color &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-system&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; ThemeProvider &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-components&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; theme &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./theme&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Box &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; styled&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;div&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;space&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;width&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;fontSize&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;color&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ThemeProvider theme&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;theme&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box p&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; bg&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;whites.10&amp;quot;&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;orange&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      This is a Box
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ThemeProvider&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div mb=&quot;4&quot; src=&quot;https://codesandbox.io/embed/2vv327jqjp?hidenavigation=1&amp;amp;module=%2Fsrc%2Ftheme.js&quot; style=&quot;width:100%;height:200px;border:0;overflow:hidden&quot; sandbox=&quot;allow-modals allow-forms allow-popups allow-scripts allow-same-origin&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;design-constraints-theme&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#design-constraints-theme&quot; aria-label=&quot;design constraints theme permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Design Constraints Theme&lt;/h2&gt;&lt;p&gt;You define your design system as a theme object (example below) and then provide it using the &lt;code class=&quot;language-text&quot;&gt;ThemeProvider&lt;/code&gt; component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; theme &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  breakpoints&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  space&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  fontSizes&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;14&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;24&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;36&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;96&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  fontWeights&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;600&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;700&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;900&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  lineHeights&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    solid&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    title&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    copy&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  letterSpacings&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    normal&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;normal&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    tracked&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;0.1em&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    tight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;-0.05em&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    mega&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;0.25em&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  fonts&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    serif&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;athelas, georgia, times, serif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    sansSerif&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;-apple-system, BlinkMacSystemFont, &amp;quot;avenir next&amp;quot;, avenir, &amp;quot;helvetica neue&amp;quot;, helvetica, ubuntu, roboto, noto, &amp;quot;segoe ui&amp;quot;, arial, sans-serif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  borders&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;1px solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;2px solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;4px solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;8px solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;16px solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;32px solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  radii&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;9999&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;100%&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  width&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  heights&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  maxWidths&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;16&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;128&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;256&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;512&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;768&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1536&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  colors&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    black&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#000&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;near-black&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#111&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;dark-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#333&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;mid-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#555&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    gray&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27; #777&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    silver&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#999&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;light-silver&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#aaa&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;moon-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#ccc&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;light-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#eee&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;near-white&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#f4f4f4&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    white&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;#fff&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    transparent&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;transparent&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    blacks&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.0125)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.025)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.05)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.1)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.2)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.3)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.4)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.5)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.6)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.7)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.8)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(0,0,0,.9)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    whites&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.0125)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.025)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.05)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.1)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.2)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.3)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.4)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.5)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.6)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.7)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.8)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rgba(255,255,255,.9)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// ... and so on&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Style functions will try to find a value from the theme object, these could be deeply nested values, and fallback to a hard-coded value if they are unable to.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// font-size: 24px (theme.fontSizes[4])&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box fontSize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// margin: 16px (theme.space[3])&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box m&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// color: #333 (theme.colors.blacks[0])&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;blacks.3&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// background color (theme.colors[&amp;#x27;light-red&amp;#x27;])&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box bg&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;light-red&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// line-height: 1.5 (theme.lineHeights.copy)&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box lineHeight&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;copy&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// renders CSS `50%` width since it&amp;#x27;s not defined in theme&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;responsive-style-props&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#responsive-style-props&quot; aria-label=&quot;responsive style props permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Responsive Style Props&lt;/h3&gt;&lt;p&gt;All core props accept arrays as values for specifying responsive styles. Refer to the &lt;a href=&quot;https://github.com/jxnblk/styled-system#table-of-style-props&quot;&gt;Table of Style Props&lt;/a&gt; to see which props support responsive values.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box
  width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 100% below the smallest breakpoint&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 50% from the next breakpoint and up&lt;/span&gt;
    &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token comment&quot;&gt;// 25% from the next breakpoint and up&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// responsive font size&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text fontSize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;system-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#system-components&quot; aria-label=&quot;system components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;System Components&lt;/h2&gt;&lt;p&gt;If you have settled on using styled-components with styled-system, then you can get an even simpler authoring experience by using system-components — a lightweight wrapper around those two libraries.&lt;/p&gt;&lt;p&gt;That’s a lot of libraries with similar sounding names 😅 To avoid confusion, here’s a quick overview of the ecosystem:&lt;/p&gt;&lt;figure font-size=&quot;2&quot; class=&quot;sc-24qoga-0 esXWRs&quot;&gt;&lt;div class=&quot;sc-24qoga-0 sc-24qoga-2 hrSszo&quot;&gt;&lt;div class=&quot;sc-24qoga-0 jGpVby&quot;&gt;&lt;p color=&quot;neutral.7&quot; font-size=&quot;2&quot; font-weight=&quot;7&quot; font-family=&quot;code&quot; class=&quot;lcfnd1-0 eUTNdf&quot;&gt;system-components&lt;/p&gt;&lt;p color=&quot;neutral.7&quot; font-size=&quot;1&quot; font-family=&quot;code&quot; class=&quot;lcfnd1-0 dQqcHS&quot;&gt;simpler authoring experience to create design-system-driven React UI components&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 hUaWaE&quot;&gt;&lt;p color=&quot;neutral.0&quot; font-size=&quot;1&quot; font-family=&quot;code&quot; class=&quot;lcfnd1-0 jSZLMI&quot;&gt;Additional features such as default value for props &amp;amp; &lt;b&gt;is&lt;/b&gt; prop&lt;/p&gt;&lt;div class=&quot;sc-24qoga-0 wsyfD&quot;&gt;&lt;p font-size=&quot;2&quot; font-weight=&quot;7&quot; font-family=&quot;code&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 ctsISy&quot;&gt;clean-tag &amp;amp; clean-element&lt;/p&gt;&lt;p color=&quot;neutral.0&quot; font-size=&quot;1&quot; font-family=&quot;code&quot; class=&quot;lcfnd1-0 gfesVv&quot;&gt;removes styled-system props from the underlying DOM elements&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 wsyfD&quot;&gt;&lt;p font-size=&quot;2&quot; font-weight=&quot;7&quot; font-family=&quot;code&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 ctsISy&quot;&gt;styled-system&lt;/p&gt;&lt;p color=&quot;neutral.0&quot; font-size=&quot;1&quot; font-family=&quot;code&quot; class=&quot;lcfnd1-0 gfesVv&quot;&gt;framework agnostic design system utilities&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;sc-24qoga-0 izWpPX&quot;&gt;&lt;p font-size=&quot;2&quot; font-weight=&quot;7&quot; font-family=&quot;code&quot; color=&quot;neutral.0&quot; class=&quot;lcfnd1-0 ctsISy&quot;&gt;styled-components&lt;/p&gt;&lt;p color=&quot;neutral.0&quot; font-size=&quot;1&quot; font-family=&quot;code&quot; class=&quot;lcfnd1-0 gfesVv&quot;&gt;a css-in-js library&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;figcaption class=&quot;sc-24qoga-6 khMaOS&quot;&gt;system-components is comprised of styled-components, styled-system, clean-tag and clean-element. It also gives us the ability to provide default values for props.&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Let’s start by creating a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt; primitive. I would recommend applying the core functions to all components. Beyond that, it depends on the component you are building. For the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt; component I include border, layout, flex and position functions.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; system &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;system-components&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Box &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// core&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;space&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;width&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;color&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;fontSize&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// borders&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;borders&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;borderColor&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;borderRadius&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// layout&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;display&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;maxWidth&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;minWidth&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;height&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;maxHeight&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;minHeight&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// flexbox&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;alignItems&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;alignContent&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;justifyContent&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;flexWrap&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;flexDirection&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;flex&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;flexBasis&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;justifySelf&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;alignSelf&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;order&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// position&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;position&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;zIndex&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;top&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;right&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;bottom&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;left&amp;#x27;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Box&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Box&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;System-components used &lt;code class=&quot;language-text&quot;&gt;clean-tag&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;clean-element&lt;/code&gt; to strip out styled-system props automatically. Preventing them from passing down onto the underlying DOM elements. It allows you to control which DOM element is rendered by using the &lt;code class=&quot;language-text&quot;&gt;is&lt;/code&gt; prop. And you can also specify default values for all the props.&lt;/p&gt;&lt;p&gt;System-components automatically apply styled-system functions based on the keys of the default values object. In the example below, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Text /&amp;gt;&lt;/code&gt; will have &lt;code class=&quot;language-text&quot;&gt;fontSize&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;color&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;fontFamily&lt;/code&gt; functions automatically applied so, you don’t need to list them out.&lt;/p&gt;&lt;p&gt;This is honestly my favourite way to build UI components right now &lt;img src=&quot;/13d2c87d597ba5c56edff9a85dcef8df/parrot.gif&quot; alt=&quot;party parrot&quot; display=&quot;inline&quot; width=&quot;1em&quot; mb=&quot;{0}&quot;/&gt;&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    is&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;p&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;dark-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fontFamily&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;sansSerif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;space&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;width&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;textAlign&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;lineHeight&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;fontWeight&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;letterSpacing&amp;#x27;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Text&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Heading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    is&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;h1&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    m&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;dark-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fontFamily&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;sansSerif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;width&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;textAlign&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;lineHeight&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;fontWeight&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;letterSpacing&amp;#x27;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Heading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Heading&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the previous, post I had created a Profile Card component. Here’s the whole example recreated with system-components.&lt;/p&gt;&lt;p&gt;
  &lt;a href=&quot;https://codesandbox.io/s/v86m4zkyy0&quot; display:=&quot;&quot;&gt;
    &lt;img alt=&quot;Edit Design System Demo — Profile Card&quot; src=&quot;https://codesandbox.io/static/img/play-codesandbox.svg&quot;/&gt;
  &lt;/a&gt;
&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Card&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Box&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Heading&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Text&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Avatar &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./design-system&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;ProfileCard&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; p&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; borderColor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;blacks.3&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box textAlign&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;center&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Avatar width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; height&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; mb&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; borderColor&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;blacks.2&amp;quot;&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Heading is&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;h2&amp;quot;&lt;/span&gt; fontSize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; mb&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Heading&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text fontSize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; my&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Card&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;input-with-adornment-example&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#input-with-adornment-example&quot; aria-label=&quot;input with adornment example permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Input With Adornment Example&lt;/h2&gt;&lt;p&gt;Moving onto some more complex examples. The &lt;code class=&quot;language-text&quot;&gt;&amp;lt;InputWithAdornment/&amp;gt;&lt;/code&gt; component allows you to place an adornment before or after an input. The adornment can be a bit of text, an icon or any valid node.&lt;/p&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; display=&quot;block&quot; viewBox=&quot;0 0 800 192&quot; class=&quot;sc-24qoga-1 btetzN&quot;&gt;&lt;title id=&quot;CurrencyInputTitle&quot;&gt;Currency Input&lt;/title&gt;&lt;desc id=&quot;CurrencyInputDesc&quot;&gt;An illustration of the currency input with an icon adornment&lt;/desc&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;rect width=&quot;738&quot; height=&quot;98&quot; x=&quot;31&quot; y=&quot;47&quot; stroke=&quot;#CCC&quot; stroke-width=&quot;2&quot; rx=&quot;4&quot;&gt;&lt;/rect&gt;&lt;text fill=&quot;#333&quot; font-family=&quot;AvenirNext-Bold, Avenir Next&quot; font-size=&quot;24&quot; font-weight=&quot;bold&quot;&gt;&lt;tspan x=&quot;32&quot; y=&quot;28&quot;&gt;Currency&lt;/tspan&gt;&lt;/text&gt;&lt;path fill=&quot;#333&quot; fill-rule=&quot;nonzero&quot; d=&quot;M74.667 110.444c-5.578 0-10.4-3.155-12.8-7.777h12.8v-4.445H60.4A14.743 14.743 0 0160.222 96c0-.756.067-1.489.178-2.222h14.267v-4.445h-12.8c2.4-4.622 7.244-7.777 12.8-7.777a14.38 14.38 0 019.4 3.488L88 81.111A19.9 19.9 0 0074.667 76c-8.711 0-16.09 5.578-18.845 13.333H48v4.445h6.8A18.36 18.36 0 0054.667 96c0 .756.044 1.489.133 2.222H48v4.445h7.822C58.578 110.422 65.956 116 74.667 116c5.133 0 9.8-1.933 13.333-5.111l-3.956-3.933a14.234 14.234 0 01-9.377 3.488z&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;p&gt;One possible way of building this is to wrap an HTML &lt;code class=&quot;language-text&quot;&gt;&amp;lt;input /&amp;gt;&lt;/code&gt; and containers for the adornments in a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt;. The adornment containers are absolutely positioned while the input has padding to &lt;em&gt;make room&lt;/em&gt; for the adornment.&lt;/p&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; display=&quot;block&quot; viewBox=&quot;0 0 800 192&quot; class=&quot;sc-24qoga-1 btetzN&quot;&gt;&lt;title id=&quot;InputWithAdornmentTitle&quot;&gt;Input With Adornment&lt;/title&gt;&lt;desc id=&quot;InputWithAdornmentDesc&quot;&gt;An illustration of the Input With Adornment component layout&lt;/desc&gt;&lt;defs&gt;&lt;path id=&quot;a&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;c&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#333&quot; stroke-width=&quot;2&quot; d=&quot;M31 47h738v98H31z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#F90&quot; stroke-width=&quot;2&quot; d=&quot;M159 63h482v66H159z&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#95A&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; transform=&quot;translate(96 136)&quot;&gt;&lt;tspan x=&quot;56&quot; y=&quot;42&quot;&gt;Before Adornment Container&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M96 136v16l48 18&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#95A&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; transform=&quot;translate(434 16)&quot;&gt;&lt;tspan x=&quot;0&quot; y=&quot;18&quot;&gt;After Adornment Container&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M704 56V40l-48-10&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#F90&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot;&gt;&lt;tspan x=&quot;176&quot; y=&quot;102&quot;&gt;&amp;lt;input /&amp;gt;&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#333&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot;&gt;&lt;tspan x=&quot;30&quot; y=&quot;37&quot;&gt;&amp;lt;InputWithAdornment /&amp;gt;&lt;/tspan&gt;&lt;/text&gt;&lt;g transform=&quot;translate(48 64)&quot;&gt;&lt;mask id=&quot;b&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#a&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M1.5-10.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#b)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(656 64)&quot;&gt;&lt;mask id=&quot;d&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#c&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M1.5-10.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#d)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;p&gt;You can pass in any node to the &lt;code class=&quot;language-text&quot;&gt;before&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;after&lt;/code&gt; props, while all other props are spread onto the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;input /&amp;gt;&lt;/code&gt; element so as not to limit any functionality.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;InputWithAdornment&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; before&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; after&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; disabled&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box display&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;flex&amp;quot;&lt;/span&gt; alignItems&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;center&amp;quot;&lt;/span&gt; position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;relative&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;before &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Adornment left&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt; pl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; disabled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;disabled&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;before&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Adornment&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;HtmlInput
      py&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      pl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;before &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      pr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;after &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      disabled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;disabled&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;after &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Adornment right&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;0&amp;quot;&lt;/span&gt; pr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; disabled&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;disabled&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;after&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Adornment&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;extending-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#extending-components&quot; aria-label=&quot;extending components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Extending Components&lt;/h3&gt;&lt;p&gt;System-components generate styled-components, allowing you to use all built-in methods such as &lt;code class=&quot;language-text&quot;&gt;.extend&lt;/code&gt;. &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Adornment /&amp;gt;&lt;/code&gt; is a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt; extended to have an absolute position and a style function to control opacity based on the &lt;code class=&quot;language-text&quot;&gt;disabled&lt;/code&gt; prop.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Adornment &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Box&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;extend&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  position: absolute;
  opacity: &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;disabled &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;;
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;using-custom-functions&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#using-custom-functions&quot; aria-label=&quot;using custom functions permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Using Custom Functions&lt;/h3&gt;&lt;p&gt;You can also pass in custom style functions to the system function. The function signature is &lt;code class=&quot;language-text&quot;&gt;system(defaultValues, styleFn1, styleFn2, ... customStyleFn)&lt;/code&gt;. For the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;HtmlInput /&amp;gt;&lt;/code&gt; component a custom style function adds styling for focus and disabled states. &lt;a href=&quot;https://github.com/jxnblk/styled-system#themeget&quot;&gt;themeGet&lt;/a&gt; is a utility to get a value from your theme.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; themeGet &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;styled-system&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; HtmlInput &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    is&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;input&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;text&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fontFamily&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;sansSerif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    fontSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;inherit&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    p&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    m&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    lineHeight&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;solid&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    width&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;mid-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    bg&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;white&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    border&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    borderRadius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    borderColor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;moon-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    display&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;inline-block&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    verticalAlign&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;middle&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    appearance&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;none&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    flex&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;1 0 auto&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;amp;:focus&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      outline&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;none&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      borderColor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;themeGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;colors.blue&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;amp;:disabled&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      opacity&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      backgroundColor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;themeGet&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;colors.light-gray&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div mb=&quot;4&quot; src=&quot;https://codesandbox.io/embed/myoj1yzwmx?hidenavigation=1&amp;amp;module=%2Fsrc%2Fdesign-system%2FInputWithAdornment.js&quot; style=&quot;width:100%;height:500px;border:0;overflow:hidden&quot; sandbox=&quot;allow-modals allow-forms allow-popups allow-scripts allow-same-origin&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;product-card-example&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#product-card-example&quot; aria-label=&quot;product card example permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Product Card Example&lt;/h2&gt;&lt;p&gt;The &lt;a href=&quot;https://www.aldoshoes.com/ca/en/men/footwear/dress-shoes&quot;&gt;Aldo&lt;/a&gt; product card is perfect for demonstrating the power of composition. It displays an image with a particular aspect ratio. Its other contents change based on the status of the product.&lt;/p&gt;&lt;style&gt;
  .product-card-img {
    width: 49% !important;
    margin-bottom: 0.5rem;
  }
  @media screen and (min-width: 30em) {
    .product-card-img { width: 33% !important; margin-bottom: 0.25rem; }
  }
&lt;/style&gt;&lt;figure class=&quot;sc-24qoga-0 sc-24qoga-2 bfFrku&quot;&gt;&lt;img src=&quot;static/product-card-1-19a35d7e3db739ad8f09ef9bfc53b0dd.png&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 sc-1k10hsi-0 kdMjxW&quot;/&gt;&lt;img src=&quot;static/product-card-2-cc62dffa8d82138d4a0e486c42339ebe.png&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 sc-1k10hsi-0 kdMjxW&quot;/&gt;&lt;img src=&quot;static/product-card-3-52c82e418ed536251c5032a9dc747d4f.png&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 sc-1k10hsi-0 kdMjxW&quot;/&gt;&lt;img src=&quot;static/product-card-4-335b6d243bcdf08574508cf058a84e0b.png&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 sc-1k10hsi-0 kdMjxW&quot;/&gt;&lt;img src=&quot;static/product-card-5-b47c8d34ce617117ac0174dbb5a48139.png&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 sc-1k10hsi-0 kdMjxW&quot;/&gt;&lt;img src=&quot;static/product-card-6-884ea55af3394c3895956a61e22779fc.png&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 sc-1k10hsi-0 kdMjxW&quot;/&gt;&lt;figcaption class=&quot;sc-24qoga-6 khMaOS&quot;&gt;Product Cards &lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;A more generic form of this component is the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ImageCard /&amp;gt;&lt;/code&gt; component. It consists of a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;BackgroundImage /&amp;gt;&lt;/code&gt; component and containers for content that can be absolutely positioned on top of it. All wrapped in a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot; width=&quot;100%,75%&quot; display=&quot;block&quot; viewBox=&quot;0 0 416 416&quot; class=&quot;sc-24qoga-1 fzLmob&quot;&gt;&lt;title id=&quot;ImageCardTitle&quot;&gt;Image Card&lt;/title&gt;&lt;desc id=&quot;ImageCardDesc&quot;&gt;An illustration of the Image Card component layout&lt;/desc&gt;&lt;defs&gt;&lt;path id=&quot;a&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;c&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;e&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;g&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;i&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;k&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;m&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;o&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;q&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;s&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;u&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;w&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;y&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;A&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;C&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;E&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;G&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;I&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;K&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;M&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;O&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;Q&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;S&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;path id=&quot;U&quot; d=&quot;M0 0h96v64H0z&quot;&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#333&quot; stroke-width=&quot;2&quot; d=&quot;M31 31h354v354H31z&quot;&gt;&lt;/path&gt;&lt;g transform=&quot;rotate(90 56 88)&quot;&gt;&lt;mask id=&quot;b&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#a&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#b)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 16 128)&quot;&gt;&lt;mask id=&quot;d&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#c&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#d)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 -8 104)&quot;&gt;&lt;mask id=&quot;f&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#e&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#f)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 32 64)&quot;&gt;&lt;mask id=&quot;h&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#g&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#h)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 48 160)&quot;&gt;&lt;mask id=&quot;j&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#i&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#j)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 88 120)&quot;&gt;&lt;mask id=&quot;l&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#k&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#l)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(208 32)&quot;&gt;&lt;mask id=&quot;n&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#m&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#n)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(208 96)&quot;&gt;&lt;mask id=&quot;p&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#o&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#p)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(288 96)&quot;&gt;&lt;mask id=&quot;r&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#q&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#r)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(288 144)&quot;&gt;&lt;mask id=&quot;t&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#s&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#t)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(208 144)&quot;&gt;&lt;mask id=&quot;v&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#u&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#v)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(288 32)&quot;&gt;&lt;mask id=&quot;x&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#w&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#x)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 88 296)&quot;&gt;&lt;mask id=&quot;z&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#y&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#z)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 56 264)&quot;&gt;&lt;mask id=&quot;B&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#A&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#B)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 16 304)&quot;&gt;&lt;mask id=&quot;D&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#C&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#D)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 -8 280)&quot;&gt;&lt;mask id=&quot;F&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#E&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#F)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 32 240)&quot;&gt;&lt;mask id=&quot;H&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#G&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#H)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;rotate(90 48 336)&quot;&gt;&lt;mask id=&quot;J&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#I&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#J)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(32 208)&quot;&gt;&lt;mask id=&quot;L&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#K&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#L)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(32 272)&quot;&gt;&lt;mask id=&quot;N&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#M&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#N)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(112 272)&quot;&gt;&lt;mask id=&quot;P&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#O&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#P)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(112 320)&quot;&gt;&lt;mask id=&quot;R&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#Q&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#R)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(32 320)&quot;&gt;&lt;mask id=&quot;T&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#S&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#T)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g transform=&quot;translate(112 208)&quot;&gt;&lt;mask id=&quot;V&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#U&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#95A&quot; stroke-linecap=&quot;square&quot; d=&quot;M-34.5 25.5l73.335 73.335M-30.5 21.5l73.335 73.335M-26.5 17.5l73.335 73.335M-22.5 13.5l73.335 73.335M-18.5 9.5l73.335 73.335M-14.5 5.5l73.335 73.335M-10.5 1.5l73.335 73.335M-6.5-2.5l73.335 73.335M-2.5-6.5l73.335 73.335M2.5-9.5l73.335 73.335M15.5-4.5l73.335 73.335M19.5-8.5l73.335 73.335M33.5-2.5l73.335 73.335M37.5-6.5l73.335 73.335M41.5-10.5l73.335 73.335M45.5-14.5l73.335 73.335M49.5-18.5l73.335 73.335M53.5-22.5l73.335 73.335M57.5-26.5l73.335 73.335M61.5-30.5l73.335 73.335M65.5-34.5l73.335 73.335&quot; mask=&quot;url(#V)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;path stroke=&quot;#FFF&quot; stroke-width=&quot;8&quot; d=&quot;M207 208h173v172H207z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#FFF&quot; stroke-width=&quot;8&quot; d=&quot;M36 208h173v172H36zM207 36h173v172H207z&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#FFF&quot; stroke-width=&quot;8&quot; d=&quot;M36 36h173v172H36z&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#FFF&quot; d=&quot;M76 100h88v56H76z&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#95A&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; transform=&quot;translate(76 100)&quot;&gt;&lt;tspan x=&quot;10.266&quot; y=&quot;23&quot;&gt;Top Left&lt;/tspan&gt;&lt;tspan x=&quot;8.195&quot; y=&quot;46&quot;&gt;Container&lt;/tspan&gt;&lt;/text&gt;&lt;path fill=&quot;#FFF&quot; d=&quot;M252 100h88v56h-88z&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#95A&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; transform=&quot;translate(252 100)&quot;&gt;&lt;tspan x=&quot;6.98&quot; y=&quot;23&quot;&gt;Top Right&lt;/tspan&gt;&lt;tspan x=&quot;8.195&quot; y=&quot;46&quot;&gt;Container&lt;/tspan&gt;&lt;/text&gt;&lt;path fill=&quot;#FFF&quot; d=&quot;M240 268h112v56H240z&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#95A&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; transform=&quot;translate(240 268)&quot;&gt;&lt;tspan x=&quot;5.32&quot; y=&quot;23&quot;&gt;Bottom Right&lt;/tspan&gt;&lt;tspan x=&quot;19.695&quot; y=&quot;46&quot;&gt;Container&lt;/tspan&gt;&lt;/text&gt;&lt;path fill=&quot;#FFF&quot; d=&quot;M64 268h112v56H64z&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#95A&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot; transform=&quot;translate(64 268)&quot;&gt;&lt;tspan x=&quot;9.105&quot; y=&quot;23&quot;&gt;Bottom Left&lt;/tspan&gt;&lt;tspan x=&quot;20.195&quot; y=&quot;46&quot;&gt;Container&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#333&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot;&gt;&lt;tspan x=&quot;32.484&quot; y=&quot;19&quot;&gt;&amp;lt;ImageCard /&amp;gt;&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F90&quot; stroke-width=&quot;2&quot; d=&quot;M39 39h338v338H39z&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#F90&quot; font-family=&quot;ComicSansMS-Bold, Comic Sans MS&quot; font-size=&quot;16&quot; font-weight=&quot;bold&quot;&gt;&lt;tspan x=&quot;131&quot; y=&quot;410&quot;&gt;&amp;lt;BackgroundImage /&amp;gt;&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F90&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;2&quot; d=&quot;M88 381v15l40 8&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;&amp;lt;BackgroundImage /&amp;gt;&lt;/code&gt; is essentially the same as Rebass’ &lt;a href=&quot;http://jxnblk.com/rebass/components/BackgroundImage&quot;&gt;BackgroundImage&lt;/a&gt; component. It uses the &lt;a href=&quot;https://css-tricks.com/aspect-ratio-boxes&quot;&gt;padding technique&lt;/a&gt; to render images in a specific aspect ratio.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; BackgroundImage &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    width&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ratio&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    backgroundSize&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;cover&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    backgroundPosition&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;center&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    blacklist&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;src&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;space&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;color&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;fontSize&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;ratio&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    backgroundImage&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;src &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;url(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;src&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice how you can use the &lt;code class=&quot;language-text&quot;&gt;blacklist&lt;/code&gt; prop to prevent props from passing onto the DOM element.&lt;/p&gt;&lt;p&gt;The absolutely positioned content containers use &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt;. Alternatively, you could create an &lt;a href=&quot;http://jxnblk.com/rebass/components/Absolute&quot;&gt;Absolute&lt;/a&gt; component. The wrapper &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box /&amp;gt;&lt;/code&gt; has all other props spread onto it. Allowing you to the control the size and layout of the entire component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;ImageCard&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; tl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; tr&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; br&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bl&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; ratio&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;relative&amp;quot;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;BackgroundImage width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;100%&amp;quot;&lt;/span&gt; ratio&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;ratio&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;src&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tl &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt; top&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; left&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tl&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tr &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt; top&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; right&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;tr&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;br &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt; bottom&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; right&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;br&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;bl &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box position&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;absolute&amp;quot;&lt;/span&gt; bottom&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; left&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;bl&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ProductCard /&amp;gt;&lt;/code&gt; is a more domain-specific version of the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ImageCard /&amp;gt;&lt;/code&gt;. It holds the logic to display the appropriate product-tag, pricing and the favourite button. See the CodeSandbox below for the implementation of those other components.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;ProductCard&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; shoe&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ImageCard
    ratio&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;803&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;632&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shoe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    tl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shoe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ProductTag&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;statusText&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;shoe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;status&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;ProductTag&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    tr&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;FavouriteButton p&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; m&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; isFavourite&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shoe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;favourite&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    bl&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box ml&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; mb&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;HeadingWithDash dashWidth&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; fontSize&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; lineHeight&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;solid&amp;quot;&lt;/span&gt; mb&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;shoe&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;HeadingWithDash&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Price &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;shoe&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div mb=&quot;4&quot; src=&quot;https://codesandbox.io/embed/woy5w424zl??view=split&amp;amp;hidenavigation=1&amp;amp;module=%2Fsrc%2FProductCard%2FProductCard.js&quot; style=&quot;width:100%;height:500px;border:0;overflow:hidden&quot; sandbox=&quot;allow-modals allow-forms allow-popups allow-scripts allow-same-origin&quot;&gt;&lt;/div&gt;&lt;p&gt;These are just a few examples that demonstrate how you can use styled-system. There are other features such as &lt;a href=&quot;https://github.com/jxnblk/styled-system#complexstyle&quot;&gt;complex-styles&lt;/a&gt;, &lt;a href=&quot;https://github.com/jxnblk/styled-system#pseudostyle&quot;&gt;pseudo-styles&lt;/a&gt; and even creating custom style &lt;a href=&quot;https://github.com/jxnblk/styled-system#style&quot;&gt;utilities&lt;/a&gt; for you to explore. For further real-world examples check out &lt;a href=&quot;https://github.com/jxnblk/rebass&quot;&gt;Rebass&lt;/a&gt; and &lt;a href=&quot;https://github.com/pricelinelabs/design-system&quot;&gt;Priceline Design System&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In my opinion, styled-system is a genuinely fantastic tool for building a component-based design system. It manages to get the balance right between flexibility and maintainability.&lt;/p&gt;&lt;h4 id=&quot;further-reading&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#further-reading&quot; aria-label=&quot;further reading permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Further reading&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://jxnblk.com/writing/posts/patterns-for-style-composition-in-react&quot;&gt;Patterns For Style Composition In React&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://varun.ca/flattening-deep-hierarchies-of-components&quot;&gt;Flattening Deep Hierarchies of Components&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://daneden.me/2018/01/05/subatomic-design-systems&quot;&gt;Subatomic Design Systems&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Component Based Design System With Tachyons]]></title><description><![CDATA[A Design system is a collection of rules, constraints and principles applied to your design and development process. I most often encounter…]]></description><link>https://varun.ca/tachyons-components/</link><guid isPermaLink="false">https://varun.ca/tachyons-components/</guid><pubDate>Thu, 10 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A Design system is a collection of rules, constraints and principles applied to your design and development process. I most often encounter it as a set of rules that control the typography, colours, &lt;a href=&quot;https://medium.com/eightshapes-llc/space-in-design-systems-188bcbae0d62&quot;&gt;spacing&lt;/a&gt;, sizing, icons and other visual styles. These rules form a foundation that guides your work. They reduce inconsistencies in both design and development implementations yet giving you the room to explore creative solutions.&lt;/p&gt;&lt;h2 id=&quot;tachyons-design-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tachyons-design-system&quot; aria-label=&quot;tachyons design system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tachyons Design System&lt;/h2&gt;&lt;p&gt;Tachyons is a functional CSS framework and a design system. If you are new to Tachyons, I suggest starting with Jason Li’s &lt;a href=&quot;http://notebook.hongkonggong.com/2017/12/11/a-tachyons-css-reading-list&quot;&gt;Tachyons CSS Reading List&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;dib&quot;&gt;
  &lt;div class=&quot;h1 bg-black-10 br1 br--top flex items-center&quot;&gt;
    &lt;div style=&quot;width:0.5rem;height:0.5rem&quot; class=&quot;ml2 br-100 bg-light-red&quot;&gt;&lt;/div&gt;
    &lt;div style=&quot;width:0.5rem;height:0.5rem&quot; class=&quot;ml1 br-100 bg-gold&quot;&gt;&lt;/div&gt;
    &lt;div style=&quot;width:0.5rem;height:0.5rem&quot; class=&quot;ml1 br-100 bg-green&quot;&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;a href=&quot;https://tachyons-tldr.now.sh/#/scales&quot; class=&quot;pt3 b0&quot;&gt;
    &lt;img alt=&quot;tachyons design constraints&quot; src=&quot;/999fc3a4138a1d6265d0977640c2adb8/tachyons-design-system.gif&quot; style=&quot;width:400px&quot;/&gt;
  &lt;/a&gt;&lt;/div&gt;&lt;p&gt;The Tachyons design system uses a spacing scale, based on powers of two, which starts at &lt;code class=&quot;language-text&quot;&gt;0.25rem&lt;/code&gt; and modular scale for typography. Other styles such as sizing, borders, opacity and shadows also use scales. It then exposes this design system via a set of &lt;a href=&quot;http://basscss.com/v7/docs/reference/principles/#immutable-utilities&quot;&gt;immutable classes&lt;/a&gt;. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Typographic scale &lt;code class=&quot;language-text&quot;&gt;.f1&lt;/code&gt; – &lt;code class=&quot;language-text&quot;&gt;.f7&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Spacing scale &lt;code class=&quot;language-text&quot;&gt;.ma0&lt;/code&gt; – &lt;code class=&quot;language-text&quot;&gt;.ma7&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;.pa0&lt;/code&gt; – &lt;code class=&quot;language-text&quot;&gt;.pa7&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Widths &lt;code class=&quot;language-text&quot;&gt;.w1&lt;/code&gt; – &lt;code class=&quot;language-text&quot;&gt;.w5&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Max-Widths &lt;code class=&quot;language-text&quot;&gt;.mw1&lt;/code&gt; – &lt;code class=&quot;language-text&quot;&gt;.mw9&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You compose these classes in markup to construct components and layouts, for example, &lt;code class=&quot;language-text&quot;&gt;className=&amp;quot;f2 mt4 mb2&amp;quot;&lt;/code&gt;. You have the option to customize this design system using &lt;a href=&quot;https://github.com/tachyons-css/generator&quot;&gt;tachyons-css/generator&lt;/a&gt;. Alternatively, extend it by writing CSS that follows the same API as that used by Tachyons itself. There are handy tools such as &lt;a href=&quot;https://tachyons-tldr.now.sh/#/tools&quot;&gt;tachyons-tldr&lt;/a&gt; to assist you with this.&lt;/p&gt;&lt;h2 id=&quot;component-based-design-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#component-based-design-system&quot; aria-label=&quot;component based design system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Component-Based Design System&lt;/h2&gt;&lt;p&gt;Having experimented with BEM and modular CSS in the past, I’ve settled on components as my preferred API for a design system. As &lt;a href=&quot;https://medium.learnreact.com/scale-fud-and-style-components-c0ce87ec9772&quot;&gt;Michael Chan&lt;/a&gt; puts it, “components are a more powerful styling construct than CSS class names.” I wholeheartedly agree! In my experience, composing components has been a much better experience than having to write CSS.&lt;/p&gt;&lt;p&gt;Remember, you are the design system author and your users are other developers. Aim to give them a good user experience.&lt;/p&gt;&lt;p&gt;Using Tachyons is not at all like writing BEM or modular CSS. You rarely have to write CSS. Most of the work tends to be composing classes in templates or JSX. I enjoyed this workflow. However, I did find I was repeating specific tasks often. That is where components come in. They allowed me to abstract out some of those repetitive tasks and hide the implementation details.&lt;/p&gt;&lt;p&gt;In this two-part series, I am going to share techniques that I have used for building component-based design systems. Part one focuses on using &lt;a href=&quot;http://tachyons.io&quot;&gt;Tachyons&lt;/a&gt; and part two on using &lt;a href=&quot;http://jxnblk.com/styled-system&quot;&gt;Styled-System&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;tachyons-design-system-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tachyons-design-system-components&quot; aria-label=&quot;tachyons design system components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tachyons Design System Components&lt;/h2&gt;&lt;p&gt;The first, somewhat obvious, approach is to build low-level components that encapsulate styling and allow customization through the &lt;code class=&quot;language-text&quot;&gt;className&lt;/code&gt; prop.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; className &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;bn f6 dim br2 pv3 ph4 white bg-purple &amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; className&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;button className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Button Text&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;PeJowy&quot; title=&quot;basic tachyons-component&quot; height=&quot;200&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;There is a problem with this approach. You won’t always be able to customize the component when using it. For example, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Button className=&amp;quot;f7&amp;quot;&amp;gt;Button Text&amp;lt;/Button&amp;gt;&lt;/code&gt; will work because &lt;code class=&quot;language-text&quot;&gt;.f7&lt;/code&gt; class is declared after &lt;code class=&quot;language-text&quot;&gt;.f6&lt;/code&gt; in the Tachyons stylesheet. However, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Button className=&amp;quot;f1&amp;quot;&amp;gt;Button Text&amp;lt;/Button&amp;gt;&lt;/code&gt; won’t work as intended. The &lt;code class=&quot;language-text&quot;&gt;.f6&lt;/code&gt; class is declared after &lt;code class=&quot;language-text&quot;&gt;.f1&lt;/code&gt; so, it has a higher specificity and will win out.&lt;/p&gt;&lt;div hash=&quot;deVRgj&quot; title=&quot;basic tachyons-components&quot; height=&quot;200&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;design-system-as-props&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#design-system-as-props&quot; aria-label=&quot;design system as props permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Design System As Props&lt;/h3&gt;&lt;p&gt;You can provide your users with a lot more control by exposing the design system as props. I would suggest using the &lt;a href=&quot;https://github.com/JedWatson/classNames&quot;&gt;classNames&lt;/a&gt; library to make generating and joining class names a bit easier.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Button &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  f &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  color &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;white&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  bg &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;purple&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  className&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; cx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;classNames&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;bn dim br2 pv3 ph4&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;f&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    color&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;bg-&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;bg&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    className
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;button className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;cx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Update&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Button bg&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;moon-gray&amp;quot;&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;dark-gray&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      Cancel
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;PeJKzw&quot; title=&quot;tachyons components with design system as props&quot; height=&quot;200&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;props--design-system-️-classname&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#props--design-system-%EF%B8%8F-classname&quot; aria-label=&quot;props  design system ️ classname permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Props 🔀 Design System ➡️ className&lt;/h3&gt;&lt;p&gt;I love this pattern of mapping props onto the Tachyons design system and outputting class names. So, simple yet so effective. It allows you to build extremely reusable components that have base styling applied to them and accept overrides via props. You can choose to limit what is customizable depending on the component you are building.&lt;/p&gt;&lt;p&gt;You might notice a few missing features here such as media query support and type checking props. Plus it is going to be quite cumbersome to have to keep repeating this pattern for all your components.&lt;/p&gt;&lt;h3 id=&quot;withdesignsystem-higher-order-component&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#withdesignsystem-higher-order-component&quot; aria-label=&quot;withdesignsystem higher order component permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;withDesignSystem Higher-Order Component&lt;/h3&gt;&lt;p&gt;You can create a higher-order component (HOC) that encapsulates the functionality of mapping props to the Tachyons design system. See the &lt;a href=&quot;https://codesandbox.io/s/ywwpmp1jy1&quot;&gt;CodeSandbox&lt;/a&gt; below for a sample implementation. &lt;a href=&quot;https://github.com/winkerVSbecks/tachyons-measured#media-query-mq-support&quot;&gt;Tachyons-measured&lt;/a&gt;, while no longer maintained, shows how you can add media query support to this HOC.&lt;/p&gt;&lt;p&gt;You can use this HOC to enhance elements or other components into design system components quickly. A good place to get started is by creating a whole bunch of primitives. These are essentially HTML elements styled in accordance with your product’s design language and enhanced by &lt;code class=&quot;language-text&quot;&gt;withDesignSystem&lt;/code&gt;. For example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Box (general purpose layout component)&lt;/li&gt;&lt;li&gt;Text &amp;amp; Heading&lt;/li&gt;&lt;li&gt;Image &amp;amp; Avatar (circular image)&lt;/li&gt;&lt;li&gt;Button &amp;amp; Link&lt;/li&gt;&lt;li&gt;Input, TextArea &amp;amp; Label&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Beyond that, I would suggest looking at &lt;a href=&quot;http://jxnblk.com/rebass/components&quot;&gt;Rebass’&lt;/a&gt; documentation. It is a fantastic example of the type of low-level primitives you should be building.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Box &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;withStyleProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;div&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Box&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Box&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;withStyleProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;p&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Text&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Heading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;withStyleProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; level &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;h&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; level&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Heading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Heading&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;example&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#example&quot; aria-label=&quot;example permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Example&lt;/h3&gt;&lt;p&gt;Consider this profile card taken from the Tachyons &lt;a href=&quot;http://tachyons.io/components/cards/profile-card-title-subtitle/index.html&quot;&gt;documentation&lt;/a&gt;. You can start by breaking down this layout into its various constituting components. There are many different ways you can approach this. I would personally break this down into: &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Card /&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box/&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Avatar /&amp;gt;&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Heading/&amp;gt;&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Text/&amp;gt;&lt;/code&gt; components.&lt;/p&gt;&lt;figure display=&quot;flex&quot; flexWrap=&quot;wrap&quot; mb=&quot;0&quot;&gt;&lt;img src=&quot;static/tachyons-card-77fa7c77fffff3a35eefecb8d154d23a.png&quot; alt=&quot;tachyons card&quot; mb=&quot;4&quot; style=&quot;width:240px&quot;/&gt;&lt;img src=&quot;static/tachyons-card-slice-ff88515047fd89fa2b69e33036d38cc9.png&quot; alt=&quot;tachyons card slices&quot; mb=&quot;4&quot; style=&quot;width:240px&quot;/&gt;&lt;/figure&gt;&lt;p&gt;As shown above, &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Box/&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Text/&amp;gt;&lt;/code&gt; are enhanced HTML elements. &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Heading/&amp;gt;&lt;/code&gt; is an enhanced component that uses the &lt;code class=&quot;language-text&quot;&gt;level&lt;/code&gt; prop to decide which heading tag to render. &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Card /&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Avatar /&amp;gt;&lt;/code&gt; require a bit more work. Using the &lt;a href=&quot;https://github.com/acdlite/recompose/blob/master/docs/API.md#defaultprops&quot;&gt;defaultProps&lt;/a&gt; HOC from Recompose you can provide some default styling. &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Card /&amp;gt;&lt;/code&gt; is essentially an &lt;code class=&quot;language-text&quot;&gt;&amp;lt;article /&amp;gt;&lt;/code&gt; with a rounded border and some padding. And &lt;code class=&quot;language-text&quot;&gt;&amp;lt;Avatar /&amp;gt;&lt;/code&gt; is a circular image with a border.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Card &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;defaultProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    bg&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;white&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    radius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pa&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ba&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;black-10&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  withStyleProps
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;article&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Card&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Card&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Avatar &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;defaultProps&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    h&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    w&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    ba&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;black-05&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    pa&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    radius&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;-100&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  withStyleProps
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Avatar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Avatar&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lastly, we can compose these components to create the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;ProfileCard /&amp;gt;&lt;/code&gt; component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;ProfileCard&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; title&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; image&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Box tc&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Avatar src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;image&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;Photo of &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;name&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;dib&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Heading f&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; mb&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Heading&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text f&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; fw&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; color&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;gray&amp;quot;&lt;/span&gt; mt&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Box&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Card&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div src=&quot;https://codesandbox.io/embed/ywwpmp1jy1?hidenavigation=1&amp;amp;module=%2Fsrc%2Fwith-style-props%2Fwith-style-props.hoc.js&quot; style=&quot;width:100%;height:530px;border:0;overflow:hidden&quot; sandbox=&quot;allow-modals allow-forms allow-popups allow-scripts allow-same-origin&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;tachyons-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tachyons-components&quot; aria-label=&quot;tachyons components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tachyons-Components&lt;/h3&gt;&lt;p&gt;Not everyone can or even wants to invest time into building a &lt;code class=&quot;language-text&quot;&gt;withDesignSystem&lt;/code&gt; HOC. I had a hard time maintaining tachyons-measured 😊 Luckily; Brent Jackson built a library called &lt;a href=&quot;https://github.com/jxnblk/tachyons-components&quot;&gt;Tachyons-Components&lt;/a&gt; that gives you a slightly different but, faster way of building Tachyons design system components.&lt;/p&gt;&lt;p&gt;Instead of mapping props to the design system, it enables you to apply Tachyons class names directly as props. Using a styled-components like API you can set default styles when creating a component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styled &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;tachyons-components&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Box &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;styled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;div&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Box&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Box&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Text &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;styled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;p&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Text&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Text&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Heading &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;styled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; level &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;h&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; level&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Heading&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Heading&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Card &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;styled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;article&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  bg-white br2 pa3 ba b--black-10
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Card&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Card&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Avatar &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;styled&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
  h4 w4 ba b--black-05 pa2 br-100
&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Avatar&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;displayName &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Avatar&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then apply Tachyons classes as props when using the component to extend or customize its styles. Below you can see the complete profile card example recreated with tachyons-components.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Text f5 fw4 gray mt0&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;title&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Text&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div src=&quot;https://codesandbox.io/embed/xp61ww84mw?view=split&amp;amp;hidenavigation=1&amp;amp;module=%2Fsrc%2Fwith-style-props%2Fwith-style-props.hoc.js&quot; style=&quot;width:100%;height:530px;border:0;overflow:hidden&quot; sandbox=&quot;allow-modals allow-forms allow-popups allow-scripts allow-same-origin&quot;&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;TL;DR use tachyons-components&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Component-based design systems are a fantastic tool to make your product UI more consistent and improve the development workflow. By baking design decisions within the system itself, it reduces the number of decision that developers have to make. Therefore, allowing teams to make changes or build new features faster.&lt;/p&gt;&lt;p&gt;One restriction with Tachyons is that it does come with an opinionated set of design constraints. In &lt;a href=&quot;/styled-system&quot;&gt;part two&lt;/a&gt; I’m going to cover a different tool called Styled-System which gives you full control over defining your design system and uses a similar approach to &lt;code class=&quot;language-text&quot;&gt;withDesignSystem&lt;/code&gt; to expose the design system constraints as props.&lt;/p&gt;&lt;h4 id=&quot;further-reading&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#further-reading&quot; aria-label=&quot;further reading permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Further reading&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://youtu.be/bLgZwFRYTJ4&quot;&gt;Siddharth Kshetrapal - We Need To Talk About Our Frontend Workflow&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrmrs.github.io/writing/2016/04/21/developing-ui&quot;&gt;UI Development As A First Class Citizen&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://www.dropbox.com/sh/ki31bh2j7i0ocv8/AAAMN1BKtAJNxRMl2M0kGJLHa?dl=0&quot;&gt;Design System with Glamorous&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Components]]></title><description><![CDATA[Everything is a component. It took me a surprisingly long time to come to terms with this idea. I learnt to build UIs using templates. These…]]></description><link>https://varun.ca/components/</link><guid isPermaLink="false">https://varun.ca/components/</guid><pubDate>Wed, 09 May 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Everything is a component. It took me a surprisingly long time to come to terms with this idea.&lt;/p&gt;&lt;p&gt;I learnt to build UIs using templates. These templates were driven by routing. The routing structure of the app dictated how the UI was sliced up.&lt;/p&gt;&lt;p&gt;I mostly worked with AngularJS with MVVM architecture. Initially, these views had massive templates. Switching to UI-Router forced me to break them down a bit more; this was because UI-Router supported nested routes. There were some chunks of the UI which fit the component ideology, for example, modals and forms. However, that was rare.&lt;/p&gt;&lt;p&gt;Making the switch to components was hard. There were no apparent boundaries for a view. What is a component? What is the right level at which to slice a component? I struggled with this a lot. I know I am not the only one. I often saw other people taking the template style approach to components. Creating large components that handled everything from design language to UI logic and state.&lt;/p&gt;&lt;p&gt;It turns out we all sort of knew what the right answer was. Designers had been using symbols in design tools to break down the UI and create appropriate abstractions. Developers did the same thing in CSS with BEM and other such techniques. We were all reasoning about the UI in similar ways. We weren’t extending that approach to the way we built it, or at least I wasn’t.&lt;/p&gt;&lt;p width=&quot;451px&quot; mx=&quot;auto&quot; p=&quot;3&quot; bg=&quot;#fff&quot;&gt;
  &lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:902px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:42.708333333333336%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;170\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20170\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M1%2036v16h398V19H1v17m1-1v15h396V21H2v14m-1%2065v16h180V84H1v16m1%200v15h178V85H2v15m-2%2055v15h77v-30H0v15m1%200v14h75v-28H1v14\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;A sign up form with email and password inputs and a sign-up button&quot; title=&quot;A sign up form with email and password inputs and a sign-up button&quot; src=&quot;/static/452e80bd98c05468dc8ac146ec69ef41/58213/signup-form.png&quot; srcSet=&quot;/static/452e80bd98c05468dc8ac146ec69ef41/477c9/signup-form.png 288w,/static/452e80bd98c05468dc8ac146ec69ef41/533c1/signup-form.png 576w,/static/452e80bd98c05468dc8ac146ec69ef41/58213/signup-form.png 902w&quot; sizes=&quot;(max-width: 902px) 100vw, 902px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;
&lt;/p&gt;&lt;p&gt;Everything is a component. The Sign-up form above is a component. The Button, Labels, Inputs and FieldGroups are components too.&lt;/p&gt;&lt;h2 id=&quot;ui-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#ui-system&quot; aria-label=&quot;ui system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;UI System&lt;/h2&gt;&lt;p&gt;Your UI is a system of components; where each component should be flexible, independent, reusable and often stateless. Start small, use a design system and compose variations &amp;amp; complexity.&lt;/p&gt;&lt;p&gt;A well-designed UI system should be composable. Much like functions are composed together to complete more complex tasks. Components can be composed together to create more complex UI patterns. See my &lt;a href=&quot;/flattening-deep-hierarchies-of-components&quot;&gt;previous&lt;/a&gt; blog post for a deeper dive on this subject.&lt;/p&gt;&lt;h2 id=&quot;component-dichotomy&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#component-dichotomy&quot; aria-label=&quot;component dichotomy permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Component Dichotomy&lt;/h2&gt;&lt;p&gt;Like many, I started by applying the concepts of &lt;a href=&quot;http://bradfrost.com/blog/post/atomic-web-design&quot;&gt;Atomic Design&lt;/a&gt; to components; creating a hierarchy of components — atoms, molecules, organisms &amp;amp; containers. In hindsight, these classifications were helpful guides but, not something that was necessary. In some cases, this even introduced unnecessary restrictions. I now use more of an “everything is a composition” approach as outlined in Daniel Eden’s theory of &lt;a href=&quot;https://daneden.me/2018/01/05/subatomic-design-systems&quot;&gt;Subatomic Design Systems&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Design System constraints or variables are the lowest level building blocks. Compose them with HTML/JSX/etc. to create the first set of components. These form the foundation of your component-based design system. Compose them into UI patterns. State is yet another layer of composition.&lt;/p&gt;&lt;p&gt;At some point, these compositions become more &lt;em&gt;aware&lt;/em&gt; of the product that they belong to. A language emerges. A product-specific language shared between designers and developers. Which allows you to discuss ideas using abstracted components and not get lost in the minutia of rems, pixels and hex codes.&lt;/p&gt;&lt;h4 id=&quot;further-reading&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#further-reading&quot; aria-label=&quot;further reading permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Further reading&lt;/h4&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://jxnblk.com/writing/posts/components&quot;&gt;Components&lt;/a&gt; by Brent Jackson&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://mrmrs.github.io/writing/2016/04/21/developing-ui&quot;&gt;Developing UI&lt;/a&gt; by Adam Morse&lt;/li&gt;&lt;li&gt;Chris Biscardi’s &lt;a href=&quot;https://twitter.com/chrisbiscardi/status/976363118656831489&quot;&gt;twitter thread&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[JavaScript Frameworks: The Year of Convergence]]></title><description><![CDATA[If 2016 was the year of JavaScript fatigue then 2017 was most certainly the year of convergence. Most JavaScript frameworks have converged…]]></description><link>https://varun.ca/convergence/</link><guid isPermaLink="false">https://varun.ca/convergence/</guid><pubDate>Sun, 24 Dec 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If 2016 was the year of JavaScript fatigue then 2017 was most certainly the year of convergence. Most JavaScript frameworks have converged towards using similar tooling and concepts.&lt;/p&gt;&lt;p&gt;In this post, I am going to focus on some of the similarities between JavaScript frameworks. I want to show how knowledge of one framework transfers quite well to the others.&lt;/p&gt;&lt;h2 id=&quot;component-based-architecture&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#component-based-architecture&quot; aria-label=&quot;component based architecture permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Component Based Architecture&lt;/h2&gt;&lt;p&gt;If there is one thing &lt;em&gt;everyone&lt;/em&gt; can agree on, it is that components are awesome. Designers love them because it allows them to create a shared language with developers and roll out design systems. Developers love them because it means they can focus on building small, self-contained and reusable features, then composing them to build larger views and the entire application itself. Product managers love them because they enable sharing code across multiple apps.&lt;/p&gt;&lt;p&gt;React popularized the component model for modern front-end development. In the 1.x days, some people in the Angular community started writing &lt;a href=&quot;https://www.airpair.com/angularjs/posts/component-based-angularjs-directives#1-component-based-directives-in-angularjs&quot;&gt;Component-Based Directives&lt;/a&gt;. Then Angular 1.6 introduced &lt;code class=&quot;language-text&quot;&gt;angular.component()&lt;/code&gt; which made it easier to write those directive components. In 2016, with Angular 2.0 we got real components. Meanwhile, Vue was launched with components as one of its core features.&lt;/p&gt;&lt;p&gt;Below are examples of how you would write components with all three frameworks. You’ll notice a lot of similarities.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// React Component&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Welcome&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular Component&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;greet&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;lt;h1&amp;gt;Hello, {{ name }}&amp;lt;/h1&amp;gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WelcomeComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Vue Component&lt;/span&gt;
Vue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;greet&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;name&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;lt;h1&amp;gt;Hello, {{ name }}&amp;lt;/h1&amp;gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are variations available. For example, in React you can write components as functions. Angular and Vue allow you to reference templates defined in HTML files. Vue also allows you to write single-file components where HTML, CSS and JS for your component are all in one &lt;code class=&quot;language-text&quot;&gt;.vue&lt;/code&gt; file (more on that later). However, the core idea of what constitutes a component is the same in all three frameworks.&lt;/p&gt;&lt;h2 id=&quot;defining-the-view&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#defining-the-view&quot; aria-label=&quot;defining the view permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Defining the View&lt;/h2&gt;&lt;p&gt;The &lt;em&gt;view&lt;/em&gt; part of a component is what we want the framework to render when we use the component somewhere in our application. With Angular we define the &lt;em&gt;view&lt;/em&gt; as templates. These are HTML partials that use a mustache/handlebars-like syntax to bind to data — two curly braces wrapping a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions&quot;&gt;JavaScript expression&lt;/a&gt;. These templates also support several built-in components and directives, which allow you to define template logic such as conditional and list rendering.&lt;/p&gt;&lt;p&gt;React uses &lt;a href=&quot;https://facebook.github.io/jsx/&quot;&gt;JSX&lt;/a&gt;, which allows you to define views in JavaScript using XML-like syntax. Bindings work pretty much like templates — single curly brace wrapping an expression. The biggest difference is how we add control statements and template logic. With templates you need to use built-in components and directives; with JSX, however, you just use JavaScript features such as &lt;code class=&quot;language-text&quot;&gt;if&lt;/code&gt; statements, ternary operator or &lt;code class=&quot;language-text&quot;&gt;Array.map&lt;/code&gt;. There is a bit of a learning curve to it, but you’ll be surprised by how much of your knowledge of working with templates translates to JSX.&lt;/p&gt;&lt;p&gt;Vue supports both! Templates in Vue were inspired by Angular. They use pretty much the same components and directives for template logic and the double curly brace syntax for bindings. You can also use JSX with Vue by defining a &lt;a href=&quot;https://vuejs.org/v2/guide/render-function.html#Basics&quot;&gt;render function&lt;/a&gt;, instead of using the template property.&lt;/p&gt;&lt;p&gt;One of the major benefits of JSX is that it allows you to write all the code for a component in one file. That is the view, the JavaScript logic and even styles. Vue supports &lt;a href=&quot;https://vuejs.org/v2/guide/single-file-components.html&quot;&gt;Single File Components&lt;/a&gt;, which allow you to write all the component code in one file. However, you are not limited to using just JavaScript. You can write your view in an HTML template or Pug or just use a render function. Styles can be written in CSS or SCSS or PostCSS, etc.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;f1&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Hello, {{ name }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;
  &lt;span class=&quot;token selector&quot;&gt;.f1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;styling--encapsulation&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#styling--encapsulation&quot; aria-label=&quot;styling  encapsulation permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Styling &amp;amp; Encapsulation&lt;/h2&gt;&lt;p&gt;Styling of components generally comes in three different flavours:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Classic:&lt;/strong&gt; all your CSS is available globally and the components can use any styles.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Encapsulated:&lt;/strong&gt; each component has styles scoped to itself. It doesn’t use any global styles and none of the component styles leak out.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Mix:&lt;/strong&gt; your components rely mostly on scoped styles, but there are also some globally defined defaults that cascade down.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Do you prefer one approach over the others? Good news! All three frameworks support all three approaches. Global CSS just works out of the box. You can use the &lt;code class=&quot;language-text&quot;&gt;class&lt;/code&gt; attribute in templates or the &lt;code class=&quot;language-text&quot;&gt;className&lt;/code&gt; prop in JSX.&lt;/p&gt;&lt;p&gt;Angular also has built-in support for scoping. You can choose from one of three &lt;a href=&quot;https://angular.io/api/core/ViewEncapsulation&quot;&gt;encapsulation&lt;/a&gt; strategies and styles can be run through pre-processors, such as Sass or PostCSS, before loading them in a component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Angular Component&lt;/span&gt;
@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;greet&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;lt;h1 class=&amp;quot;f1&amp;quot;&amp;gt;Hello, {{ name }}&amp;lt;/h1&amp;gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  styleUrls&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;./welcome.component.css&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  encapsulation&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; ViewEncapsulation&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Emulated&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WelcomeComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vue supports scoping through the single file component syntax. Just add the &lt;code class=&quot;language-text&quot;&gt;scoped&lt;/code&gt; attribute to the &lt;code class=&quot;language-text&quot;&gt;style&lt;/code&gt; tag. And similar to Angular, you can set up your build tool to pre-process the CSS before loading it.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;f1&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Hello, {{ name }}&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&quot;&gt;&lt;span class=&quot;token language-javascript&quot;&gt;
  &lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;scoped&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;
  &lt;span class=&quot;token selector&quot;&gt;.f1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/css-modules/css-modules&quot;&gt;CSS Modules&lt;/a&gt; is another popular system for modularizing and scoping CSS. To use CSS Modules with Vue you can add the &lt;code class=&quot;language-text&quot;&gt;module&lt;/code&gt; attribute to the &lt;code class=&quot;language-text&quot;&gt;style&lt;/code&gt; tag.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;h1&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;:class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;$style.f1&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    {% raw %}Hello, {{ name }}{% endraw %}
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;h1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;template&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;style&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token style&quot;&gt;&lt;span class=&quot;token language-css&quot;&gt;
  &lt;span class=&quot;token selector&quot;&gt;.f1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;font-size&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 3rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;style&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;React does not have built in scoping support. However, the React community has many vibrant and innovative solutions for writing component scoped CSS. You can of course, use CSS Modules.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; styles &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;./welcome.css&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Welcome&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;h1 className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;styles&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;f1&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;h1&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More often though, scoped CSS in React is achieved using CSS-in-JS based solutions such as &lt;a href=&quot;https://www.styled-components.com&quot;&gt;styled-components&lt;/a&gt;, &lt;a href=&quot;https://glamorous.rocks/&quot;&gt;glamorous&lt;/a&gt;, &lt;a href=&quot;https://emotion.sh/&quot;&gt;emotion&lt;/a&gt;, and &lt;a href=&quot;https://github.com/MicheleBertoli/css-in-js&quot;&gt;many more&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;If you prefer the CSS-in-JS approach, some popular CSS-in-JS libraries support Vue too, e.g. &lt;a href=&quot;https://github.com/styled-components/vue-styled-components&quot;&gt;styled-components/vue-styled-components&lt;/a&gt; and &lt;a href=&quot;https://github.com/emotion-js/emotion/blob/d5d34c0df2be5bae19d21da4e950b03fae03a1b7/README.md#vue-styled&quot;&gt;emotion — vue styled&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;passing-data-into-a-component&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#passing-data-into-a-component&quot; aria-label=&quot;passing data into a component permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Passing Data Into a Component&lt;/h2&gt;&lt;p&gt;Each instance of a component is isolated. It can, however, receive data from its parent. In React and Vue this concept is known as props. In Angular this is referred to as inputs.&lt;/p&gt;&lt;p&gt;Props and inputs are read-only data that can be used by a component in its view or further pass down to its children. They flow unidirectionally down the component hierarchy. When these props or inputs update, they trigger the components that are receiving them to re-render.&lt;/p&gt;&lt;p&gt;The child component must explicitly declare the props or inputs it expects to receive. We can also specify the types for these props. The &lt;a href=&quot;https://www.npmjs.com/package/prop-types&quot;&gt;PropTypes&lt;/a&gt; library is one way of specifying prop types in React. For example:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;MyComponent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;propTypes &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  optionalArray&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PropTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;array&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  optionalBool&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PropTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;bool&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  requiredFunc&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PropTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;func&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;isRequired&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  optionalNumber&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PropTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;number&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  optionalObject&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PropTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;object&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  optionalEnum&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; PropTypes&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;oneOf&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;News&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;Photos&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;customProp&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; propName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; componentName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vue provides similar support for prop validation.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;Vue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;example&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  props&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    propA&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Number&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    propB&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; Number&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    propC&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; String&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; required&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    propD&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token function-variable function&quot;&gt;validator&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Angular 2+ was created to use with TypeScript primarily. Therefore, it relies on the TypeScript for validating input types. You just need to annotate the input properties with a type.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;WelcomeComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; inputA&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; inputB&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; number&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; inputC&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; MyModelClass&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Input&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; inputC&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; MyFunctionInterface&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This idea of using static type checkers is quite powerful. They generally improve developer workflow by identifying certain issues even before the code is executed. This can be extremely beneficial for larger apps. Therefore, in early 2017 &lt;code class=&quot;language-text&quot;&gt;PropTypes&lt;/code&gt; was moved out of React core. The current official &lt;a href=&quot;https://reactjs.org/docs/static-type-checking.html#flow&quot;&gt;recommendation&lt;/a&gt; (for larger apps) is to use Flow or TypeScript.&lt;/p&gt;&lt;p&gt;TypeScript support for Vue is not as robust as that for Angular and React, but it is improving fast. Microsoft maintains a &lt;a href=&quot;https://github.com/Microsoft/TypeScript-Vue-Starter&quot;&gt;TypeScript-Starter&lt;/a&gt; and there is even an &lt;a href=&quot;https://vuejs.org/v2/guide/typescript.html#Class-Style-Vue-Components&quot;&gt;official library&lt;/a&gt; that allows you to use class style syntax to write a Vue component.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Vue &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;vue&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; Component &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;vue-class-component&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; raw &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;lt;h1&amp;gt;Hello, {{ name }}&amp;lt;/h1&amp;gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt; endraw &lt;span class=&quot;token operator&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;MyComponent&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Vue&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; string&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;events&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#events&quot; aria-label=&quot;events permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Events&lt;/h2&gt;&lt;p&gt;All three frameworks allow you to specify event handlers on components. This allows us to listen to DOM events and execute some JavaScript when they are triggered.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// React&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;button onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;handleClick&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Action&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Angular --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;(click)&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;handleClick($event)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Action&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Vue --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;@click&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;handleClick($event)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Action&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Props and Inputs allow data to flow down into a component, but we quite often want to propagate changes back up the component hierarchy. Angular and Vue allow us to do that by emitting custom events. Components can then bind onto these custom events.&lt;/p&gt;&lt;p&gt;With Vue we can trigger a custom event by using &lt;code class=&quot;language-text&quot;&gt;$emit&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;Vue&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;counter&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;button @click=&amp;quot;increment&amp;quot;&amp;gt;
      {% raw %}{{ count }}{% endraw %}
    &amp;lt;/button&amp;gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  methods&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;$emit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;increment&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With Angular custom events are instances of &lt;code class=&quot;language-text&quot;&gt;EventEmitter&lt;/code&gt; annotated with an &lt;code class=&quot;language-text&quot;&gt;@Output&lt;/code&gt; decorator. To trigger a custom event we call the event emitter’s emit method.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; Component&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; EventEmitter &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;@angular/core&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

@&lt;span class=&quot;token function&quot;&gt;Component&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  selector&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;counter&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  template&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;
    &amp;lt;button (click)=&amp;quot;increment()&amp;quot;&amp;gt;
      {% raw %}{{ count }}{% endraw %}
    &amp;lt;/button&amp;gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;CounterComponent&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;private&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; number &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  @&lt;span class=&quot;token function&quot;&gt;Output&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; increment &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;number&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;increment&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;increment&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;React takes a slightly different approach here. Instead of bubbling up custom events we can pass handlers down as props and call those handlers at the appropriate time.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Counter&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token parameter&quot;&gt;prevState&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; count&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; prevState&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;handleIncrement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;button onClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;I’ve focused primarily on the idea of components here but, similarities extend beyond that. Bundling, state management, reactivity and CLIs are other concepts where frameworks have learnt from each other and ended up picking not too dissimilar solutions. There is even &lt;a href=&quot;https://github.com/TheLarkInn/unity-component-specification&quot;&gt;hope&lt;/a&gt; that someday we will be able to share components across frameworks.&lt;/p&gt;&lt;p&gt;The past few years have been a bit stressful because there seemed to be a new framework to learn every month. People were worried about investing time in the “wrong” framework. Now that things have converged, I am excited to say that investment in any one of those frameworks will pay off. Your knowledge and learning from one framework applies just about everywhere.&lt;/p&gt;&lt;div&gt;This post was first published on &lt;a href=&quot;http://blog.rangle.io/javascript-frameworks-the-year-of-convergence&quot;&gt;blog.rangle.io&lt;/a&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Polar Coordinates 🌀]]></title><description><![CDATA[Cartesian Coordinate System A coordinate system allows us to use numbers to determine the position of points in a 2D or 3D space. The most…]]></description><link>https://varun.ca/polar-coords/</link><guid isPermaLink="false">https://varun.ca/polar-coords/</guid><pubDate>Thu, 23 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h2 id=&quot;cartesian-coordinate-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#cartesian-coordinate-system&quot; aria-label=&quot;cartesian coordinate system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Cartesian Coordinate System&lt;/h2&gt;&lt;p&gt;A coordinate system allows us to use numbers to determine the position of points in a 2D or 3D space. The most popular coordinate system is probably the Cartesian coordinate system. It allows you to locate each point by a pair of numerical coordinates &lt;code class=&quot;language-text&quot;&gt;(x, y)&lt;/code&gt;. There is a very good chance that you have used this system. It is everywhere — SVG, Canvas, WebGL and even Sketch &amp;amp; Illustrator.&lt;/p&gt;&lt;figure mx=&quot;auto&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; display=&quot;block&quot; width=&quot;60%&quot; viewBox=&quot;0 0 228 228&quot; class=&quot;sc-24qoga-1 eFrKCS&quot;&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M227.118 199.307H.346&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#BFBFBF&quot; d=&quot;M221.449 196.472l5.772 2.607a.25.25 0 010 .456l-5.772 2.607 2.834-2.835&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M28.693.882v226.772&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#BFBFBF&quot; d=&quot;M25.858 6.551L28.465.779a.25.25 0 01.456 0l2.607 5.772-2.835-2.834&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#0F0&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M126.888 199.307v-56.693m-98.195 0h98.195&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M126.888 142.614l-98.195 56.693&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M128.277 142.6a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-98.16 56.7a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;139.228&quot; y=&quot;195.173&quot;&gt;(x, y)&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;8&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;124.574&quot; y=&quot;264.606&quot;&gt;x&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;8&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;17.868&quot; y=&quot;199.391&quot;&gt;y&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;10&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;131.518&quot; y=&quot;196.253&quot;&gt;P&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;10&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;19.892&quot; y=&quot;263.269&quot;&gt;O&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;/svg&gt;&lt;figcaption font-family=&quot;code&quot;&gt;&lt;b&gt;Figure 1:&lt;/b&gt; Cartesian coordinate system&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id=&quot;polar-coordinate-system&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#polar-coordinate-system&quot; aria-label=&quot;polar coordinate system permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Polar Coordinate System&lt;/h2&gt;&lt;p&gt;Polar coordinate system is a 2D coordinate system in which each point is determined by &lt;code class=&quot;language-text&quot;&gt;r&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;θ&lt;/code&gt;. Where &lt;code class=&quot;language-text&quot;&gt;r&lt;/code&gt; is the distance from the origin and &lt;code class=&quot;language-text&quot;&gt;θ&lt;/code&gt; is the angle from the x-axis.&lt;/p&gt;&lt;figure mx=&quot;auto&quot;&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; display=&quot;block&quot; width=&quot;70%&quot; viewBox=&quot;0 0 228 228&quot; class=&quot;sc-24qoga-1 oevSK&quot;&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M227.118 114.268H.346&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#BFBFBF&quot; d=&quot;M221.449 111.433l5.772 2.607a.25.25 0 010 .456l-5.772 2.606 2.834-2.834&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M113.732.882v226.772&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#BFBFBF&quot; d=&quot;M110.898 6.551l2.606-5.772a.25.25 0 01.456 0l2.607 5.772-2.835-2.834&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#000&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M170.413 114.22c0-31.294-25.399-56.693-56.693-56.693-31.294 0-56.693 25.399-56.693 56.693 0 31.294 25.399 56.693 56.693 56.693 31.294 0 56.693-25.399 56.693-56.693&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#0F0&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M162.831 114.268V85.921m-49.099 0h49.099&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M162.831 85.921l-49.099 28.347&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M164.277 85.9a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-49.14 28.38a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;131.655&quot; y=&quot;165.773&quot;&gt;θ = 30°&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;122.07&quot; y=&quot;149.942&quot;&gt;r = 2&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;8&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;160.549&quot; y=&quot;179.588&quot;&gt;x&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;8&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;102.947&quot; y=&quot;142.732&quot;&gt;y&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;10&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;167.433&quot; y=&quot;139.534&quot;&gt;P&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;10&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;104.911&quot; y=&quot;178.19&quot;&gt;O&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M127.906 114.268c0-2.488-.655-4.932-1.899-7.087&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;figcaption font-family=&quot;code&quot;&gt;&lt;b&gt;Figure 2:&lt;/b&gt; Polar coordinate system&lt;/figcaption&gt;&lt;/figure&gt;&lt;h3 id=&quot;converting-between-polar-and-cartesian-coordinates&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#converting-between-polar-and-cartesian-coordinates&quot; aria-label=&quot;converting between polar and cartesian coordinates permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Converting Between Polar and Cartesian Coordinates&lt;/h3&gt;&lt;p&gt;Trigonometry! Love it or hate, it is everywhere. You can convert a point from polar coordinates &lt;code class=&quot;language-text&quot;&gt;(r, θ)&lt;/code&gt; to Cartesian coordinates &lt;code class=&quot;language-text&quot;&gt;(x, y)&lt;/code&gt; using the equations below. These come in really handy since most tools only accept &lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;y&lt;/code&gt; as point locations.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;patterns&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#patterns&quot; aria-label=&quot;patterns permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Patterns&lt;/h2&gt;&lt;p&gt;Below I have a few animations by &lt;a href=&quot;https://dribbble.com/beesandbombs&quot;&gt;Dave Whyte&lt;/a&gt; aka bees &amp;amp; bombs. They all have one thing in common, they use polar coordinates to generate a pattern.&lt;/p&gt;&lt;div as=&quot;figure&quot; flexWrap=&quot;wrap&quot; justifyContent=&quot;space-evenly&quot; mx=&quot;0&quot; my=&quot;5&quot;&gt;&lt;img width=&quot;8rem&quot; height=&quot;6rem&quot; src=&quot;//cdn.dribbble.com/users/583436/screenshots/1735131/bubbles2.gif&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 fZwYcE&quot;/&gt;&lt;img width=&quot;8rem&quot; height=&quot;6rem&quot; src=&quot;//cdn.dribbble.com/users/583436/screenshots/1702158/spiraldots.gif&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 fZwYcE&quot;/&gt;&lt;img width=&quot;8rem&quot; height=&quot;6rem&quot; src=&quot;//cdn.dribbble.com/users/583436/screenshots/1660784/spins.gif&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 fZwYcE&quot;/&gt;&lt;img width=&quot;8rem&quot; height=&quot;6rem&quot; src=&quot;//cdn.dribbble.com/users/583436/screenshots/1570346/spiralbig.gif&quot; display=&quot;block&quot; class=&quot;sc-24qoga-0 sc-12f03xz-0 fZwYcE&quot;/&gt;&lt;figcaption font-family=&quot;code&quot; width=&quot;100%&quot;&gt;&lt;b&gt;Figure 3:&lt;/b&gt; Patterns generated using polar coordinates&lt;/figcaption&gt;&lt;/div&gt;&lt;p&gt;Cartesian coordinates are a great choice for placing things evenly on a rectangular grid. However, if you want to distribute things evenly around a circle then polar coordinates are generally the better option. Keeping the radius constant we compute the angle for each point as &lt;code class=&quot;language-text&quot;&gt;angle = 360° * index / number of sides&lt;/code&gt;.&lt;/p&gt;&lt;figure&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; display=&quot;block&quot; width=&quot;60%&quot; viewBox=&quot;0 0 198 192&quot; class=&quot;sc-24qoga-1 bhiOZD&quot;&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#0F0&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M105.867 95.28c0-3.912-3.175-7.087-7.087-7.087s-7.087 3.175-7.087 7.087 3.175 7.087 7.087 7.087 7.087-3.175 7.087-7.087m7.026 0c0-7.824-6.349-14.173-14.173-14.173S84.547 87.456 84.547 95.28s6.349 14.173 14.173 14.173 14.173-6.349 14.173-14.173m7.087 0c0-11.735-9.525-21.26-21.26-21.26-11.735 0-21.26 9.525-21.26 21.26 0 11.735 9.525 21.26 21.26 21.26 11.735 0 21.26-9.525 21.26-21.26m7.086 0c0-15.647-12.699-28.346-28.346-28.346S70.374 79.633 70.374 95.28s12.699 28.346 28.346 28.346 28.346-12.699 28.346-28.346m7.087 0c0-19.559-15.874-35.433-35.433-35.433-19.559 0-35.433 15.874-35.433 35.433 0 19.559 15.874 35.433 35.433 35.433 19.559 0 35.433-15.874 35.433-35.433m7.087 0c0-23.471-19.049-42.52-42.52-42.52-23.471 0-42.52 19.049-42.52 42.52 0 23.471 19.049 42.52 42.52 42.52 23.471 0 42.52-19.049 42.52-42.52m7.086 0c0-27.383-22.223-49.606-49.606-49.606-27.383 0-49.606 22.223-49.606 49.606 0 27.383 22.223 49.606 49.606 49.606 27.383 0 49.606-22.223 49.606-49.606m7.087-.06c0-31.294-25.399-56.693-56.693-56.693-31.294 0-56.693 25.399-56.693 56.693 0 31.294 25.399 56.693 56.693 56.693 31.294 0 56.693-25.399 56.693-56.693&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M183.772 95.268h-85.04&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;187.153&quot; y=&quot;100.212&quot;&gt;360°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M172.379 52.748l-73.647 42.52&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;176.455&quot; y=&quot;53.394&quot;&gt;30°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M141.252 21.621l-42.52 73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;142.196&quot; y=&quot;19.195&quot;&gt;60°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M98.732 10.228v85.04&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;95.438&quot; y=&quot;7&quot;&gt;90°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M56.213 21.621l42.519 73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;46.881&quot; y=&quot;19.195&quot;&gt;120°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M25.085 52.748l73.647 42.52&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;12.621&quot; y=&quot;53.394&quot;&gt;150°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M13.693 95.268h85.039&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;0.064&quot; y=&quot;100.212&quot;&gt;180°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M25.085 137.787l73.647-42.519&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;12.621&quot; y=&quot;146.969&quot;&gt;210°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M56.213 168.915l42.519-73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;46.881&quot; y=&quot;181.229&quot;&gt;240°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M98.732 180.307V95.268&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;93.638&quot; y=&quot;193.726&quot;&gt;270°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M141.252 168.915l-42.52-73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;140.396&quot; y=&quot;181.229&quot;&gt;300°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M172.379 137.787L98.732 95.268&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;174.655&quot; y=&quot;146.969&quot;&gt;330°&lt;/tspan&gt;&lt;/text&gt;&lt;path fill=&quot;#000&quot; d=&quot;M156.837 95.28a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-7.56-28.38a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-20.76-20.7a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-28.38-7.62a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-28.32 7.62a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-20.76 20.7a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-7.62 28.38a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m7.62 28.32a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m20.76 20.76a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m28.32 7.62a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m28.38-7.62a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m20.76-20.76a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-1.2-41.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-12.84-22.26a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-22.26-12.84a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-25.68 0a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-22.26 12.84a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-12.84 22.26a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m0 25.68a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m12.84 22.2a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m22.26 12.84a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m25.68 0a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m22.26-12.84a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m12.84-22.2a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-11.1-34.08a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-15.54-15.6a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-21.3-5.7a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-21.24 5.7a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-15.54 15.6a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-5.76 21.24a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m5.76 21.24a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m15.54 15.6a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m21.24 5.64a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m21.3-5.64a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m15.54-15.6a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m5.7-21.24a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-17.46-25.08a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-15.9-9.18a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-18.36 0a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-15.84 9.18a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-9.18 15.9a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m0 18.36a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m9.18 15.9a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m15.84 9.12a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m18.36 0a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m15.9-9.12a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m9.18-15.9a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m0-18.36a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-20.04-15.36a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-14.22-3.84a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-14.16 3.84a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-10.38 10.38a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-3.78 14.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m3.78 14.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m10.38 10.38a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m14.16 3.78a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m14.22-3.78a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m10.32-10.38a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m3.84-14.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-3.84-14.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-19.02-6.36a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-10.98 0a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-9.54 5.46a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-5.52 9.54a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m0 11.04a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m5.52 9.48a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m9.54 5.52a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m10.98 0a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m9.54-5.52a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m5.52-9.48a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m0-11.04a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-5.52-9.54a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-15.06.9a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-7.08 1.86a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-5.16 5.22a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-1.92 7.08a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m1.92 7.08a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m5.16 5.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m7.08 1.92a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m7.08-1.92a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m5.22-5.16a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m1.92-7.08a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-1.92-7.08a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-5.22-5.22a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;figcaption font-family=&quot;code&quot;&gt;&lt;b&gt;Figure 4:&lt;/b&gt; Placing items evenly around a circle&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Below is the JavaScript implementation of this idea. The &lt;code class=&quot;language-text&quot;&gt;points&lt;/code&gt; function also accepts an optional &lt;code class=&quot;language-text&quot;&gt;offset&lt;/code&gt; argument to shift the points along the perimeter of the circle. For example, the outermost circle of points in &lt;strong&gt;Figure 4&lt;/strong&gt; can be generated using &lt;code class=&quot;language-text&quot;&gt;points(12, 200)&lt;/code&gt;. The next one inwards using &lt;code class=&quot;language-text&quot;&gt;points(12, 175, 15)&lt;/code&gt;. The one after that using &lt;code class=&quot;language-text&quot;&gt;points(12, 150, 30)&lt;/code&gt; and so on. My &lt;a href=&quot;https://codepen.io/winkerVSbecks/pen/oLmqQo&quot;&gt;splash&lt;/a&gt; CodePen is was built using this.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;count&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;360&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; count&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; vertexIndices &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; vertexIndices&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;index&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      theta&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; offset &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;degreesToRadians&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;offset &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; angle &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; index&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      r&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; radius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// number =&amp;gt; [0, 1, 2, ... number]&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;range&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; Array&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;count&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;degreesToRadians&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;angleInDegrees&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; angleInDegrees&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;180&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;polygon-generator&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#polygon-generator&quot; aria-label=&quot;polygon generator permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Polygon Generator&lt;/h2&gt;&lt;p&gt;A regular polygon is a polygon that is equiangular i.e., all its angles are equal and all its sides have the same length. This means that all the vertices of a regular polygon are points evenly spaced on a circle. And isn’t it handy that we just created a function that generates exactly this!&lt;/p&gt;&lt;figure&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; display=&quot;block&quot; width=&quot;60%&quot; viewBox=&quot;0 0 198 192&quot; class=&quot;sc-24qoga-1 bhiOZD&quot;&gt;&lt;defs&gt;&lt;path id=&quot;a&quot; d=&quot;M76.889 90.401H18.575L.555 34.938 47.732.661l47.177 34.277z&quot;&gt;&lt;/path&gt;&lt;/defs&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#0F0&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M105.867 95.28c0-3.912-3.175-7.087-7.087-7.087s-7.087 3.175-7.087 7.087 3.175 7.087 7.087 7.087 7.087-3.175 7.087-7.087m7.026 0c0-7.824-6.349-14.173-14.173-14.173S84.547 87.456 84.547 95.28s6.349 14.173 14.173 14.173 14.173-6.349 14.173-14.173m7.087 0c0-11.735-9.525-21.26-21.26-21.26-11.735 0-21.26 9.525-21.26 21.26 0 11.735 9.525 21.26 21.26 21.26 11.735 0 21.26-9.525 21.26-21.26m7.086 0c0-15.647-12.699-28.346-28.346-28.346S70.374 79.633 70.374 95.28s12.699 28.346 28.346 28.346 28.346-12.699 28.346-28.346m7.087 0c0-19.559-15.874-35.433-35.433-35.433-19.559 0-35.433 15.874-35.433 35.433 0 19.559 15.874 35.433 35.433 35.433 19.559 0 35.433-15.874 35.433-35.433m7.087 0c0-23.471-19.049-42.52-42.52-42.52-23.471 0-42.52 19.049-42.52 42.52 0 23.471 19.049 42.52 42.52 42.52 23.471 0 42.52-19.049 42.52-42.52m7.086 0c0-27.383-22.223-49.606-49.606-49.606-27.383 0-49.606 22.223-49.606 49.606 0 27.383 22.223 49.606 49.606 49.606 27.383 0 49.606-22.223 49.606-49.606m7.087-.06c0-31.294-25.399-56.693-56.693-56.693-31.294 0-56.693 25.399-56.693 56.693 0 31.294 25.399 56.693 56.693 56.693 31.294 0 56.693-25.399 56.693-56.693&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M183.772 95.268h-85.04&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;187.153&quot; y=&quot;100.212&quot;&gt;360°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M172.379 52.748l-73.647 42.52&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;176.455&quot; y=&quot;53.394&quot;&gt;30°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M141.252 21.621l-42.52 73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;142.196&quot; y=&quot;19.195&quot;&gt;60°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M98.732 10.228v85.04&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;95.438&quot; y=&quot;7&quot;&gt;90°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M56.213 21.621l42.519 73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;46.881&quot; y=&quot;19.195&quot;&gt;120°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M25.085 52.748l73.647 42.52&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;12.621&quot; y=&quot;53.394&quot;&gt;150°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M13.693 95.268h85.039&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;0.064&quot; y=&quot;100.212&quot;&gt;180°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M25.085 137.787l73.647-42.519&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;12.621&quot; y=&quot;146.969&quot;&gt;210°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M56.213 168.915l42.519-73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;46.881&quot; y=&quot;181.229&quot;&gt;240°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M98.732 180.307V95.268&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;93.638&quot; y=&quot;193.726&quot;&gt;270°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M141.252 168.915l-42.52-73.647&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;140.396&quot; y=&quot;181.229&quot;&gt;300°&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M172.379 137.787L98.732 95.268&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;6&quot; transform=&quot;translate(0 -3)&quot;&gt;&lt;tspan x=&quot;174.655&quot; y=&quot;146.969&quot;&gt;330°&lt;/tspan&gt;&lt;/text&gt;&lt;g transform=&quot;translate(51 45)&quot;&gt;&lt;use xlink:href=&quot;#a&quot; fill=&quot;#fff&quot; stroke=&quot;#333&quot;&gt;&lt;/use&gt;&lt;mask id=&quot;b&quot; fill=&quot;#fff&quot;&gt;&lt;use xlink:href=&quot;#a&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;path stroke=&quot;#333&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; stroke-width=&quot;0.499&quot; d=&quot;M76.889 90.401H18.575L.555 34.938 47.732.661l47.177 34.277-18.02 55.463zm-312.621-40.133L47.732-233.196-235.732 50.268zm3.006 3.006L50.738-230.19-232.726 53.274zm3.007 3.007L53.745-227.183-229.719 56.281zm3.007 3.007L56.751-224.176-226.712 59.288zm3.006 3.006L59.758-221.17-223.706 62.294zm3.007 3.007L62.765-218.163-220.699 65.301zm3.006 3.006L65.771-215.157-217.693 68.307zm3.007 3.007L68.778-212.15-214.686 71.314zm3.006 3.006L71.784-209.143-211.68 74.32zm3.007 3.007L74.791-206.137-208.673 77.327zm3.007 3.007L77.798-203.13-205.666 80.334zm3.006 3.006L80.804-200.124-202.66 83.34zm3.007 3.007L83.811-197.117-199.653 86.347zm3.006 3.006L86.817-194.11-196.647 89.353zm3.007 3.007L89.824-191.104-193.64 92.36zm3.007 3.007L92.83-188.097-190.633 95.367zm3.006 3.006L95.837-185.091-187.627 98.373zm3.007 3.007L98.844-182.084-184.62 101.38zm3.006 3.006L101.85-179.077l-283.464 283.463zm3.007 3.007l283.464-283.464-283.464 283.464zm3.007 3.007l283.463-283.464L-175.6 110.4zm3.006 3.006L110.87-170.058l-283.464 283.464zm3.007 3.007l283.464-283.464-283.464 283.464zm3.006 3.006l283.464-283.463-283.464 283.463zm3.007 3.007L119.89-161.038l-283.464 283.464zm3.007 3.007l283.463-283.464-283.463 283.464zm3.006 3.006l283.464-283.464-283.464 283.464zm3.007 3.007L128.91-152.018l-283.464 283.464zm3.006 3.006l283.464-283.463-283.464 283.463zm3.007 3.007l283.464-283.464-283.464 283.464zm3.007 3.007l283.463-283.464-283.463 283.464zm3.006 3.006l283.464-283.464-283.464 283.464zm3.007 3.007l283.464-283.464-283.464 283.464zm3.006 3.006l283.464-283.463-283.464 283.463zm3.007 3.007l283.464-283.464-283.464 283.464zm3.007 3.007l283.463-283.464-283.463 283.464zm3.006 3.006l283.464-283.464-283.464 283.464zm3.007 3.007l283.464-283.464-283.464 283.464zm3.006 3.006l283.464-283.463-283.464 283.463zm3.007 3.007l283.464-283.464-283.464 283.464zm3.007 3.007l283.463-283.464-283.463 283.464zm3.006 3.006l283.464-283.464-283.464 283.464zm3.007 3.007l283.464-283.464-283.464 283.464zm3.006 3.006l283.464-283.463-283.464 283.463zm3.007 3.007l283.464-283.464-283.464 283.464zm3.007 3.007L183.028-97.899l-283.463 283.464zm3.006 3.006L186.035-94.893-97.429 188.571zm3.007 3.007L189.042-91.886-94.422 191.578zm3.006 3.006L192.048-88.879-91.416 194.584zm3.007 3.007L195.055-85.873-88.409 197.591zm3.007 3.007L198.061-82.866-85.402 200.598zm3.006 3.006L201.068-79.86-82.396 203.604zm3.007 3.007L204.075-76.853-79.389 206.611zm3.006 3.006L207.081-73.846-76.383 209.617zm3.007 3.007L210.088-70.84-73.376 212.624zm3.007 3.007L213.094-67.833-70.369 215.631zm3.006 3.006L216.101-64.827-67.363 218.637zm3.007 3.007L219.108-61.82-64.356 221.644zm3.006 3.006L222.114-58.814-61.35 224.65zm3.007 3.007L225.121-55.807-58.343 227.657zm3.006 3.006L228.127-52.8-55.337 230.663zm3.007 3.007L231.134-49.794-52.33 233.67zm3.007 3.007L234.141-46.787-49.323 236.677zm3.006 3.006L237.147-43.781-46.317 239.683zm3.007 3.007L240.154-40.774-43.31 242.69zm3.006 3.006L243.16-37.767-40.304 245.696zm3.007 3.007L246.167-34.761-37.297 248.703zm3.007 3.007L249.173-31.754-34.29 251.71zm3.006 3.006L252.18-28.748-31.284 254.716zm3.007 3.007L255.187-25.741-28.277 257.723zm3.006 3.006L258.193-22.734-25.271 260.729zm3.007 3.007L261.2-19.728-22.264 263.736zm3.007 3.007L264.206-16.721-19.257 266.743zm3.006 3.006L267.213-13.715-16.251 269.749zm3.007 3.007L270.219-10.708-13.244 272.756zm3.006 3.006L273.226-7.702-10.238 275.762zm3.007 3.007L276.233-4.695-7.231 278.769zm3.006 3.006L279.239-1.688-4.225 281.775zm3.007 3.007L282.246 1.318-1.218 284.782zm3.007 3.007L285.253 4.325 1.789 287.789zm3.006 3.006L288.259 7.331 4.795 290.795zm3.007 3.007L291.266 10.338 7.802 293.802zm3.006 3.006L294.272 13.345 10.808 296.808zm3.007 3.007L297.279 16.351 13.815 299.815zm3.007 3.007L300.285 19.358 16.822 302.822zm3.006 3.006L303.292 22.364 19.828 305.828zm3.007 3.007L306.299 25.371 22.835 308.835zm3.006 3.006L309.305 28.378 25.841 311.841zm3.007 3.007L312.312 31.384 28.848 314.848zm3.007 3.007L315.318 34.391 31.855 317.855zm3.006 3.006L318.325 37.397 34.861 320.861zm3.007 3.007L321.332 40.404 37.868 323.868zm3.006 3.006L324.338 43.41 40.874 326.874zm3.007 3.007L327.345 46.417 43.881 329.881zm3.006 3.006L330.351 49.424 46.887 332.887z&quot; mask=&quot;url(#b)&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;figcaption font-family=&quot;code&quot;&gt;&lt;b&gt;Figure 5:&lt;/b&gt; Drawing a polygon by connecting polar coordinates&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;To generate an SVG polygon we will generate the list of of points using the &lt;code class=&quot;language-text&quot;&gt;points&lt;/code&gt; function and then simply connect the dots. With SVG we have two options for this: &lt;code class=&quot;language-text&quot;&gt;&amp;lt;polygon&amp;gt;&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;&amp;lt;path&amp;gt;&lt;/code&gt;. The example below generates the &lt;em&gt;points&lt;/em&gt; attribute for a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;polygon&amp;gt;&lt;/code&gt; element.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * Usage with Vanilla JS/DOM:
 *   polygonEl.setAttribute(&amp;#x27;points&amp;#x27;, polygon((5, 64, 18)));
 *
 * Usage with React:
 *   &amp;lt;polygon points={polygon((5, 64, 18)} /&amp;gt;
 *
 * Usage with View:
 *   &amp;lt;polygon :points=&amp;quot;polygon((5, 64, 18)&amp;quot; /&amp;gt;
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;polygon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;noOfSides&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; circumradius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotation&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;noOfSides&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; circumradius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;toCartesian&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toCartesian&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; theta &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Seems simple but, you can do a lot of interesting things with it. Here are a couple of examples:&lt;/p&gt;&lt;figure&gt;
  &lt;img src=&quot;/e511098f5fa0a716f33f76e8ecd6f0f0/gems.gif&quot; width=&quot;400px&quot; mb=&quot;0&quot;/&gt;
  &lt;figcaption&gt;
    &lt;a href=&quot;http://winkervsbecks.github.io/gems/&quot;&gt;
      Gems generated using polar coordinates
    &lt;/a&gt;
  &lt;/figcaption&gt;&lt;/figure&gt;&lt;div hash=&quot;PmNJpJ&quot; title=&quot;Hex-a-portal (Dynamic + RGB)&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;relative-polar-coordinates&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#relative-polar-coordinates&quot; aria-label=&quot;relative polar coordinates permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Relative Polar Coordinates&lt;/h2&gt;&lt;p&gt;When you define a point as &lt;code class=&quot;language-text&quot;&gt;(r, θ)&lt;/code&gt;, by default, this is relative to the origin &lt;code class=&quot;language-text&quot;&gt;(0, 0)&lt;/code&gt;. We can define points relative to other points by shifting the origin. This is often used for defining the position of curve handles relative to a vertex.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cy &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;figure&gt;&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; display=&quot;block&quot; width=&quot;90%&quot; viewBox=&quot;0 0 511 370&quot; class=&quot;sc-24qoga-1 cfTpVZ&quot;&gt;&lt;g fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;path stroke=&quot;#0F0&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M274.182 341.307V199.575m-245.489 0h245.489&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#404040&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M510.583 341.307H.346&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#404040&quot; d=&quot;M504.913 338.472l5.773 2.607a.25.25 0 010 .456l-5.773 2.607 2.835-2.835&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#404040&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M28.693 1.15v368.504&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#404040&quot; d=&quot;M25.858 6.819l2.607-5.772a.25.25 0 01.456 0l2.607 5.772-2.835-2.835&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M510.583 199.575H274.182&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-dasharray=&quot;8.504 5.669&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M359.259 199.58c0-46.942-38.097-85.039-85.039-85.039s-85.039 38.097-85.039 85.039 38.097 85.039 85.039 85.039 85.039-38.097 85.039-85.039&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#BFBFBF&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M274.182 199.575L28.693 341.307&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M316.701 125.928l-42.519 73.647&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#000&quot; d=&quot;M30.117 341.3a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m245.46-141.72a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m42.54-73.62a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002m-42.54 215.34a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002M30.117 199.58a1.418 1.418 0 10-2.836.002 1.418 1.418 0 002.836-.002&quot;&gt;&lt;/path&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;291.043&quot; y=&quot;246.104&quot;&gt;60 deg&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;249.432&quot; y=&quot;214.813&quot;&gt;r = 3&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;267.162&quot; y=&quot;406.567&quot;&gt;cx&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;13.167&quot; y=&quot;256.333&quot;&gt;cy&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;317.728&quot; y=&quot;176.036&quot;&gt;P&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;19.265&quot; y=&quot;404.93&quot;&gt;O&lt;/tspan&gt;&lt;/text&gt;&lt;text fill=&quot;#000&quot; font-family=&quot;CourierCE, Courier&quot; font-size=&quot;12&quot; transform=&quot;translate(0 -55)&quot;&gt;&lt;tspan x=&quot;277&quot; y=&quot;266&quot;&gt;C&lt;/tspan&gt;&lt;/text&gt;&lt;path stroke=&quot;#F0F&quot; stroke-linecap=&quot;round&quot; stroke-linejoin=&quot;round&quot; d=&quot;M288.355 199.575c0-5.064-2.701-9.743-7.087-12.275&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;figcaption font-family=&quot;code&quot;&gt;&lt;b&gt;Figure 6:&lt;/b&gt; Relative polar coordinates&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;We can modify the polygon generator to allow us to draw a polygon centred at any location in the SVG canvas.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;polygon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;noOfSides&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; circumradius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotation&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cx &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cy &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;points&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;noOfSides&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; circumradius&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; rotation&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;pt&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toCartesian&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;pt&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cy&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;toCartesian&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; theta &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cx&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cy&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;cx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; cy &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;wrZQQm&quot; title=&quot;SVG Polygon Generator&quot; height=&quot;700&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;rotation&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#rotation&quot; aria-label=&quot;rotation permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Rotation&lt;/h2&gt;&lt;p&gt;Another common application of polar coordinates is to rotate things around a point. Here &lt;code class=&quot;language-text&quot;&gt;(cx, cy)&lt;/code&gt; is the point about which you want to rotate.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cy &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// somewhere in an animation loop&lt;/span&gt;
window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setInterval&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  theta&lt;span class=&quot;token operator&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;aOEeXB&quot; title=&quot;Rocket around the moon&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;polar-curves&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#polar-curves&quot; aria-label=&quot;polar curves permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Polar curves&lt;/h2&gt;&lt;p&gt;We started by looking at individual points. Then we grouped a few points into a &lt;a href=&quot;https://en.wikipedia.org/wiki/Set_(mathematics)&quot;&gt;set&lt;/a&gt; to define shapes. For this we used the polygon generator function to compute the location of each vertex of the shape. We can write similar functions using other mathematical equations. Allowing us to generate more complex shapes and curves.&lt;/p&gt;&lt;p&gt;Two dimensional curves are described by equations of the type &lt;code class=&quot;language-text&quot;&gt;y = f(x)&lt;/code&gt;. For example the equation of a circle is &lt;code&gt;x&lt;sup&gt;2&lt;/sup&gt; + y&lt;sup&gt;2&lt;/sup&gt; = r&lt;sup&gt;2&lt;/sup&gt;&lt;/code&gt;. We can generate the set of points, called &lt;a href=&quot;https://en.wikipedia.org/wiki/Locus_(mathematics)&quot;&gt;locus&lt;/a&gt;, by iterating &lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt; and computing the corresponding &lt;code class=&quot;language-text&quot;&gt;y&lt;/code&gt; value or vice-versa. Therefore, each point will be of the form &lt;code class=&quot;language-text&quot;&gt;(x, f(x))&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;(g(y), y)&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;With polar coordinates we can similarly draw polar curves. For example, the polar equation of a circle is &lt;code class=&quot;language-text&quot;&gt;r = 2 * cos(0)&lt;/code&gt;. The points on a polar curve have the form &lt;code class=&quot;language-text&quot;&gt;(r(0), 0)&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// examples of fn:&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//   circle     : 2 * Math.cos(theta)&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;//   blob thing : a * (1 - Math.cos(theta) * Math.sin(3 * theta))&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cx &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cy &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;theta&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;pdVLPo&quot; title=&quot;Cardioid&quot; height=&quot;600&quot; defaultTab=&quot;js,result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;eukleides&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#eukleides&quot; aria-label=&quot;eukleides permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Eukleides&lt;/h2&gt;&lt;p&gt;All the diagrams in this post were created using a language called &lt;a href=&quot;http://www.eukleides.org&quot;&gt;eukleides&lt;/a&gt;. It is a fantastic tool for making geometric drawings. Just look at this declarative API 😍&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;c = circle(point(3, 0), 3)
P = point(c, 170°)
M = point(0, 0)
N = point(6, 0)

draw (M.N.P)
label M, P, N right, 0.6&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Animating Clipped Shapes]]></title><description><![CDATA[Another  #postAboutYourPen  post. This time I'm going to explain how I recreated Herry Koo's  SA 15  dribbble shot using SVG and animejs…]]></description><link>https://varun.ca/clip-path/</link><guid isPermaLink="false">https://varun.ca/clip-path/</guid><pubDate>Tue, 31 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;gXOdEL&quot; title=&quot;SA 15&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;Another &lt;a href=&quot;http://postaboutyourpen.online/&quot;&gt;#postAboutYourPen&lt;/a&gt; post. This time I’m going to explain how I recreated Herry Koo’s &lt;a href=&quot;https://dribbble.com/shots/3478023-SA-15&quot;&gt;SA 15&lt;/a&gt; dribbble shot using SVG and animejs.&lt;/p&gt;&lt;h2 id=&quot;the-ingredients&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-ingredients&quot; aria-label=&quot;the ingredients permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Ingredients&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;2 Arc Slices&lt;/li&gt;&lt;li&gt;2 Clipped Rectangles&lt;/li&gt;&lt;li&gt;1 Circle&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;An &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Arcs&quot;&gt;arc&lt;/a&gt; is a section of circle or an ellipse. To create this arc you need the starting point, the end point and the radius of the circle that these two points are on. There are two circles that can connect any two points: a big one and a small one. SVG allows us to pick which one we want using the &lt;code class=&quot;language-text&quot;&gt;large-arc-flag&lt;/code&gt;. We can also control whether the arc should be drawn clockwise or anti-clockwise using the &lt;code class=&quot;language-text&quot;&gt;sweep-flag&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;A rx ry x-axis-rotation large-arc-flag sweep-flag x y&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dribbble shots are &lt;code class=&quot;language-text&quot;&gt;800 x 600px&lt;/code&gt; so that’s what I picked for the &lt;code class=&quot;language-text&quot;&gt;vieBox&lt;/code&gt;. This makes it easy to open the gif in Preview, measure stuff and use those values in the SVG. I measured the circle to be &lt;code class=&quot;language-text&quot;&gt;113px&lt;/code&gt;. The left slice was &lt;code class=&quot;language-text&quot;&gt;154px&lt;/code&gt; wide and the right slice &lt;code class=&quot;language-text&quot;&gt;72px&lt;/code&gt;. With a bit of trial and error I found the start and end-points of the arcs. I drew the arcs using the &lt;code class=&quot;language-text&quot;&gt;path&lt;/code&gt; element.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!--
  Move to the starting point then draw an arc to the end point
  and close the shape by going back to the starting point

  M start_x start_y A 113 113 0 large-arc-flag 1 end_x end_y Z
--&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;js-left-slice&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;M 441.6 405 A 113 113 0 1 1 441.6 195 Z&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;

&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;js-right-slice&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;M 441.6 195  A 113 113 0 0 1 441.6 405 Z&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;aVOaqY&quot; title=&quot;SA 15 Process 1&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;These paths create the outline. The sliding fill inside them was created using clipped rectangles. For the &lt;code class=&quot;language-text&quot;&gt;clipPath&lt;/code&gt; we use the same paths as the outline and then apply them to the rectangles using the &lt;code class=&quot;language-text&quot;&gt;clip-path&lt;/code&gt; attribute.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;clipPath&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;left-slice-mask&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;M 441.6 405 A 113 113 0 1 1 441.6 195 Z&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;#fff&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;clipPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;clipPath&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;right-slice-mask&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;M 441.6 195  A 113 113 0 0 1 441.6 405 Z&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;#fff&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;clipPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;rect&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;js-right-fill&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;441.6&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;y&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;187&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;72&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;226&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;clip-path&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;url(#right-slice-mask)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To slide the fill in-and-out I animate the &lt;code class=&quot;language-text&quot;&gt;x&lt;/code&gt; value using animejs. The &lt;code class=&quot;language-text&quot;&gt;clipPath&lt;/code&gt; remains static. It’s only the rectangles that are moving.&lt;/p&gt;&lt;div hash=&quot;XzbyQj&quot; title=&quot;SA 15 Process 2&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The combined shape is moved up-down and left-right by animating &lt;code class=&quot;language-text&quot;&gt;translateX&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;translateY&lt;/code&gt;. We apply the same animation at the same time to both the arc slice and clipped rectangle. Note, you do not need to animate the position of the &lt;code class=&quot;language-text&quot;&gt;clipPath&lt;/code&gt;.&lt;/p&gt;&lt;div hash=&quot;pdJGOZ&quot; title=&quot;SA 15 Process 5&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The little circle that burst out. Well… that’s just a circle. At the appropriate time I hide the left slice and rectangle and show the circle instead. The circle scales down as it moves to the left and then stretches — using &lt;code class=&quot;language-text&quot;&gt;scaleX&lt;/code&gt; — as it moves back to the right.&lt;/p&gt;&lt;div hash=&quot;mqJaLY&quot; title=&quot;SA 15 Process 3&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The squirmy line effect that everything has is known as &lt;a href=&quot;https://css-tricks.com/squigglevision-in-css-and-svg&quot;&gt;squigglevision&lt;/a&gt;. I used the code from &lt;a href=&quot;https://tympanus.net/codrops/2016/03/21/animated-animals-css-svg&quot;&gt;this&lt;/a&gt; example.&lt;/p&gt;&lt;div hash=&quot;Nwqoav&quot; title=&quot;SA 15 Process 4&quot; height=&quot;500&quot; defaultTab=&quot;css,result&quot;&gt;&lt;/div&gt;&lt;p&gt;The rest is all about matching the movement and timing of the original animation.&lt;/p&gt;&lt;p&gt;Here are a couple more examples of animating clipped shapes. For these I used a slightly different technique. They have shapes which are filled with an animated SVG pattern.&lt;/p&gt;&lt;div display=&quot;block,flex&quot; justifyContent=&quot;space-around&quot;&gt;&lt;div mr=&quot;3&quot; hash=&quot;GvyrbO&quot; title=&quot;Animated 📕 – The Doctor and the Soul&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div hash=&quot;xLXNRQ&quot; title=&quot;Animated 📕 – The New Technology and Human Values&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Metaballs]]></title><description><![CDATA[Metaballs, not to be confused with meatballs, are organic looking squishy gooey blobs. From a mathematical perspective they are an iso…]]></description><link>https://varun.ca/metaballs/</link><guid isPermaLink="false">https://varun.ca/metaballs/</guid><pubDate>Mon, 16 Oct 2017 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;RLyNEE&quot; title=&quot;amoeba&quot; height=&quot;400&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;Metaballs, not to be confused with meatballs, are organic looking squishy gooey blobs. From a mathematical perspective they are an iso-surface. They are rendered using equations such as &lt;code class=&quot;dib b&quot;&gt;f(x,y,z) = r / ((x - x&lt;sub&gt;0&lt;/sub&gt;)&lt;sup&gt;2&lt;/sup&gt; + (y - y&lt;sub&gt;0&lt;/sub&gt;)&lt;sup&gt;2&lt;/sup&gt; + (z - z&lt;sub&gt;0&lt;/sub&gt;)&lt;sup&gt;2&lt;/sup&gt;)&lt;/code&gt;. Jamie Wong has a fantastic &lt;a href=&quot;http://jamie-wong.com/2014/08/19/metaballs-and-marching-squares&quot;&gt;tutorial&lt;/a&gt; on rendering metaballs with canvas.&lt;/p&gt;&lt;p&gt;We can replicate the metaball effect using CSS &amp;amp; SVG by applying both &lt;a href=&quot;https://css-tricks.com/shape-blobbing-css/&quot;&gt;blur and contrast filters&lt;/a&gt; to an element. For example in Chris Gannon’s Bubble Slider below.&lt;/p&gt;&lt;div hash=&quot;GZNgLw&quot; title=&quot;SVG Bubble Slider&quot; user=&quot;chrisgannon&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;svg-metaball&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#svg-metaball&quot; aria-label=&quot;svg metaball permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;SVG Metaball&lt;/h2&gt;&lt;p&gt;I discovered another approach to creating this metaball effect from &lt;a href=&quot;http://paperjs.org/examples/meta-balls&quot;&gt;Paper.js examples&lt;/a&gt;. Back in the days of Scriptographer &lt;a href=&quot;http://shspage.com&quot;&gt;Hiroyuki Sato&lt;/a&gt; created a script for generating gooey blobs in Adobe Illustrator. Unlike the previous techniques this does not render pixels or rely on filters. Instead it connects two circles with a membrane. Which means that the we can generate the entire blob as a path. For the Amoeba CodePen I followed exactly this technique.&lt;/p&gt;&lt;div hash=&quot;NazWxg&quot; title=&quot;Meta balls Debug&quot; height=&quot;320&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;In this blog post I am going break down the steps required to generate the metaball. We are going to go through a function called &lt;code class=&quot;language-text&quot;&gt;metaball&lt;/code&gt; which generates the black shaded path that you see below. This consists of the connector plus a part of the second circle.&lt;/p&gt;&lt;div hash=&quot;qPQZPN&quot; title=&quot;Metaballs debug — the path&quot; themeId=&quot;8427&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;building-the-metaball&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#building-the-metaball&quot; aria-label=&quot;building the metaball permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Building the Metaball&lt;/h2&gt;&lt;p&gt;To figure out where the connector touches the two circles we start by locating two tangents that touch both circles. This is the widest the connector can be. BTW I’m focusing on the case when the circles are not overlapping first.&lt;/p&gt;&lt;svg height=&quot;200&quot; width=&quot;100%&quot; preserveAspectRatio=&quot;xMidYMid slice&quot; viewBox=&quot;0 0 1200 1200&quot; class=&quot;sc-24qoga-1 gaPIvs&quot;&gt;&lt;g fill=&quot;none&quot; stroke=&quot;#333&quot; stroke-width=&quot;6&quot;&gt;&lt;circle cx=&quot;487.5&quot; cy=&quot;600&quot; r=&quot;96&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;712.5&quot; cy=&quot;600&quot; r=&quot;72&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;g stroke-width=&quot;8&quot;&gt;&lt;g stroke=&quot;#5E2CA5&quot;&gt;&lt;path d=&quot;M497.74 695.452L720.18 671.589&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M497.74 504.548L720.18 528.411&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M0 0L0 0&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M0 0L0 0&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g fill=&quot;#fff&quot; stroke=&quot;#FF41B4&quot;&gt;&lt;circle cx=&quot;497.74&quot; cy=&quot;695.452&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;497.74&quot; cy=&quot;504.548&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;720.18&quot; cy=&quot;671.589&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;720.18&quot; cy=&quot;528.411&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;p&gt;We can calculate the maximum angle of spread using:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; maxSpread &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Why? This took me a while to figure out. I could attempt to explain here, but you are probably better of seeing the step-by-step illustration in this &lt;a href=&quot;http://www.mathopenref.com/consttangentsext.html&quot;&gt;external tangents to two given circles&lt;/a&gt; guide.&lt;/p&gt;&lt;svg height=&quot;200&quot; width=&quot;100%&quot; font-family=&quot;code&quot; preserveAspectRatio=&quot;xMidYMid slice&quot; viewBox=&quot;0 0 1200 1200&quot; class=&quot;sc-24qoga-1 EccIQ&quot;&gt;&lt;g fill=&quot;none&quot; stroke=&quot;#333&quot; stroke-width=&quot;6&quot;&gt;&lt;circle cx=&quot;487.5&quot; cy=&quot;600&quot; r=&quot;96&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;712.5&quot; cy=&quot;600&quot; r=&quot;72&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;path fill=&quot;#fff&quot; d=&quot;M495 585H615V615H495z&quot;&gt;&lt;/path&gt;&lt;text x=&quot;500&quot; y=&quot;605&quot; font-size=&quot;20&quot;&gt;max-spread&lt;/text&gt;&lt;g stroke-width=&quot;8&quot;&gt;&lt;g stroke=&quot;#5E2CA5&quot; stroke-linecap=&quot;round&quot;&gt;&lt;path d=&quot;M497.74 695.452L720.18 671.589&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M497.74 504.548L720.18 528.411&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M487.5 600L497.74 695.452&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M487.5 600L497.74 504.548&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g fill=&quot;#fff&quot; stroke=&quot;#FF41B4&quot;&gt;&lt;circle cx=&quot;497.74&quot; cy=&quot;695.452&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;497.74&quot; cy=&quot;504.548&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;720.18&quot; cy=&quot;671.589&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;720.18&quot; cy=&quot;528.411&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;p&gt;This is the maximum possible spread that the connector can have. We can control spread amount by multiplying it with a factor called &lt;code class=&quot;language-text&quot;&gt;v&lt;/code&gt;. The Paper.js code has &lt;code class=&quot;language-text&quot;&gt;v = 0.5&lt;/code&gt;. That seems to work well.&lt;/p&gt;&lt;div hash=&quot;aLQBdb&quot; title=&quot;Metaballs debug — spread&quot; height=&quot;300&quot; themeId=&quot;8427&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The spread for the smaller circle is &lt;code class=&quot;language-text&quot;&gt;(Math.PI - maxSpread) * v&lt;/code&gt;. This is because the sum of the opposite angles of a polygon is 180°.&lt;/p&gt;&lt;p&gt;Next we need to find the location of those four points. We know the centre of the circles (&lt;code class=&quot;language-text&quot;&gt;center1&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;center2&lt;/code&gt;) and the radii (&lt;code class=&quot;language-text&quot;&gt;radius1&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;radius2&lt;/code&gt;). Therefore, we will only be dealing in terms of angles and then use polar coordinates to convert it into &lt;code&gt;(x, y)&lt;/code&gt; values later.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; maxSpread &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Circle 1 (left)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; maxSpread &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Circle 2 (right)&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The angles need to be measured clockwise. Therefore, for the second circle we take that into account by subtracting from &lt;code class=&quot;language-text&quot;&gt;Math.PI&lt;/code&gt;. We add &lt;code class=&quot;language-text&quot;&gt;angleBetweenCenters&lt;/code&gt; to all because the circles can be moving diagonally too. Then convert polar coords to cartesian.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Points&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To convert the trapezium shaped connector into a curved one we need to add handles to all four points. The next part of the process is to figure out the location of the handles.&lt;/p&gt;&lt;div hash=&quot;rGQyVJ&quot; title=&quot;Metaballs debug — handles&quot; height=&quot;300&quot; themeId=&quot;8427&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The handle for a particular point should be aligned to the tangent to the circle at that point. Again we’ll use polar coords to locate the handle. This time however, it will be relative to the point itself.&lt;/p&gt;&lt;svg height=&quot;200&quot; width=&quot;100%&quot; font-family=&quot;code&quot; font-weight=&quot;bold&quot; preserveAspectRatio=&quot;xMidYMid slice&quot; viewBox=&quot;0 0 1200 1200&quot; class=&quot;sc-24qoga-1 dArsgp&quot;&gt;&lt;g fill=&quot;#fff&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;6&quot;&gt;&lt;circle cx=&quot;487.5&quot; cy=&quot;600&quot; r=&quot;96&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;712.5&quot; cy=&quot;600&quot; r=&quot;64&quot; stroke=&quot;none&quot;&gt;&lt;/circle&gt;&lt;path d=&quot;M560.049 662.87c49.574-44.91 73.566-39.439 110.538-14.504a64 64 0 100-96.732c-36.972 24.935-60.964 30.406-110.538-14.504&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;path fill=&quot;#fff&quot; stroke=&quot;#aaa&quot; stroke-dasharray=&quot;5, 5&quot; stroke-width=&quot;4&quot; d=&quot;M540 600a25 25 0 00-16.225-31.435L487.5 600z&quot;&gt;&lt;/path&gt;&lt;g stroke-width=&quot;8&quot;&gt;&lt;g stroke=&quot;#5E2CA5&quot;&gt;&lt;path d=&quot;M560.049 537.13L609.623 582.04&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#A463F2&quot; d=&quot;M560.049 537.13L487.5 600&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#aaa&quot; stroke-dasharray=&quot;5, 5&quot; stroke-width=&quot;4&quot; d=&quot;M300 600L900 600&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g fill=&quot;#fff&quot; stroke=&quot;#FF41B4&quot;&gt;&lt;circle cx=&quot;487.5&quot; cy=&quot;600&quot; r=&quot;8&quot; stroke=&quot;#FFA3D7&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;560.049&quot; cy=&quot;537.13&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;609.623&quot; cy=&quot;582.04&quot; r=&quot;8&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;/g&gt;&lt;g font-size=&quot;40&quot;&gt;&lt;text x=&quot;450&quot; y=&quot;615&quot;&gt;A&lt;/text&gt;&lt;text x=&quot;575&quot; y=&quot;530&quot;&gt;B&lt;/text&gt;&lt;text x=&quot;625&quot; y=&quot;600&quot;&gt;C&lt;/text&gt;&lt;text x=&quot;500&quot; y=&quot;620&quot; font-size=&quot;20&quot;&gt;angle 1&lt;/text&gt;&lt;/g&gt;&lt;/svg&gt;&lt;p&gt;The lines AB and BC are perpendicular because AB is radial and BC is a tangent to the circle. Therefore, the angle for the handle 1 is &lt;code class=&quot;language-text&quot;&gt;angle1 - Math.PI / 2&lt;/code&gt;. Similarly we can calculate the angles for the other three handles.&lt;/p&gt;&lt;p&gt;The length of the handle is relative to the radius of the circle they originate from times the factor &lt;code class=&quot;language-text&quot;&gt;d2&lt;/code&gt;. For example, the length of handle 1 is &lt;code class=&quot;language-text&quot;&gt;radius1 * d2&lt;/code&gt;. We can now calculate the location of the handles like so:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; totalRadius &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Handle length scaling factor&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; handleSize&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; totalRadius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Handle lengths&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle2 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle3 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle4 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We have all the points 🙌🏽 Time to construct the SVG path. The path is made of three sections: curve from &lt;code class=&quot;language-text&quot;&gt;point 1&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;point 3&lt;/code&gt;, arc of &lt;code class=&quot;language-text&quot;&gt;radius2&lt;/code&gt; from &lt;code class=&quot;language-text&quot;&gt;point 3&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;point 4&lt;/code&gt; and curve from &lt;code class=&quot;language-text&quot;&gt;point 4&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;point 2&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;metaballToPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; escaped&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;C&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;A&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; escaped &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;C&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;circle-overlap&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#circle-overlap&quot; aria-label=&quot;circle overlap permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Circle Overlap&lt;/h3&gt;&lt;p&gt;We have a gooey metaball! But you’ll notice that path gets all weird and twisty when the circles start to overlapping. We are going to fix this by expanding the spread in proportion to how much the circles are overlapping.&lt;/p&gt;&lt;div hash=&quot;boQadp&quot; title=&quot;Metaballs debug — no overlap&quot; height=&quot;300&quot; themeId=&quot;8427&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The spread expansion will be controlled using the angles &lt;code class=&quot;language-text&quot;&gt;u1&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;u2&lt;/code&gt;. We can calculate these using the &lt;a href=&quot;https://en.wikipedia.org/wiki/Law_of_cosines&quot;&gt;law of cosines&lt;/a&gt;.&lt;/p&gt;&lt;div height=&quot;200&quot; style=&quot;overflow:hidden&quot; class=&quot;sc-24qoga-0 dKeSIj&quot;&gt;&lt;svg height=&quot;200&quot; width=&quot;100%&quot; font-family=&quot;code&quot; font-weight=&quot;bold&quot; preserveAspectRatio=&quot;xMidYMid slice&quot; transform=&quot;scale(1.5)&quot; viewBox=&quot;0 0 1200 1200&quot; class=&quot;sc-24qoga-1 ldRUfe&quot;&gt;&lt;g fill=&quot;none&quot; stroke=&quot;#aaa&quot; stroke-width=&quot;4&quot;&gt;&lt;circle cx=&quot;487.5&quot; cy=&quot;600&quot; r=&quot;96&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;630&quot; cy=&quot;600&quot; r=&quot;64&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;g stroke-width=&quot;4&quot;&gt;&lt;g stroke=&quot;#A463F2&quot;&gt;&lt;path d=&quot;M630 600L487.5 600&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M487.5 600L577 562&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M577 562L630 600&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;g fill=&quot;#fff&quot; stroke=&quot;#FF41B4&quot;&gt;&lt;circle cx=&quot;487.5&quot; cy=&quot;600&quot; r=&quot;4&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;630&quot; cy=&quot;600&quot; r=&quot;4&quot;&gt;&lt;/circle&gt;&lt;circle cx=&quot;577&quot; cy=&quot;562&quot; r=&quot;4&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;/g&gt;&lt;g font-size=&quot;20&quot;&gt;&lt;text x=&quot;450&quot; y=&quot;575&quot;&gt;radius1&lt;/text&gt;&lt;text x=&quot;575&quot; y=&quot;620&quot;&gt;d&lt;/text&gt;&lt;text x=&quot;625&quot; y=&quot;575&quot;&gt;radius2&lt;/text&gt;&lt;text x=&quot;525&quot; y=&quot;595&quot; font-size=&quot;15&quot;&gt;u1&lt;/text&gt;&lt;text x=&quot;590&quot; y=&quot;595&quot; font-size=&quot;15&quot;&gt;u2&lt;/text&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;u1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

u2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But what shall we do with these 🤔 To be honest I’m not entirely sure how this works. What I do know is that it expands the spread as the circles get closer and then collapses it once circle 2 is completely inside circle 1.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; u1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maxSpread &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;u1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maxSpread &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;PJxQom&quot; title=&quot;Metaballs debug — overlap&quot; height=&quot;300&quot; themeId=&quot;8427&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;And one final change to account for overlapping circles. The length of the handles will also be proportional to the distance between the circles.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Define handle length by the distance between both ends of the curve&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; totalRadius &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d2Base &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; handleSize&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; totalRadius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// Take into account when circles are overlapping&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; d2Base &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;And here is the final result and the entire code snippet for &lt;code class=&quot;language-text&quot;&gt;metaball&lt;/code&gt;. Try forking it and playing around with different values of &lt;code class=&quot;language-text&quot;&gt;handleSize&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;v&lt;/code&gt;. See how they impact the shape of the connector. There are so many amazing little details in these 70 lines of code. Fascinating work by Hiroyuki Sato. I learnt so much from it!&lt;/p&gt;&lt;div hash=&quot;pWQajO&quot; title=&quot;Metaballs debug — final&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;/**
 * Based on Metaball script by Hiroyuki Sato
 * http://shspage.com/aijs/en/#metaball
 */&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;metaball&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token parameter&quot;&gt;radius1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  radius2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  center1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  handleSize &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.4&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  v &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; maxDist &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; u1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; u2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// No blob if a radius is 0&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// or if distance between the circles is larger than max-dist&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// or if circle2 is completely inside circle1&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    radius1 &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;
    radius2 &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;
    d &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; maxDist &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt;
    d &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;abs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calculate u1 and u2 if the circles are overlapping&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    u1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    u2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Else set u1 and u2 to zero&lt;/span&gt;
    u1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    u2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Calculate the max spread&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;angle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; center1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; maxSpread &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;acos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Angles for the points&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; u1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maxSpread &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;maxSpread &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
    angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; angle4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
    angleBetweenCenters &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;PI&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; u2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; maxSpread&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; v&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Point locations&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; p4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;center2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Define handle length by the distance between both ends of the curve&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; totalRadius &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d2Base &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;v &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; handleSize&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;dist&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; totalRadius&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// Take into account when circles are overlapping&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; d2Base &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;d &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;radius1 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Length of the handles&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius1 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; r2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; radius2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; d2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Handle locations&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h1 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h2 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle2 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h3 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle3 &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h4 &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getVector&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; angle4 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;HALF_PI&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token comment&quot;&gt;// Generate the connector path&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;metaballToPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; radius1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; radius2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// prettier-ignore&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;metaballToPath&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; escaped&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;C&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;A&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; escaped &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;C&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; p2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Learning CSS Grid – Part 2]]></title><description><![CDATA[In part one I introduced the CSS Grid Layout Module. We covered some basic terminology and talked about how to create layouts by placing…]]></description><link>https://varun.ca/css-grid-2/</link><guid isPermaLink="false">https://varun.ca/css-grid-2/</guid><pubDate>Mon, 04 Sep 2017 00:00:00 GMT</pubDate><content:encoded>&lt;div as=&quot;figure&quot; mx=&quot;auto&quot; p=&quot;0&quot; mt=&quot;3&quot; mb=&quot;4&quot; justifyContent=&quot;center&quot;&gt;&lt;div&gt;+-------------------------+ +---+
|                         | |   |
|  CSS Grid               | |   |
|  Layout Module          | |   |
|                         | |   |
+-------------------------+ |   |
+----+ +------------------+ |   |
|    | |                  | |   |
|    | |                  | |   |
|    | +------------------+ +---+
|    | +------+ +---------------+
|    | |      | |        part 2 |
+----+ +------+ +---------------+&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In part one I introduced the CSS Grid Layout Module. We covered some basic terminology and talked about how to create layouts by placing items onto a &lt;code class=&quot;language-text&quot;&gt;grid-area&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Let’s start with quick refresher. Grid Area is the space created by the intersection of four grid lines. We define it in terms of start and end points for columns and rows.&lt;/p&gt;&lt;div justifyContent=&quot;center&quot;&gt;&lt;div&gt;                                +-- grid-column-start
                                |
             +-- grid-column +--+
             |                  |
             |                  +-- grid-column-end
grid-area +--+
             |                  +-- grid-row-start
             |                  |
             +-- grid-row +-----+
                                |
                                +-- grid-row-end&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;Grid area is made up of a grid column and a grid row. Grid column and row both require a start and an end point.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In this post I am going to introduce another approach to creating grid based layouts – using &lt;em&gt;grid template areas&lt;/em&gt;.&lt;/p&gt;&lt;h2 id=&quot;grid-template-areas&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#grid-template-areas&quot; aria-label=&quot;grid template areas permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Grid Template Areas&lt;/h2&gt;&lt;p&gt;This property allows us to divide the grid into named areas which can then be referenced for placing items. We start by declaring the names in the &lt;code class=&quot;language-text&quot;&gt;grid-template-areas&lt;/code&gt; property. Once declared we can use them as keywords in any of the &lt;a href=&quot;https://www.w3.org/TR/css-grid-1/#grid-placement-property&quot;&gt;grid-placement properties&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;We are still defining grid areas however instead of providing row/column start &amp;amp; end points we are doing it through a layout template.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;.my-grid {
  display: grid;
  grid-template-areas: &amp;quot;header   header   header&amp;quot;
                       &amp;quot;content  content    side&amp;quot;
                       &amp;quot;footer   footer   footer&amp;quot;;
}&lt;/div&gt;&lt;div&gt;Named Areas


+-----------------------+
|░░░░░░░░░░░░░░░░░░░░░░░|
|░░░░░░░ Header ░░░░░░░░|
|░░░░░░░░░░░░░░░░░░░░░░░|
+---------------+-------+
|▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|░░░░░░░|
|▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|░░░A░░░|
|▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|░░░s░░░|
|▓▓▓ Content ▓▓▓|░░░i░░░|
|▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|░░░d░░░|
|▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|░░░e░░░|
|▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓|░░░░░░░|
+---------------+-------+
|░░░░░░░░░░░░░░░░░░░░░░░|
|░░░░░░░ Footer ░░░░░░░░|
|░░░░░░░░░░░░░░░░░░░░░░░|
+-----------------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;We can define named grid areas to place content into.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;You’ll notice that the syntax of the &lt;code class=&quot;language-text&quot;&gt;grid-template-areas&lt;/code&gt; property provides a visualization of the grid structure. This makes it relatively easy to understand the layout. To place items onto this grid we can use &lt;code class=&quot;language-text&quot;&gt;grid-area&lt;/code&gt; property. For example: &lt;code class=&quot;language-text&quot;&gt;grid-area: header;&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;grid-area: content;&lt;/code&gt;, etc.&lt;/p&gt;&lt;div hash=&quot;BZvMbM&quot; title=&quot;Named Grid Areas – step 1&quot; height=&quot;400&quot; defaultTab=&quot;css,result&quot;&gt;&lt;/div&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;grid-template-areas&lt;/code&gt; property allows us to define the shape of the layout, but not the sizing. By default the sizing is dependant on grid items placed within them. You can pair &lt;code class=&quot;language-text&quot;&gt;grid-template-areas&lt;/code&gt; with other properties such as &lt;code class=&quot;language-text&quot;&gt;grid-template-rows&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;grid-template-columns&lt;/code&gt; to control the sizing of the areas too!&lt;/p&gt;&lt;div hash=&quot;pwqyYj&quot; title=&quot;Named Grid Areas&quot; height=&quot;400&quot; defaultTab=&quot;css,result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;example-1--magazine-style-layout&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#example-1--magazine-style-layout&quot; aria-label=&quot;example 1  magazine style layout permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Example 1 – Magazine Style Layout&lt;/h2&gt;&lt;div hash=&quot;KmoxJp&quot; title=&quot;CSS Grid Magazine Style Layout&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The above is a magazine style layout of &lt;a href=&quot;https://theoutline.com/post/1424/hawaii-s-online-gaming-curse&quot;&gt;Hawaii’s Online Gaming Curse&lt;/a&gt; article from The Outline – built using both CSS Grid and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Columns/Using_multi-column_layouts&quot;&gt;multi-column layout&lt;/a&gt;. Below is a schematic of what the layout looks like at the three break points.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div&gt;Large-Breakpoint
  min-width: 60em



+----+ +------------------+ +-----------+
|meta| | title            | | copy2     |
|    | |                  | |           |
+----+ +------------------+ +-----------+
+-------------------------+ +-----------+
| copy1                   | | copy2     |
|                         | |           |
+-------------------------+ +-----------+
+-------------------------+ +-----------+
|  copy1                  | | copy2     |
|                         | |           |
+-------------------------+ +-----------+
+---------------------------------------+
| media                                 |
|                                       |
+---------------------------------------+
+-----------+ +-------------------------+
|  aside    | | copy3                   |
|           | |                         |
+-----------+ +-------------------------+&lt;/div&gt;&lt;div&gt;Medium-Breakpoint
  min-width: 30em
  and max-width: 60em


+-----+ +-------------------+
|meta | | title             |
|     | |                   |
+-----+ +-------------------+
+---------------------------+
| copy1                     |
|                           |
+---------------------------+
+---------------------------+
| copy2                     |
|                           |
+---------------------------+
+---------------------------+
| media                     |
|                           |
+---------------------------+
+---------------------------+
| aside                     |
|                           |
+---------------------------+
+---------------------------+
| copy3                     |
|                           |
+---------------------------+&lt;/div&gt;&lt;div&gt;Small-Breakpoint
  min-width: 60em



+---------------+
| title         |
|               |
+---------------+
+---------------+
| meta          |
|               |
+---------------+
+---------------+
| copy1         |
|               |
+---------------+
+---------------+
| copy2         |
|               |
+---------------+
+---------------+
| media         |
|               |
+---------------+
+---------------+
| aside         |
|               |
+---------------+
+---------------+
| copy3         |
|               |
+---------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;The magazine style layout of &lt;a href=&quot;https://theoutline.com/post/1424/hawaii-s-online-gaming-curse&quot;&gt;Hawaii&amp;#x27;s Online Gaming Curse – The Outline&lt;/a&gt; built using CSS Grid and multi-column layout.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Given this was one of the first grid layouts I ever built I made some assumptions which later turned out to be false. I defined the &lt;code class=&quot;language-text&quot;&gt;grid-template-areas&lt;/code&gt; for all three breakpoints using the same number of columns. While you &lt;em&gt;can&lt;/em&gt; do this you don’t have to. You can completely modify the template by changing the values for the &lt;code class=&quot;language-text&quot;&gt;grid-template-areas&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;grid-template-columns&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;grid-template-rows&lt;/code&gt;. The other option you have is to change the area that an element is placed in. More on that in the next example.&lt;/p&gt;&lt;h2 id=&quot;example-2--bbc-sport-live-football&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#example-2--bbc-sport-live-football&quot; aria-label=&quot;example 2  bbc sport live football permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Example 2 – BBC Sport Live Football&lt;/h2&gt;&lt;div hash=&quot;RgRomv&quot; title=&quot;BBC Live Football Coverage (CSS Grid)&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;For this example I recreated the &lt;a href=&quot;http://www.bbc.com/sport/live/football/38322056&quot;&gt;BBC Sport Live Reporting&lt;/a&gt; page. Below you can see the schematic for the large breakpoint layout on the right and its grid template representation on the left. And yes, you can use &lt;a href=&quot;https://una.im/css-grid/#%F0%9F%92%81&quot;&gt;emoji&lt;/a&gt; for template area names!&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;grid-template-areas:
  &amp;quot;✈️ ✈️ ✈️ ✈️ ✈️&amp;quot;
  &amp;quot;⚽️ ⚽️ ⚽️ ⚽️ ⚽️&amp;quot;
  &amp;quot;🖼 🖼 🖼 🖼 🖼&amp;quot;
  &amp;quot;.  👀 📻 📊  .&amp;quot;
  &amp;quot;.  👀 📻 🤼  .&amp;quot;;

Where:
✈️: Navigation
⚽️: Match Score
🖼: Media
👀: Summary
📻: Live Reporting
📊: Stats
🤼: Line-ups&lt;/div&gt;&lt;div&gt;+-------------------------------------+
|              Navigation             |
+-------------------------------------+
|             Match Score             |
+-------------------------------------+
|                                     |
|               Media                 |
|                                     |
+--+------+-+-------------+-+------+--+
|  |  su  | |             | |      |  |
|  |  mm  | |             | |      |  |
|  |  ar  | |   Live      | | stats|  |
|  |  y   | |   Reporting | |      |  |
|  +------+ |             | +------+  |
|           |             | |      |  |
|           |             | | line |  |
|           |             | | -ups |  |
|           |             | |      |  |
|           |             | |      |  |
|           |             | |      |  |
+-------------------------------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;&lt;a href=&quot;http://www.bbc.com/sport/live/football/38322056&quot;&gt;BBC Sport Live Reporting&lt;/a&gt; page recreated with CSS Grid.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;In the main content area there are three columns: summary (👀), live-reporting (📻) &amp;amp; stats/line-up (📊/🤼🏽‍). To centre this content I placed an unnamed spacer on either side. You can define &lt;a href=&quot;https://drafts.csswg.org/css-grid/#grid-template-areas-null-cell-token&quot;&gt;unnamed areas&lt;/a&gt; using a sequence of one or more &lt;code class=&quot;language-text&quot;&gt;.&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;At the medium break point live-reporting (📻), stats (📊) &amp;amp; line-up (🤼) get collapsed into a tab based interface (📋). We can do this by placing those items in the &lt;code class=&quot;language-text&quot;&gt;📋&lt;/code&gt; grid-area instead. And for the small breakpoint things collapse further.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;grid-template-areas:
  &amp;quot;✈️ ✈️ ✈️ ✈️&amp;quot;
  &amp;quot;⚽️ ⚽️ ⚽️ ⚽️&amp;quot;
  &amp;quot;🖼 🖼 🖼 🖼&amp;quot;
  &amp;quot;.  👀 📋  .&amp;quot;;

Where:
✈️: Navigation
⚽️: Match Score
🖼: Media
👀: Summary
🗂: Tabs
📋: Tab-Content&lt;/div&gt;&lt;div&gt;+-------------------------------------+
|              Navigation             |
+-------------------------------------+
|             Match Score             |
+-------------------------------------+
|                                     |
|               Media                 |
|                                     |
+--+------+-+---+---+---+----------+--+
|  |  su  | |   |   |   |          |  |
|  |  mm  | +---+---+---+----------+  |
|  |  ar  | |                      |  |
|  |  y   | |                      |  |
|  +------+ |                      |  |
|           |                      |  |
|           |          Tabs!       |  |
|           |                      |  |
|           |                      |  |
|           |                      |  |
|           |                      |  |
+-------------------------------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;&lt;a href=&quot;http://www.bbc.com/sport/live/football/38322056&quot;&gt;BBC Sport Live Reporting&lt;/a&gt; page recreated with CSS Grid.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Each entry in the live-reporting (📻) section is also using a grid layout, but I’ll let you discover that by reading through the code.&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;One of the main takeaways for me from these experiments was that CSS Grid removes the need for wrapper elements to create layouts. This flattens the markup and the main &lt;em&gt;blocks&lt;/em&gt; of content generally end up being direct descendants of the grid container i.e. grid-items. Or at least, we should aim to have them be grid items. This then allows us to drastically modify how the content will be displayed by moving items anywhere within the grid.&lt;/p&gt;&lt;p&gt;You can find all my CSS Grid experiments in this &lt;a href=&quot;https://codepen.io/collection/nZBOPV&quot;&gt;CodePen collection&lt;/a&gt;. Also, I would highly recommend reading the &lt;a href=&quot;https://drafts.csswg.org/css-grid/&quot;&gt;CSS Grid Spec&lt;/a&gt;. It has a lot of amazing examples, detailed explanation of all concepts and it is not as daunting as you would think.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Draggable Elements with RxJS]]></title><description><![CDATA[I've written previously about making DOM elements draggable using a combination of  mouse and touch events . Recently I discovered a more…]]></description><link>https://varun.ca/drag-with-rxjs/</link><guid isPermaLink="false">https://varun.ca/drag-with-rxjs/</guid><pubDate>Sun, 27 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;yoRBMj&quot; title=&quot;Curves and Handles&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;I’ve written previously about making DOM elements draggable using a combination of &lt;a href=&quot;/touch-and-mouse-together&quot;&gt;mouse and touch events&lt;/a&gt;. Recently I discovered a more elegant way to achieve this using RxJS and Hammer.&lt;/p&gt;&lt;h2 id=&quot;tools&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tools&quot; aria-label=&quot;tools permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tools&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;http://hammerjs.github.io&quot;&gt;Hammer JS&lt;/a&gt; needs no introduction. It is the go to library for supporting touch gestures. Plus it provides an abstraction over the browser events allowing us to handle mouse and touch at the same time.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/reactivex/rxjs&quot;&gt;RxJS&lt;/a&gt; is a reactive programming library for JavaScript. We will use it to convert events into an observable stream and for animations.&lt;/p&gt;&lt;p&gt;I’ve been using RxJS for a couple of years now. Mostly for state management with Angular and with &lt;a href=&quot;https://redux-observable.js.org&quot;&gt;redux-observable&lt;/a&gt;. I love working with observables. It allows me to write succinct and declarative code.&lt;/p&gt;&lt;p&gt;A few months ago &lt;a href=&quot;https://twitter.com/davidkpiano&quot;&gt;David Khourshid&lt;/a&gt; introduced me to his library &lt;a href=&quot;https://github.com/davidkpiano/RxCSS&quot;&gt;RxCSS&lt;/a&gt; and to the idea of using observables to create reactive animations. Reactive programming makes it really easy to convert events into data and drive animations. This pushed me to learn more about observables and discover lots of new patterns. In this post I am going to share one of those patterns.&lt;/p&gt;&lt;p&gt;⚠️ I am going to assume a basic understanding of RxJS. If you are new to RxJS then I would highly recommend reading David’s &lt;a href=&quot;https://css-tricks.com/animated-intro-rxjs&quot;&gt;animated intro to RxJS&lt;/a&gt; first.&lt;/p&gt;&lt;h2 id=&quot;drag-gesture&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#drag-gesture&quot; aria-label=&quot;drag gesture permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Drag Gesture&lt;/h2&gt;&lt;p&gt;The drag gesture can be broken down into three stages: start, move &amp;amp; end. On start we grab the current location of the element. The move event provides the delta which we can use to move the element. Lastly, the end event provides us with a hook to do any kind of cleanup once the gesture has ended. Hammer’s &lt;a href=&quot;http://hammerjs.github.io/recognizer-pan/&quot;&gt;Pan Recognizer&lt;/a&gt; provides us with &lt;code class=&quot;language-text&quot;&gt;panstart&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;panmove&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;panend&lt;/code&gt; events which work perfectly for the drag gesture.&lt;/p&gt;&lt;h3 id=&quot;events-to-observable&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#events-to-observable&quot; aria-label=&quot;events to observable permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Events to Observable&lt;/h3&gt;&lt;p&gt;We start by creating a Hammer manager and configure it to handle pan in all directions. &lt;code class=&quot;language-text&quot;&gt;Rx.Observable.fromEvent&lt;/code&gt; allows us to convert events into an observable sequence. This one observable stream – &lt;code class=&quot;language-text&quot;&gt;pan$&lt;/code&gt; – will allow us to subscribe to events for pan-start, pan-move and pan-end.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Create a new Hammer Manager&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; hammerPan &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Hammer&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;element&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  direction&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Hammer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DIRECTION_ALL&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

hammerPan&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;pan&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; direction&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; Hammer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;DIRECTION_ALL&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Convert hammer events to an observable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; pan$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Rx&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Observable&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;fromEvent&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;hammerPan&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;panstart panmove panend&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;composing-the-drag-observable&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#composing-the-drag-observable&quot; aria-label=&quot;composing the drag observable permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Composing the Drag Observable&lt;/h3&gt;&lt;p&gt;For the drag gesture we want to create an observable stream such that it emits values from the pan-move event once the pan-start event has been triggered and then stops emitting those values once the pan-end event is triggered.&lt;/p&gt;&lt;figure my=&quot;5&quot;&gt;&lt;svg style=&quot;width:100%;margin:0 auto;cursor:default;display:block;dominant-baseline:central;font-family:Arial, sans-serif;font-size:14;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;min-height:219px;background-color:#fff;padding:8px 16px 8px 0&quot; text-anchor=&quot;middle&quot; viewBox=&quot;0 0 565 219&quot;&gt;&lt;g font-family=&quot;monospace&quot; font-size=&quot;20&quot; font-weight=&quot;800&quot; text-anchor=&quot;end&quot;&gt;&lt;text x=&quot;545&quot; y=&quot;20&quot; fill=&quot;#5E2CA5&quot;&gt;drag$&lt;/text&gt;&lt;text x=&quot;545&quot; y=&quot;72&quot; fill=&quot;#D5008F&quot;&gt;panStart$&lt;/text&gt;&lt;text x=&quot;545&quot; y=&quot;124&quot; fill=&quot;#D5008F&quot;&gt;panMove$&lt;/text&gt;&lt;text x=&quot;545&quot; y=&quot;176&quot; fill=&quot;#D5008F&quot;&gt;panEnd$&lt;/text&gt;&lt;/g&gt;&lt;path stroke=&quot;#767676&quot; stroke-dasharray=&quot;3,3&quot; d=&quot;M76.643 37L76.643 89&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#767676&quot; stroke-dasharray=&quot;3,3&quot; d=&quot;M92.129 37L92.129 141&quot;&gt;&lt;/path&gt;&lt;path stroke=&quot;#767676&quot; stroke-dasharray=&quot;3,3&quot; d=&quot;M374.188 37L374.188 193&quot;&gt;&lt;/path&gt;&lt;g transform=&quot;translate(0 11) translate(21)&quot;&gt;&lt;path stroke=&quot;#000&quot; stroke-width=&quot;2&quot; d=&quot;M0 26L534 26&quot; shape-rendering=&quot;crispEdges&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M534 21l10 5-10 5z&quot;&gt;&lt;/path&gt;&lt;circle r=&quot;15&quot; cx=&quot;0&quot; cy=&quot;0&quot; fill=&quot;#767676&quot; transform=&quot;translate(55.643 26)&quot;&gt;&lt;/circle&gt;&lt;circle r=&quot;15&quot; cx=&quot;0&quot; cy=&quot;0&quot; fill=&quot;#767676&quot; transform=&quot;translate(71.129 26)&quot;&gt;&lt;/circle&gt;&lt;circle r=&quot;15&quot; cx=&quot;0&quot; cy=&quot;0&quot; fill=&quot;#767676&quot; transform=&quot;translate(353.188 26)&quot;&gt;&lt;/circle&gt;&lt;/g&gt;&lt;g transform=&quot;translate(0 63) translate(21)&quot;&gt;&lt;path stroke=&quot;#767676&quot; stroke-width=&quot;2&quot; d=&quot;M55.643 26L534 26&quot; shape-rendering=&quot;crispEdges&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#767676&quot; d=&quot;M534 21l10 5-10 5z&quot;&gt;&lt;/path&gt;&lt;g transform=&quot;translate(55.75 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;⬇️&lt;/text&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(0 115) translate(21)&quot;&gt;&lt;path stroke=&quot;#767676&quot; stroke-width=&quot;2&quot; d=&quot;M71.129 26L534 26&quot; shape-rendering=&quot;crispEdges&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#767676&quot; d=&quot;M534 21l10 5-10 5z&quot;&gt;&lt;/path&gt;&lt;g transform=&quot;translate(71.45 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(104.984 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(138.84 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(172.589 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(206.444 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(240.3 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(274.049 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(307.904 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;g transform=&quot;translate(341.76 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;🔁&lt;/text&gt;&lt;/g&gt;&lt;/g&gt;&lt;g transform=&quot;translate(0 167) translate(21)&quot;&gt;&lt;path stroke=&quot;#767676&quot; stroke-width=&quot;2&quot; d=&quot;M353.188 26L534 26&quot; shape-rendering=&quot;crispEdges&quot;&gt;&lt;/path&gt;&lt;path fill=&quot;#767676&quot; d=&quot;M534 21l10 5-10 5z&quot;&gt;&lt;/path&gt;&lt;g transform=&quot;translate(353.294 26)&quot;&gt;&lt;circle r=&quot;15&quot; fill=&quot;#fff&quot; stroke=&quot;#767676&quot; stroke-width=&quot;2&quot;&gt;&lt;/circle&gt;&lt;text fill=&quot;#767676&quot;&gt;⬆️&lt;/text&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;figcaption&gt;Visualization of the drag observables. Generated using &lt;a href=&quot;https://rxviz.com/&quot;&gt;rxviz.com&lt;/a&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;The &lt;a href=&quot;https://www.learnrxjs.io/operators/filtering/filter.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;filter&lt;/code&gt;&lt;/a&gt; operator allows us to filter values based on a provided condition. We can use this to target specific events. For example, &lt;code class=&quot;language-text&quot;&gt;pan$.filter(e =&amp;gt; e.type === &amp;#x27;panstart&amp;#x27;)&lt;/code&gt; to subscribe only to pan-start events. Then to generate the &lt;code class=&quot;language-text&quot;&gt;drag$&lt;/code&gt; observable we then need to combine &lt;code class=&quot;language-text&quot;&gt;panstart$&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;panmove$&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;panend$&lt;/code&gt; in the following pattern:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; drag$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; panstart$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;switchMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt;
  panmove$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;calculateNewPosition&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;takeUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;panend$&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let’s break this down step by step. &lt;code class=&quot;language-text&quot;&gt;panstart$&lt;/code&gt; is the observable that is driving the whole thing. When it emits the first value it &lt;em&gt;switches&lt;/em&gt; to the &lt;code class=&quot;language-text&quot;&gt;panmove$&lt;/code&gt; observable. This switching is done using the &lt;a href=&quot;https://www.learnrxjs.io/operators/transformation/switchmap.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;switchMap&lt;/code&gt;&lt;/a&gt; operator. The &lt;code class=&quot;language-text&quot;&gt;panmove$&lt;/code&gt; observable then starts emitting the location values. We can tell it to stop when &lt;code class=&quot;language-text&quot;&gt;panend$&lt;/code&gt; emits a value by chaining on the &lt;a href=&quot;https://www.learnrxjs.io/operators/filtering/takeuntil.html&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;takeUntil&lt;/code&gt;&lt;/a&gt; operator. Therefore, all subscribers to &lt;code class=&quot;language-text&quot;&gt;drag$&lt;/code&gt; only ever receive location values. You can see a simulated visualization of this setup &lt;a href=&quot;https://rxviz.com/v/A8DdXm8d&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Now that we understand the basic structure we can flush out the details. The &lt;code class=&quot;language-text&quot;&gt;panmove&lt;/code&gt; event only provides delta values. To calculate the absolute position we need to start by getting the initial location. In this example I am getting that information from the element itself. To provide a cleanup hook we can subscribe to the &lt;code class=&quot;language-text&quot;&gt;move$&lt;/code&gt; observable and handle it via the &lt;code class=&quot;language-text&quot;&gt;onComplete&lt;/code&gt; callback.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Generates the drag$ observable&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;drag&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; element&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; pan$ &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; panStart$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pan$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;panstart&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; panMove$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pan$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;panmove&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; panEnd$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; pan$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;panend&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  panstart$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;switchMap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// Get the starting point on pan-start&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; start &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;cx&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;element&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;cy&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// Create observable to handle pan-move and stop on pan-end&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; move$ &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; panmove$
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;pmEvent&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; start&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; pmEvent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deltaX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; start&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; pmEvent&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deltaY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;takeUntil&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;panend$&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token comment&quot;&gt;// We can subscribe to move$ and handle cleanup in the onComplete callback&lt;/span&gt;
    move$&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;subscribe&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token comment&quot;&gt;/* Handle cleanup when pan ends */&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; move$&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The pattern I shared above is based on the &lt;a href=&quot;https://github.com/Reactive-Extensions/RxJS/blob/8fa95ac884181fb6cbff8ce7c1d669ffb190f5e4/examples/dragndrop/dragndrop.js&quot;&gt;dragndrop example&lt;/a&gt; from the RxJS documentation.&lt;/p&gt;&lt;h3 id=&quot;scaling-to-canvas&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#scaling-to-canvas&quot; aria-label=&quot;scaling to canvas permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Scaling to Canvas&lt;/h3&gt;&lt;p&gt;Quite often I end up having to limit the element to a parent container. For example, a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;circle&amp;gt;&lt;/code&gt; that can only be dragged within the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; container where the &lt;code class=&quot;language-text&quot;&gt;cx&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;cy&lt;/code&gt; values need to be calculated in the &lt;code class=&quot;language-text&quot;&gt;viewBox&lt;/code&gt; coordinate system.&lt;/p&gt;&lt;p&gt;This is essentially a global to local coordinate transform. With SVG this can get slightly tricky depending on how you want the SVG to scale. I generally prefer &lt;code class=&quot;language-text&quot;&gt;preserveAspectRatio=&amp;quot;xMidYMid slice&amp;quot;&lt;/code&gt;. This makes the SVG grow until it entirely covers the container – very similar to &lt;code class=&quot;language-text&quot;&gt;background-size: cover&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;{% include diagrams/svg-scaling.html %}&lt;/p&gt;&lt;p&gt;Therefore, we can figure out how much the SVG has scaled using the aspect ratio of the container. Then use that value to map the viewport based coordinates to the SVG coordinate system.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;scaleToCanvas&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; start&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; svgW &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;VIEWBOX_SIZE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VIEWBOX_SIZE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;W&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; svgH &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;VIEWBOX_SIZE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token constant&quot;&gt;VIEWBOX_SIZE&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token constant&quot;&gt;H&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapFromToRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deltaX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; svgW&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapFromToRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deltaY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; svgH&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;mapFromToRange&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;y2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; y1&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here’s the complete example:&lt;/p&gt;&lt;div hash=&quot;RZeNRE&quot; title=&quot;Drag Gesture with RxJS &amp;amp; Hammer – without smooth motion&quot; height=&quot;400&quot; defaultTab=&quot;js,result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;smooth-motion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#smooth-motion&quot; aria-label=&quot;smooth motion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Smooth Motion&lt;/h3&gt;&lt;p&gt;In the example above you’ll notice that the motion is somewhat rigid. The circle is stuck to the pointer and instantly stops wherever the pointer stops. We can make this better by adding smooth motion. This will also provide a bit of momentum to the circle.&lt;/p&gt;&lt;p&gt;For smooth motion I am using the LERP-ing technique. It is described in detail by David Khourshid in the &lt;a href=&quot;https://css-tricks.com/animated-intro-rxjs/#article-header-id-3&quot;&gt;An Animated Intro to RxJS&lt;/a&gt; article I mentioned earlier. The gist of it is that instead of using the &lt;code class=&quot;language-text&quot;&gt;drag$&lt;/code&gt; observable directly we combine it with an animation timer. This allows us to smooth out the motion by using linear interpolation. However, we still have the possibility to subscribe to &lt;code class=&quot;language-text&quot;&gt;drag$&lt;/code&gt; if we want access to the raw location.&lt;/p&gt;&lt;p&gt;Here’s the final version with smooth motion.&lt;/p&gt;&lt;div hash=&quot;QMVymp&quot; title=&quot;Drag Gesture with RxJS &amp;amp; Hammer&quot; height=&quot;500&quot; defaultTab=&quot;js,result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;You can see the power of RxJS here. We were able to convert events into observable streams. Then we composed those streams to create the &lt;code class=&quot;language-text&quot;&gt;drag$&lt;/code&gt; observable. And finally we added the animation layer to smooth out the motion. The code is quite declarative. Each layer that we created is modular and can be easily composed to create complex scenarios – for example see the demo below and the one at the top of the page. Looking for more inspiration? Checkout CodePen for many more &lt;a href=&quot;https://codepen.io/search/pens/?q=rxcss&quot;&gt;examples&lt;/a&gt;.&lt;/p&gt;&lt;div hash=&quot;yoVQbp&quot; title=&quot;Napoleon&amp;#x27;s Theoremr&quot; height=&quot;400&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Learning CSS Grid]]></title><description><![CDATA[CSS Grid is here! As of March 2017, all major browsers support it. Given this good news I decided to spend some time to better understand…]]></description><link>https://varun.ca/css-grid/</link><guid isPermaLink="false">https://varun.ca/css-grid/</guid><pubDate>Tue, 16 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;div as=&quot;figure&quot; mx=&quot;auto&quot; p=&quot;0&quot; mt=&quot;3&quot; mb=&quot;4&quot; justifyContent=&quot;center&quot;&gt;&lt;div&gt;+-------------------------+ +---+
|                         | |   |
|  CSS Grid               | |   |
|  Layout Module          | |   |
|                         | |   |
+-------------------------+ |   |
+----+ +------------------+ |   |
|    | |                  | |   |
|    | |                  | |   |
|    | +------------------+ +---+
|    | +------+ +---------------+
|    | |      | |               |
+----+ +------+ +---------------+&lt;/div&gt;&lt;/div&gt;&lt;p&gt;CSS Grid is here! As of March 2017, all major browsers support it. Given this good news I decided to spend some time to better understand how to use it. The learning curve was much steeper than I expected – the module introduces something like 17 new concepts. It was quite overwhelming to take it all in, so I started breaking things down, taking notes and making demos, which I am going to share here. This is by no means an exhaustive guide. It might not even be 100% factually correct. But this should be enough information for you to form a basic mental model of how CSS Grids work and start building layouts with it.&lt;/p&gt;&lt;h2 id=&quot;terminology&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#terminology&quot; aria-label=&quot;terminology permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Terminology&lt;/h2&gt;&lt;p&gt;Before we start creating grid layouts we need to learn a few new terms. A &lt;strong&gt;Grid Container&lt;/strong&gt; is an element on which &lt;code class=&quot;language-text&quot;&gt;display: grid&lt;/code&gt; has been applied. All its direct descendants become &lt;strong&gt;Grid Items&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;When we define the grid we specify the number of rows and columns we want. The grid layout system then generates numbered lines which divide the grid horizontally and vertically. These are known as &lt;strong&gt;Grid Lines&lt;/strong&gt;. The space between any two adjacent grid lines is called &lt;strong&gt;Grid Track&lt;/strong&gt;. This is essentially a generic term for &lt;em&gt;columns&lt;/em&gt; and &lt;em&gt;rows&lt;/em&gt;.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div&gt;Grid Lines


+---+---+---+---+---+---+ 1
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-------+---+-----------+ 2
|   |xxx|   |   |   |   |
|   |xxx|&amp;lt;-- Grid Cell  |
|   |xxx|   |   |   |   |
+-----------------------+ 3
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+---+---+---+---+---+---+ 4
1   2   3   4   5   6   7&lt;/div&gt;&lt;div&gt;Row Tracks


+---+---+---+---+---+---+
|xxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxx|
|xxxxxxxxxxxxxxxxxxxxxxx|
+-----------------------+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+-----------------------+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+---+---+---+---+---+---+&lt;/div&gt;&lt;div&gt;Column Tracks


+---+---+---+---+---+---+
|xxx|   |   |   |   |   |
|xxx|   |   |   |   |   |
|xxx|   |   |   |   |   |
+xxx--------------------+
|xxx|   |   |   |   |   |
|xxx|   |   |   |   |   |
|xxx|   |   |   |   |   |
+xxx--------------------+
|xxx|   |   |   |   |   |
|xxx|   |   |   |   |   |
|xxx|   |   |   |   |   |
+---+---+---+---+---+---+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;The grid gives us numbered lines to use when positioning items. A grid track is the space between any two lines on the grid.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A &lt;strong&gt;Grid Cell&lt;/strong&gt; is the smallest unit on the grid. It is the intersection of a row and column. Conceptually it is quite similar to a table cell.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Grid Area&lt;/strong&gt; is the space created by the intersection of four grid lines. In other words, it is a collection of one or more adjacent grid cells. The grid area can only be rectangular! It is not possible to create T- or L-shaped grid areas. Which for some reason was the first thing I wanted to do.&lt;/p&gt;&lt;div justifyContent=&quot;center&quot;&gt;&lt;div&gt;Grid Area


+---+---+---+---+---+---+
|   |   |   |   |   |   |
|   |   |   |   |   |   |
|   |   |   |   |   |   |
+---+---+-----------+---+
|   |   |xxxxxxxxxxx|   |
|   |   |xxxxxxxxxxx|   |
|   |   |xxxxxxxxxxx|   |
+---+---|xxxxxxxxxxx|---+
|   |   |xxxxxxxxxxx|   |
|   |   |xxxxxxxxxxx|   |
|   |   |xxxxxxxxxxx|   |
+---+---+-----------+---+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;Grid items can span one or more cells – by row or by column – this is called a grid area.&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;defining-a-grid&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#defining-a-grid&quot; aria-label=&quot;defining a grid permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Defining a Grid&lt;/h2&gt;&lt;p&gt;There are many different ways to define a grid. I’m going to start by focusing on a basic scenario: 4 columns x 5 rows. &lt;code class=&quot;language-text&quot;&gt;grid-template-rows&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;grid-template-columns&lt;/code&gt; allow us to define the count and sizing of rows and columns respectively. We can list out the tracks as shown in the example below.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;.my-grid-container {
  display: grid;
  grid-template-columns: 20px 20px 20px 20px;
  grid-template-rows: 20px 20px 20px 20px 20px;
}&lt;/div&gt;&lt;div&gt;.my-grid-container
+---+----+----+----+-------------+
|   |    |    |    |             |
|   |    |    |    |             |
+---+----+----+----+             |
|   |    |    |    |             |
|   |    |    |    |             |
+---+----+----+----+             |
|   |    |    |    |             |
|   |    |    |    |             |
+---+----+----+----+             |
|   |    |    |    |             |
|   |    |    |    |             |
+---+----+----+----+             |
|   |    |    |    |             |
|   |    |    |    |             |
+---+----+----+----+             |
|                                |
|                                |
|                                |
|                                |
+--------------------------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;A basic grid with 4 columns and 5 rows. The rows are defined using grid-template-rows and columns using grid-template-columns.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We have a grid ✅ Not the most useful grid ever, but a grid nonetheless. In the above example, each row is &lt;code class=&quot;language-text&quot;&gt;20px&lt;/code&gt; tall and each column is &lt;code class=&quot;language-text&quot;&gt;20px&lt;/code&gt; wide. The one thing to note here is that &lt;code class=&quot;language-text&quot;&gt;grid-template-rows&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;grid-template-columns&lt;/code&gt; allow us to define the grid tracks. The browser then generates the grid lines automatically. These lines are invisible. They are there to help us with positing items on the grid, but do not impact our design visually. That said, being able to see these lines is extremely helpful for debugging. Luckily for us Firefox has a built-in &lt;a href=&quot;https://www.mozilla.org/en-US/developer/css-grid&quot;&gt;Grid Inspector&lt;/a&gt; which visualizes the grid for us 🙌🏽&lt;/p&gt;&lt;p&gt;In this example, the grid has fixed track sizes. Which is a fancy way of saying that rows and/or columns have fixed widths. Therefore, the grid will remain the same size regardless of how big/small the container is.&lt;/p&gt;&lt;h3 id=&quot;flexible-grids&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#flexible-grids&quot; aria-label=&quot;flexible grids permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Flexible Grids&lt;/h3&gt;&lt;p&gt;We can also define grids with flexible track sizes. Or even have both fixed and flexible tracks at the same time! (See the example below.) Here percentage values refer to a percentage of the grid container.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;.my-weird-but-flexible-grid {
  display: grid;
  grid-template-columns: 20px 5% 80px 40%;
  grid-template-rows: 4rem 2vh 12% 80px 20em;
}&lt;/div&gt;&lt;div&gt;.my-weird-but-flexible-grid

+-+--+----+----------------------+
| |  |    |                 |    |
+-+--+----+-----------------+    |
+-+--+----+-----------------+    |
| |  |    |                 |    |
| |  |    |                 |    |
+-+--+----+-----------------+    |
| |  |    |                 |    |
+-+--+----+-----------------+    |
| |  |    |                 |    |
| |  |    |                 |    |
| |  |    |                 |    |
| |  |    |                 |    |
| |  |    |                 |    |
+-+--+----+-----------------+    |
|                                |
|                                |
|                                |
|                                |
|                                |
+--------------------------------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;A flexible grid where we are using a mixture of units for track measurements such as, pixels, percentage, viewport units and ems.&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;the-fr-unit&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-fr-unit&quot; aria-label=&quot;the fr unit permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The fr Unit&lt;/h3&gt;&lt;p&gt;Let’s look at another example of a flexible grid. In this case we are still building a 4x5 grid, but we want the rows and columns to stretch out and fill the entire container. To do this, we will use the &lt;code class=&quot;language-text&quot;&gt;fr&lt;/code&gt; unit.&lt;/p&gt;&lt;p&gt;At this point you are probably asking yourself. &lt;em&gt;The what unit?&lt;/em&gt; 🤷🏽‍♂️&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;.my-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
}
  /*
    The above can also be written as:
    grid-template-columns: repeat(4, 1fr);
    grid-template-rows: repeat(5, 1fr);
  */&lt;/div&gt;&lt;div&gt;.my-grid

+------+------+------+------+
|      |      |      |      |
|      |      |      |      |
|      |      |      |      |
+------+------+------+------+
|      |      |      |      |
|      |      |      |      |
|      |      |      |      |
+------+------+------+------+
|      |      |      |      |
|      |      |      |      |
|      |      |      |      |
+------+------+------+------+
|      |      |      |      |
|      |      |      |      |
|      |      |      |      |
+------+------+------+------+
|      |      |      |      |
|      |      |      |      |
|      |      |      |      |
+------+------+------+------+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;A flexible grid with 4 columns and 5 rows. It is made flexible by setting the rows and columns to 1fr.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;We have a new unit! The &lt;code class=&quot;language-text&quot;&gt;fr&lt;/code&gt; unit represents a fraction of the available space in the grid container. Have you ever used &lt;code class=&quot;language-text&quot;&gt;flex: 1&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;flex: 2&lt;/code&gt;, etc? This works exactly like that. You can specify track sizing as a ratio of free space, eg: &lt;code class=&quot;language-text&quot;&gt;1fr 2fr&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;📝 We can define track sizing as length, percentage or &lt;code class=&quot;language-text&quot;&gt;fr&lt;/code&gt;.&lt;/p&gt;&lt;h3 id=&quot;gutters&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#gutters&quot; aria-label=&quot;gutters permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Gutters&lt;/h3&gt;&lt;p&gt;It wouldn’t be a real grid without some gutters. For this we can use &lt;code class=&quot;language-text&quot;&gt;grid-column-gap&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;grid-row-gap&lt;/code&gt; properties, or the shorthand &lt;code class=&quot;language-text&quot;&gt;grid-gap&lt;/code&gt;. The grid only generates gutters between the tracks. There is no gutter before the first track or after the last track.&lt;/p&gt;&lt;p&gt;⚠️ Even though there is a gap between two adjacent tracks there is still only one grid line.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div lineHeight=&quot;copy&quot;&gt;.my-grid {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr 1fr 1fr;
  grid-gap: 1rem;
}&lt;/div&gt;&lt;div&gt;.my-grid


1     2      3      4     5
+----+-+----+-+----+-+----+ 1
|    | |    | |    | |    |
|    | |    | |    | |    |
+----+ +----+ +----+ +----+
+----+ +----+ +----+ +----+ 2
|    | |    | |    | |    |
|    | |    | |    | |    |
+----+ +----+ +----+ +----+
+----+ +----+ +----+ +----+ 3
|    | |    | |    | |    |
|    | |    | |    | |    |
+----+ +----+ +----+ +----+
+----+ +----+ +----+ +----+ 4
|    | |    | |    | |    |
|    | |    | |    | |    |
+----+ +----+ +----+ +----+
+----+ +----+ +----+ +----+ 5
|    | |    | |    | |    |
|    | |    | |    | |    |
+----+-+----+-+----+-+----+ 6&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;A flexible 4x5 grid with gutters. Gutters can be created by using grid-gap property.&lt;/div&gt;&lt;/div&gt;&lt;h2 id=&quot;positioning-grid-items&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#positioning-grid-items&quot; aria-label=&quot;positioning grid items permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Positioning Grid Items&lt;/h2&gt;&lt;p&gt;Now that we have defined a grid, let’s explore some options for how to place items on it. Much like flexbox, grid placement is not dependent on source order. This allows us to create complex layouts that can be drastically re-arranged using media queries. More on that later. Let’s focus on some basics for now.&lt;/p&gt;&lt;p&gt;Positioning items on a grid is quite similar to using absolute positioning. Except, instead of specifying locations in measurement units we specify start and end grid lines.&lt;/p&gt;&lt;div justifyContent=&quot;center&quot;&gt;&lt;div&gt;                      .my-grid

                      1     2      3      4     5
                      +----+-+----+-+----+-+----+ 1
                      |    | |    | |    | |    |
                      |    | |    | |    | |    |
                      |    | |    | |    | |    |
   grid-row-start (2)-------------&amp;gt; o-----------o &amp;lt;-----(5) grid-column-end
grid-column-start (3) |    | |    | |xxxxxxxxxxx|
                      |    | |    | |xxxxxxxxxxx|
                      |    | |    | |xxxxxxxxxxx|
                      +----+ +----+ |xxxxxxxxxxx|
                      |    | |    | |xxxxxxxxxxx|
                      |    | |    | |xxxxxxxxxxx|
                      |    | |    | |xxxxxxxxxxx|
grid-row-end (4)------------------&amp;gt; o-----------o 4
                      |    | |    | |    | |    |
                      |    | |    | |    | |    |
                      |    | |    | |    | |    |
                      +----+ +----+ +----+ +----+ 5
                      |    | |    | |    | |    |
                      |    | |    | |    | |    |
                      |    | |    | |    | |    |
                      +----+-+----+-+----+-+----+ 6&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;We can position items on the grid using grid-column-start, grid-column-end and grid-row-start, grid-row-end.&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Grid lines are automatically numbered. Starting with &lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt; for the topmost and leftmost lines. We use these numbers to declare &lt;code class=&quot;language-text&quot;&gt;grid-column-start&lt;/code&gt; / &lt;code class=&quot;language-text&quot;&gt;grid-column-end&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;grid-row-start&lt;/code&gt; / &lt;code class=&quot;language-text&quot;&gt;grid-row-end&lt;/code&gt;. We can also start counting from the end. For that we start with &lt;code class=&quot;language-text&quot;&gt;-1&lt;/code&gt; for the rightmost and topmost lines. Lastly, we can also specify these locations as spans. For example, &lt;code class=&quot;language-text&quot;&gt;grid-row-end: span 3&lt;/code&gt; means that the end location is &lt;code class=&quot;language-text&quot;&gt;starting grid line&lt;/code&gt; + &lt;code class=&quot;language-text&quot;&gt;3 tracks&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Below is a CodePen that demonstrates a few different positioning styles. Notice how grid items can overlap. We can use the &lt;code class=&quot;language-text&quot;&gt;z-index&lt;/code&gt; property to &lt;a href=&quot;https://drafts.csswg.org/css-grid/#z-order&quot;&gt;control the stacking order&lt;/a&gt;.&lt;/p&gt;&lt;div hash=&quot;pPKBqB&quot; title=&quot;CSS Grid Positioning&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;-automate-all-the-things&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#-automate-all-the-things&quot; aria-label=&quot; automate all the things permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;🤖 Automate All the Things&lt;/h2&gt;&lt;p&gt;I want to end by showcasing a couple more concepts through an example. I am going to replicate this &lt;a href=&quot;https://www.aldoshoes.com/us/en_US/men/laid-back-loafers&quot;&gt;product grid&lt;/a&gt; from the Aldo website. A few things to note here:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It is a 4x5 grid on large devices (&lt;code class=&quot;language-text&quot;&gt;&amp;gt; 60em&lt;/code&gt;)&lt;/li&gt;&lt;li&gt;There are 13 items placed on it&lt;/li&gt;&lt;li&gt;Some items span 2 columns and/or 2 rows&lt;/li&gt;&lt;li&gt;All images have a ratio of &lt;code class=&quot;language-text&quot;&gt;1000 : 1270&lt;/code&gt;&lt;/li&gt;&lt;li&gt;There is a &lt;code class=&quot;language-text&quot;&gt;1rem&lt;/code&gt; gutter and a &lt;code class=&quot;language-text&quot;&gt;1rem&lt;/code&gt; padding all around the grid&lt;/li&gt;&lt;li&gt;The maximum width of the grid is restricted to &lt;code class=&quot;language-text&quot;&gt;60em&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div hash=&quot;Gmdwxj&quot; title=&quot;Aldo Style Product Grid (CSS Grid)&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The grid also changes based on break points. It reduces to 3 columns on medium-sized devices (&lt;code class=&quot;language-text&quot;&gt;30em ↔️ 60em&lt;/code&gt;) and 2 columns on small devices &lt;code class=&quot;language-text&quot;&gt;&amp;lt; 30em&lt;/code&gt;. Finally, we need to maintain &lt;code class=&quot;language-text&quot;&gt;1000 : 1270&lt;/code&gt; ratio between the row and column track sizing.&lt;/p&gt;&lt;div justifyContent=&quot;space-around&quot; flexWrap=&quot;wrap&quot;&gt;&lt;div&gt;Large-Breakpoint
  min-width: 60em
(4 columns)


+-----------+ +-----------+
|  wide 2   | |           |
|           | |           |
+-----------+ |   wide 2  |
+----+ +----+ |   tall 2  |
|    | |    | |           |
|    | |    | |           |
+----+ +----+ +-----------+
+----+ +----+ +----+ +----+
|    | |    | |    | |    |
|    | |    | |    | |    |
+----+ +----+ +----+ +----+
+-----------+ +----+ +----+
|           | |    | |    |
|           | |    | |    |
|  wide 2   | +----+ +----+
|  tall 2   | +----+ +----+
|           | |    | |    |
|           | |    | |    |
+-----------+ +----+ +----+

|&amp;lt;----max-width: 60em----&amp;gt;|&lt;/div&gt;&lt;div&gt;Medium-Breakpoint
  min-width: 30em
  and max-width: 60em
(3 columns)

+------------------+
|      wide 3      |
|                  |
+------------------+
+-----------+ +----+
|           | |    |
|           | |    |
|  wide 2   | +----+
|  tall 2   | +----+
|           | |    |
|           | |    |
+-----------+ +----+
+----+ +----+ +----+
|    | |    | |    |
|    | |    | |    |
+----+ +----+ +----+
+-----------+ +----+
|           | |    |
|           | |    |
|  wide 2   | +----+
|  tall 2   | +----+
|           | |    |
|           | |    |
+-----------+ +----+
+----+ +----+ +----+
|    | |    | |    |
|    | |    | |    |
+----+ +----+ +----+&lt;/div&gt;&lt;div&gt;Small-Breakpoint
  min-width: 60em
(2 columns)


+-----------+
|  wide 2   |
|           |
+-----------+
+-----------+
|           |
|           |
|  wide 2   |
|  tall 2   |
|           |
|           |
+-----------+
+----+ +----+
|    | |    |
|    | |    |
+----+ +----+
+----+ +----+
|    | |    |
|    | |    |
+----+ +----+
+----+ +----+
|    | |    |
|    | |    |
+----+ +----+
+-----------+
|           |
|           |
|  wide 2   |
|  tall 2   |
|           |
|           |
+-----------+
+----+ +----+
|    | |    |
|    | |    |
+----+ +----+
+----+ +----+
|    | |    |
|    | |    |
+----+ +----+&lt;/div&gt;&lt;div as=&quot;figcaption&quot;&gt;The aldo style product grid. 2 columns on small devices, 3 on medium and 4 on large devices.&lt;/div&gt;&lt;/div&gt;&lt;h3 id=&quot;defining-the-row-and-column-sizes&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#defining-the-row-and-column-sizes&quot; aria-label=&quot;defining the row and column sizes permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Defining the Row and Column Sizes&lt;/h3&gt;&lt;p&gt;Previously, we used something like &lt;code class=&quot;language-text&quot;&gt;grid-template-columns: repeat(4, 1fr)&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;grid-template-rows: repeat(5, 1fr)&lt;/code&gt; to generate the grid. Because of the &lt;code class=&quot;language-text&quot;&gt;1000 : 1270&lt;/code&gt; ratio we can no longer do that. Instead, we need to use a bit of math to figure out the row and column sizes. For this we can use CSS variables and &lt;code class=&quot;language-text&quot;&gt;calc&lt;/code&gt; 🏄 We can calculate the width of the columns and height of the rows using this formula:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;width &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width_of_grid &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gutters &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; padding&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; number_of_columns&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
height &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1270&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div my=&quot;5&quot; style=&quot;overflow:auto&quot;&gt;&lt;div as=&quot;table&quot; width=&quot;100%&quot; mx=&quot;auto&quot; cellSpacing=&quot;0&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Break Point&lt;/th&gt;&lt;th&gt;Width of Grid&lt;/th&gt;&lt;th&gt;Gutters + Padding&lt;/th&gt;&lt;th&gt;Number of Columns&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;div as=&quot;tr&quot; bg=&quot;neutral.5&quot;&gt;&lt;td textAlign=&quot;left&quot;&gt;Default (less than 30em)&lt;/td&gt;&lt;td&gt;100vw&lt;/td&gt;&lt;td&gt;(1 + 2)rem&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;/div&gt;&lt;tr&gt;&lt;td textAlign=&quot;left&quot;&gt;min-width: 30em and&lt;br/&gt;max-width: 60em&lt;/td&gt;&lt;td&gt;100vw&lt;/td&gt;&lt;td&gt;(2 + 2)rem&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;/tr&gt;&lt;div as=&quot;tr&quot; bg=&quot;neutral.5&quot;&gt;&lt;td textAlign=&quot;left&quot;&gt;min-width: 60em&lt;/td&gt;&lt;td&gt;60em&lt;/td&gt;&lt;td&gt;(3 + 2)rem&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/div&gt;&lt;/tbody&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;So, for the default case &lt;code class=&quot;language-text&quot;&gt;width = (100vw - 3rem) / 2&lt;/code&gt;. Awesome! Let’s put it all together. We start by defining the default value in &lt;code class=&quot;language-text&quot;&gt;:root&lt;/code&gt;. Then at each break point we recalculate &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt; and update the &lt;code class=&quot;language-text&quot;&gt;grid-template-columns&lt;/code&gt; property.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;100vw - 3rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / 2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;--height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1270 * &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / 1000&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token selector&quot;&gt;.layout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-gap&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 1rem&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-auto-rows&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--height&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; screen &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 60em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;--width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;100vw - 4rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / 3&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.layout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;3&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; screen &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 60em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;:root&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;--width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calc&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;60em - 5rem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; / 4&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.layout&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;grid-template-columns&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;repeat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;4&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;--width&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;auto-rows&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#auto-rows&quot; aria-label=&quot;auto rows permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Auto Rows&lt;/h3&gt;&lt;p&gt;In the code snippet above you might have noticed &lt;code class=&quot;language-text&quot;&gt;grid-auto-rows: var(--height)&lt;/code&gt;. This tells the browser to automatically generate just enough rows to fit all the items. So if we add more items, it will add more rows and vice versa. The value for &lt;code class=&quot;language-text&quot;&gt;grid-auto-rows&lt;/code&gt; is what we want the height of the row to be.&lt;/p&gt;&lt;p&gt;The CodePen below demonstrates what the grid would look like at this point. Open it in the &lt;a href=&quot;http://codepen.io/winkerVSbecks/pen/dWjjWw&quot;&gt;edit mode&lt;/a&gt; to see how the resizing works and what happens when you add or remove items.&lt;/p&gt;&lt;div hash=&quot;dWjjWw&quot; title=&quot;Aldo Style Product Grid (CSS Grid) STEP 1 for blogpost&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;📝 Did you notice that we did not have to place the items on the grid?! If you don’t specify positioning then the browser automatically places items on the grid. This is known as &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-flow&quot;&gt;auto flow&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&quot;item-spans-️&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#item-spans-%EF%B8%8F&quot; aria-label=&quot;item spans ️ permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Item Spans ↔️&lt;/h3&gt;&lt;p&gt;As I mentioned earlier, some items span multiple tracks. For this we can use the &lt;code class=&quot;language-text&quot;&gt;grid-&amp;lt;row|column&amp;gt;-end: span &amp;lt;number&amp;gt;&lt;/code&gt; technique. The span size for the images remains the same across all break points. However, the product info spans 3 columns on medium-sized devices and 2 columns for all other breakpoints. Therefore, we apply &lt;code class=&quot;language-text&quot;&gt;wide-2 wide-3-m&lt;/code&gt; to it. The other items use &lt;code class=&quot;language-text&quot;&gt;wide-2 tall-2&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;.wide-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-column-end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; span 2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token selector&quot;&gt;.tall-2&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;grid-row-end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; span 2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token atrule&quot;&gt;&lt;span class=&quot;token rule&quot;&gt;@media&lt;/span&gt; screen &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;min-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 30em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;max-width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 60em&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token selector&quot;&gt;.wide-3-m&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;grid-column-end&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; span 3&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;vmazxG&quot; title=&quot;Aldo Style Product Grid (CSS Grid) STEP 2 for blogpost&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;p&gt;Want to learn more about auto placement? Check out Rachel Andrew’s fantastic &lt;a href=&quot;http://gridbyexample.com/video/series-auto-placement-span&quot;&gt;tutorial&lt;/a&gt; and &lt;a href=&quot;http://codepen.io/rachelandrew/pen/LRWPNp&quot;&gt;demo&lt;/a&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;h3 id=&quot;dense-packing&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#dense-packing&quot; aria-label=&quot;dense packing permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Dense Packing&lt;/h3&gt;&lt;p&gt;We have a grid. We used auto placement to position items and some items span multiple columns &amp;amp; rows. So we’re done? Not quite. If you inspect the above CodePen in &lt;a href=&quot;http://codepen.io/winkerVSbecks/pen/vmazxG&quot;&gt;edit mode&lt;/a&gt; you will notice that the grid ends up with &lt;em&gt;holes&lt;/em&gt; at certain break points.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:48.958333333333336%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;196\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20196\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M13%201C4%203%204%203%205%206l1%203h23l24-1%203-3c2%200%204-1%204-3V0H39L13%201m101%201c-8%201-8%201-7%204%200%203%201%203%207%203l14%201c7%200%2030-1%2028-2-2%200-1-2%202-2%203-1%205-3%205-5-1-2-41-1-49%201m147%201c-2%207-3%2010-2%2011l21%204c6%200%209-4%206-6l-4-2-7-5c-5-4-6-5-10-5-3%200-4%200-4%203m30%2097v62h93V38h-93v62m1%200v61h91V39h-91v61M0%2056c0%2015%200%2016%202%2016l2%201-1%201H2v1l2%201-1%201c-1%200-2%201-1%202l-1%201c-2%200-1%207%201%209v4c-2%200-3%208-1%208s2%203%201%204l-2%205%201%204%201%202-1%202-1%205v6h6l7%201H0v30h80V40H0v16m107%2070v15h21c16%201%2037%200%2030-1l2-1c5-3%202-8-4-8-5%200-8-1-8-2%200-2-13-7-16-7v3c1%203%201%203-13%200l-10-3-2%204m102%2012v3h19c20%201%2035%200%2031-1-1-1-1-1%201-1l4-2v-1c-10%203-23%204-32%202l-14-2h-9v2M80%20177c-6%203-8%206-8%2011%201%208%202%208%2013%208l9-1h2c1%201%201%201%201-3l-1-8c-1-7-9-10-16-7\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;holes in the grid&quot; title=&quot;holes in the grid&quot; src=&quot;/static/a6a37a3f738abf26fece64bbffc66a57/4ad3a/grid-holes.png&quot; srcSet=&quot;/static/a6a37a3f738abf26fece64bbffc66a57/477c9/grid-holes.png 288w,/static/a6a37a3f738abf26fece64bbffc66a57/533c1/grid-holes.png 576w,/static/a6a37a3f738abf26fece64bbffc66a57/4ad3a/grid-holes.png 1152w,/static/a6a37a3f738abf26fece64bbffc66a57/b8bf8/grid-holes.png 1728w,/static/a6a37a3f738abf26fece64bbffc66a57/ca3c3/grid-holes.png 1850w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;This is because by default auto placement uses a &lt;em&gt;sparse&lt;/em&gt; packing algorithm which can lead to &lt;em&gt;holes&lt;/em&gt; in the layout. The good news is that we can switch to a &lt;em&gt;dense&lt;/em&gt; packing algorithm which causes the browser to backtrack and fill any empty cells in the layout &lt;img src=&quot;/13d2c87d597ba5c56edff9a85dcef8df/parrot.gif&quot; alt=&quot;party parrot&quot; display=&quot;inline&quot; width=&quot;1em&quot; mb=&quot;{0}&quot;/&gt;&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;diff&quot;&gt;&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;.layout {
&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; grid-gap: 1rem;
&lt;/span&gt;&lt;span class=&quot;token inserted-sign inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;+&lt;/span&gt; grid-auto-flow: dense;
&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; grid-template-columns: repeat(2, var(--width));
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; grid-auto-rows: var(--height);
&lt;/span&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That’s it! Below is the final version. And here’s &lt;a href=&quot;https://winkervsbecks.github.io/grid-experiments/vinyl&quot;&gt;another example&lt;/a&gt; that uses auto layout and dense packing to display music albums.&lt;/p&gt;&lt;div hash=&quot;Gmdwxj&quot; title=&quot;Aldo Style Product Grid (CSS Grid)&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div demo=&quot;https://winkervsbecks.github.io/grid-experiments&quot; source=&quot;https://github.com/winkerVSbecks/grid-experiments&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;conclusion&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#conclusion&quot; aria-label=&quot;conclusion permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Take a moment to think about the possibilities 🤔 Think of all the crazy layouts we can build now. Can’t think of any? Not a problem. Hop on over to Jen Simmons’s &lt;a href=&quot;http://labs.jensimmons.com&quot;&gt;Layout Lab&lt;/a&gt; for some ideas. CSS Grids will likely have a drastic impact on web design. All those layouts you abandoned because they were not possible with CSS will likely be possible thanks to CSS Grids.&lt;/p&gt;&lt;p&gt;What Next? Did you know you can name grid lines? Did you know you can align items in a track using &lt;code class=&quot;language-text&quot;&gt;align&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;justify&lt;/code&gt; properties? Did you know you can specify sizes as a range using &lt;code class=&quot;language-text&quot;&gt;minmax&lt;/code&gt;? There is so much more to discover! I know it can feel a bit overwhelming. Take little steps. Build things. Experiment. It’s okay to not understand everything at once.&lt;/p&gt;&lt;h5&gt;Further Reading&lt;/h5&gt;&lt;ul&gt;&lt;li class=&quot;mb2&quot;&gt;&lt;a href=&quot;http://gridbyexample.com&quot;&gt;Grid by Example&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;mb2&quot;&gt;&lt;a href=&quot;http://jonibologna.com/spring-into-css-grid&quot;&gt;Spring Into CSS Grid 🌼&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;mb2&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout&quot;&gt;Basic concepts of grid layout – MDN&lt;/a&gt;&lt;/li&gt;&lt;li class=&quot;mb2&quot;&gt;&lt;a href=&quot;https://drafts.csswg.org/css-grid&quot;&gt;CSS Grid Spec&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Git Rebase]]></title><description><![CDATA[What is a rebase? Assume the following git history where you are working on the  my-feature  branch. After  git rebase master  this would…]]></description><link>https://varun.ca/rebase/</link><guid isPermaLink="false">https://varun.ca/rebase/</guid><pubDate>Wed, 01 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;h3 id=&quot;what-is-a-rebase&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#what-is-a-rebase&quot; aria-label=&quot;what is a rebase permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;What is a rebase?&lt;/h3&gt;&lt;p&gt;Assume the following git history where you are working on the &lt;code class=&quot;language-text&quot;&gt;my-feature&lt;/code&gt; branch.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;          A---B---C my-feature
         /
    D---E---F---G master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After &lt;code class=&quot;language-text&quot;&gt;git rebase master&lt;/code&gt; this would become:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;                  A--B--C my-feature
                 /
    D---E---F---G master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;git rebase origin/master&lt;/code&gt; rebases your current branch against master&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;git rebase -i origin/master&lt;/code&gt; is the interactive version which allows you to do things such as squashing commits.&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;workflow-for-single-remote&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#workflow-for-single-remote&quot; aria-label=&quot;workflow for single remote permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Workflow for Single Remote&lt;/h2&gt;&lt;p&gt;This is assuming:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Everyone on your team is working from one repository.&lt;/li&gt;&lt;li&gt;You are currently on a feat/chore/fix branch and not on &lt;code class=&quot;language-text&quot;&gt;master&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;git fetch origin
git rebase -i origin/master&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point the editor will launch and will allow you to pick commits for squashing:&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:70.83333333333333%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;284\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20284\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M23%2038c-2%2027-1%20211%200%20213%202%202%20352%202%20354%200%201-2%202-211%200-223v-6H23v16\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;rebase starts&quot; title=&quot;rebase starts&quot; src=&quot;/static/add9985ccba41df0bacf86e69cedf71b/4ad3a/rebase-open.png&quot; srcSet=&quot;/static/add9985ccba41df0bacf86e69cedf71b/477c9/rebase-open.png 288w,/static/add9985ccba41df0bacf86e69cedf71b/533c1/rebase-open.png 576w,/static/add9985ccba41df0bacf86e69cedf71b/4ad3a/rebase-open.png 1152w,/static/add9985ccba41df0bacf86e69cedf71b/b8bf8/rebase-open.png 1728w,/static/add9985ccba41df0bacf86e69cedf71b/5b503/rebase-open.png 1976w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;We are going to squash all commits into one. Leave the first commit untouched and convert all the other &lt;code class=&quot;language-text&quot;&gt;pick&lt;/code&gt; into &lt;code class=&quot;language-text&quot;&gt;squash&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;s&lt;/code&gt;. Save and close the editor window.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:70.83333333333333%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;284\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20284\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M23%2038c-2%2027-1%20211%200%20213%202%202%20352%202%20354%200%201-2%202-211%200-223v-6H23v16\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;squash the commits&quot; title=&quot;squash the commits&quot; src=&quot;/static/e244f1c9065fdec264882916a9037ffe/4ad3a/rebase-squash.png&quot; srcSet=&quot;/static/e244f1c9065fdec264882916a9037ffe/477c9/rebase-squash.png 288w,/static/e244f1c9065fdec264882916a9037ffe/533c1/rebase-squash.png 576w,/static/e244f1c9065fdec264882916a9037ffe/4ad3a/rebase-squash.png 1152w,/static/e244f1c9065fdec264882916a9037ffe/b8bf8/rebase-squash.png 1728w,/static/e244f1c9065fdec264882916a9037ffe/5b503/rebase-squash.png 1976w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;If no conflicts were encountered the rebase will complete and you move to the final step. Your editor will open up again. This time it shows you the messages from the various commits that are going to be squashed. Here you get a chance to compose the message for the new squashed commit.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use a descriptive commit message.&lt;/li&gt;&lt;li&gt;If you have a Pivotal Tracker, JIRA, or Github issue number for the feature, reference it in the commit.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:70.83333333333333%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;284\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20284\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M23%2031c-2%2016-1%20218%200%20220%202%202%20352%202%20354%200l1-111-1-114v-4H23v9\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;all the commit messages&quot; title=&quot;all the commit messages&quot; src=&quot;/static/24b0386d7c11bba31905860194c6ba89/4ad3a/all-the-messages.png&quot; srcSet=&quot;/static/24b0386d7c11bba31905860194c6ba89/477c9/all-the-messages.png 288w,/static/24b0386d7c11bba31905860194c6ba89/533c1/all-the-messages.png 576w,/static/24b0386d7c11bba31905860194c6ba89/4ad3a/all-the-messages.png 1152w,/static/24b0386d7c11bba31905860194c6ba89/b8bf8/all-the-messages.png 1728w,/static/24b0386d7c11bba31905860194c6ba89/5b503/all-the-messages.png 1976w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Save and close the editor window once you have composed a new git message.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:70.83333333333333%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;284\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20284\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M23%2031c-2%2016-1%20218%200%20220%202%202%20352%202%20354%200%201-2%202-211%200-223v-6H23v9\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;new commit message&quot; title=&quot;new commit message&quot; src=&quot;/static/e1c726df1ed31f8387d35e37e419f67b/4ad3a/new-message.png&quot; srcSet=&quot;/static/e1c726df1ed31f8387d35e37e419f67b/477c9/new-message.png 288w,/static/e1c726df1ed31f8387d35e37e419f67b/533c1/new-message.png 576w,/static/e1c726df1ed31f8387d35e37e419f67b/4ad3a/new-message.png 1152w,/static/e1c726df1ed31f8387d35e37e419f67b/b8bf8/new-message.png 1728w,/static/e1c726df1ed31f8387d35e37e419f67b/5b503/new-message.png 1976w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;At this point the rebase is complete 🎉 Last step, push your changes to remote.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin my-feature -f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Yes, that’s a force push there. Because you have successfully re-written git history. Where you previously had multiple commits you now only have one commit.&lt;/p&gt;&lt;h3 id=&quot;resolving-conflicts&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#resolving-conflicts&quot; aria-label=&quot;resolving conflicts permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Resolving Conflicts&lt;/h3&gt;&lt;p&gt;During the rebase process you might encounter conflicts.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:51.041666666666664%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;204\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20204\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M20%2018l-1%2083%201%2075h361v-75l-1-83v-7H20v7\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;conflitc&quot; title=&quot;conflitc&quot; src=&quot;/static/9ac6e91d9027b086b45c27f318037ef2/4ad3a/conflicts.png&quot; srcSet=&quot;/static/9ac6e91d9027b086b45c27f318037ef2/477c9/conflicts.png 288w,/static/9ac6e91d9027b086b45c27f318037ef2/533c1/conflicts.png 576w,/static/9ac6e91d9027b086b45c27f318037ef2/4ad3a/conflicts.png 1152w,/static/9ac6e91d9027b086b45c27f318037ef2/b8bf8/conflicts.png 1728w,/static/9ac6e91d9027b086b45c27f318037ef2/9cac8/conflicts.png 2288w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Relax. Take a deep to breath. We can deal with this 💪&lt;/p&gt;&lt;p&gt;Start by running &lt;code class=&quot;language-text&quot;&gt;git status&lt;/code&gt; this will show you a list of files that have conflicts. Go through them one by one and resolve conflicts.&lt;/p&gt;&lt;p&gt;The conflicts show up something like this (there can be more than one in a file):&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;diff&quot;&gt;&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the first line
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the second line
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the third line I added
&lt;/span&gt;&lt;span class=&quot;token deleted-arrow deleted&quot;&gt;&lt;span class=&quot;token prefix deleted&quot;&gt;&amp;lt;&lt;/span&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD
&lt;/span&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; Someone else added this line
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; Someone else added this line too
&lt;/span&gt;=======
&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the fourth line I added
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the fifth line I added
&lt;/span&gt;&lt;span class=&quot;token inserted-arrow inserted&quot;&gt;&lt;span class=&quot;token prefix inserted&quot;&gt;&amp;gt;&lt;/span&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; f78d8ae... &amp;lt;commit message&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here everything between &lt;code class=&quot;language-text&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;=======&lt;/code&gt; is stuff that is in the &lt;code class=&quot;language-text&quot;&gt;master&lt;/code&gt; branch. And everything between &lt;code class=&quot;language-text&quot;&gt;=======&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt; f78d8ae... &amp;lt;commit message&amp;gt;&lt;/code&gt; is your on the &lt;code class=&quot;language-text&quot;&gt;my-feature&lt;/code&gt; branch. Git could not automatically merge these so it wants you to decide how these lines should be merged.&lt;/p&gt;&lt;p&gt;You can pick &lt;code class=&quot;language-text&quot;&gt;master&lt;/code&gt; version or your version depending on what you were implementing. You are the best judge here. Sometimes the correct answer will be a combination of the two.&lt;/p&gt;&lt;p&gt;Pick the appropriate combination and delete the conflict markers (&lt;code class=&quot;language-text&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;=======&lt;/code&gt;, etc).&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;diff&quot;&gt;&lt;pre class=&quot;language-diff&quot;&gt;&lt;code class=&quot;language-diff&quot;&gt;&lt;span class=&quot;token unchanged&quot;&gt;&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the first line
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the second line
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the third line I added
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; Someone else added this line
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the fourth line I added
&lt;span class=&quot;token prefix unchanged&quot;&gt; &lt;/span&gt; This is the fifth line I added&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Do the same for all the other files with conflicts. Then:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Stage the changes by executing &lt;code class=&quot;language-text&quot;&gt;git add &amp;lt;file-name&amp;gt;&lt;/code&gt;&lt;/li&gt;&lt;li&gt;Continue the rebase &lt;code class=&quot;language-text&quot;&gt;git rebase --contine&lt;/code&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;If you messed something up you can always &lt;code class=&quot;language-text&quot;&gt;git rebase --abort&lt;/code&gt;. Remember to rebase early and often. This will prevent messy merge conflicts.&lt;/p&gt;&lt;h2 id=&quot;workflow-for-multiple-remotes&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#workflow-for-multiple-remotes&quot; aria-label=&quot;workflow for multiple remotes permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Workflow for Multiple Remotes&lt;/h2&gt;&lt;p&gt;This is assuming:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;There is a main repository that you can only update through pull requests. We will call this remote &lt;code class=&quot;language-text&quot;&gt;upstream&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;You create a fork of this repository and clone that locally. We will call your forked remote &lt;code class=&quot;language-text&quot;&gt;origin&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The setup process will be something like this:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; clone git@github.com:&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;your user name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;/&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;your repo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;.git
$ &lt;span class=&quot;token builtin class-name&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;your repo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; remote &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt; upstream git@github.com:rangle/&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;your repo&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;.git&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The only difference between this setup and previous is that you will be fetching &lt;code class=&quot;language-text&quot;&gt;upstream&lt;/code&gt; and rebasing against &lt;code class=&quot;language-text&quot;&gt;upstream/master&lt;/code&gt;. Then push to your forked &lt;code class=&quot;language-text&quot;&gt;origin&lt;/code&gt;. The actual rebase &amp;amp; conflict resolution process is the same.&lt;/p&gt;&lt;p&gt;Let us break this down step-by-step:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;shell&quot;&gt;&lt;pre class=&quot;language-shell&quot;&gt;&lt;code class=&quot;language-shell&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;# (1) Start by updating your fork from the main repo.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# At this point you are on the master branch.&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; fetch upstream
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; rebase upstream/master

&lt;span class=&quot;token comment&quot;&gt;# (2) Create a new branch for your feature&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; checkout -b my-feature

&lt;span class=&quot;token comment&quot;&gt;# (3) Implement the feature and commit your changes as usual.&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# This might be single or multiple commits.&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;# (4) Push your changes to origin&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin my-feature

&lt;span class=&quot;token comment&quot;&gt;# (5) Before we rebase we must get the latest upstream&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; fetch upstream

&lt;span class=&quot;token comment&quot;&gt;# (6) Next, do the actual rebase. This point onwards it is the&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;# same process as single remote workflow above.&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; rebase upstream/master

&lt;span class=&quot;token comment&quot;&gt;# (7) Push your changes to origin not upstream!&lt;/span&gt;
$ &lt;span class=&quot;token function&quot;&gt;git&lt;/span&gt; push origin my-feature -f&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;github&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#github&quot; aria-label=&quot;github permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Github&lt;/h2&gt;&lt;p&gt;If you are using github then a lot of this stuff can be done through their GUI. Read more about it &lt;a href=&quot;https://github.com/blog/2243-rebase-and-merge-pull-requests&quot;&gt;here&lt;/a&gt;.
&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:60.06944444444444%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;241\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20241\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M10%2019v10h21V8H10v11m39-1c-4%204-1%2012%205%2012%203%200%207-4%207-7%200-6-8-9-12-5m103%201h-3l-3%201h-1c-2-1-7-1-8%201h-1l-1-2-2%202h-1c-2-3-4-2-4%201%200%202%200%203%201%202h7c3%200%204-1%204-2l1-1%201%201c0%201%201%202%204%202l3-1h2c2%202%203%201%204-2%200-3-1-4-3-2M49%2053c-4%204-1%2012%205%2012%203%200%207-4%207-7%200-6-9-9-12-5m-1%2033l-1%208v8h91V85H93l-45%201m-1%2072v18h150v-36H47v18m282%2054l-1%208%201%208h44v-16h-44m5%206v3h14l2%201%201-1h11c1%202%204%201%204-2%200-1%200-2-1-1h-26c0-2-4-1-5%200\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;github squash and rebase features&quot; title=&quot;github squash and rebase features&quot; src=&quot;/static/019129bdd10f0dbeedc8501a82bb76f0/4ad3a/github.png&quot; srcSet=&quot;/static/019129bdd10f0dbeedc8501a82bb76f0/477c9/github.png 288w,/static/019129bdd10f0dbeedc8501a82bb76f0/533c1/github.png 576w,/static/019129bdd10f0dbeedc8501a82bb76f0/4ad3a/github.png 1152w,/static/019129bdd10f0dbeedc8501a82bb76f0/573d3/github.png 1650w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;h2 id=&quot;undo&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#undo&quot; aria-label=&quot;undo permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Undo&lt;/h2&gt;&lt;p&gt;Scenario: I messed up conflict resolution during a rebase, pushed changes to remote and lost hours of work 😭&lt;/p&gt;&lt;img src=&quot;/d8127238a47c9720f5fbaae2433f8184/ive-made-a-huge-mistake.gif&quot; alt=&quot;i&amp;#x27;ve made a huge mistake&quot; class=&quot;center&quot; style=&quot;width:275px&quot;/&gt;&lt;p&gt;Use &lt;code class=&quot;language-text&quot;&gt;git reflog&lt;/code&gt; to undo your rebase. Running the command will show you the &lt;a href=&quot;https://git-scm.com/docs/git-reflog&quot;&gt;reflog&lt;/a&gt; for your local repository. For example:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;adc164e HEAD@{0}: rebase -i (finish): returning to refs/heads/my-feature
adc164e HEAD@{1}: rebase -i (pick): Bugfix: SVG icons on android
8ab621c HEAD@{2}: rebase -i (start): checkout master
067be75 HEAD@{3}: checkout: moving from master to my-feature
8ab621c HEAD@{4}: pull: Fast-forward&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this scenario to undo my rebase I need to run &lt;code class=&quot;language-text&quot;&gt;git reset --hard HEAD@{3}&lt;/code&gt; because that was the last state before I started the rebase.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Component based SVG Icon System]]></title><description><![CDATA[Much has been written about  SVG Icon Systems  and why they are  amazing . In this post I want to share my workflow for creating a component…]]></description><link>https://varun.ca/icon-component/</link><guid isPermaLink="false">https://varun.ca/icon-component/</guid><pubDate>Sat, 11 Feb 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:67.3611111111111%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;270\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20270\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M28%2018l-1%202-1%202h-3c0-1%200-2-1-1l-1%203-1%204-1%20107c0%20104%200%20106%202%20109l5%205c6%204%20342%204%20348%200l5-5c2-3%203-5%203-109a1250%201250%200%2000-3-109c0-8-1-9-6-9l-4%201-1%204-1%202c0-2%200-2-1-1-2%202-14%201-16-1h-2c0%202-1%202-7%202l-8-1h-54l-73%201h-72v-2c0-1%200-2-1-1h-1l-1%201c0%203-14%203-15%200-1-2-23-2-24%200-1%203-14%203-15%200l-2-1-1-1c-1-1-1%200-1%201v3H63c-9%200-10%200-10-2-1-2-3-2-4%200l-1-2c0-3-3-4-5-1-2%202-3%203-3%201%200-3-3-3-5%200l-2%202-1-2c-1-2-3-4-4-2m154%202c0%202%201%202%205%202h28c22%200%2021%200%2021-1%200-3-3-3-4-1h-2l-7-1h-28l-2%201-6-2c-5%200-5%201-5%202M22%20133v105h356V28H22v105m84-56c-3%203%200%205%207%204h17c2-2%200-4-3-4h-17l-1%201-1%203-1-3-1-1m152%201c0%202%201%203%202%203%2021%201%2023%201%2023-2%200-1-1-2-3-2h-17c-1-1-1-1-2%201l-1%201c0-3-2-3-2-1m-29%20150l-1%202c0%202%202%202%2014%202%2014%200%2015%200%2015-2l-13-1-12-1h-3\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;icons&quot; title=&quot;icons&quot; src=&quot;/static/ccd0c0bbb4c18f6d804c563ec2389fb7/4ad3a/icons.png&quot; srcSet=&quot;/static/ccd0c0bbb4c18f6d804c563ec2389fb7/477c9/icons.png 288w,/static/ccd0c0bbb4c18f6d804c563ec2389fb7/533c1/icons.png 576w,/static/ccd0c0bbb4c18f6d804c563ec2389fb7/4ad3a/icons.png 1152w,/static/ccd0c0bbb4c18f6d804c563ec2389fb7/b8bf8/icons.png 1728w,/static/ccd0c0bbb4c18f6d804c563ec2389fb7/efb68/icons.png 2032w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;div demo=&quot;https://react-icon.now.sh&quot; source=&quot;https://github.com/winkerVSbecks/react-icon-system-demo&quot;&gt;&lt;/div&gt;&lt;p&gt;Much has been written about &lt;a href=&quot;https://css-tricks.com/svg-sprites-use-better-icon-fonts/&quot;&gt;SVG Icon Systems&lt;/a&gt; and why they are &lt;a href=&quot;http://jonibologna.com/svg-sprites-and-icon-systems-are-super/&quot;&gt;amazing&lt;/a&gt;. In this post I want to share my workflow for creating a component based SVG icon system.&lt;/p&gt;&lt;p&gt;The focus here is on front-end JavaScript frameworks such as React, Angular, Vue.js, etc. These frameworks allow us to split the UI into discrete, reusable components. Which means we can create a generic icon component. And use the &lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt; property to render inline the appropriate icon.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- React --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;cloud-with-snow&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;f4 blue&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Angular --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;cloud-with-snow&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;f4 blue&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Vue.JS --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;cloud-with-snow&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;f4 blue&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;icon&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;prepare-svg-files&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#prepare-svg-files&quot; aria-label=&quot;prepare svg files permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Prepare SVG Files&lt;/h2&gt;&lt;p&gt;Our starting point will be &lt;code class=&quot;language-text&quot;&gt;.svg&lt;/code&gt; files – one per icon. In most cases these will be generated using an app such as Illustrator or Sketch, although you can also obtain them from an icon pack, for example: &lt;a href=&quot;https://github.com/google/material-design-icons&quot;&gt;Material Design icons&lt;/a&gt;, &lt;a href=&quot;http://iconmonstr.com/&quot;&gt;iconmonstr&lt;/a&gt;, &lt;a href=&quot;http://svgicons.sparkk.fr/&quot;&gt;SVG Icons&lt;/a&gt;, etc.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:63.19444444444444%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;253\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20253\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M134%2041v7h13V36l-7-1h-6v6m218-3l-2%203%202%203c0%202%204%203%207%202h2l2-3c0-4-1-5-5-7-3-1-3-1-6%202m-217%204v5h11V37l-6-1h-5v6m107%2036l1%207h12V72h-13v6m-104-2c-6%205-5%208%203%208h6v-4c0-8-3-9-9-4m105%202l1%205h10V73h-11v5m-141%2031l-1%206c0%205%201%207%204%207%202%200%206-5%206-7%200-4-6-8-9-6m36%200c-5%202-5%208-1%2011%203%203%207%201%209-3s-3-10-8-8m35%201c-5%204-3%2011%204%2011%206%200%208-7%203-11l-3-2-4%202m38-1c-7%202-7%2010%201%2012%206%202%209-7%204-11-2-2-3-2-5-1M18%20224c0%206%202%209%208%2011l177%201h173l3-3%203-5v-2H19v-4c-1-3-1-3-1%202\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;folder full of SVG icon files&quot; title=&quot;folder full of SVG icon files&quot; src=&quot;/static/5d60baa3f816f5580e7c35e573be6122/4ad3a/folder-of-icons.png&quot; srcSet=&quot;/static/5d60baa3f816f5580e7c35e573be6122/477c9/folder-of-icons.png 288w,/static/5d60baa3f816f5580e7c35e573be6122/533c1/folder-of-icons.png 576w,/static/5d60baa3f816f5580e7c35e573be6122/4ad3a/folder-of-icons.png 1152w,/static/5d60baa3f816f5580e7c35e573be6122/b8bf8/folder-of-icons.png 1728w,/static/5d60baa3f816f5580e7c35e573be6122/cb93d/folder-of-icons.png 2304w,/static/5d60baa3f816f5580e7c35e573be6122/03692/folder-of-icons.png 2440w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;I like to start by running all the files through &lt;a href=&quot;https://github.com/svg/svgo&quot;&gt;GitHub - svg/svgo&lt;/a&gt; or &lt;a href=&quot;https://jakearchibald.github.io/svgomg/&quot;&gt;SVGOMG&lt;/a&gt;. This not only optimizes the SVG but also strips out any editor artifacts and tries to reduce it to a single &lt;code class=&quot;language-text&quot;&gt;&amp;lt;path&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Take a moment to visually check all your icon files. You might have to play with the SVGO settings, especially the precision setting, to ensure that the optimized version does not get distorted.&lt;/p&gt;&lt;p&gt;Next we are going to make a couple of modifications to all the &lt;code class=&quot;language-text&quot;&gt;.svg&lt;/code&gt; files.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;Ensure that all the icons use &lt;code class=&quot;language-text&quot;&gt;viewBox&lt;/code&gt; and remove any &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt; or &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt; attributes. You can configure SVGO to do this for you automatically. This will &lt;a href=&quot;https://youtu.be/af4ZQJ14yu8?t=309&quot;&gt;make it easier&lt;/a&gt; to control the size of the icon.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Set the &lt;code class=&quot;language-text&quot;&gt;fill&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;stroke&lt;/code&gt; (or whichever of the two you are using) to &lt;code class=&quot;language-text&quot;&gt;currentColor&lt;/code&gt;. This sets the icon colour to be the same as the surrounding text. We can then control this colour by setting the &lt;code class=&quot;language-text&quot;&gt;color&lt;/code&gt; property on the &lt;code class=&quot;language-text&quot;&gt;icon&lt;/code&gt; element.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;At this point the SVG files should look something like this:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;viewBox&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;0 0 20 20&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;currentColor&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;generate-the-sprite-sheet&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#generate-the-sprite-sheet&quot; aria-label=&quot;generate the sprite sheet permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Generate the Sprite Sheet&lt;/h2&gt;&lt;p&gt;One of the more popular techniques for implementing an icon system is to use &lt;code class=&quot;language-text&quot;&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;&amp;lt;use&amp;gt;&lt;/code&gt; elements.&lt;/p&gt;&lt;blockquote class=&quot;mv5&quot;&gt;&lt;p&gt;An improvement is to use the &lt;code&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; element in SVG instead of directly referencing shapes (or a &lt;code&gt;&amp;lt;g&amp;gt;&lt;/code&gt;), because you can define the &lt;code&gt;viewBox&lt;/code&gt; directly on the &lt;code&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; and then not need one when you &lt;code&gt;&amp;lt;use&amp;gt;&lt;/code&gt; it later in an &lt;code&gt;&amp;lt;svg&amp;gt;&lt;/code&gt;.&lt;/p&gt;&lt;cite&gt;— Chris Coyier (&lt;a href=&quot;https://css-tricks.com/svg-symbol-good-choice-icons/&quot;&gt;SVG symbol a Good Choice for Icons&lt;/a&gt;)&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;&amp;lt;symbol&amp;gt;&lt;/code&gt; element allows us to define an SVG template. It is never displayed. Therefore, we can use it to create an icon sprite sheet.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;http://www.w3.org/2000/svg&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xmlns:&lt;/span&gt;xlink&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;http://www.w3.org/1999/xlink&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token style-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token style language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;position&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;absolute&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;0&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;span class=&quot;token property&quot;&gt;visibility&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt;hidden&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;symbol&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;sun&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;viewBox&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;0 0 20 20&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;currentColor&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;symbol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;symbol&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;moon&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;viewBox&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;0 0 20 20&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;currentColor&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;...&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;symbol&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can then render an icon using the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;use&amp;gt;&lt;/code&gt; element.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;use&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;&lt;span class=&quot;token namespace&quot;&gt;xlink:&lt;/span&gt;href&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;moon&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you are working with React or Angular or Vue.js then there is a good chance that your project was setup using &lt;a href=&quot;https://webpack.js.org/&quot;&gt;webpack&lt;/a&gt;. We will use the &lt;a href=&quot;https://www.npmjs.com/package/svg-sprite-loader&quot;&gt;svg-sprite-loader&lt;/a&gt; for webpack to convert a folder full of SVG files into an icon sprite sheet.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; files &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; require&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;!svg-sprite-loader!./assets&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;.*\.svg$&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
files&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;files&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To do so:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;We are using &lt;a href=&quot;https://webpack.js.org/guides/dependency-management/#require-context&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;require.conext&lt;/code&gt;&lt;/a&gt; to generate a list of SVG files in the &lt;code class=&quot;language-text&quot;&gt;assets&lt;/code&gt; folder.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We then iterate over this list and load all the files using &lt;code class=&quot;language-text&quot;&gt;svg-sprite-loader&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;svg-sprite-loader&lt;/code&gt; then generates the sprite sheet and injects it into DOM on run-time. Similar to how &lt;a href=&quot;https://github.com/webpack/style-loader&quot;&gt;style-loader&lt;/a&gt; works.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:20.48611111111111%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;82\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%2082\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2037v3h8l18%201-2%201c-2%200-2%200-1%201%203%202%205%202%206%201v-3h-2l2-1%202%202c0%202%200%202%201%201h1c1%201%201%202%202%201l-1-2c-2-2-2-2%205-2%208-1%2012%200%209%202-2%200-2%200-1%202%202%201%202%201%205-1%201-1%201-1-1-2-1-1-1-1%201-1l2%202v3l1-3%202-2h344v-7H0v4m150%2024l2%202v1l-2-1c-2-2-3-2-3%200h-1l-1-2-1%201v2l-2-1h-2c-1-2-1-2-2-1h-1l-1%201h-2c0-1-1-2-3-2-1%200-2%200-1%201l-1%201-1-1h-1c0%202%200%202-1%200h-2c0%202-2%203-2%201h-1c-1%202%202%202%2038%202s38-1%2039-2l-1-2-1%202-1%201-1-1v-2l-1%201-2%202-2-2c0-1-1-2-7-2-5%200-6%200-6%202l-1%202v-2l-1-2-1%202-1%202v-2l-1-2-1%202c0%202%200%202-1%200%200-2-1-2-1-1l-1%202-2%201-2-2c0-2-2-1-2%201h-1l-1-2v2h-1c0-2-6-3-8-2\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Injected sprite sheet&quot; title=&quot;Injected sprite sheet&quot; src=&quot;/static/48f677cec42304036cf3089de6e0f8bc/5ef17/injected-sprite-sheet.jpg&quot; srcSet=&quot;/static/48f677cec42304036cf3089de6e0f8bc/c14c5/injected-sprite-sheet.jpg 288w,/static/48f677cec42304036cf3089de6e0f8bc/ac097/injected-sprite-sheet.jpg 576w,/static/48f677cec42304036cf3089de6e0f8bc/5ef17/injected-sprite-sheet.jpg 1152w,/static/48f677cec42304036cf3089de6e0f8bc/7e35d/injected-sprite-sheet.jpg 1728w,/static/48f677cec42304036cf3089de6e0f8bc/ff762/injected-sprite-sheet.jpg 1836w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;⚠️ Not using webpack? There are also &lt;a href=&quot;https://github.com/jkphl/svg-sprite&quot;&gt;node&lt;/a&gt;, &lt;a href=&quot;https://github.com/jkphl/gulp-svg-sprite&quot;&gt;gulp&lt;/a&gt; or &lt;a href=&quot;https://github.com/jkphl/grunt-svg-sprite&quot;&gt;grunt&lt;/a&gt; based tools that you can use as an alternative.&lt;/p&gt;&lt;h2 id=&quot;icon-component&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#icon-component&quot; aria-label=&quot;icon component permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Icon Component&lt;/h2&gt;&lt;p&gt;Time to put everything together and build the icon component. Below is the React version of the component – the &lt;a href=&quot;https://github.com/winkerVSbecks/ng2-icon-system-demo/blob/master/src/app/icon/icon.component.ts&quot;&gt;Angular&lt;/a&gt; and &lt;a href=&quot;https://github.com/winkerVSbecks/vue-icon-system-demo/blob/master/src/components/Icon.vue&quot;&gt;Vue.js&lt;/a&gt; versions are quite similar. For the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element I have set &lt;code class=&quot;language-text&quot;&gt;display&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;inline-block&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;verticalAlign&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;middle&lt;/code&gt;. I am using &lt;a href=&quot;http://tachyons.io/&quot;&gt;tachyons&lt;/a&gt; for styling here; however, you can set those styles using any technique.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; React &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; files &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; require&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;!svg-sprite-loader!./assets&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token regex&quot;&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token regex-source language-regex&quot;&gt;.*\.svg$&lt;/span&gt;&lt;span class=&quot;token regex-delimiter&quot;&gt;/&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
files&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;files&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Icon&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; type&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; className &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;svg className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;dib v-mid &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;className&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; width&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;1em&amp;quot;&lt;/span&gt; height&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;1em&amp;quot;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;use xlinkHref&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;type&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;use&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;svg&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; Icon&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt; attributes are set to &lt;code class=&quot;language-text&quot;&gt;1em&lt;/code&gt;. If needed, adjust the values based on the aspect ratio of your icons. This will give us more flexibility to control the size of the icon.&lt;/p&gt;&lt;p&gt;The component itself has two props:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;type&lt;/code&gt;: to pick which icon needs to be rendered.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;className&lt;/code&gt;: to allow us to add more CSS classes to &lt;code class=&quot;language-text&quot;&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The following will render a &lt;code class=&quot;language-text&quot;&gt;cloud-with-snow&lt;/code&gt; icon.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;cloud-with-snow&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;colour&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#colour&quot; aria-label=&quot;colour permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Colour&lt;/h3&gt;&lt;p&gt;We can control the colour of the icon by using the &lt;code class=&quot;language-text&quot;&gt;font-color&lt;/code&gt;. The following will render a green &lt;code class=&quot;language-text&quot;&gt;rainbow&lt;/code&gt; icon.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;rainbow&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;green&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;size&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#size&quot; aria-label=&quot;size permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Size&lt;/h3&gt;&lt;p&gt;We have two options for setting size of the icon:&lt;/p&gt;&lt;p&gt;Using &lt;code class=&quot;language-text&quot;&gt;font-size&lt;/code&gt;: this works great when you are rendering the icon next to some kind of text. For example, in a paragraph or a button. Because we set the &lt;code class=&quot;language-text&quot;&gt;width&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;height&lt;/code&gt; attributes to &lt;code class=&quot;language-text&quot;&gt;1em&lt;/code&gt; the icon scales to match the font size. The following will render a blue &lt;code class=&quot;language-text&quot;&gt;wind&lt;/code&gt; icon that is &lt;a href=&quot;http://tachyons.io/docs/typography/scale&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;1.25rem&lt;/code&gt;&lt;/a&gt; tall.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;wind&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;f4 blue&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In some scenarios you might want to set the size of the icon manually instead of relying on &lt;code class=&quot;language-text&quot;&gt;font-size&lt;/code&gt;. SVG attributes have the lowest specificity so, you can always override them using CSS. The following will render a yellow &lt;code class=&quot;language-text&quot;&gt;orbit&lt;/code&gt; icon that is &lt;code class=&quot;language-text&quot;&gt;4rem&lt;/code&gt; wide and tall.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;orbit&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;w3 h3 yellow&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;usage-with-base-element&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#usage-with-base-element&quot; aria-label=&quot;usage with base element permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Usage with Base Element&lt;/h2&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;&amp;lt;base&amp;gt;&lt;/code&gt; element specifies the base URL to use for resolving all the relative URLs in an HTML document. On some browsers this prevents the icons from rendering 😞 We can fix this by using absolute values for &lt;code class=&quot;language-text&quot;&gt;xlinkHref&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; baseUrl &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;href&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;location&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;hash&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; xlinkHref &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; baseUrl &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;#&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;type&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;cite&gt;— [svgfixer.js](https://gist.github.com/leonderijke/c5cf7c5b2e424c0061d2)&lt;/cite&gt;&lt;p&gt;I recently encountered this issue when working with the Angular router. It relies on the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;base&amp;gt;&lt;/code&gt; element being set. However, you can provide &lt;code class=&quot;language-text&quot;&gt;APP_BASE_HREF&lt;/code&gt; instead and still use the router and the SVG sprite sheet.&lt;/p&gt;&lt;p&gt;🍞 Full source for &lt;a href=&quot;https://github.com/winkerVSbecks/react-icon-system-demo&quot;&gt;React&lt;/a&gt;, &lt;a href=&quot;https://github.com/winkerVSbecks/vue-icon-system-demo&quot;&gt;Vue.js&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://github.com/winkerVSbecks/ng2-icon-system-demo&quot;&gt;Angular&lt;/a&gt; versions.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Touch and Mouse Together]]></title><description><![CDATA[If you have built a web app in the past few years, you've probably had to deal with touch events. In many cases this was limited to handling…]]></description><link>https://varun.ca/touch-and-mouse-together/</link><guid isPermaLink="false">https://varun.ca/touch-and-mouse-together/</guid><pubDate>Tue, 15 Nov 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you have built a web app in the past few years, you’ve probably had to deal with touch events. In many cases this was limited to handling tap and removing that pesky &lt;a href=&quot;https://developers.google.com/web/updates/2013/12/300ms-tap-delay-gone-away&quot;&gt;300ms delay&lt;/a&gt;. However with touch devices becoming more powerful, we now have to implement more complex gestures— gestures that work for both mouse and touch.&lt;/p&gt;&lt;img alt=&quot;chat-head demo&quot; src=&quot;/11268cdb98d160cab0ccd3e4d5d898d7/chat-head-demo.gif&quot;/&gt;&lt;p&gt;In this post we will walk through the process of implementing one such gesture– pan. I will demonstrate this by building a draggable chat-head component.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Note: This will not be the most robust implementation of a draggable component. It is intended to demonstrate how one would handle touch and mouse event simultaneously.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;This example consists of three components:&lt;/p&gt;&lt;h4 id=&quot;1-app-component&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#1-app-component&quot; aria-label=&quot;1 app component permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;1. App Component&lt;/h4&gt;&lt;p&gt;The root node of the application.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;App&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Draggable&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;ChatHead src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;https://s3-us-west-2.amazonaws.com/s.cdpn.io/149125/profile.jpg&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Draggable&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&quot;2-chathead&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#2-chathead&quot; aria-label=&quot;2 chathead permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;2. ChatHead&lt;/h4&gt;&lt;p&gt;A stateless component that renders a circular avatar.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ChatHead&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; src&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;img
      draggable&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;false&amp;quot;&lt;/span&gt;
      src&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;src&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; transition&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;all 300ms ease-in-out&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;br-100 pa1 ba b--black-10 h3 w3&amp;quot;&lt;/span&gt;
      alt&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;chat head&amp;quot;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&quot;3-draggable&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#3-draggable&quot; aria-label=&quot;3 draggable permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;3. Draggable&lt;/h4&gt;&lt;p&gt;A stateful component for making components draggable. To achieve this, we start by wrapping &lt;code class=&quot;language-text&quot;&gt;children&lt;/code&gt; with a &lt;code class=&quot;language-text&quot;&gt;div&lt;/code&gt;. This will act as a draggable container.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Draggable&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;React&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;Component&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;constructor&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;super&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerWidth &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; window&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;innerHeight &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
      dragging&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token function-variable function&quot;&gt;onPanStart&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onPan&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function-variable function&quot;&gt;onPanEnd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token function&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; dragging &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;state&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;div draggable&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;true&amp;quot;&lt;/span&gt;
        className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;dib move&amp;quot;&lt;/span&gt;
        style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
          display&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;inline-block&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          cursor&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;move&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          WebkitTransform&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;translate3d(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;px, &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;px, 0)&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
          transform&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;translate3d(&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;px, &lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt; y &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;32&lt;/span&gt; &lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;px, 0)&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onTouchStart&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanStart &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onDragStart&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanStart &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onDrag&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPan &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onTouchMove&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPan &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onTouchEnd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanEnd &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        onDragEnd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanEnd&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;div&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;pan-gesture&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#pan-gesture&quot; aria-label=&quot;pan gesture permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Pan Gesture&lt;/h3&gt;&lt;p&gt;The pan gesture can be broken down into three stages: pan start, pan &amp;amp; pan end. On desktop these map quite nicely to the drag event handlers, while for touch devices we will have to use touch events. In the end we have three event handlers:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Pan Start:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;onTouchStart&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanStart &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
onDragStart&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanStart &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Pan:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;onTouchMove&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPan &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
onDrag&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPan &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Pan End:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;onTouchEnd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanEnd &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
onDragEnd&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;onPanEnd&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img alt=&quot;breakdown of the drag gesture&quot; src=&quot;/ef5283c824f8550ce34e5ff1f57801cb/drag.gif&quot;/&gt;&lt;h3 id=&quot;pan-start&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#pan-start&quot; aria-label=&quot;pan start permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Pan Start&lt;/h3&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;onPanStart&lt;/code&gt; handler is primarily responsible for setting the &lt;code class=&quot;language-text&quot;&gt;dragging&lt;/code&gt; state to true.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onPanStart&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type &lt;span class=&quot;token operator&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;dragstart&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;dataTransfer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setDragImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getDragImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; dragging&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;true&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you drag an element on desktop you end up with a &lt;em&gt;ghost&lt;/em&gt; image. This is known as the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#dragfeedback&quot;&gt;drag image&lt;/a&gt;. To get around this we can set the drag image to a fake &lt;code class=&quot;language-text&quot;&gt;0px × 0px&lt;/code&gt; image.&lt;/p&gt;&lt;img alt=&quot;ghost image that appears while dragging on desktop&quot; src=&quot;/01797f5a8904a0152e4939485db23511/ghost.gif&quot;/&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getDragImage&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; img &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  img&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;src &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;fake.gif&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; img&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;pan&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#pan&quot; aria-label=&quot;pan permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Pan&lt;/h3&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;onPan&lt;/code&gt; handler allows us to get the drag location and update the &lt;code class=&quot;language-text&quot;&gt;x, y&lt;/code&gt; coordinates in state. Again, we have to account for both touch and mouse events here.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onPan&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clientX &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;||&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clientY &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For drag events we just have one location for the mouse. Therefore, the drag location is &lt;code class=&quot;language-text&quot;&gt;e.clientX&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;e.clientY&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;For touch events we receive a list of &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent/touches&quot;&gt;touches&lt;/a&gt; instead. In this scenario we only care about the first touch which is responsible for panning. We can access that at &lt;code class=&quot;language-text&quot;&gt;e.targetTouches[0]&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;getPan&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;type&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;includes&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;drag&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clientX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clientY &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; touch &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;targetTouches&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; x&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; touch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clientX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; touch&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;clientY &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;pan-end&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#pan-end&quot; aria-label=&quot;pan end permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Pan End&lt;/h3&gt;&lt;p&gt;Finally, the &lt;code class=&quot;language-text&quot;&gt;onPanEnd&lt;/code&gt; handler is responsible for setting the &lt;code class=&quot;language-text&quot;&gt;dragging&lt;/code&gt; state to false.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function-variable function&quot;&gt;onPanEnd&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token parameter&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; dragging&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token boolean&quot;&gt;false&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here is the final result:&lt;/p&gt;&lt;div hash=&quot;BLYOLW&quot; title=&quot;React Draggable Chat Head&quot; height=&quot;400&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;pointer-events&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#pointer-events&quot; aria-label=&quot;pointer events permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Pointer events&lt;/h3&gt;&lt;p&gt;The upcoming &lt;a href=&quot;https://www.w3.org/TR/pointerevents&quot;&gt;Pointer events spec&lt;/a&gt; aims to unify all input devices – such as a mouse, pen/stylus or touch – into a single model. This will simplify the implementation process for us developers and allow us to provide a good user experience regardless hardware choices.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Flattening Deep Hierarchies of Components]]></title><description><![CDATA[Components are an awesome tool for building interfaces. They allow you to break down the UI into distinct reusable elements. These can then…]]></description><link>https://varun.ca/flattening-deep-hierarchies-of-components/</link><guid isPermaLink="false">https://varun.ca/flattening-deep-hierarchies-of-components/</guid><pubDate>Tue, 18 Oct 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Components are an awesome tool for building interfaces. They allow you to break down the UI into distinct reusable elements. These can then be composed to build complex applications in a more sustainable way.&lt;/p&gt;&lt;p&gt;Each component has its own well defined public API. In React this is defined by the component props. Where as, in Angular 2 it’s inputs and outputs. The choice of this API can have a drastic impact on your application. Consider the following example of a &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; component.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:44.44444444444444%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;178\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20178\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M152%2043l-1%2012%201%209%201-2%202%202%201%201h1c1-2%201-2%201%200l1%202%201-2c0-4%202%208%202%2017%200%206%201%209%202%209l1-5c0-2%200-3%201-2%200%201%200%202%201%201h8l7%201h2l1-1%201-2%201-4c0-4%202-5%204-3%201%201%201%200%201-1l1%207%201%209h55V43l-49-1-48%201\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Basic card with a title&quot; title=&quot;Basic card with a title&quot; src=&quot;/static/dfc316c42db42928298ff60d057790a6/4ad3a/card-with-title.png&quot; srcSet=&quot;/static/dfc316c42db42928298ff60d057790a6/477c9/card-with-title.png 288w,/static/dfc316c42db42928298ff60d057790a6/533c1/card-with-title.png 576w,/static/dfc316c42db42928298ff60d057790a6/4ad3a/card-with-title.png 1152w,/static/dfc316c42db42928298ff60d057790a6/3c492/card-with-title.png 1300w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;It has one job: display an image with a title. You might be tempted to build it out such that it abstracts away all the logic for its constituent parts: image, title, etc.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card
  img&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img/rotary-phone.png&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;Choosing the Right Antique Rotary Phone for You.&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  contentPaddingX&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  contentPaddingY&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As the complexity of your app grows you might introduce other scenarios for this &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; component. The card should now be able to display a caption or an icon with a click action?&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:44.44444444444444%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;178\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20178\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M110%2043l-30%201%201%201%201%202h6l1%202h1l1-1%202%202c1-1%201%200%201%201%200%202%200%202%201%201%201-2%201-2%201%200l-1%202c-1%200-1%201%201%201%201%201%201%201-1%201l-2%201c0%201-1%202-2%201-2%200-2%200-2%206l1%207%201%2011%201%209%201-5c0-4%200-4%202-4%209%203%2011%203%2012%202l2-1%201-3a152%20152%200%20013-12c0-2%200-2%201-1s1%200%201-2c0-3%200-4%201-3h2c2-1%202-1%202%203l1%205%201%204c-1%207%200%2017%201%2017l1-4c0-6%200-6%204-3%202%202%209%204%2011%203%202%200%201%203-1%203-1%201%208%201%2019%201h20V67l-1-24-19-1-47%201m128%200l-1%2024v25h98V43l-49-1-48%201\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;Card with other requirements such as caption and icon&quot; title=&quot;Card with other requirements such as caption and icon&quot; src=&quot;/static/990d7b1a67afb9c1962d9c0c454af7ae/4ad3a/cards-with-other-requirements.png&quot; srcSet=&quot;/static/990d7b1a67afb9c1962d9c0c454af7ae/477c9/cards-with-other-requirements.png 288w,/static/990d7b1a67afb9c1962d9c0c454af7ae/533c1/cards-with-other-requirements.png 576w,/static/990d7b1a67afb9c1962d9c0c454af7ae/4ad3a/cards-with-other-requirements.png 1152w,/static/990d7b1a67afb9c1962d9c0c454af7ae/3c492/cards-with-other-requirements.png 1300w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Card with title and caption&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card
  img&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img/rotary-phone.png&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;Choosing the Right Antique Rotary Phone for You.&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  caption&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;21 hours ago&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  contentPaddingX&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  contentPaddingY&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// Card with title, caption and icon&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card
  img&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img/rotary-phone.png&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  title&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;Choosing the Right Antique Rotary Phone for You.&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  caption&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;21 hours ago&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  contentPaddingX&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  contentPaddingY&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  icon&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;add-to-cart&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  iconAction&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;addToCart&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You now have to add more logic to this component. It has to account for all these permutations and combinations of its constituent parts. You can probably see the issue here. What started as a simple component has bloated into something that is hard to maintain, hard to test and not at all flexible.&lt;/p&gt;&lt;p&gt;We can write better components by adopting an approach similar to function composition.&lt;/p&gt;&lt;h2 id=&quot;function-composition&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#function-composition&quot; aria-label=&quot;function composition permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Function Composition&lt;/h2&gt;&lt;p&gt;Function composition is the act of combining simple functions to build more complicated ones.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token function&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Consider the following example:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;complexFunction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; a &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here the &lt;code class=&quot;language-text&quot;&gt;complexFunction&lt;/code&gt; is very similar to what we attempted with the &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; component. This one function is trying to do too much. We can achieve the same behaviour using &lt;code class=&quot;language-text&quot;&gt;compose&lt;/code&gt; instead:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;divideBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;r&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; x&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; x &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; r&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; complexFunction &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;divideBy&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;compose&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token function&quot;&gt;multiply&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here we have broken out the various math operations into pure functions. We can now &lt;code class=&quot;language-text&quot;&gt;compose&lt;/code&gt; these functions to create the &lt;code class=&quot;language-text&quot;&gt;complexFunction&lt;/code&gt; or any other type of combination.&lt;/p&gt;&lt;p&gt;Instead of having one massive function which accounts for various scenarios we have created a toolbox of smaller single responsibility functions. Testing this is much easier since you don’t have to account for the different scenarios.&lt;/p&gt;&lt;h2 id=&quot;applying-function-composition-to-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#applying-function-composition-to-components&quot; aria-label=&quot;applying function composition to components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Applying Function Composition to Components&lt;/h2&gt;&lt;p&gt;Let us apply this same principle to the &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; component. We start by breaking out its sub-components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Media&lt;/code&gt;: a generic image component&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Body&lt;/code&gt;: body container for the card&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Title&lt;/code&gt;: the card title&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Caption&lt;/code&gt;: card caption&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Icon&lt;/code&gt;: a generic icon component&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:44.44444444444444%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;178\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20178\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M152%2043l-1%2024v24h14l49%201h35V43l-49-1-48%201\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;example of a basic card&quot; title=&quot;example of a basic card&quot; src=&quot;/static/d4d79f52c45be252ef4ed261f3b65cc0/4ad3a/card-example.png&quot; srcSet=&quot;/static/d4d79f52c45be252ef4ed261f3b65cc0/477c9/card-example.png 288w,/static/d4d79f52c45be252ef4ed261f3b65cc0/533c1/card-example.png 576w,/static/d4d79f52c45be252ef4ed261f3b65cc0/4ad3a/card-example.png 1152w,/static/d4d79f52c45be252ef4ed261f3b65cc0/3c492/card-example.png 1300w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now, instead of passing all data into the &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; component we instead use &lt;code class=&quot;language-text&quot;&gt;children&lt;/code&gt; (React) or &lt;code class=&quot;language-text&quot;&gt;ng-content&lt;/code&gt; (known as projection in Angular 2, and transclusion in Angular 1). The card on the right will now look something like this:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Card with title, caption and icon&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Media source&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img/rotary-phone.png&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Body paddingX&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; paddingY&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Title&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Choosing the Right Antique Rotary Phone &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; You&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Title&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Caption&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;21 hours ago&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Icon name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;add-to-cart&amp;quot;&lt;/span&gt; handleClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;addToCart&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Caption&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Body&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Card&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is much better. Let’s observe some benefits:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; is now agnostic to what content goes inside it. This flattens our component tree. There is less data that needs to be passed through the various levels of the component hierarchy.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Each component has one responsibility which makes testing trivial.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;We gain a lot more flexibility. Developers can compose different types of cards or even create new ones since they have full control over the content of the card.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 id=&quot;highly-reusable-components&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#highly-reusable-components&quot; aria-label=&quot;highly reusable components permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Highly Reusable Components&lt;/h2&gt;&lt;p&gt;We can improve this further. You might notice that &lt;code class=&quot;language-text&quot;&gt;Body&lt;/code&gt;, &lt;code class=&quot;language-text&quot;&gt;Title&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;Caption&lt;/code&gt; all seem like specialized components. They are somewhat tied to the &lt;code class=&quot;language-text&quot;&gt;Card&lt;/code&gt; component. We can instead replace them with a few generic components:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Block&lt;/code&gt;: a generic box with visual styling&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Heading&lt;/code&gt;: a heading component with size based on a font scale&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;Button&lt;/code&gt;: a generic button component with various styles&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Notice the &lt;code class=&quot;language-text&quot;&gt;muted&lt;/code&gt; property for &lt;code class=&quot;language-text&quot;&gt;Heading&lt;/code&gt;. Instead of creating a &lt;code class=&quot;language-text&quot;&gt;Caption&lt;/code&gt; component we are reusing the &lt;code class=&quot;language-text&quot;&gt;Heading&lt;/code&gt; component and simply passing in a boolean with applies the muted colours.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Card with title, caption and icon&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Card&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Media source&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;img/rotary-phone.png&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Block paddingX&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; paddingY&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Heading size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;Choosing the Right Antique Rotary Phone &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; You&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Heading&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Block&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Heading size&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; muted&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token number&quot;&gt;21&lt;/span&gt; hours ago
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Heading&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Button style&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;clear&amp;quot;&lt;/span&gt; handleClick&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;addToCart&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Icon name&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;add-to-cart&amp;quot;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Button&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Block&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Block&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;Card&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here is the final version in Angular 2:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Card with title, caption and icon --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Card&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Media&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;[source]&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;img/rotary-phone.png&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Media&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Block&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;paddingX&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;2&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;paddingY&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;2&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Heading&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;2&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      Choosing the Right Antique Rotary Phone for You.
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Heading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;

    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Heading&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;3&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;muted&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;21 hours ago&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Heading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;button&lt;/span&gt; &lt;span class=&quot;token style-attr&quot;&gt;&lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token style language-css&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;(handleClick)&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;addToCart($event)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
        &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;Icon&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;add-to-cart&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;button&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Block&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;Card&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[OAM and React & SVG Starter]]></title><description><![CDATA[Last April  Ainsley Wagoner  posted this awesome dribbble shot. I loved the idea – it reminded me of colour field paintings. I reached out…]]></description><link>https://varun.ca/oam/</link><guid isPermaLink="false">https://varun.ca/oam/</guid><pubDate>Sun, 14 Aug 2016 00:00:00 GMT</pubDate><content:encoded>&lt;img alt=&quot;OAM&quot; style=&quot;margin-left:auto;margin-right:auto;width:400px&quot; src=&quot;/ed37acd7fed0a1649898a38f3cc4b4f1/oam.gif&quot;/&gt;&lt;div demo=&quot;http://ooaamm.com&quot; source=&quot;https://github.com/winkerVSbecks/oam-site&quot;&gt;&lt;/div&gt;&lt;p&gt;Last April &lt;a href=&quot;http://ainsleywagoner.com&quot;&gt;Ainsley Wagoner&lt;/a&gt; posted this awesome dribbble shot. I loved the idea – it reminded me of colour field paintings. I reached out to her and a few months later we started working together to built it.&lt;/p&gt;&lt;figure px=&quot;4&quot;&gt;
  &lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:800px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:75%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;300\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20300\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%20150v150h401V0H0v150m158-89a6560%206560%200%2001-130%2074c-3-3-7-1-7%203%200%203%200%203-5%207l-5%203h186V94l-1-55-38%2022m196-1l-36%2022-1%2015v15h-39v-7l-28%2016c-23%2013-27%2016-28%2015-2-4-8-1-7%203a2838%202838%200%2000-7%207l-3%202h186V94l-1-55-36%2021m-56%2033l-14%2010c0%201%201%203%204%204%2010%208%2024%202%2027-11l-2-11-15%208m-128%2089l-58%2033-5-5-3-6-7%2012-9%2013a901%20901%200%2001-61%2034c-3-4-7-1-6%203%201%202%200%203-5%206l-5%203h186V166l-27%2016m184%206l-37%2021v28h-39v-2c0-3-2-2-27%2013a295%20295%200%2000-33%2021c-1-1-4%201-8%203l-5%203h186V166l-37%2022m-61%2036c-6%203-10%207-11%208l-2%203%2017%201h18c0-3-9-18-11-18l-11%206\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;ooaamm ainsley&quot; title=&quot;ooaamm ainsley&quot; src=&quot;/static/71efaf2fb20ba713ad199353bb64ad39/5a190/ooaamm-ainsley.png&quot; srcSet=&quot;/static/71efaf2fb20ba713ad199353bb64ad39/477c9/ooaamm-ainsley.png 288w,/static/71efaf2fb20ba713ad199353bb64ad39/533c1/ooaamm-ainsley.png 576w,/static/71efaf2fb20ba713ad199353bb64ad39/5a190/ooaamm-ainsley.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;
  &lt;figcaption&gt;
    &lt;a href=&quot;https://dribbble.com/shots/2028321-OAM-site&quot;&gt;
      OAM site dribbble shot
    &lt;/a&gt;
  &lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Around this time I had started to learn how to use &lt;a href=&quot;http://redux.js.org/index.html&quot;&gt;redux&lt;/a&gt;. So, instead of building yet another &lt;em&gt;To Do app&lt;/em&gt; I decided to learn redux by building &lt;a href=&quot;http://ooaamm.com&quot;&gt;OAM&lt;/a&gt;. This turned out to be a great experience. I learnt a lot about, React, redux and animating SVG.&lt;/p&gt;&lt;h2 id=&quot;react-svg-starter&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#react-svg-starter&quot; aria-label=&quot;react svg starter permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;React SVG Starter&lt;/h2&gt;&lt;p&gt;I’ve been using React, SVG and redux for a lot of projects lately. Therefore, in order to save myself some time I made a &lt;a href=&quot;https://github.com/winkerVSbecks/react-svg-starter&quot;&gt;React Redux SVG Starter&lt;/a&gt;. It’s based off of Rangle.io’s &lt;a href=&quot;https://github.com/rangle/react-redux-starter&quot;&gt;react-redux-starter&lt;/a&gt; and comes with the usual stuff like Webpack, Babel, HMR, Eslint, etc. In addition to this I’ve also setup a few components and reducers to get started quickly.&lt;/p&gt;&lt;h2 id=&quot;the-canvas&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-canvas&quot; aria-label=&quot;the canvas permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Canvas&lt;/h2&gt;&lt;p&gt;To setup the root SVG node I created a Canvas component. I learnt a few lessons here. First of all use &lt;code class=&quot;language-text&quot;&gt;children&lt;/code&gt; to keep the Canvas component light. This way the it doesn’t need to know about the state of the shapes being rendered. It is simply responsible for maintaining the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;svg&amp;gt;&lt;/code&gt; element and sizing it to fill the window.&lt;/p&gt;&lt;p&gt;Secondly, using &lt;code class=&quot;language-text&quot;&gt;viewBox&lt;/code&gt; allows us to detach the canvas coordinate system from any pixel values. Thanks to this all the shapes can be described using relative coordinates yet, the SVG scales to whatever size you want.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;jsx&quot;&gt;&lt;pre class=&quot;language-jsx&quot;&gt;&lt;code class=&quot;language-jsx&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;Canvas&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; children &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; viewBox &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; w&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;version&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;1.1&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;http://www.w3.org/2000/svg&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;viewBox&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;viewBox&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;token script language-javascript&quot;&gt;&lt;span class=&quot;token script-punctuation punctuation&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;styles&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;children&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token plain-text&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That state for window and view box sizes is stored in the &lt;a href=&quot;https://github.com/winkerVSbecks/react-svg-starter/blob/master/src/reducers/canvas.js&quot;&gt;canvas reducer&lt;/a&gt;. The &lt;a href=&quot;https://github.com/winkerVSbecks/react-svg-starter/blob/master/src/containers/app.js&quot;&gt;App container &lt;/a&gt; binds the window resize events to redux actions for updating this state.&lt;/p&gt;&lt;p&gt;The view box is calculated using this formula:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;width &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; height&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; height &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; width &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;height &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This means that the longer side of SVG is &lt;code class=&quot;language-text&quot;&gt;100&lt;/code&gt; and the shorter side will be some value between &lt;code class=&quot;language-text&quot;&gt;0 - 100&lt;/code&gt; based on the aspect ratio. I found this made it easier to &lt;a href=&quot;https://github.com/winkerVSbecks/react-svg-starter/blob/master/src/containers/app.js#L39&quot;&gt;size &amp;amp; place any shapes&lt;/a&gt; and achieve &lt;a href=&quot;https://github.com/winkerVSbecks/oam-site/blob/master/src/styles/toolbar-styles.js&quot;&gt;responsive behaviour&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;animations&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#animations&quot; aria-label=&quot;animations permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Animations&lt;/h2&gt;&lt;p&gt;Chrome is going to &lt;a href=&quot;https://www.chromestatus.com/feature/5371475380928512&quot;&gt;deprecate SMIL&lt;/a&gt; so, I tried to use CSS for animations as much as possible. This came with a lot of cross browser issues. Eventually I gave up and switched to using &lt;a href=&quot;http://greensock.com/gsap&quot;&gt;GSAP&lt;/a&gt; for all animations. In the future I plan experiment more with &lt;a href=&quot;https://github.com/chenglou/react-motion&quot;&gt;React Motion&lt;/a&gt; and &lt;a href=&quot;https://github.com/web-animations/web-animations-js&quot;&gt;Web Animation API&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;sound&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#sound&quot; aria-label=&quot;sound permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Sound&lt;/h2&gt;&lt;p&gt;To load the sounds I used the webpack file loader which works great. For triggering them I initially used the HTML5 Audio API before switching to &lt;a href=&quot;https://github.com/goldfire/howler.js&quot;&gt;Howler&lt;/a&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; oam1 &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;../audio/OAM_1.mp3&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; Sounds &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt; base&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;Audio&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;oam1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
Sounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;base&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With the Audio API, I found that if I triggered &lt;code class=&quot;language-text&quot;&gt;play&lt;/code&gt; in quick succession it wouldn’t actually play the sound if the previous play call was still executing. I haven’t worked much with the Audio API and probably just don’t know how to use it properly. In any case, Howler did exactly what we were looking for.&lt;/p&gt;&lt;p&gt;All the sounds are connected to UI actions. Therefore, I ended up placing them in the reducers, for example: &lt;a href=&quot;https://github.com/winkerVSbecks/oam-site/blob/master/src/reducers/circle-reducer.js#L30&quot;&gt;circle-reducer.js#L30&lt;/a&gt;. This way the sound is played when the state is updated.&lt;/p&gt;&lt;h2 id=&quot;creative-coding-with-react--svg&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#creative-coding-with-react--svg&quot; aria-label=&quot;creative coding with react  svg permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Creative Coding with React &amp;amp; SVG&lt;/h2&gt;&lt;p&gt;Lastly I want to share the video for a talk I gave a talk at &lt;a href=&quot;http://fitc.ca/event/to16&quot;&gt;FITC Toronto 2016&lt;/a&gt;. In this talk I go through a basic tutorial of how to get started creating SVG images with React and adding animations to them. Also, I shared some examples and talked about the benefits of using this approach.&lt;/p&gt;&lt;div position=&quot;relative&quot; paddingBottom=&quot;56.25%&quot; height=&quot;0&quot; overflow=&quot;hidden&quot; maxWidth=&quot;100%&quot; mb=&quot;3&quot;&gt;&lt;div position=&quot;absolute&quot; top=&quot;0&quot; left=&quot;0&quot; width=&quot;100%&quot; height=&quot;100%&quot; src=&quot;https://www.youtube.com/embed/D40JphLwqpk&quot; frameBorder=&quot;0&quot; allow=&quot;accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;🎬 slides: &lt;a href=&quot;http://winkervsbecks.github.io/creative-coding-with-react-svg&quot;&gt;winkervsbecks.github.io/creative-coding-with-react-svg&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Chillwave]]></title><description><![CDATA[A few days ago I came across this creative studio called  This Also . They just launched a new site. It not only showcases some of their…]]></description><link>https://varun.ca/chillwave/</link><guid isPermaLink="false">https://varun.ca/chillwave/</guid><pubDate>Mon, 23 Nov 2015 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;EVJGVj&quot; title=&quot;This Also Chillwave&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;A few days ago I came across this creative studio called &lt;a href=&quot;http://thisalso.com&quot;&gt;This Also&lt;/a&gt;. They just launched a new site. It not only showcases some of their amazing work but, also has this fun little loading animation.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/2bd9006aa7dfda70698c53db3671b085/chillwave.gif&quot; alt=&quot;chillwave&quot;/&gt;&lt;/p&gt;&lt;p&gt;I absolutely love this! First thing I did was &lt;em&gt;right click &amp;amp; inspect element&lt;/em&gt; and was expecting to find an SVG with SMIL animation baked in. To my surprise it turned out to be a &lt;a href=&quot;http://thisalso.com../assets/global/chillwave.png&quot;&gt;sprite&lt;/a&gt; based animation with 24 frames. So, let’s recreate this with only SVG.&lt;/p&gt;&lt;h2 id=&quot;draw-the-wave&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#draw-the-wave&quot; aria-label=&quot;draw the wave permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Draw the Wave&lt;/h2&gt;&lt;p&gt;Step one was obvious… draw the wave using the SVG &lt;code class=&quot;language-text&quot;&gt;&amp;lt;path&amp;gt;&lt;/code&gt; element. In Sketch/Illustrator you would create something like this using the pen tool. It’s a Bézier curve with 2 points – each with a handle (control point). The wave is simply a collection of this path alternating with its mirror image.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:1152px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:37.84722222222222%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;151\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20151\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M247%2019c-12%202-24%2011-33%2024-4%207-9%2017-18%2040-14%2034-25%2045-47%2048-8%202-6%203%202%203%2022-3%2034-17%2051-59%2015-38%2028-52%2050-54%205%200%207-1%207-2h-12\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;wave path&quot; title=&quot;wave path&quot; src=&quot;/static/49f2181629382f3df8ed3d74a7f682dc/5ef17/wave-path.jpg&quot; srcSet=&quot;/static/49f2181629382f3df8ed3d74a7f682dc/c14c5/wave-path.jpg 288w,/static/49f2181629382f3df8ed3d74a7f682dc/ac097/wave-path.jpg 576w,/static/49f2181629382f3df8ed3d74a7f682dc/5ef17/wave-path.jpg 1152w,/static/49f2181629382f3df8ed3d74a7f682dc/7e35d/wave-path.jpg 1728w,/static/49f2181629382f3df8ed3d74a7f682dc/6e754/wave-path.jpg 2120w&quot; sizes=&quot;(max-width: 1152px) 100vw, 1152px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;To create this path with SVG we will use the Bézier curve command &lt;code class=&quot;language-text&quot;&gt;c&lt;/code&gt; – lower case which means &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths&quot;&gt;relative coordinates&lt;/a&gt;. We need to repeat this pattern several times, instead of trying to figure out the absolute location of each point we can use relative coordinates to make our life easier.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!--
  dx1 dy1: control point for the start
  dx2 dy2: control point for the end
  dx dy: the end point
--&amp;gt;&lt;/span&gt;
c dx1 dy1, dx2 dy2, dx dy&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&quot;the-building-blocks&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-building-blocks&quot; aria-label=&quot;the building blocks permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Building Blocks&lt;/h3&gt;&lt;p&gt;For this example let’s assume that the width of the SVG element is &lt;code class=&quot;language-text&quot;&gt;w&lt;/code&gt;, the height is &lt;code class=&quot;language-text&quot;&gt;h&lt;/code&gt; and the wave has an amplitude of &lt;code class=&quot;language-text&quot;&gt;0.25 * h&lt;/code&gt;. The path can then be constructed by:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Moving to start point which will be the middle of the SVG (&lt;code class=&quot;language-text&quot;&gt;0.5 * h&lt;/code&gt;) + half the amplitude (&lt;code class=&quot;language-text&quot;&gt;0.125 * h&lt;/code&gt;):&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.625&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Then we begin the curve &lt;code class=&quot;language-text&quot;&gt;c&lt;/code&gt; and add the first control point. This is using relative coordinates so, the &lt;em&gt;y coordinate&lt;/em&gt; is simply &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt;. The &lt;em&gt;x coordinate&lt;/em&gt; is &lt;code class=&quot;language-text&quot;&gt;m&lt;/code&gt; times the amplitude; where &lt;code class=&quot;language-text&quot;&gt;m = 0.512286623256592433&lt;/code&gt;. The value of &lt;code class=&quot;language-text&quot;&gt;m&lt;/code&gt; is &lt;a href=&quot;http://stackoverflow.com/a/13935397/1365008&quot;&gt;chosen&lt;/a&gt; such that it approximately creates a sine wave.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.625&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;c&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Then we add the second control point. For the &lt;em&gt;y coordinate&lt;/em&gt; we have to go up by one amplitude and up means negative in SVG. Therefore, &lt;code class=&quot;language-text&quot;&gt;-0.25 * h&lt;/code&gt;. To calculate the &lt;em&gt;x coordinate&lt;/em&gt; we go all the way to the end &lt;code class=&quot;language-text&quot;&gt;0.25 * h&lt;/code&gt; and come back by &lt;code class=&quot;language-text&quot;&gt;0.25 * h * m&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.625&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;c&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Finally we add the end point and create the path definition using the technique described in the &lt;a href=&quot;http://jxnblk.com/react-icons&quot;&gt;react icons&lt;/a&gt; tutorial.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; pathData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.625&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;c&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;OyGGqr&quot; title=&quot;SVG wave section&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The next path section is a mirror of the one above. Luckily SVG has the &lt;code class=&quot;language-text&quot;&gt;s&lt;/code&gt; command.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;You can string together several Bezier curves to create extended, smooth shapes. Often, in this case, the control point on one side of a point will be a reflection of the control point used on the other side (to keep the slope constant). In this case, you can use a shortcut version of the cubic Bezier, designated by the command S (or s).&lt;/p&gt;&lt;cite&gt;— &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths&quot;&gt;MDN tutorial on Paths&lt;/a&gt;&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;Therefore, we can use the &lt;code class=&quot;language-text&quot;&gt;s&lt;/code&gt; command and extend our path definition. Remember the first control point is ✨automagically✨ inserted for us so, we only need to specify the 2&lt;sup&gt;nd&lt;/sup&gt; control point and the end point of the second section.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; pathData &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;M&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.625&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;c&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token string&quot;&gt;&amp;#x27;s&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;#x27; &amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;YyMbYB&quot; title=&quot;SVG wave - mirror section&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;and-repeat&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#and-repeat&quot; aria-label=&quot;and repeat permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;And Repeat&lt;/h3&gt;&lt;p&gt;We can now use the &lt;code class=&quot;language-text&quot;&gt;s&lt;/code&gt; command technique to expand this wave – alternating between down and up.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// down&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&amp;#x27;s&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token comment&quot;&gt;// and back up&lt;/span&gt;
&lt;span class=&quot;token string&quot;&gt;&amp;#x27;s&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; m&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0.25&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; h&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;wKZbma&quot; title=&quot;SVG wave - repeat&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;move-the-wave&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#move-the-wave&quot; aria-label=&quot;move the wave permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Move the Wave&lt;/h2&gt;&lt;p&gt;To animate the wave we move the path from left to right using CSS transforms. The distance is equal to the width of the SVG element: &lt;code class=&quot;language-text&quot;&gt;transform: translate3d(-90px, 0 , 0)&lt;/code&gt;. And we have to ensure that wave is long enough otherwise the animation doesn’t quite work.&lt;/p&gt;&lt;div hash=&quot;zvXQmW&quot; title=&quot;Chillwave – Move the Wave&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h2 id=&quot;the-finishing-touch&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-finishing-touch&quot; aria-label=&quot;the finishing touch permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Finishing Touch&lt;/h2&gt;&lt;p&gt;We could stop here, but you’ll notice that in the original GIF the wave has rounded ends. Adding that to a static wave is easy. We use &lt;code class=&quot;language-text&quot;&gt;stroke-linecap=&amp;quot;round&amp;quot;&lt;/code&gt; and call it a day. But, in order to animate the wave its path extends beyond the visible SVG canvas.&lt;/p&gt;&lt;p&gt;The rounded ends are both somewhere offscreen. Therefore, to achieve the appropriate effect we have to rely on &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray&quot;&gt;stroke-dasharray&lt;/a&gt;. The dash array takes values for lengths of dashes and gaps.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;css&quot;&gt;&lt;pre class=&quot;language-css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token selector&quot;&gt;#wave&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token property&quot;&gt;stroke-dasharray&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0 16 101 16&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;We begin with &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; since we want a gap to begin with but, by default the &lt;code class=&quot;language-text&quot;&gt;dasharray&lt;/code&gt; applies the first value to a dash.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;16&lt;/code&gt; is then the length of the first gap.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;101&lt;/code&gt; is the length of the dash.&lt;/li&gt;&lt;li&gt;And finally&lt;code class=&quot;language-text&quot;&gt;16&lt;/code&gt; is then the length of the last gap.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The total path is approximately 120px long. Using that as a starting point, I picked these numbers after a bit of trial and error.&lt;/p&gt;&lt;div hash=&quot;KdYLJm&quot; title=&quot;SVG wave – add the rounded ends&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;At this point if we re-introduce the animation you’ll notice that it breaks the optical illusion of the wave staying in place as it oscillates. The path is moving left to right. To counter this movement we need to move the dash (yup, from the dasharray above) right to left at the same speed.&lt;/p&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;gap + dash + gap = 16 + 101 + 16 = 133&lt;/code&gt;. And we can move the dash using &lt;code class=&quot;language-text&quot;&gt;stroke-dashoffset&lt;/code&gt; by exactly that amount – the now famous &lt;a href=&quot;https://css-tricks.com/svg-line-animation-works&quot;&gt;SVG line animation technique&lt;/a&gt;. Notice the difference. The one of the left doesn’t have the dashoffset and the one on the right does.&lt;/p&gt;&lt;div hash=&quot;JYVqVe&quot; title=&quot;Chillwave – Move &amp;amp; Wiggle the Wave&quot; height=&quot;300&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;h3 id=&quot;update&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#update&quot; aria-label=&quot;update permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Update&lt;/h3&gt;&lt;p&gt;Had to add the following fix for Safari. For some reason the SVG view-port is larger on it than other browsers.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;http://www.w3.org/2000/svg&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;80px&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;60px&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;viewBox&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;5 0 80 60&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Parallax With Angular]]></title><description><![CDATA[Lately I've been obsessed with Monument Valley. Love the game and the aesthetic even more. I even set up my  Electric Object EO1  with a…]]></description><link>https://varun.ca/parallax/</link><guid isPermaLink="false">https://varun.ca/parallax/</guid><pubDate>Mon, 19 Oct 2015 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;RWxXpE&quot; title=&quot;Monument Valley in Space for blog post&quot; height=&quot;800&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/explorers-on-the-moon/monument-valley&quot; source=&quot;https://github.com/winkerVSbecks/explorers-on-the-moon&quot;&gt;&lt;/div&gt;&lt;p&gt;Lately I’ve been obsessed with Monument Valley. Love the game and the aesthetic even more. I even set up my &lt;a href=&quot;https://www.electricobjects.com&quot;&gt;Electric Object EO1&lt;/a&gt; with a “print” from the game. So, I just had to build something inspired by it – why not a Tintin/Monument Valley mash-up?&lt;/p&gt;&lt;p&gt;The starting point was this image. The shapes and gradients are easy to replicate with SVG. And instead of worrying about the low-poly sky I decided to focus on introducing some parallax effect.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:768px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:86.1111111111111%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;344\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20344\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M0%2033l1%2033%203-2%203-2%201-1%207-3%201-1%202-1c2%200%202%200%201-1s-1-1%201-1c6-2%209-2%2011-1%201%201%201%201-1%201s-2%200-1%201v1l-2%201c0%202%202%202%203%201h5v-2c-3-2-2-3%2013-5%2011-1%2012-1%2015%201h12l15-1c5%200%206%200%206-2l3%201c3%202%2012%202%2013%200l9-1c5%200%209%200%208-1-2-1-1-2%203-2l4-1%205-1%207-2%203-2%204-2%208-1c8%200%209%200%207%201s-2%201%200%201l2-2c1-2%203-3%203-1l6%201%209%202%208%201%207%201h8c3%202%203%202%201%203-4%202-2%203%208%202%209%200%2010%200%2010%202h2c5-5%2014-12%2018-13l3-3%205%201h5l4-1%204-1%202-1c2%200%201%203-1%206-3%202-3%203%200%203h2l2%201h5c2%200%202%200%201%201-2%202-1%205%201%205l2%201%209%201h7l-2-4c-2-3-2-5%201-5%202%200%202%200%201%201-3%201%200%202%205%202l4%201%205%201%2015%203%202%201%202%201%208%202c7%202%2011%204%209%206h2c3-1%206%202%204%203l-3%201c-2%200-2%200-1%201l2%202%201%201%201-1%201-1c1%200%202%201%201%203%200%202%200%202%203%201l3-1%204%201%205%201%208%203c2%202%2015%207%2016%205l1-38V0H0v33m0%20205v106h401V238l-1-103c0%203-4%208-4%205l-2-1v1c3%202%200%205-4%204l-4%202c-2%202-2%202-2%200l1-2%201-1c0-2-3-1-4%200l-2%201-1%201%201%201v1l-1%201v5c-2%200-3-1-3-3%200-3-1-3-5%202-5%205-8%205-9%201l-2-2v3l-1%201c-1-1-5%203-4%204l-1%201-30%2028-57%2056a912%20912%200%2001-35%2031h-3c-3-1-12%200-13%201h-2l-8%205c0%202-3%201-6-2-10-10-11-10-12-9h-12v3l1%201c-1%201-7-5-77-73a337%20337%200%2000-40-37l1%202c-1%202-2%201-2-1s-2-3-2%200h-1l-4-2-4-1c0-2-3-4-5-4s-3-1-3-2c0-2-1-2-5-2s-10-2-7-2v-2c-3-2-4-3-4%200%200%201-3%201-7-2-2-1-3-3-1-3%201-1%201-1-1-1-1%201-4-1-8-5l-7-6v105m0%201\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;monument valley&quot; title=&quot;monument valley&quot; src=&quot;/static/786ff4181cd124f7350e013a9177d2d8/212bf/monument-valley.jpg&quot; srcSet=&quot;/static/786ff4181cd124f7350e013a9177d2d8/c14c5/monument-valley.jpg 288w,/static/786ff4181cd124f7350e013a9177d2d8/ac097/monument-valley.jpg 576w,/static/786ff4181cd124f7350e013a9177d2d8/212bf/monument-valley.jpg 768w&quot; sizes=&quot;(max-width: 768px) 100vw, 768px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;h2 id=&quot;svg-with-angularjs&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#svg-with-angularjs&quot; aria-label=&quot;svg with angularjs permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;SVG with AngularJS&lt;/h2&gt;&lt;p&gt;For my day job I primarily work with Angular and I was curious to see how the whole &lt;em&gt;dynamically composed SVG&lt;/em&gt; thing would work out with it. So, instead of &lt;code class=&quot;language-text&quot;&gt;React + SVG&lt;/code&gt; this time it is &lt;code class=&quot;language-text&quot;&gt;Angular + SVG&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Adopting the same technique as React the SVG layers are just components – known as directives in the Angular world. To create a directive that renders SVG you need to specify &lt;code class=&quot;language-text&quot;&gt;templateNamespace: &amp;#x27;svg&amp;#x27;&lt;/code&gt;. This allows you to have templates that contain SVG partials.&lt;/p&gt;&lt;p&gt;I call the top level component in this case the &lt;code class=&quot;language-text&quot;&gt;valley&lt;/code&gt; directive. This is where the SVG starts and the template for it is simply:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;svg&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;xmlns&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;http://www.w3.org/svg/2000&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;width&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;100%&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;g&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-transclude&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;svg&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, since we are composing these layers in markup we need to set &lt;code class=&quot;language-text&quot;&gt;transclude: true&lt;/code&gt; for this directive. Angular by default strips the content within the directive tags. Enabling transclude allows us to have nested content, like so:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;valley&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;valley&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dx&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dy&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;defs&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-include&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;templates/gradients&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;defs&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;g&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-repeat&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;peak in main.peaks&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;peak&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{ { peak.fill }}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.width&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.height&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;peak.left&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dx&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dy&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;ng-attr-opacity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{ { peak.opacity }}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;peak&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;peak&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{ { peak.fill }}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.width&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.height&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;peak.right&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dx&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dy&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
      &lt;span class=&quot;token attr-name&quot;&gt;ng-attr-opacity&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{ { peak.opacity }}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;peak&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;g&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;mountain-range&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;url(#black-gradient)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.width&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;h&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.height&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;dx&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dx&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
    &lt;span class=&quot;token attr-name&quot;&gt;dy&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;main.dy&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;valley&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;constructing-the-shapes&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#constructing-the-shapes&quot; aria-label=&quot;constructing the shapes permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Constructing the Shapes&lt;/h2&gt;&lt;p&gt;I decided to construct the black peaks 🌄 in the front as one shape in the &lt;code class=&quot;language-text&quot;&gt;mountain-range&lt;/code&gt; directive. The shape is simply a &lt;code class=&quot;language-text&quot;&gt;path&lt;/code&gt; element. The path is made of 5 vertices… it’s like connect the dots:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;2*               *4

        3*

1*               *5&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;All the other peaks were constructed individually using the &lt;code class=&quot;language-text&quot;&gt;peak&lt;/code&gt; directive. The shape here is once again a &lt;code class=&quot;language-text&quot;&gt;path&lt;/code&gt; but with 3 vertices. Let’s connect the dots again:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;text&quot;&gt;&lt;pre class=&quot;language-text&quot;&gt;&lt;code class=&quot;language-text&quot;&gt;        2*


1*               *3&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now that shape is ready we can focus on the parallax. Parallax effect is a simple technique to fake 3D&lt;em&gt;-ish&lt;/em&gt; in 2D. This would be achieved by moving the peaks in the back by a larger distance than those in the front.&lt;/p&gt;&lt;p&gt;On the iPhone you might have noticed the parallax effect when you tilt your phone. While that is awesome and can be replicated with JS I chose to simply use the mouse pointer to drive the parallax.&lt;/p&gt;&lt;h2 id=&quot;tracking-the-mouse&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#tracking-the-mouse&quot; aria-label=&quot;tracking the mouse permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Tracking the Mouse&lt;/h2&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;mousemove&lt;/code&gt; event gives use the mouse position: &lt;code class=&quot;language-text&quot;&gt;event.pageX&lt;/code&gt; &amp;amp; &lt;code class=&quot;language-text&quot;&gt;event.pageY&lt;/code&gt;. This position is relative to the window. We only care about the position inside the card. So, to calculate the position relative to the card we use:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; cardInfo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cardElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBoundingClientRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; mouseX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageX &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; cardInfo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; mouseY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageY &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; cardInfo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We have the mouse coordinates relative to the card. However, the origin for these coordinates is the top left corner of the card. For the parallax effect it would be helpful to move the origin to the centre of the card – makes the math easier. For that we do a little transformation:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; cardInfo &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cardElement&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getBoundingClientRect&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; mouseX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageX &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; cardInfo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;left&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; mouseY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; event&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;pageY &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; cardInfo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;top&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; w &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cardInfo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;width&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; cardInfo&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;height&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; transformedMouseX &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;w &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; x&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; transformedMouseY &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; y&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And finally we &lt;a href=&quot;http://p5js.org/reference/#/p5/map&quot;&gt;map&lt;/a&gt; &amp;amp; &lt;a href=&quot;http://p5js.org/reference/#/p5/constrain&quot;&gt;constrain&lt;/a&gt; these values between -1 and 1 (again, to make the math easier).&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Re-maps a number from one range to another&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;n&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; start1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stop1&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; start2&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; stop2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;n &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; start1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stop1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; start1&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;stop2 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; start2&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; start2&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-height=&quot;400&quot; data-theme-id=&quot;7569&quot; data-slug-hash=&quot;rOpRrx&quot; data-default-tab=&quot;result&quot; data-user=&quot;winkerVSbecks&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/winkerVSbecks/pen/rOpRrx/&quot;&gt;Mouse Position&lt;/a&gt; by Varun Vachhar (&lt;a href=&quot;http://codepen.io/winkerVSbecks&quot;&gt;@winkerVSbecks&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;//assets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;h2 id=&quot;the-parallax&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-parallax&quot; aria-label=&quot;the parallax permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Parallax&lt;/h2&gt;&lt;p&gt;The easiest way to move the peaks is to use CSS transforms. We could manipulate the &lt;code class=&quot;language-text&quot;&gt;path&lt;/code&gt; too but, that gets a bit more complex.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;path&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-attr-d&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{ { peak.d() }}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-attr-transform&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;{ { peak.translate() }}&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;path&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You’ll notice the &lt;code class=&quot;language-text&quot;&gt;ng-attr&lt;/code&gt; prefix. We need this because the transform value is calculated dynamically based on the mouse position:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If an attribute with a binding is prefixed with the ng-attr prefix… allows you to bind to attributes that would otherwise be eagerly processed by browsers (e.g. an SVG element&amp;#x27;s circle[cx] attributes).&lt;/p&gt;&lt;cite&gt;—&lt;a href=&quot;https://docs.angularjs.org/guide/directive&quot;&gt;docs.angularjs.org/guide/directive&lt;/a&gt;&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;Each peak can be displaced by a maximum amount in the X and Y direction. The SVG is responsive therefore, we need to dynamically calculate the pixel value using the width and height of the SVG.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// Ratio is a number between 0 &amp;amp; 1&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xBase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; svgWidth &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ratio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; yBase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; svgHeight &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ratio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To achieve the parallax effect each peak needs a different ratio. It’s largest for the peak in the back and reduces as we go forward. The translate value is calculated by mapping the normalized mouse position from &lt;code class=&quot;language-text&quot;&gt;-xBase&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;xBase&lt;/code&gt;.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xBase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; svgWidth &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ratio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; yBase &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; svgHeight &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ratio&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xAmt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normalizedMouseX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;xBase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; xBase&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; yAmt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normalizedMouseY&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;yBase&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; yBase&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; translate &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;translate(&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; xAmt &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;,&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; yAmt &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p data-height=&quot;268&quot; data-theme-id=&quot;7569&quot; data-slug-hash=&quot;QjaXyZ&quot; data-default-tab=&quot;result&quot; data-user=&quot;winkerVSbecks&quot; class=&quot;codepen&quot;&gt;See the Pen &lt;a href=&quot;http://codepen.io/winkerVSbecks/pen/QjaXyZ/&quot;&gt;parallax step 1&lt;/a&gt; by Varun Vachhar (&lt;a href=&quot;http://codepen.io/winkerVSbecks&quot;&gt;@winkerVSbecks&lt;/a&gt;) on &lt;a href=&quot;http://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/p&gt;&lt;script async=&quot;&quot; src=&quot;//assets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;&lt;p&gt;The card movement works in a similar fashion. Except we have to rotate the card instead of translate.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; yRotation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normalizedMouseX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; xRotation &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;normalizedMouseX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  transform&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;rotateX(&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
    xRotation &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;deg)&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27; rotateY(&amp;#x27;&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
    yRotation &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
    &lt;span class=&quot;token string&quot;&gt;&amp;#x27;deg) rotateZ(0deg)&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Mix all the ingredients together for a parallax filled card.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://i.giphy.com/yohzBk3lFhUcg.gif&quot; alt=&quot;animated gif of a person whisking&quot;/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Truncation]]></title><description><![CDATA[I recently discovered the idea of truncation. It is a fascinating concept. You rip apart a vertex to create a new facet and in turn more…]]></description><link>https://varun.ca/truncation/</link><guid isPermaLink="false">https://varun.ca/truncation/</guid><pubDate>Fri, 03 Jul 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/176da525a1c5f1c5c37cff5062dd9650/truncation.gif&quot;/&gt;&lt;/p&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/truncation&quot; source=&quot;https://github.com/winkerVSbecks/truncation&quot;&gt;&lt;/div&gt;&lt;p&gt;I recently discovered the idea of truncation. It is a fascinating concept. You rip apart a vertex to create a new facet and in turn more complex geometry. This pen by Ana Tudor shows the truncation of a tetrahedron:&lt;/p&gt;&lt;div hash=&quot;QEdGZQ&quot; title=&quot;tetrahedron truncation sequence (interactive)&quot; height=&quot;400&quot; user=&quot;thebabydino&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;You start with a simple tetrahedron. As you execute the truncation you can create some fairly complex shapes. So, what exactly is happening here? Let us break this down step by step:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Each vertex is connected to some edges. In the case of a tetrahedron each vertex is connected to 3 edges.&lt;/li&gt;&lt;li&gt;We pick one vertex called &lt;strong&gt;A&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;We start by splitting &lt;strong&gt;A&lt;/strong&gt; three times since it is connected to 3 edges.&lt;/li&gt;&lt;li&gt;The split vertices are called: &lt;strong&gt;A1&lt;/strong&gt;, &lt;strong&gt;A2&lt;/strong&gt; &amp;amp; &lt;strong&gt;A3&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;They are connected to edges: &lt;strong&gt;L1&lt;/strong&gt;, &lt;strong&gt;L2&lt;/strong&gt; &amp;amp; &lt;strong&gt;L3&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;To execute the truncation we simply move &lt;strong&gt;A1&lt;/strong&gt; along &lt;strong&gt;L1&lt;/strong&gt;. Towards the mid-point of &lt;strong&gt;L1&lt;/strong&gt;.&lt;/li&gt;&lt;li&gt;We do the same for &lt;strong&gt;A2&lt;/strong&gt; and &lt;strong&gt;A3&lt;/strong&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;A fairly simple algorithm that can be generalise for the entire shape/solid. You can even generalize it for a set of shapes, such as 2D polygons. Which is exactly what I did for my &lt;a href=&quot;http://winkervsbecks.github.io/truncation&quot;&gt;demo&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I used React and SVG for this project too. A quick overview of the code:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Construct the polygon using polar coordinates — an array of points.&lt;/li&gt;&lt;li&gt;Calculate the mid-points of each side.&lt;/li&gt;&lt;li&gt;To split the vertices we create a new array with duplicates of each vertex (each vertex is only connected to 2 sides in this case).&lt;/li&gt;&lt;li&gt;Then we have to link each split vertex to a mid-point. For this we create another array where each item has two properties:&lt;ul&gt;&lt;li&gt;the split vertex&lt;/li&gt;&lt;li&gt;mid-point of the line it belongs to&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Finally, use liner interpolation to execute the truncation.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The end result is react component that requires two properties: vertex count &amp;amp; truncation amount.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Triangle.life]]></title><description><![CDATA[I love triangles! Last year I spent 30 days making a new  triangle every day . It was a great experience. I learnt so much and it was…]]></description><link>https://varun.ca/triangles/</link><guid isPermaLink="false">https://varun.ca/triangles/</guid><pubDate>Fri, 26 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/f783e31053e26d55cfd27589c65df966/triangle-life.gif&quot;/&gt;&lt;/p&gt;&lt;div demo=&quot;http://triangle.life&quot; source=&quot;https://github.com/winkerVSbecks/triangle.life&quot;&gt;&lt;/div&gt;&lt;p&gt;I love triangles!&lt;/p&gt;&lt;p&gt;Last year I spent 30 days making a new &lt;a href=&quot;http://winkervsbecks.github.io/a-triangle-everyday&quot;&gt;triangle every day&lt;/a&gt;. It was a great experience. I learnt so much and it was amazing how much you can do with just one simple shape.&lt;/p&gt;&lt;p&gt;After a brief hiatus I have decided to get back to constructing more triangles. You can follow the progress at &lt;a href=&quot;http://triangle.life&quot;&gt;triangle.life&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;In case you are wondering त्रिकोण is the Hindi word for triangle.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[SVG with React]]></title><description><![CDATA[I've been using ReactJS for about 6 months now and have been very happy with my experience as a developer. I never considered it for…]]></description><link>https://varun.ca/react-svg/</link><guid isPermaLink="false">https://varun.ca/react-svg/</guid><pubDate>Sun, 21 Jun 2015 00:00:00 GMT</pubDate><content:encoded>&lt;img src=&quot;/b28eea694f36724c01920c602200d6ca/fermat-point.gif&quot; alt=&quot;interactive fermat point visualization&quot;/&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/fermat-point&quot; source=&quot;https://github.com/winkerVSbecks/fermat-point&quot;&gt;&lt;/div&gt;&lt;p&gt;I’ve been using ReactJS for about 6 months now and have been very happy with my experience as a developer. I never considered it for generative art because it just seemed like a needlessly complex approach. Then I came across projects such as &lt;a href=&quot;https://github.com/Flipboard/react-canvas&quot;&gt;Flipboard’s react-canvas&lt;/a&gt; and &lt;a href=&quot;https://github.com/reactjs/react-art&quot;&gt;React Art&lt;/a&gt; which made me reconsider this opinion. I love the idea of being able to build small isolated reusable components. Then use them to compose complex systems.&lt;/p&gt;&lt;p&gt;More recently I came across Brent Jackson’s fantastic tutorial on &lt;a href=&quot;http://jxnblk.com/react-icons&quot;&gt;Building SVG Icons with React&lt;/a&gt;. Not sure about everyone else but, I prefer the Canvas API to that of SVG. The SVG syntax for constructing shapes just seems extremely complicated and then having to manipulate them in JS is even more painful. The upside of SVG however is that it’s part of the DOM. You can mix it with other parts of the DOM in more &lt;em&gt;ehm&lt;/em&gt; real world scenarios.&lt;/p&gt;&lt;p&gt;With React you can compose a complex SVG images inside out — without having to worry about DOM manipulation. Every time state changes the document is re-rendered. Therefore, the SVG element updates to reflect this new state too.&lt;/p&gt;&lt;p&gt;I was really inspired by Brent’s tutorial and just had to try this out myself. The first thing I built was a &lt;a href=&quot;http://winkervsbecks.github.io/react-tetrahedrons&quot;&gt;Tetrahedron Generator&lt;/a&gt;. Fairly straightforward, not the most complex geometry in the world. You can find the source code here: &lt;a href=&quot;https://github.com/winkerVSbecks/react-tetrahedrons&quot;&gt;github.com/winkerVSbecks/react-tetrahedrons&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/e3c4ed97938bcab508a8033c8c15ede0/tetrahedron.gif&quot;/&gt;&lt;/p&gt;&lt;p&gt;It was really fast to build and this weird SVG syntax didn’t seem that weird any more. The next step was to build something a bit more complex… a &lt;a href=&quot;http://winkervsbecks.github.io/fermat-point&quot;&gt;Fermat point calculator&lt;/a&gt;. This required a bit more thinking but that was mostly because of geometry and math rather than SVG or React.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/de36e09f574eb5afd7af2b716da0d129/moving-triangles.gif&quot;/&gt;&lt;/p&gt;&lt;p&gt;Let’s look at an example of a component. I needed to build an SVG circle and then allow the user to click and drag it around. I started by creating a new component called &lt;em&gt;Handle&lt;/em&gt;. Here’s the template for it:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;circle
  className&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&amp;quot;handle&amp;quot;&lt;/span&gt;
  id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;id&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  cx&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  cy&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;props&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  fill&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;clrs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;yellow&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  onMouseDown&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;selectElement&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  onMouseMove&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;drag&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  onMouseUp&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deSelectElement&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  onMouseLeave&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;deSelectElement&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The logic for clicking and dragging and all the event handlers are isolated within this component itself. However, you can still pass in callbacks. This allows you to capture the drag and respond to it. Here’s an example of how you would use the &lt;em&gt;Handle&lt;/em&gt; component:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt;Handle x&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pt&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; y&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;pt&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; id&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;idx&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; onUpdate&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;dragUpdate&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the long term I hope to extend this ideology to Canvas. The idea is to build a library of such components with React. Each component would then be rendered to Canvas using PaperJS.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Location Services With AngularJS]]></title><description><![CDATA[Building mobile apps often requires working with location information. While, the Cordova geo-location plugin makes it quite trivial to get…]]></description><link>https://varun.ca/locator/</link><guid isPermaLink="false">https://varun.ca/locator/</guid><pubDate>Mon, 05 Jan 2015 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;4d0c2a06e9671ec046baf30a16d811a8&quot; title=&quot;Location Services with AngularJS&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/locator&quot; source=&quot;https://github.com/winkerVSbecks/locator&quot;&gt;&lt;/div&gt;&lt;p&gt;Building mobile apps often requires working with location information. While, the Cordova geo-location plugin makes it quite trivial to get the latitude and longitude values for the user’s current location, what we often want is location identifiers that are meaningful to the user - and not necessarily corresponding to the place where the user is right now. Below we look at two ways at acquiring meaningful location identifiers.&lt;/p&gt;&lt;h2 id=&quot;1-geo-location-to-nearby-locations&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#1-geo-location-to-nearby-locations&quot; aria-label=&quot;1 geo location to nearby locations permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;1. Geo-Location to Nearby Locations&lt;/h2&gt;&lt;p&gt;We fetch nearby locations based on the geo-location data and allow the user to pick the most appropriate option. For this method we can split the tasks into two services:&lt;/p&gt;&lt;h3 id=&quot;location&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#location&quot; aria-label=&quot;location permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Location&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/winkerVSbecks/locator/blob/master/src/location-picker/services/location.js&quot;&gt;Location service&lt;/a&gt; checks to see if geo-location is available and grabs the current location. It also allows us to register &lt;em&gt;on-ready-tasks&lt;/em&gt; with it. Therefore, all the other directives/services which depend on the geo-location data only bootstrap once the data is available.&lt;/p&gt;&lt;p&gt;The geo-location data is captured using using the &lt;code class=&quot;language-text&quot;&gt;navigator.geolocation.getCurrentPosition&lt;/code&gt; method. This works for both desktop browsers and Cordova/PhoneGap.&lt;/p&gt;&lt;h3 id=&quot;reverse-geocoder&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#reverse-geocoder&quot; aria-label=&quot;reverse geocoder permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Reverse Geocoder&lt;/h3&gt;&lt;p&gt;Reverse geocoding is the process of converting geographic coordinates (like latitude 43.647118 and longitude -79.420194) into a human-readable address (such as Ossington Ave at Argyle St, Toronto, ON, M6J 2Z5).&lt;/p&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/winkerVSbecks/locator/blob/master/src/location-picker/services/reverse-geocoder.js&quot;&gt;Reverse Geocoder&lt;/a&gt; sets up the &lt;a href=&quot;https://developers.google.com/maps/documentation/javascript/reference#Geocoder&quot;&gt;Google Geocoder service&lt;/a&gt; and uses the geo-location data to fetch, reverse geocoded, nearby locations. The service provides various options with reducing resolution, for example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;House #, Street, City, Province, Postal Code, Country&lt;/li&gt;&lt;li&gt;Street, City, Province, Postal Code, Country&lt;/li&gt;&lt;li&gt;Neighbourhood, City, Province, Country&lt;/li&gt;&lt;li&gt;City, Province, Postal Code, Country&lt;/li&gt;&lt;/ul&gt;&lt;h3 id=&quot;location-picker&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#location-picker&quot; aria-label=&quot;location picker permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Location-Picker&lt;/h3&gt;&lt;p&gt;The &lt;a href=&quot;https://github.com/winkerVSbecks/locator/blob/master/src/location-picker/directives/location-picker.js&quot;&gt;Location-Picker&lt;/a&gt; packages this into a simple directive. It utilizes the &lt;code class=&quot;language-text&quot;&gt;reverse-geocoder&lt;/code&gt; service to fetch a set of options for the user. The user selection is then bound to the object passed in through the &lt;code class=&quot;language-text&quot;&gt;ng-model&lt;/code&gt; attribute.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Requires access to the user&amp;#x27;s geo-location data --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;location-picker&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-model&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;pickedLocation&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;limit-to&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;5&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;location-picker&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;2-manually-query-the-location-database&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#2-manually-query-the-location-database&quot; aria-label=&quot;2 manually query the location database permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;2. Manually Query the Location Database&lt;/h2&gt;&lt;p&gt;The second method is to allow the user to query the location database manually. In this case we use a set of nested directives and the &lt;a href=&quot;https://developers.google.com/maps/documentation/javascript/examples/places-autocomplete&quot;&gt;Google Auto-complete service&lt;/a&gt;.&lt;/p&gt;&lt;h3 id=&quot;location-predictions&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#location-predictions&quot; aria-label=&quot;location predictions permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Location-Predictions&lt;/h3&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/winkerVSbecks/locator/blob/master/src/location-lookup/directives/location-predictions-directive.js&quot;&gt;Location-Predictions directive&lt;/a&gt; generates a search box and sets up the Google Auto-complete service. The auto-complete service fetches predictions based on the user submitted query string.&lt;/p&gt;&lt;h3 id=&quot;location-lookup&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#location-lookup&quot; aria-label=&quot;location lookup permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Location-Lookup&lt;/h3&gt;&lt;p&gt;The location-predictions directive generates a set of options which are passed into the &lt;a href=&quot;https://github.com/winkerVSbecks/locator/blob/master/src/location-lookup/directives/location-lookup-directive.js&quot;&gt;Location-Lookup directive&lt;/a&gt;. Which in turn displays them as a list for the user to choose from. Once the user picks a location it uses the &lt;a href=&quot;https://developers.google.com/maps/documentation/javascript/places&quot;&gt;Google Places service&lt;/a&gt; to fetch the geo-location data for it.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;&amp;lt;!-- Requires user to enter a query --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;location-lookup&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;ng-model&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;lookedUpLocation&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;limit-to&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;4&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;location-lookup&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Google Places Library has certain &lt;a href=&quot;https://developers.google.com/maps/documentation/javascript/places#LogoRequirements&quot;&gt;logo requirements&lt;/a&gt;. In this case we are not using a map therefore, we are required to display a &lt;strong&gt;Powered by Google&lt;/strong&gt; logo along with the data.&lt;/p&gt;&lt;h2 id=&quot;usage&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#usage&quot; aria-label=&quot;usage permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Usage&lt;/h2&gt;&lt;p&gt;Both, location-lookup and location picker, directives are fairly straight forward to use. They essentially behave as a &lt;code class=&quot;language-text&quot;&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element. The selection is captured using &lt;code class=&quot;language-text&quot;&gt;ng-model&lt;/code&gt;. Optionally you can limit the number of choices by using the &lt;code class=&quot;language-text&quot;&gt;limit-to&lt;/code&gt; attribute.&lt;/p&gt;&lt;p&gt;The selection returns data of the following type:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  name&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;CN Tower&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  description&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&amp;#x27;CN Tower, Front Street West, Toronto, ON, Canada&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  latitude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;43.642566&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
  longitude&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;79.38705700000003&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&quot;alternative-geocoding-providers&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#alternative-geocoding-providers&quot; aria-label=&quot;alternative geocoding providers permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Alternative Geocoding Providers&lt;/h2&gt;&lt;p&gt;In this example I’ve used &lt;a href=&quot;https://developers.google.com/maps/documentation/javascript&quot;&gt;Google Maps JavaScript API v3&lt;/a&gt; for all the location services required. Depending on your business and/or technical needs this might not be the best option. However, the idea remains the same and you could swap out the Google services with your preferred alternative.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[The Core]]></title><description><![CDATA[Another p5js/Codepen.io experiment. This time playing around with  contours  and  lerp  to get gradient fills inside a polygon. I've been…]]></description><link>https://varun.ca/the-core/</link><guid isPermaLink="false">https://varun.ca/the-core/</guid><pubDate>Mon, 18 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;lkqGo&quot; title=&quot;The Core&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/the-core&quot; source=&quot;https://github.com/winkerVSbecks/the-core&quot;&gt;&lt;/div&gt;&lt;p&gt;Another p5js/Codepen.io experiment. This time playing around with &lt;a href=&quot;http://p5js.org/reference/#/p5/beginContour&quot;&gt;contours&lt;/a&gt; and &lt;a href=&quot;http://p5js.org/reference/#/p5/lerpColor&quot;&gt;lerp&lt;/a&gt; to get gradient fills inside a polygon.&lt;/p&gt;&lt;p&gt;I’ve been trying to learn a bit more about easing functions. More specifically elastic easing. It is fairly easy to do a single bounce with CSS. Tools such as &lt;a href=&quot;http://bouncejs.com/#%7Bs:%5B%7BT:%22c%22,e:%22b%22,d:1000,D:0,f:%7Bx:1,y:1%7D,t:%7Bx:2,y:1%7D,s:1,b:4%7D,%7BT:%22c%22,e:%22b%22,d:1000,D:0,f:%7Bx:1,y:1%7D,t:%7Bx:1,y:2%7D,s:1,b:6%7D%5D%7D&quot;&gt;bounce.js&lt;/a&gt; can be used to generate more complex versions. However, I had no idea how to do this with JS or what the underlying equations were …&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Despite the commonality of the classic easing equations, largely attributed to Penner, there doesn’t seem to be the in-depth examination of “how it works” that a lot of code is subject to nowadays.&lt;/p&gt;&lt;cite&gt;— &lt;a href=&quot;http://upshots.org/actionscript/jsas-understanding-easing&quot;&gt;Explaining Penner’s equations – JavaScript and ActionScript&lt;/a&gt;&lt;/cite&gt;&lt;/blockquote&gt;&lt;p&gt;We start with this basic equation where:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;t&lt;/code&gt; is the current time (or position) of the tween. This can be seconds or frames, steps, seconds, ms, whatever – as long as the unit is the same as is used for the total time.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;b&lt;/code&gt; is the beginning value of the property.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;c&lt;/code&gt; is the change between the beginning and destination value of the property.&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;d&lt;/code&gt; is the total time of the tween.&lt;/li&gt;&lt;/ul&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;noEasing&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; c \&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; d &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And then use polynomial functions to create all kinds of easing effects:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;bounce&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;t&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; b&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; c&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; d&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ts &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;t &lt;span class=&quot;token operator&quot;&gt;/=&lt;/span&gt; d&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; tc &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; ts &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; b &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; c &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;33&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; tc &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ts &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;106&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ts &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ts &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;126&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; tc &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;67&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; ts &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; t&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tim Groleau built this a really cool &lt;a href=&quot;http://www.timotheegroleau.com/Flash/experiments/easing_function_generator.htm&quot;&gt;Easing Function Generator&lt;/a&gt; which I used to generate the bounce easing function.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Vector Field]]></title><description><![CDATA[While going through the Google  Material Design handbook  the illustration in the  Users Initiate Change  caught my eye. Around the same…]]></description><link>https://varun.ca/vector-field/</link><guid isPermaLink="false">https://varun.ca/vector-field/</guid><pubDate>Thu, 14 Aug 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;GCulK&quot; title=&quot;Vector Field&quot; height=&quot;400&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/material-vector-field&quot; source=&quot;https://github.com/winkerVSbecks/material-vector-field&quot;&gt;&lt;/div&gt;&lt;p&gt;While going through the Google &lt;a href=&quot;https://static.googleusercontent.com/media/www.google.com/en//design/material-design.pdf&quot;&gt;Material Design handbook&lt;/a&gt; the illustration in the &lt;em&gt;Users Initiate Change&lt;/em&gt; caught my eye. Around the same time &lt;a href=&quot;http://p5js.org/reference/&quot;&gt;p5js&lt;/a&gt; was announced, so I figured it would be fun replicating this with Canvas.&lt;/p&gt;&lt;p&gt;My first attempt was to build a grid of vectors and then rotate them towards the mouse location. The rotation would be scaled down based on the distance from the mouse location, i.e: &lt;code class=&quot;language-text&quot;&gt;rotation = angle * scale(0, 1, 0, width-of-the-canvas)&lt;/code&gt;. This gave an interesting result but, it wasn’t quite the same spiral effect.&lt;/p&gt;&lt;p&gt;The next step was to look into how vector fields work. With a bit of help from &lt;a href=&quot;http://tutorial.math.lamar.edu/Classes/CalcIII/VectorFields.aspx&quot;&gt;Paul’s Online Math Notes&lt;/a&gt;, &lt;a href=&quot;http://www.wolframalpha.com/share/clip?f=d41d8cd98f00b204e9800998ecf8427e8rdj53cf6e&quot;&gt;Wolfram Alpha&lt;/a&gt; and &lt;a href=&quot;http://math.stackexchange.com/questions/896356/equation-for-a-vector-field-spiraling-to-a-point&quot;&gt;math.stackexchange.com&lt;/a&gt; I discovered that: &lt;code class=&quot;language-text&quot;&gt;f(x,y) = [(y−5)-(x−5), -(x−5)-(y−5)]&lt;/code&gt; produces the exact spiralling effect.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:800px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:50%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;200\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20200\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M122%2096v84h168V12H122v84m2-83a126%20126%200%20000%2026%2097%2097%200%20000%2029%2097%2097%200%20000%2029%2097%2097%200%20000%2029l-1%2014%201%2014v1l-1%2013v11h12l12-1h118l12%201h12v-12l-1-12v-1l1-14-1-14v-1l1-14-1-14v-1c2%200%202-28%200-28v-1l1-14-1-14v-1l1-12V13h-12l-12%201h-1a97%2097%200%2000-29%200%2097%2097%200%2000-29%200%2097%2097%200%2000-29%200%20104%20104%200%2000-30%200l-23-1\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;vector field&quot; title=&quot;vector field&quot; src=&quot;/static/f214e40d3aadeaadaef9037662e441ab/5a190/vector-field.png&quot; srcSet=&quot;/static/f214e40d3aadeaadaef9037662e441ab/477c9/vector-field.png 288w,/static/f214e40d3aadeaadaef9037662e441ab/533c1/vector-field.png 576w,/static/f214e40d3aadeaadaef9037662e441ab/5a190/vector-field.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Building this with p5js was fairly straightforward. Processing has an awesome drawing API and p5js brings it to the web. If you are interested in getting started with p5js I have built a &lt;a href=&quot;https://github.com/winkerVSbecks/p5js-seed&quot;&gt;seed project&lt;/a&gt;. There are some great &lt;a href=&quot;http://p5js.org/learn/&quot;&gt;tutorials&lt;/a&gt; on the project site and Daniel Shiffman has ported his amazing &lt;a href=&quot;https://github.com/shiffman/The-Nature-of-Code-Examples-p5.js&quot;&gt;The Nature of Code Examples&lt;/a&gt; to p5js too.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; locs&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;token operator&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; h &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;calcVec&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;locs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; mouseX&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; locs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; mouseY&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token function&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    locs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    locs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    locs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;cos&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;h&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;heading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    locs&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;i&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;15&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;sin&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;h&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;heading&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Squiggle]]></title><description><![CDATA[I've been obsessed with this  illustration  for a while now and really want to build an animated/generative version of it. But, as usual I…]]></description><link>https://varun.ca/squiggle/</link><guid isPermaLink="false">https://varun.ca/squiggle/</guid><pubDate>Wed, 30 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;kdFsh&quot; title=&quot;Squiggle&quot; height=&quot;268&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;I’ve been obsessed with this &lt;a href=&quot;https://dribbble.com/shots/1128300-Jupiter-Study-no-01&quot;&gt;illustration&lt;/a&gt; for a while now and really want to build an animated/generative version of it. But, as usual I have no idea how to do that.&lt;/p&gt;&lt;p&gt;The aim is to get those paths to flow across the screen with an organic movement. Which probably means using a 2D &lt;a href=&quot;http://en.wikipedia.org/wiki/Perlin_noise&quot;&gt;Perlin noise&lt;/a&gt; field. This is just a first step towards animating Jupiter.&lt;/p&gt;&lt;p&gt;Next step is figuring out how to make those tentacle like paths. Probably using &lt;a href=&quot;http://marcinignac.com/blog/cindermedusae-making-generative-creatures/mesh05.html&quot;&gt;spline extrusions&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Built using &lt;a href=&quot;https://github.com/josephg/noisejs&quot;&gt;Joseph Gentle’s noisejs&lt;/a&gt; library and &lt;a href=&quot;http://jonobr1.github.io/two.js&quot;&gt;Two.js&lt;/a&gt; for the graphics.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Custom Easing with Sass]]></title><description><![CDATA[patakk  is an insanely talented GIF artist and on his  tumblr blog  he shared this simple yet amazing easing function: The  time  variable…]]></description><link>https://varun.ca/custom-easing-with-sass/</link><guid isPermaLink="false">https://varun.ca/custom-easing-with-sass/</guid><pubDate>Mon, 28 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;http://patakk.tumblr.com/&quot;&gt;patakk&lt;/a&gt; is an insanely talented GIF artist and on his &lt;a href=&quot;http://patakk.tumblr.com/post/88602945835/heres-a-simple-function-you-can-use-for-easing&quot;&gt;tumblr blog&lt;/a&gt; he shared this simple yet amazing easing function:&lt;/p&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;time&lt;/code&gt; variable goes from &lt;code class=&quot;language-text&quot;&gt;0&lt;/code&gt; to &lt;code class=&quot;language-text&quot;&gt;1&lt;/code&gt; and &lt;code class=&quot;language-text&quot;&gt;g&lt;/code&gt; adjusts the amount of easing.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;x &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;300&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;time&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

float &lt;span class=&quot;token function&quot;&gt;ease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;float p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; float g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;p &lt;span class=&quot;token operator&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;p&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0.5&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; p&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; g&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;3D animation has this concept of &lt;em&gt;&lt;a href=&quot;http://softimage.wiki.softimage.com/xsidocs/ani_proc_PlottingAnimation.htm&quot;&gt;baking an animation&lt;/a&gt;&lt;/em&gt;. The same idea can be extended to &lt;em&gt;baking an easing effect&lt;/em&gt; with Sass. The &lt;code class=&quot;language-text&quot;&gt;easingGenerator&lt;/code&gt; generates keyframe animations using this custom easing function.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;scss&quot;&gt;&lt;pre class=&quot;language-scss&quot;&gt;&lt;code class=&quot;language-scss&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;@function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$time&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;@if&lt;/span&gt; &lt;span class=&quot;token selector&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$time&lt;/span&gt; &amp;lt; 50 &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;@return&lt;/span&gt; 0.5 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$time&lt;/span&gt;/100&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;@else&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;@return&lt;/span&gt; 1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;0.5 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;pow&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;2 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;1 &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$time&lt;/span&gt;/100&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;@mixin&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;easingGenerator&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;@for&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; 0 &lt;span class=&quot;token keyword&quot;&gt;through&lt;/span&gt; &lt;span class=&quot;token selector&quot;&gt;100 &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// calculate&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$percent&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0% &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token property&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$left&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; 0% &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; 100 &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;ease&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token variable&quot;&gt;$i&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$g&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token comment&quot;&gt;// set position&lt;/span&gt;
    &lt;span class=&quot;token selector&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;#{$percent}&lt;/span&gt; &lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token property&quot;&gt;left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token variable&quot;&gt;$left&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div hash=&quot;Cihkr&quot; title=&quot;Sass Mixin for Generating a Custom Easing Function&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Jamie XX]]></title><description><![CDATA[Trying out the  React  framework for the first time. Built a very minimal animation for  Far Nearer  by  Jamie XX . Using the  Rdio  API to…]]></description><link>https://varun.ca/jamie-xx/</link><guid isPermaLink="false">https://varun.ca/jamie-xx/</guid><pubDate>Thu, 17 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/fa5f37a7e81714a749460e6d0bda5899/jamiexx.gif&quot;/&gt;&lt;/p&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/jamieXX&quot; source=&quot;https://github.com/winkerVSbecks/jamieXX&quot;&gt;&lt;/div&gt;&lt;p&gt;Trying out the &lt;a href=&quot;http://facebook.github.io/react/index.html&quot;&gt;React&lt;/a&gt; framework for the first time. Built a very minimal animation for &lt;strong&gt;Far Nearer&lt;/strong&gt; by &lt;strong&gt;Jamie XX&lt;/strong&gt;. Using the &lt;a href=&quot;http://www.rdio.com/developers/docs&quot;&gt;Rdio&lt;/a&gt; API to for the music.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Open & Close]]></title><description><![CDATA[I wanted to replicate CreativeDash's open  &  close animation with pure CSS/SASS, but don't think it's possible without SVG path animations…]]></description><link>https://varun.ca/open-and-close/</link><guid isPermaLink="false">https://varun.ca/open-and-close/</guid><pubDate>Mon, 07 Jul 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;mpjkd&quot; title=&quot;Burger to Cross&quot; height=&quot;500&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;I wanted to replicate CreativeDash’s open &amp;amp; close animation with pure CSS/SASS, but don’t think it’s possible without SVG path animations. This is the closest I got.&lt;/p&gt;&lt;p&gt;Kyle Henwood wrote a great &lt;a href=&quot;https://raygun.io/blog/2014/07/making-svg-html-burger-button&quot;&gt;blog post&lt;/a&gt; on how to build this with SVG.&lt;/p&gt;&lt;p&gt;Also, Anders Ingemann’s tutorial – &lt;a href=&quot;https://medium.com/@andsens/radial-progress-indicator-using-css-a917b80c43f9&quot;&gt;Radial progress indicator using CSS&lt;/a&gt; – was really helpful in trying to figure out the circular mask.&lt;/p&gt;&lt;div&gt;The animation is based on this &lt;a to=&quot;https://dribbble.com/shots/1623679-Open-Close&quot;&gt;Open &amp;amp; Close dribbble shot&lt;/a&gt; by CreativeDash&lt;/div&gt;</content:encoded></item><item><title><![CDATA[Two Level Shrinking Header and Footer with Ionic Framework]]></title><description><![CDATA[The  Ionic Framework  is an open source front-end framework for developing hybrid mobile apps with Cordova and AngularJS. I'm a big fan and…]]></description><link>https://varun.ca/shrinking-header-footer/</link><guid isPermaLink="false">https://varun.ca/shrinking-header-footer/</guid><pubDate>Wed, 25 Jun 2014 00:00:00 GMT</pubDate><content:encoded>&lt;div hash=&quot;ptvqJ&quot; title=&quot;Shrinking header and footer&quot; height=&quot;600&quot; defaultTab=&quot;result&quot;&gt;&lt;/div&gt;&lt;p&gt;The &lt;a href=&quot;http://ionicframework.com/&quot;&gt;Ionic Framework&lt;/a&gt; is an open source front-end framework for developing hybrid mobile apps with Cordova and AngularJS. I’m a big fan and use it a lot in my work at &lt;a href=&quot;http://rangle.io&quot;&gt;Rangle.io&lt;/a&gt;! We are a full-stack web and mobile app development consultancy.&lt;/p&gt;&lt;p&gt;One of the apps we are currently developing has an infinite stream similar to Facebook. Therefore, we decided to mimic the iOS shrinking header UI, to give the user more screen space for actual content. Ionic has had a &lt;a href=&quot;http://codepen.io/ionic/pen/hIzFp&quot;&gt;demo&lt;/a&gt; for this for quite some time. However, the shrinking behaviour is limited to the top of the scroll view.&lt;/p&gt;&lt;p&gt;We wanted to take this one step further and allow the shrinking and expansion to happen at any point during the scroll view. Also, we have a two level header: main header and a secondary toolbar.&lt;/p&gt;&lt;p&gt;Since, the animation can occur at any point we have to keep a track of the scroll direction. This is done by calculating the delta:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;delta &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollTop &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; prev&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If delta is greater than zero then the user is scrolling up and vice versa:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;dir &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; delta &lt;span class=&quot;token operator&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The shrink amount is calculated based on the scroll position:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// If Shrinking&lt;/span&gt;
shrinkAmt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; headerHeight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; subHeaderHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;starty &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; headerHeight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; subHeaderHeight&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollTop&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// If Expanding&lt;/span&gt;
shrinkAmt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prevShrinkAmt &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;starty &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollTop&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This works great until the user scrolls to the top/bottom edge and the view has bounce. The bounce causes all kinds of weird glitches. To prevent these from happening we need to add max and min limits:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token comment&quot;&gt;// If Shrinking&lt;/span&gt;
shrinkAmt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;
  headerHeight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt;
  subHeaderHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;
  Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;max&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; starty &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; headerHeight &lt;span class=&quot;token operator&quot;&gt;+&lt;/span&gt; subHeaderHeight &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollTop&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;token comment&quot;&gt;// If Expanding&lt;/span&gt;
shrinkAmt &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; prevShrinkAmt &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;min&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;threshold&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; starty &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt; e&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;detail&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;scrollTop&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The final step is to apply the actual CSS transforms from within the &lt;code class=&quot;language-text&quot;&gt;ionic.requestAnimationFrame&lt;/code&gt; function. This is also where we check to see if the shrink amount is greater than the height of the &lt;code class=&quot;language-text&quot;&gt;sub-header&lt;/code&gt; and only apply the transforms to the &lt;code class=&quot;language-text&quot;&gt;main-header&lt;/code&gt; if it is.&lt;/p&gt;&lt;p&gt;The &lt;code class=&quot;language-text&quot;&gt;ionic.requestAnimationFrame&lt;/code&gt; calls the &lt;code class=&quot;language-text&quot;&gt;window.requestAnimationFrame&lt;/code&gt; or a polyfill if it’s not available. This helps optimize the animation updates making it much more smoother:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;The window.requestAnimationFrame() method tells the browser that you wish to perform an animation and requests that the browser call a specified function to update an animation before the next repaint. The method takes as an argument a callback to be invoked before the repaint.&lt;/p&gt;&lt;p&gt;This will request that your animation function be called before the browser performs the next repaint. The number of callbacks is usually 60 times per second.&lt;/p&gt;&lt;cite&gt;— &lt;a href=&quot;https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame&quot;&gt;Mozilla Developer Network&lt;/a&gt;&lt;/cite&gt;&lt;/blockquote&gt;</content:encoded></item><item><title><![CDATA[Swipe-Li]]></title><description><![CDATA[Recently we  –  at  rangle.io   –  had a chance to work on a short project. The app was largely a functional prototype built in 1 week. One…]]></description><link>https://varun.ca/swipe-li/</link><guid isPermaLink="false">https://varun.ca/swipe-li/</guid><pubDate>Fri, 28 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/26c63b45483a38979ad6d52dc6313342/swipe-li-small.gif&quot; alt=&quot;swipable list elements&quot;/&gt;&lt;/p&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/swipe-li&quot; source=&quot;https://github.com/winkerVSbecks/swipe-li&quot;&gt;&lt;/div&gt;&lt;p&gt;Recently we – at &lt;a href=&quot;http://rangle.io&quot;&gt;rangle.io&lt;/a&gt; – had a chance to work on a short project. The app was largely a functional prototype built in 1 week. One of the requirements was to build an interface to allow the user to quickly accept or reject items. We came up with &lt;strong&gt;swipe-li&lt;/strong&gt;: a three pane swipeable &lt;code class=&quot;language-text&quot;&gt;&amp;lt;li&amp;gt;&lt;/code&gt; element. Swipe right for accept. Swipe left for reject.&lt;/p&gt;&lt;p&gt;Most of the &lt;em&gt;swiping&lt;/em&gt; code is taken from the &lt;a href=&quot;http://hammerjs.github.io/&quot;&gt;hammer.js&lt;/a&gt; carousel example. To support the directive I built a &lt;strong&gt;hammerRemote&lt;/strong&gt; service. This delegate service allows you to register/destroy/control multiple instances of hammer.&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;html&quot;&gt;&lt;pre class=&quot;language-html&quot;&gt;&lt;code class=&quot;language-html&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;&lt;/span&gt;div&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;swipe-li&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;disabled&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;intent&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;true&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;accept&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;done(item)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;reject&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;skip(item)&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;main-content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;sample-content.html&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;accept-content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;accept-content.html&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;reject-content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;reject-content.html&lt;span class=&quot;token punctuation&quot;&gt;&amp;#x27;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  &lt;span class=&quot;token attr-name&quot;&gt;reset-to-content&lt;/span&gt;&lt;span class=&quot;token attr-value&quot;&gt;&lt;span class=&quot;token punctuation attr-equals&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;false&lt;span class=&quot;token punctuation&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token tag&quot;&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;lt;/&lt;/span&gt;div&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;disabled&lt;/code&gt;: disable the swipe-li element&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;intent&lt;/code&gt;: user intent detection, if the user drags the pane &amp;gt; 50% of the width - the swipe will auto complete&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;accept&lt;/code&gt;: accept callback&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;reject&lt;/code&gt;: reject callback&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;main-content&lt;/code&gt;: template for the start pane&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;accept-content&lt;/code&gt;: template for the accept pane&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;reject-content&lt;/code&gt;: template for the reject pane&lt;/li&gt;&lt;li&gt;&lt;code class=&quot;language-text&quot;&gt;reset-to-content&lt;/code&gt;: should the swiped pane reset back to start pane on complete&lt;/li&gt;&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[Ellsworth Kelly Animated]]></title><description><![CDATA[In February 2014 Google launched it's  DevArt  project in partnership with  Barbican . In Google's words: DevArt is a celebration of art…]]></description><link>https://varun.ca/ellsworth-kelly-animated/</link><guid isPermaLink="false">https://varun.ca/ellsworth-kelly-animated/</guid><pubDate>Mon, 24 Mar 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/235c3126e2e74aba0ab516f9ccc81d91/orange.gif&quot; alt=&quot;bouncy orange blob&quot;/&gt;&lt;/p&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/ellsworthKellyAnimated&quot; source=&quot;https://github.com/winkerVSbecks/ellsworthKellyAnimated&quot;&gt;&lt;/div&gt;&lt;p&gt;In February 2014 Google launched it’s &lt;a href=&quot;https://devart.withgoogle.com/#/about&quot;&gt;DevArt&lt;/a&gt; project in partnership with &lt;a href=&quot;https://www.barbican.org.uk/&quot;&gt;Barbican&lt;/a&gt;. In Google’s words:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;DevArt is a celebration of art made with code by artists that push the possibilities of creativity - where technology is their canvas and code is their raw material.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;This was my entry and it ended up being &lt;a href=&quot;https://devart.withgoogle.com/#/project/18198727&quot;&gt;shortlisted&lt;/a&gt; for the finals.&lt;/p&gt;&lt;p&gt;A couple of years ago I made a &lt;a href=&quot;http://processing.org/&quot;&gt;Processing&lt;/a&gt; sketch with the logic described in the image below. Shortly thereafter I came across Ellsworth Kelly’s &lt;a href=&quot;http://www.matthewmarks.com/new-york/exhibitions/2011-02-12_ellsworth-kelly/works-in-exhibition/#/images/5/&quot;&gt;Black Relief II&lt;/a&gt;. It seemed that, unknowingly, I had created an animated version of his painting.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:800px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:62.5%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;250\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20250\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M211%2092a7516%207516%200%2001-48%2019l-1%2021c0%2023-1%2021%2012%2028l9%204%2024-12c14-6%2025-12%2025-13a1101%201101%200%2000-13-50l-8%203\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;polygon&quot; title=&quot;polygon&quot; src=&quot;/static/54962cb8e74520a84f8610a80cfab60d/5a190/polygon.png&quot; srcSet=&quot;/static/54962cb8e74520a84f8610a80cfab60d/477c9/polygon.png 288w,/static/54962cb8e74520a84f8610a80cfab60d/533c1/polygon.png 576w,/static/54962cb8e74520a84f8610a80cfab60d/5a190/polygon.png 800w&quot; sizes=&quot;(max-width: 800px) 100vw, 800px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;This led me to explore more of his work. His paintings carry an immense amount of potential energy in my opinion. It’s as if they are kinetic sculptures frozen in time.&lt;/p&gt;&lt;p&gt;This project is an attempt to animate some of his pieces using web-based technologies.&lt;/p&gt;&lt;p&gt;Most of the works are made using &lt;a href=&quot;https://code.google.com/p/box2dweb/&quot;&gt;Box2dWeb&lt;/a&gt;. A simple mouse click allows you to animate them.&lt;/p&gt;&lt;p&gt;In the first piece, you can grab the interface of the blue blob and the surrounding green fill and drag it around. Press &lt;code class=&quot;language-text&quot;&gt;?&lt;/code&gt; to see the underlying skeleton.&lt;/p&gt;&lt;p&gt;The project is also available as a Google Chrome App: &lt;a href=&quot;https://chrome.google.com/webstore/detail/ellsworth-kelly-animated/mhgohnogimfoohafafblgpgonabjhlal&quot;&gt;Ellsworth Kelly Animated&lt;/a&gt;&lt;/p&gt;&lt;h2 id=&quot;the-code&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#the-code&quot; aria-label=&quot;the code permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;The Code&lt;/h2&gt;&lt;p&gt;I wanted to play around with the idea of springy membranes. This was particularly inspired by the &lt;a href=&quot;http://1.bp.blogspot.com/-h8vIARrJHTI/TVgr1IHdJbI/AAAAAAAADZM/eF_8iRYRX08/s1600/43b6c106.jpg&quot;&gt;Red Curve Relief&lt;/a&gt; artwork by Ellsworth Kelly.&lt;/p&gt;&lt;p&gt;To do so, I had two options:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use easing functions to replicate springy movements&lt;/li&gt;&lt;li&gt;Use a physics engine to create a skeleton and add organic movements&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I see these shapes as animated creatures, so I chose the latter. The skeleton is made up of particles and spring-links.&lt;/p&gt;&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:816px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:66.31944444444444%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;265\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20265\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M144%2050c-3%203-3%203-3%207l1%206%202%202%203%201%205%201a29495%2029495%200%200045%20168l-3%203-3%201-1%204-1%203h22l-1-3-1-4-3-1-3-3a25594%2025594%200%200045-168l5-1%203-1%202-2%201-6c0-5-5-11-10-11s-11%205-11%208c0%202-4%202-38%202s-38%200-38-2l-3-5c-5-4-10-4-15%201m17%209l-3%205-3%203%209%2035%2033%20130c1%205%205%205%206%200l33-130%209-35-3-3-3-5-1-2h-76l-1%202m-78%2060c-2%202-3%202-5%201-10-6-20%208-12%2016l4%204-13%2047a672%20672%200%2001-14%2054v5h11l-1-3-4-5-3-3a2483%202483%200%200024-92c1-3%202-4%204-4l4-1h3c2%202%203%201%202-1-1-1-2-2-1-3v-10c-1-1%200-2%202-5l2-3-3%203m233%200c2%203%203%204%202%205v10c1%201%200%202-1%203-1%202%200%203%202%201h3l4%201c2%200%203%201%204%204l12%2048%2012%2045-3%202-4%205-1%203h11v-5l-1-5c-1%200-7-22-13-49l-13-47%204-4c8-8-2-22-12-16-2%201-3%201-5-1-4-4-5-4-1%200\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;skeleton&quot; title=&quot;skeleton&quot; src=&quot;/static/ea8e7a499c9fd35d4bdb007d9026eb7e/b4098/skeleton.png&quot; srcSet=&quot;/static/ea8e7a499c9fd35d4bdb007d9026eb7e/477c9/skeleton.png 288w,/static/ea8e7a499c9fd35d4bdb007d9026eb7e/533c1/skeleton.png 576w,/static/ea8e7a499c9fd35d4bdb007d9026eb7e/b4098/skeleton.png 816w&quot; sizes=&quot;(max-width: 816px) 100vw, 816px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;p&gt;The bottom three particles are anchors. The remaining are dynamic particles connected to the anchors and adjacent particles using springs.&lt;/p&gt;&lt;p&gt;An example of how the impulse is provided to the particles in order to animate the shapes:&lt;/p&gt;&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;js&quot;&gt;&lt;pre class=&quot;language-js&quot;&gt;&lt;code class=&quot;language-js&quot;&gt;&lt;span class=&quot;token class-name&quot;&gt;SpringyTriangle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;prototype&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function-variable function&quot;&gt;impulse&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; ping &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; Math&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; pinger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ping &lt;span class=&quot;token operator&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; pinger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;ping &lt;span class=&quot;token operator&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; pinger &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;var&lt;/span&gt; appliedForce &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;b2Vec2&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;force&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;x &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; pinger&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; scale&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;force&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;y &lt;span class=&quot;token operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token number&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;*&lt;/span&gt; scale&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;imp &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a_imp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getPosition&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;a_imp&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;body&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;ApplyImpulse&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;appliedForce&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;imp&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The other pieces used similar ideas of node based skeleton with an overlaid shape. I explain the process behind each piece in more detail on the &lt;a href=&quot;https://devart.withgoogle.com/#/project/18198727&quot;&gt;project site&lt;/a&gt;.&lt;/p&gt;&lt;h2 id=&quot;early-prototypes-made-with-processing&quot; style=&quot;position:relative&quot;&gt;&lt;a href=&quot;#early-prototypes-made-with-processing&quot; aria-label=&quot;early prototypes made with processing permalink&quot; class=&quot;heading-anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; width=&quot;16&quot; height=&quot;16&quot; viewBox=&quot;0 0 24 24&quot; fill=&quot;none&quot; stroke=&quot;currentcolor&quot; stroke-width=&quot;2&quot;&gt;&lt;path d=&quot;M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3&quot;&gt;&lt;/path&gt;&lt;line x1=&quot;8&quot; y1=&quot;12&quot; x2=&quot;16&quot; y2=&quot;12&quot;&gt;&lt;/line&gt;&lt;/svg&gt;&lt;/a&gt;Early Prototypes Made with Processing&lt;/h2&gt;&lt;p&gt;&lt;img src=&quot;/a0556885d3921f0b9f3fa850acc48b32/springywavybox.gif&quot; alt=&quot;springy wavy-box&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/6a55449001fde8b0ce6ce54f87a40ae2/springytriangles.gif&quot; alt=&quot;springy triangles&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;/6c0675a692cd9eae413447b19a1ecb91/manypolygons.gif&quot; alt=&quot;many polygons&quot;/&gt;&lt;/p&gt;</content:encoded></item><item><title><![CDATA[AngularJS WebGL Directive]]></title><description><![CDATA[AngularJS directives are siloed reusable components. This is an example of a WebGL directive built using  three.js . You can pass setup…]]></description><link>https://varun.ca/angularjs-webgl-directive/</link><guid isPermaLink="false">https://varun.ca/angularjs-webgl-directive/</guid><pubDate>Tue, 11 Feb 2014 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;span class=&quot;gatsby-resp-image-wrapper&quot; style=&quot;position:relative;display:block;margin-left:auto;margin-right:auto;max-width:960px&quot;&gt;
      &lt;span class=&quot;gatsby-resp-image-background-image&quot; style=&quot;padding-bottom:45.833333333333336%;position:relative;bottom:0;left:0;background-image:url(&amp;#x27;data:image/svg+xml,%3csvg%20xmlns=\&amp;#x27;http://www.w3.org/2000/svg\&amp;#x27;%20width=\&amp;#x27;400\&amp;#x27;%20height=\&amp;#x27;183\&amp;#x27;%20viewBox=\&amp;#x27;0%200%20400%20183\&amp;#x27;%20preserveAspectRatio=\&amp;#x27;none\&amp;#x27;%3e%3cpath%20d=\&amp;#x27;M130%2052l-13%205-9%208-8%209-4%2013-3%2013%203%2013%203%2014%209%209%2010%209%2013%204%2013%204%2014-4%2014-3%207-9c8-8%2010-12%2016-28l2-8-5-14c-5-13-5-15-12-22l-8-9-27-8-15%204\&amp;#x27;%20fill=\&amp;#x27;%23d3d3d3\&amp;#x27;%20fill-rule=\&amp;#x27;evenodd\&amp;#x27;/%3e%3c/svg%3e&amp;#x27;);background-size:cover;display:block&quot;&gt;&lt;/span&gt;
  &lt;img class=&quot;gatsby-resp-image-image&quot; alt=&quot;angularJS webGL Directive&quot; title=&quot;angularJS webGL Directive&quot; src=&quot;/static/069d209630e079215955dc2cfc0e28e8/d9199/angularWebGL.png&quot; srcSet=&quot;/static/069d209630e079215955dc2cfc0e28e8/477c9/angularWebGL.png 288w,/static/069d209630e079215955dc2cfc0e28e8/533c1/angularWebGL.png 576w,/static/069d209630e079215955dc2cfc0e28e8/d9199/angularWebGL.png 960w&quot; sizes=&quot;(max-width: 960px) 100vw, 960px&quot; style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0&quot; loading=&quot;lazy&quot;/&gt;
    &lt;/span&gt;&lt;/p&gt;&lt;div demo=&quot;http://winkervsbecks.github.io/angularWebglDirective&quot; source=&quot;https://github.com/winkerVSbecks/angularWebglDirective&quot;&gt;&lt;/div&gt;&lt;p&gt;AngularJS directives are siloed reusable components. This is an example of a WebGL directive built using &lt;a href=&quot;http://threejs.org/&quot;&gt;three.js&lt;/a&gt;. You can pass setup information such as: canvas size, model size, material, lighting, etc. to the directive.&lt;/p&gt;&lt;p&gt;You can even bind these values to the WebGL context – use the controls below to resize the object or change it’s material type.&lt;/p&gt;&lt;p&gt;Events such as window resizing or mouse moved can also be bound to the directive to update the scene. With the Responsive Canvas checkbox selected try resizing the window. The canvas and the scene will resize to fit the container.&lt;/p&gt;</content:encoded></item></channel></rss>