<?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[Mary Knize | mary.codes]]></title><description><![CDATA[The personal website of Mary Knize. Web development, art, and tinkering with fun projects.]]></description><link>https://mary.codes</link><generator>GatsbyJS</generator><lastBuildDate>Fri, 24 Oct 2025 17:03:23 GMT</lastBuildDate><item><title><![CDATA[I started painting again]]></title><link>https://mary.codes/blog/art/i_started_painting_again/</link><guid isPermaLink="false">https://mary.codes/blog/art/i_started_painting_again/</guid><pubDate>Mon, 01 Apr 2024 20:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I don&apos;t love how this painting turned out, but I enjoyed every moment of creating it.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b44a52bf07a9493c0d56acfe6fb4975a/998db/painting-front.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.1081081081081%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b44a52bf07a9493c0d56acfe6fb4975a/f51c2/painting-front.webp 148w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/66888/painting-front.webp 295w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/bc8a3/painting-front.webp 590w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/4ce34/painting-front.webp 885w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/f490a/painting-front.webp 1180w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/5f914/painting-front.webp 3072w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b44a52bf07a9493c0d56acfe6fb4975a/ca928/painting-front.jpg 148w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/278fa/painting-front.jpg 295w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/8a7c7/painting-front.jpg 590w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/b4485/painting-front.jpg 885w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/096b1/painting-front.jpg 1180w,
/static/b44a52bf07a9493c0d56acfe6fb4975a/998db/painting-front.jpg 3072w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b44a52bf07a9493c0d56acfe6fb4975a/8a7c7/painting-front.jpg&quot;
            alt=&quot;Painting&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;(I did the best I could on the photography with a tripod, my phone, and my office lights.)&lt;/p&gt;
&lt;p&gt;I absolutely adore how the background turned out, and I&apos;m sure I&apos;ll use some of those techniques in the future (texturing with paper, diluted paint splatter). However, I don&apos;t love how the really experimental parts turned out. The 3D printing didn&apos;t come out quite how I envisioned, and the smaller drops, added to cover some &quot;happy little accidents&quot;, feel like too much.&lt;/p&gt;
&lt;h3 id=&quot;why-i-paint&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#why-i-paint&quot; aria-label=&quot;why i paint permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Why I paint&lt;/h3&gt;
&lt;p&gt;I enjoy painting mostly because it&apos;s something I&apos;ve been doing since childhood. Growing up, there was an almost endless supply of craft paints and things to paint on, whether it was canvas, wood, or ceramic.&lt;/p&gt;
&lt;p&gt;While I love creating digital art, I feel like I can mentally work myself into a frenzy as I&apos;m coding. Ideas snowball into more ideas, and I can spend hours traveling down different avenues trying to create cool effects.&lt;/p&gt;
&lt;p&gt;With paint, everything slows down. The time between idea and execution is much longer. While acrylic paint dries quickly, it&apos;s best to give layers ample time to dry. You also have to settle on the best idea and commit to it. The only undo is repainting and starting over again.&lt;/p&gt;
&lt;p&gt;The background of this piece took well over a day to complete. There were a few paint-overs when I didn&apos;t like an effect, but in general, I painted over with diluted paint, so the past &quot;mistakes&quot; could still show through and give character to the 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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/104650574b244b637b95b49a8f8cbdb7/998db/painting-right.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 133.1081081081081%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/104650574b244b637b95b49a8f8cbdb7/f51c2/painting-right.webp 148w,
/static/104650574b244b637b95b49a8f8cbdb7/66888/painting-right.webp 295w,
/static/104650574b244b637b95b49a8f8cbdb7/bc8a3/painting-right.webp 590w,
/static/104650574b244b637b95b49a8f8cbdb7/4ce34/painting-right.webp 885w,
/static/104650574b244b637b95b49a8f8cbdb7/f490a/painting-right.webp 1180w,
/static/104650574b244b637b95b49a8f8cbdb7/5f914/painting-right.webp 3072w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/104650574b244b637b95b49a8f8cbdb7/ca928/painting-right.jpg 148w,
/static/104650574b244b637b95b49a8f8cbdb7/278fa/painting-right.jpg 295w,
/static/104650574b244b637b95b49a8f8cbdb7/8a7c7/painting-right.jpg 590w,
/static/104650574b244b637b95b49a8f8cbdb7/b4485/painting-right.jpg 885w,
/static/104650574b244b637b95b49a8f8cbdb7/096b1/painting-right.jpg 1180w,
/static/104650574b244b637b95b49a8f8cbdb7/998db/painting-right.jpg 3072w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/104650574b244b637b95b49a8f8cbdb7/8a7c7/painting-right.jpg&quot;
            alt=&quot;Another view&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;a-different-kind-of-problem-solving&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#a-different-kind-of-problem-solving&quot; aria-label=&quot;a different kind of problem solving permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;A different kind of problem-solving&lt;/h3&gt;
&lt;p&gt;You probably don&apos;t think about problem-solving when creating art, but I feel like I&apos;m constantly problem-solving when I&apos;m painting. How do I get the effect I&apos;m going for? What&apos;s the best way to mask part of this painting? Should I go mixed-media or just paint traditionally?&lt;/p&gt;
&lt;p&gt;One of the problems I came across in this painting was that the tops of my 3D printed elements looked much worse than the bottoms. The simple fix was to flip the 3D printed pieces so the bottoms were now the tops. In hindsight, I probably should&apos;ve taken the extra time to flip the pieces in the slicer and try printing the bottom layer with different patterns to see which I liked the best.&lt;/p&gt;
&lt;p&gt;I also encountered a problem with a big white glob of paint dripping right into the center of the canvas. I hid the blob with the small drop, but now I just can&apos;t stop thinking about how it doesn&apos;t look right. Sometimes, the best solution is to take the time to redo it right.&lt;/p&gt;
&lt;h3 id=&quot;adventures-in-mixed-media&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#adventures-in-mixed-media&quot; aria-label=&quot;adventures in mixed media permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Adventures in mixed media&lt;/h3&gt;
&lt;p&gt;Adding 3D elements to paintings has been something I&apos;ve wanted to do for a long time. The last time I painted, which has to be over six months ago, I was trying to use 3D prints as stencils, but they haven&apos;t been a great stencil material for me, at least on canvas. A smoother surface like wood might yield better results.&lt;/p&gt;
&lt;p&gt;Instead, I&apos;ve been thinking about using 3D printing to emphasize geometric elements in my paintings, as well as to introduce some generative features. In this painting, I used some existing code to generate flow fields, saved the one I liked the most, then used Inkscape to &quot;cut out&quot; the drop shapes. Then, I used &lt;a href=&quot;https://www.tinkercad.com/&quot;&gt;Tinkercad&lt;/a&gt; to create the extruded designs.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6e60913ed1095ef2e0c32a817123ad56/82af4/tinkercad.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/6e60913ed1095ef2e0c32a817123ad56/f51c2/tinkercad.webp 148w,
/static/6e60913ed1095ef2e0c32a817123ad56/66888/tinkercad.webp 295w,
/static/6e60913ed1095ef2e0c32a817123ad56/bc8a3/tinkercad.webp 590w,
/static/6e60913ed1095ef2e0c32a817123ad56/4ce34/tinkercad.webp 885w,
/static/6e60913ed1095ef2e0c32a817123ad56/f490a/tinkercad.webp 1180w,
/static/6e60913ed1095ef2e0c32a817123ad56/fb727/tinkercad.webp 1856w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/6e60913ed1095ef2e0c32a817123ad56/c5084/tinkercad.png 148w,
/static/6e60913ed1095ef2e0c32a817123ad56/60cc9/tinkercad.png 295w,
/static/6e60913ed1095ef2e0c32a817123ad56/6d370/tinkercad.png 590w,
/static/6e60913ed1095ef2e0c32a817123ad56/540ae/tinkercad.png 885w,
/static/6e60913ed1095ef2e0c32a817123ad56/2561a/tinkercad.png 1180w,
/static/6e60913ed1095ef2e0c32a817123ad56/82af4/tinkercad.png 1856w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/6e60913ed1095ef2e0c32a817123ad56/6d370/tinkercad.png&quot;
            alt=&quot;Tinkercad&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The process is similar to my older post, &lt;a href=&quot;/blog/art/3d_printing_generative_art_with_p5_and_blender/&quot;&gt;3D printing generative art with P5.js and Blender&lt;/a&gt;, but instead of using Blender I&apos;ve found that Tinkercad can be much faster and easier to work with for simple extruded designs. The code that I used for that earlier blog post is the same that I used for this painting, with a few changes.&lt;/p&gt;
&lt;h3 id=&quot;thoughts-for-future-paintings&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#thoughts-for-future-paintings&quot; aria-label=&quot;thoughts for future paintings permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Thoughts for future paintings&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I&apos;m looking into fancy specialty filaments and build plates for the 3D printed elements, specifically &lt;a href=&quot;https://www.instructables.com/Holographic-Rainbow-Reflective-3D-Prints/&quot;&gt;holographic build plates&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I like the ModPodge finish and the way that I painted it on. The X-shaped texture really looks great in person.&lt;/li&gt;
&lt;li&gt;I want to experiment more with different ways to affix the 3D printed pieces to the canvas. I used ModPodge to glue the pieces on, but I&apos;m thinking of other ways, like pins, thread, and even magnets.&lt;/li&gt;
&lt;li&gt;More geometry. I really like bold, simple geometric art. It&apos;s surprisingly hard to make good, simple, geometric art without it looking too basic.&lt;/li&gt;
&lt;li&gt;More color! I really need to get better at mixing large amounts of colors and more mindfully mixing colors to achieve the effect I want.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[100 days of Japanese on Duolingo]]></title><link>https://mary.codes/blog/life/100-days-of-japanese-duolingo/</link><guid isPermaLink="false">https://mary.codes/blog/life/100-days-of-japanese-duolingo/</guid><pubDate>Fri, 22 Mar 2024 21: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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6788893e6ff7ab53f50b0881201761bb/1263b/duolingo-100-days.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 100%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/6788893e6ff7ab53f50b0881201761bb/f51c2/duolingo-100-days.webp 148w,
/static/6788893e6ff7ab53f50b0881201761bb/66888/duolingo-100-days.webp 295w,
/static/6788893e6ff7ab53f50b0881201761bb/bc8a3/duolingo-100-days.webp 590w,
/static/6788893e6ff7ab53f50b0881201761bb/4ce34/duolingo-100-days.webp 885w,
/static/6788893e6ff7ab53f50b0881201761bb/80c60/duolingo-100-days.webp 1000w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/6788893e6ff7ab53f50b0881201761bb/c5084/duolingo-100-days.png 148w,
/static/6788893e6ff7ab53f50b0881201761bb/60cc9/duolingo-100-days.png 295w,
/static/6788893e6ff7ab53f50b0881201761bb/6d370/duolingo-100-days.png 590w,
/static/6788893e6ff7ab53f50b0881201761bb/540ae/duolingo-100-days.png 885w,
/static/6788893e6ff7ab53f50b0881201761bb/1263b/duolingo-100-days.png 1000w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/6788893e6ff7ab53f50b0881201761bb/6d370/duolingo-100-days.png&quot;
            alt=&quot;Duolingo 100 days&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Today I officially hit a 100 day &lt;a href=&quot;/blog/life/streaking_into_the_new_year/&quot;&gt;streak&lt;/a&gt; of learning Japanese on Duolingo. I&apos;m proud of the accomplishment, but at the same time, not feeling incredibly motivated to continue. While I plan to keep going, I&apos;ve identified some pain points that I need to address going forward.&lt;/p&gt;
&lt;h3 id=&quot;the-gamification-is-too-much&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-gamification-is-too-much&quot; aria-label=&quot;the gamification is too much permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The gamification is too much&lt;/h3&gt;
&lt;p&gt;I&apos;m fine with keeping up a streak, but Duolingo layers on levels of gamification. Right now, I&apos;m in the semifinals of the Diamond Tournament. When I last stopped using Duolingo, they had just introduced the league system. When I started learning Japanese, I didn&apos;t care too much about progressing in the leagues. However, my motivation to learn the language gave me plenty of XP to easily reach Diamond League.&lt;/p&gt;
&lt;p&gt;Now, as I&apos;m getting deeper into Japanese and the lesson are getting harder, I&apos;m struggling to keep up. I want to win the Diamond Tournament now that I&apos;m close, but I also dread the upcoming grind. I hope, once I finish the tournament, I can go back to not caring about the leagues.&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: 270px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/dcd17b7ce76e66becb7e7e352e816ed8/8c112/duolingo-diamond.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 222.2972972972973%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/dcd17b7ce76e66becb7e7e352e816ed8/f51c2/duolingo-diamond.webp 148w,
/static/dcd17b7ce76e66becb7e7e352e816ed8/78721/duolingo-diamond.webp 270w&quot;
              sizes=&quot;(max-width: 270px) 100vw, 270px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/dcd17b7ce76e66becb7e7e352e816ed8/c5084/duolingo-diamond.png 148w,
/static/dcd17b7ce76e66becb7e7e352e816ed8/8c112/duolingo-diamond.png 270w&quot;
            sizes=&quot;(max-width: 270px) 100vw, 270px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/dcd17b7ce76e66becb7e7e352e816ed8/8c112/duolingo-diamond.png&quot;
            alt=&quot;Diamond Tournament&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;new-lessons-arent-sticking&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#new-lessons-arent-sticking&quot; aria-label=&quot;new lessons arent sticking permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;New lessons aren&apos;t sticking&lt;/h3&gt;
&lt;p&gt;This relates to the earlier gamification problem. Each unit is throwing new vocabulary and sentence structures at me, and I&apos;m not able to absorb everything before moving on to the next level.&lt;/p&gt;
&lt;p&gt;Why? It&apos;s all about the double XP bonuses.&lt;/p&gt;
&lt;p&gt;To really get the most XP and stay at the top of the league, you have to effectively stack XP bonuses. This involves doing at least one lesson in the morning and evening every day to get the Early Bird and Night Owl XP chests. Then, each completed level grants double XP for 15 minutes.&lt;/p&gt;
&lt;p&gt;I feel pressured to grind levels in order to get XP bonuses, so I&apos;m &quot;faking my way&quot; through new concepts instead of taking my time understanding what I&apos;m learning. It&apos;s all about doing as much as possible within 15 minutes to get the next bonus.&lt;/p&gt;
&lt;p&gt;Also, XP bonuses only exist in the mobile app. This deters me from using the website. I think if I used the website I would consult other resources more often.&lt;/p&gt;
&lt;p&gt;This is really a problem of my own making, I know, but also, it&apos;s the way this app was designed. Duolingo is created to generate maximum engagement to sell subscriptions and generate ad revenue, not to teach you a language.&lt;/p&gt;
&lt;h3 id=&quot;i-cant-read&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#i-cant-read&quot; aria-label=&quot;i cant read permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;I can&apos;t read&lt;/h3&gt;
&lt;iframe width=&quot;100%&quot; style=&quot;aspect-ratio: 2.39/1&quot; src=&quot;https://www.youtube.com/embed/t6qhq1IvdGw?si=MtDp0d0JMziiJF0D&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;The first section forces you to learn hiragana and katakana to progress, and it&apos;s not exactly a fun time. You&apos;re finishing units and then you&apos;re hit with doing 15 or so hiragana/katakana lessons. You don&apos;t get any XP bonuses for these lessons. Because the writing system lessons aren&apos;t similarly rewarded, it feels like a slog.&lt;/p&gt;
&lt;p&gt;Once the first section is finished, there are no more forced writing system roadblocks, but there&apos;s still an unstated expectation that you&apos;ll keep up with those lessons and move on to kanji for each unit.&lt;/p&gt;
&lt;p&gt;Again, my bad for not finishing the hiragana and katakana lessons and starting with kanji, but it&apos;s honestly not emphasized. It feels like an afterthought within the app.&lt;/p&gt;
&lt;h3 id=&quot;not-everything-is-bad&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#not-everything-is-bad&quot; aria-label=&quot;not everything is bad permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Not everything is bad&lt;/h3&gt;
&lt;p&gt;Even with these problems, I still actually do like learning with Duolingo! While I feel like the program could use more grammar instruction, I kind of like figuring it out for myself by parsing out sentences. Duolingo feels designed to give you those &quot;aha!&quot; moments when something finally clicks. This is opposed to more traditional learning methods, where you learn a concept, then implement what you learned.&lt;/p&gt;
&lt;p&gt;Personally, I learn best with &quot;aha!&quot; moments. It&apos;s one reason why I love tinkering with things and strange programming problems. I also enjoy the pattern recognition skills that I get to use with this type of learning. Getting the language thrown at me feels like the most engaging way for me to learn, even when it&apos;s temporarily frustrating.&lt;/p&gt;
&lt;h3 id=&quot;supplementing-with-other-resources&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#supplementing-with-other-resources&quot; aria-label=&quot;supplementing with other resources permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Supplementing with other resources&lt;/h3&gt;
&lt;p&gt;I&apos;m to a point where I really do want more information on Japanese grammar. I do worry that if I continue making assumptions based on parsing out sentences, I&apos;m going to make some wrong assumptions that will become ingrained.&lt;/p&gt;
&lt;p&gt;For learning kanji, I found WaniKani. &lt;a href=&quot;https://www.wanikani.com/&quot;&gt;WaniKani&lt;/a&gt; is a resource specifically geared towards learning kanji and vocabulary. While I&apos;m still trying to progress with hiragana/katakana, I know that I need to get a jump start on kanji as well, and this resource is highly recommended.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/8135ff087b7822d9167840b171a7f7fd/687ee/wanikani-dashboard.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/8135ff087b7822d9167840b171a7f7fd/f51c2/wanikani-dashboard.webp 148w,
/static/8135ff087b7822d9167840b171a7f7fd/66888/wanikani-dashboard.webp 295w,
/static/8135ff087b7822d9167840b171a7f7fd/bc8a3/wanikani-dashboard.webp 590w,
/static/8135ff087b7822d9167840b171a7f7fd/4ce34/wanikani-dashboard.webp 885w,
/static/8135ff087b7822d9167840b171a7f7fd/f490a/wanikani-dashboard.webp 1180w,
/static/8135ff087b7822d9167840b171a7f7fd/c6318/wanikani-dashboard.webp 1838w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/8135ff087b7822d9167840b171a7f7fd/c5084/wanikani-dashboard.png 148w,
/static/8135ff087b7822d9167840b171a7f7fd/60cc9/wanikani-dashboard.png 295w,
/static/8135ff087b7822d9167840b171a7f7fd/6d370/wanikani-dashboard.png 590w,
/static/8135ff087b7822d9167840b171a7f7fd/540ae/wanikani-dashboard.png 885w,
/static/8135ff087b7822d9167840b171a7f7fd/2561a/wanikani-dashboard.png 1180w,
/static/8135ff087b7822d9167840b171a7f7fd/687ee/wanikani-dashboard.png 1838w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/8135ff087b7822d9167840b171a7f7fd/6d370/wanikani-dashboard.png&quot;
            alt=&quot;WaniKani dashboard&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For learning grammar, I found &lt;a href=&quot;https://bunpro.jp/&quot;&gt;Bunpro&lt;/a&gt;. I&apos;m really enjoying Bunpro. WaniKani and Bunpro emphasize slower learning and spaced repetition. Bunpro in particular warns about trying to learn too much at once. This is contrary to Duolingo&apos;s attention-based approach.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/a9cc2d038beb86e7852b1273d5cac263/78496/bunpro-dashboard.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/a9cc2d038beb86e7852b1273d5cac263/f51c2/bunpro-dashboard.webp 148w,
/static/a9cc2d038beb86e7852b1273d5cac263/66888/bunpro-dashboard.webp 295w,
/static/a9cc2d038beb86e7852b1273d5cac263/bc8a3/bunpro-dashboard.webp 590w,
/static/a9cc2d038beb86e7852b1273d5cac263/4ce34/bunpro-dashboard.webp 885w,
/static/a9cc2d038beb86e7852b1273d5cac263/f490a/bunpro-dashboard.webp 1180w,
/static/a9cc2d038beb86e7852b1273d5cac263/a9c35/bunpro-dashboard.webp 1836w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/a9cc2d038beb86e7852b1273d5cac263/c5084/bunpro-dashboard.png 148w,
/static/a9cc2d038beb86e7852b1273d5cac263/60cc9/bunpro-dashboard.png 295w,
/static/a9cc2d038beb86e7852b1273d5cac263/6d370/bunpro-dashboard.png 590w,
/static/a9cc2d038beb86e7852b1273d5cac263/540ae/bunpro-dashboard.png 885w,
/static/a9cc2d038beb86e7852b1273d5cac263/2561a/bunpro-dashboard.png 1180w,
/static/a9cc2d038beb86e7852b1273d5cac263/78496/bunpro-dashboard.png 1836w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/a9cc2d038beb86e7852b1273d5cac263/6d370/bunpro-dashboard.png&quot;
            alt=&quot;Bunpro dashboard&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;My favorite part of Bunpro is how each lesson is broken down to really teach the quirks of Japanese grammar. If Bunpro&apos;s explanation isn&apos;t enough, there are additional resources linked at the bottom of each lesson. Before finding Bunpro I spent some time trying to read &lt;a href=&quot;https://imabi.org/&quot;&gt;Imabi&lt;/a&gt; and &lt;a href=&quot;https://guidetojapanese.org/learn/&quot;&gt;Tae Kim&lt;/a&gt;, which are both excellent grammar resources, but they&apos;re a lot to take in all at once. I&apos;m finding them much more useful linked to actual grammar lessons.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f286da193b7b074b0391592f23466713/f533c/bunpro-resources.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f286da193b7b074b0391592f23466713/f51c2/bunpro-resources.webp 148w,
/static/f286da193b7b074b0391592f23466713/66888/bunpro-resources.webp 295w,
/static/f286da193b7b074b0391592f23466713/bc8a3/bunpro-resources.webp 590w,
/static/f286da193b7b074b0391592f23466713/4ce34/bunpro-resources.webp 885w,
/static/f286da193b7b074b0391592f23466713/f490a/bunpro-resources.webp 1180w,
/static/f286da193b7b074b0391592f23466713/e3fc7/bunpro-resources.webp 1833w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f286da193b7b074b0391592f23466713/c5084/bunpro-resources.png 148w,
/static/f286da193b7b074b0391592f23466713/60cc9/bunpro-resources.png 295w,
/static/f286da193b7b074b0391592f23466713/6d370/bunpro-resources.png 590w,
/static/f286da193b7b074b0391592f23466713/540ae/bunpro-resources.png 885w,
/static/f286da193b7b074b0391592f23466713/2561a/bunpro-resources.png 1180w,
/static/f286da193b7b074b0391592f23466713/f533c/bunpro-resources.png 1833w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f286da193b7b074b0391592f23466713/6d370/bunpro-resources.png&quot;
            alt=&quot;Bunpro additional resources&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I also enjoy that Bunpro quizzes require typing in answers as opposed to using a word bank. I feel like I use the Duolingo word bank too much as a crutch.&lt;/p&gt;
&lt;p&gt;Bunpro also offers additional &quot;decks&quot; (courses), and I&apos;ve added on a vocabulary course as well. I do feel like I might end up overdoing it with new vocabulary, but I&apos;m taking Bunpro at a much slower pace than Duolingo.&lt;/p&gt;
&lt;p&gt;An additional resource that I&apos;m interested in is &lt;a href=&quot;https://marumori.io/&quot;&gt;MaruMori&lt;/a&gt;, which is a newer site that aims to be an all-in-one resource for learning Japanese. It aims to replace Duolingo, Bunpro, WaniKani, and Anki (a flashcard app). However, I&apos;m not looking to replace Duolingo, and I also don&apos;t want to restart from the beginning. Also, MaruMori only offers a 14-day free trial, vs. the 30-day trials of Bunpro and WaniKani. (Bunpro also has a totally free option.) While I think MaruMori looks interesting (and beautifully crafted), I think I&apos;ll stick with the other options for now.&lt;/p&gt;
&lt;p&gt;I&apos;ve also looked at textbooks like &lt;a href=&quot;https://genki.japantimes.co.jp/site/index.en.html&quot;&gt;Genki&lt;/a&gt;, which are highly recommended, but at $40 per textbook, plus an additional workbook, I kind of want to see how I fare with the online options.&lt;/p&gt;
&lt;h3 id=&quot;the-next-100-days&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#the-next-100-days&quot; aria-label=&quot;the next 100 days permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;The next 100 days&lt;/h3&gt;
&lt;p&gt;I&apos;m going to be switching up my tactics a bit. I&apos;m going to emphasize grammar over blindly following Duolingo&apos;s lead. I&apos;m only a few days in with Bunpro and WaniKani, but I plan to utilize those resources more as I continue with Duolingo. Instead of blindly memorizing patterns as I&apos;m doing now, I&apos;m going to take the time to learn the grammar rules behind the patterns.&lt;/p&gt;
&lt;h3 id=&quot;my-current-progress&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#my-current-progress&quot; aria-label=&quot;my current progress permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;My current progress&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Section 2: Explorer, Unit 10. There are 18 total units in section 2.
&lt;ul&gt;
&lt;li&gt;This means I&apos;ve completed 15 units out of a total of 143 units over 6 sections (section 7 has 6 levels, unknown if those are &quot;units&quot;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;87216 total XP (this goes back to 2014).&lt;/li&gt;
&lt;li&gt;11 top 3 finishes (I think this also counts all language courses).&lt;/li&gt;
&lt;li&gt;Average 352.88 XP per day (just for Japanese).&lt;/li&gt;
&lt;li&gt;Most XP in a day: 1928 (Feb. 10, 2024).&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title><![CDATA[How I'm organizing my work in 2024]]></title><link>https://mary.codes/blog/programming/how_im_organizing_my_work_in_2024/</link><guid isPermaLink="false">https://mary.codes/blog/programming/how_im_organizing_my_work_in_2024/</guid><pubDate>Wed, 20 Mar 2024 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lately, I&apos;ve had a lot of projects going on. I have some ongoing projects at work as well as multiple projects I&apos;m working on in my free time (my &lt;a href=&quot;/blog/programming/generating_a_vr_map_with_osm_and_aframe/&quot;&gt;3D OSM map&lt;/a&gt;, &lt;a href=&quot;/blog/web_accessibility/are_animated_gifs_accessible/&quot;&gt;investigating animated gif accessibility&lt;/a&gt;, &lt;a href=&quot;/blog/programming/word_of_the_day_google_ai_studio/&quot;&gt;learning Japanese&lt;/a&gt;, etc.) I&apos;m always looking for good ways to organize my work notes. Here&apos;s a few new tactics I&apos;ve been using for work and personal projects.&lt;/p&gt;
&lt;h3 id=&quot;google-keep&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#google-keep&quot; aria-label=&quot;google keep permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Google Keep&lt;/h3&gt;
&lt;p&gt;I used Google Keep years ago and recently picked it back up as a bookmark alternative. When I find an interesting article or resource, I either use the &lt;a href=&quot;https://chromewebstore.google.com/detail/google-keep-chrome-extens/lpcaedmchfhocbbapmcbpinfpgnhiddi?pli=1&quot;&gt;Google Keep Chrome Extension&lt;/a&gt; if I&apos;m on desktop (although it&apos;s been intermittently broken) or share to Keep on mobile. I have a bunch of labels that I use to sort my notes, and I&apos;m trying to get better at re-organizing notes on a weekly basis.&lt;/p&gt;
&lt;p&gt;A peek at my Keep:&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/3c1535c5e68974e40935f7a64e3373a7/c807c/google-keep.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 50%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/3c1535c5e68974e40935f7a64e3373a7/f51c2/google-keep.webp 148w,
/static/3c1535c5e68974e40935f7a64e3373a7/66888/google-keep.webp 295w,
/static/3c1535c5e68974e40935f7a64e3373a7/bc8a3/google-keep.webp 590w,
/static/3c1535c5e68974e40935f7a64e3373a7/4ce34/google-keep.webp 885w,
/static/3c1535c5e68974e40935f7a64e3373a7/f490a/google-keep.webp 1180w,
/static/3c1535c5e68974e40935f7a64e3373a7/924cd/google-keep.webp 1850w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/3c1535c5e68974e40935f7a64e3373a7/c5084/google-keep.png 148w,
/static/3c1535c5e68974e40935f7a64e3373a7/60cc9/google-keep.png 295w,
/static/3c1535c5e68974e40935f7a64e3373a7/6d370/google-keep.png 590w,
/static/3c1535c5e68974e40935f7a64e3373a7/540ae/google-keep.png 885w,
/static/3c1535c5e68974e40935f7a64e3373a7/2561a/google-keep.png 1180w,
/static/3c1535c5e68974e40935f7a64e3373a7/c807c/google-keep.png 1850w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/3c1535c5e68974e40935f7a64e3373a7/6d370/google-keep.png&quot;
            alt=&quot;Keep notes&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The Verge has a good article on &lt;a href=&quot;https://www.theverge.com/24073806/google-keep-how-to-note-app&quot;&gt;&quot;How to make the most of Google Keep&quot;&lt;/a&gt;. I don&apos;t use colors to organize much, but I might actually start color-coding some of my notes.&lt;/p&gt;
&lt;p&gt;I generally only use Keep for personal notes, not for work, but I should probably utilize the Keep attached to my work email. Instead, I&apos;ve been using Discord channels.&lt;/p&gt;
&lt;h3 id=&quot;discord-channels&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#discord-channels&quot; aria-label=&quot;discord channels permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Discord channels&lt;/h3&gt;
&lt;p&gt;I started using a personal Discord server to quickly jot down notes related to Jira tickets. I create a new private text channel for each ticket. It&apos;s more convenient than using Keep because I already use Discord for communication, but I do worry about running into a limit on text channels. I believe I can have up to 50 at a time. This should be plenty, because I delete tickets as they&apos;re no longer relevant.&lt;/p&gt;
&lt;p&gt;This is a good way to keep notes for myself that I would have cluttered Jira comments with before, or would&apos;ve lost within a Google Doc. Anything that is pertinent to the ticket or testing will go in comments, but miscellaneous other info can live in the Discord channel as I work on it.&lt;/p&gt;
&lt;p&gt;I do wonder if I should transfer these notes to Keep instead, but that&apos;s one more window that I have to keep open during the day. I tend to already have a lot of Chrome tabs open, which takes me to my last and favorite new organizing tactic.&lt;/p&gt;
&lt;h3 id=&quot;chrome-tab-groups&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#chrome-tab-groups&quot; aria-label=&quot;chrome tab groups permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Chrome tab groups&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/1d470f8e9e9ff74b865d863c9cb45c29/c0214/chrome-tabs.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 5.405405405405405%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/1d470f8e9e9ff74b865d863c9cb45c29/f51c2/chrome-tabs.webp 148w,
/static/1d470f8e9e9ff74b865d863c9cb45c29/66888/chrome-tabs.webp 295w,
/static/1d470f8e9e9ff74b865d863c9cb45c29/bc8a3/chrome-tabs.webp 590w,
/static/1d470f8e9e9ff74b865d863c9cb45c29/c6463/chrome-tabs.webp 796w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/1d470f8e9e9ff74b865d863c9cb45c29/c5084/chrome-tabs.png 148w,
/static/1d470f8e9e9ff74b865d863c9cb45c29/60cc9/chrome-tabs.png 295w,
/static/1d470f8e9e9ff74b865d863c9cb45c29/6d370/chrome-tabs.png 590w,
/static/1d470f8e9e9ff74b865d863c9cb45c29/c0214/chrome-tabs.png 796w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/1d470f8e9e9ff74b865d863c9cb45c29/6d370/chrome-tabs.png&quot;
            alt=&quot;Tab groups&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This has been the best productivity discovery of the year. Every new ticket goes into a tab group, and just like with Discord, the tab group gets removed once the ticket is safely deployed. I like to keep documentation, articles, GitHub repos, etc. open while I&apos;m working on a project, and this has been the best way I&apos;ve found to keep all that information at the ready.&lt;/p&gt;
&lt;p&gt;I also bounce between projects sometimes. When that happens, I can easily reopen a tab group and pick up right where I left off. I can also save a group for long-term projects so they display right in the bookmark bar, and saved groups can also be hidden to the bookmark bar as well. Again, The Verge has an article all about &lt;a href=&quot;https://www.theverge.com/23384844/chrome-google-tab-groups-create-save-how-to&quot;&gt;&quot;How to create and save Chrome tab groups&quot;&lt;/a&gt; that I found to be really helpful.&lt;/p&gt;
&lt;p&gt;I&apos;ve started using tab groups for my personal browsing, too. Right now I have groups for things that I&apos;m currently researching, like OpenStreetMaps and AI UX design.&lt;/p&gt;
&lt;p&gt;It&apos;s a constant battle to find ways to organize work that are both easy and useful. If I check back in six months, I may very well be trying something new. But for right now, these three things have really helped me capture and organize articles and resources without having to backtrack and re-find resources in my browser history or within a virtual pile of disorganized documents.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Watch the documentary 'Good Night Oppy' if you're feeling science-y]]></title><link>https://mary.codes/blog/life/good_night_oppy/</link><guid isPermaLink="false">https://mary.codes/blog/life/good_night_oppy/</guid><pubDate>Mon, 18 Mar 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Good Night Oppy&lt;/em&gt; was an impulse watch, and totally worth it. Currently, it&apos;s available to stream on Prime Video.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/be94a/good-night-oppy.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 147.97297297297297%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/f51c2/good-night-oppy.webp 148w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/66888/good-night-oppy.webp 295w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/bc8a3/good-night-oppy.webp 590w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/4ce34/good-night-oppy.webp 885w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/f490a/good-night-oppy.webp 1180w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/31711/good-night-oppy.webp 2764w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/ca928/good-night-oppy.jpg 148w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/278fa/good-night-oppy.jpg 295w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/8a7c7/good-night-oppy.jpg 590w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/b4485/good-night-oppy.jpg 885w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/096b1/good-night-oppy.jpg 1180w,
/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/be94a/good-night-oppy.jpg 2764w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/2fc3ed94577cf9fae2c1f9e3d80c1b76/8a7c7/good-night-oppy.jpg&quot;
            alt=&quot;Good Night Oppy&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;A documentary, &lt;em&gt;Good Night Oppy&lt;/em&gt; follows the lifetimes of the &lt;a href=&quot;https://science.nasa.gov/mission/mer-spirit/&quot;&gt;Spirit&lt;/a&gt; and &lt;a href=&quot;https://science.nasa.gov/mission/mer-opportunity/&quot;&gt;Opportunity&lt;/a&gt; Mars rovers and their respective crews. Originally scheduled for 90-day missions, both rovers outlived their missions many times over. The film begins by explaining the reason for a geological mission to Mars: to find evidence of water. It then goes through the approval of the mission and the building of the two rovers before proceeding to the launch and harrowing descent of both rovers to the Martian surface.&lt;/p&gt;
&lt;p&gt;Spirit and Opportunity landed on opposite sides of the planet. Spirit was surrounded by volcanic rock. Opportunity, however, landed in a crater, and immediately found bedrock and signs of ancient water (acidic water, but still water) on Mars.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Good Night Oppy&lt;/em&gt; also chronicles the lives of the people who worked on the Mars rover program. For some of them, their work ended once the rovers were built and deployed. But for others, they faced 90 days of working weird Martian hours. Little did they realize that they would end up working with their rovers for years.&lt;/p&gt;
&lt;p&gt;Once the rovers were a few years into their missions, the operations crews decided to drive them as far as they could before they stopped working. Spirit and Opportunity both managed to get stuck a few times, but Spirit was the first to get permanently stuck and lose communication with Earth after 6 years. Opportunity managed to continue for 14 years, and at its 5,000 sol (Martian day) birthday, the crew used its camera to take a selfie.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/efa04336580f4002f0340706c14a1e78/23b91/opportunity-selfie.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 81.08108108108108%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/efa04336580f4002f0340706c14a1e78/f51c2/opportunity-selfie.webp 148w,
/static/efa04336580f4002f0340706c14a1e78/66888/opportunity-selfie.webp 295w,
/static/efa04336580f4002f0340706c14a1e78/bc8a3/opportunity-selfie.webp 590w,
/static/efa04336580f4002f0340706c14a1e78/4ce34/opportunity-selfie.webp 885w,
/static/efa04336580f4002f0340706c14a1e78/f490a/opportunity-selfie.webp 1180w,
/static/efa04336580f4002f0340706c14a1e78/2449b/opportunity-selfie.webp 1639w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/efa04336580f4002f0340706c14a1e78/ca928/opportunity-selfie.jpg 148w,
/static/efa04336580f4002f0340706c14a1e78/278fa/opportunity-selfie.jpg 295w,
/static/efa04336580f4002f0340706c14a1e78/8a7c7/opportunity-selfie.jpg 590w,
/static/efa04336580f4002f0340706c14a1e78/b4485/opportunity-selfie.jpg 885w,
/static/efa04336580f4002f0340706c14a1e78/096b1/opportunity-selfie.jpg 1180w,
/static/efa04336580f4002f0340706c14a1e78/23b91/opportunity-selfie.jpg 1639w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/efa04336580f4002f0340706c14a1e78/8a7c7/opportunity-selfie.jpg&quot;
            alt=&quot;Opportunity selfie&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The film ends with the Mars rover team coming to terms with eventually losing contact with both rovers. By the end of the mission, 14 years later, some of the original team had been replaced. Some of the new crew members were children who were inspired to study aerospace engineering by the launch of the rovers years before.&lt;/p&gt;
&lt;p&gt;One of the most interesting things about this documentary are the scenes from Mars, created by Industrial Light &amp;#x26; Magic. You forget that you&apos;re watching a computer generated rover. It feels like authentic footage from another planet. While the rovers are being built, you see them in archive footage, but they become true characters once they&apos;re on Mars.&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; style=&quot;aspect-ratio: 16/9&quot; src=&quot;https://www.youtube.com/embed/W4t58Yruhds?si=46ysnD9Jg9juZNAy&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;p&gt;Overall, I&apos;d say this is one of the best documentaries I&apos;ve watched in a while. It made me immediately want to check up on how the current rovers, &lt;a href=&quot;https://mars.nasa.gov/msl/home/&quot;&gt;Curiosity&lt;/a&gt; and &lt;a href=&quot;https://mars.nasa.gov/mars2020/&quot;&gt;Perserverance&lt;/a&gt;, are doing. I haven&apos;t been as tuned into space exploration lately as I had been in the past, and this film has recharged my interest in the subject.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Sculpted robo-goldfish, a rainbow office building, and a look inside click farms]]></title><link>https://mary.codes/blog/friday_faves/robo_goldfish_a_rainbow_office_and_click_farms/</link><guid isPermaLink="false">https://mary.codes/blog/friday_faves/robo_goldfish_a_rainbow_office_and_click_farms/</guid><pubDate>Fri, 15 Mar 2024 12:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Five-ish things that I loved this week.&lt;/p&gt;
&lt;h4 id=&quot;i-made-a-chill-space-roving-robo-goldfish--transforming-junk-into-cosmic-wonders-video&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#i-made-a-chill-space-roving-robo-goldfish--transforming-junk-into-cosmic-wonders-video&quot; aria-label=&quot;i made a chill space roving robo goldfish  transforming junk into cosmic wonders video permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=0sOkV26WMyU&quot;&gt;I made a Chill Space-Roving Robo-Goldfish / Transforming Junk into Cosmic Wonders (video)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;The attention to detail on this sculpture is &lt;em&gt;stunning&lt;/em&gt;.&lt;/p&gt;
&lt;iframe width=&quot;100%&quot; style=&quot;aspect-ratio: 16/9;&quot; src=&quot;https://www.youtube.com/embed/0sOkV26WMyU?si=lCn_J6Ktb5ev_2-D&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h4 id=&quot;digital-walled-gardens-blog-post&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#digital-walled-gardens-blog-post&quot; aria-label=&quot;digital walled gardens blog post permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://manuelmoreale.com/digital-walled-gardens&quot;&gt;Digital walled gardens (blog post)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I really enjoyed this short post about walled gardens vs. digital gardens. It compares traversing through personal blogs to wandering through open, welcoming gardens. A few days later, I read &lt;a href=&quot;https://blog.jim-nielsen.com/2024/following-links/&quot;&gt;&quot;Following Links&quot;&lt;/a&gt;, which shares similar thoughts about surfing the web. Following links wherever they may lead is more interesting than relying on an algorithm.&lt;/p&gt;
&lt;p&gt;That&apos;s one of my main motivations for &lt;a href=&quot;/blog/friday_faves/&quot;&gt;Friday Faves&lt;/a&gt;. I want to present the most interesting links I&apos;ve found by following links through the &lt;a href=&quot;https://indieweb.org/&quot;&gt;IndieWeb&lt;/a&gt; or through one of my RSS subscriptions.&lt;/p&gt;
&lt;p&gt;Speaking of walled gardens and algorithms...&lt;/p&gt;
&lt;h4 id=&quot;photographer-steps-inside-vietnams-shadowy-click-farms-article&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#photographer-steps-inside-vietnams-shadowy-click-farms-article&quot; aria-label=&quot;photographer steps inside vietnams shadowy click farms article permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://www.cnn.com/style/vietnam-farms-jack-latham-beggars-honey/index.html&quot;&gt;Photographer steps inside Vietnam’s shadowy ‘click farms’ (article)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;In this interview, photographer Jack Latham recalls what he experienced researching &quot;click farms&quot; in Vietnam for his book &lt;a href=&quot;https://www.jacklatham.com/beggars-honey&quot;&gt;&quot;Beggar&apos;s Honey&quot;&lt;/a&gt;. These businesses are able to simulate thousands of user interactions which are easily used to manipulate popular opinion.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;While researching, Latham said he found that algorithms — a topic of his previous book, “Latent Bloom” — often recommended videos that he said got increasingly “extreme” with each click.&lt;/p&gt;
&lt;p&gt;“If you only digest a diet of that, it’s a matter of time you become diabetically conspiratorial,” he said. “The spreading of disinformation is the worst thing. It happens in your pocket, not newspapers, and it’s terrifying that it’s tailored to your kind of neurosis.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I generally like to post feel-good things in my faves, but I found this too fascinating to pass up. I think if more people realized how easily algorithms can be manipulated... well, honestly, I think many people &lt;em&gt;do&lt;/em&gt; understand, at some level, that everything they see on social media is artifically manipulated. They just don&apos;t care.&lt;/p&gt;
&lt;h4 id=&quot;a-rainbow-office-building-brightens-up-the-tokyo-streets-with-prismatic-color-article&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#a-rainbow-office-building-brightens-up-the-tokyo-streets-with-prismatic-color-article&quot; aria-label=&quot;a rainbow office building brightens up the tokyo streets with prismatic color article permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://www.thisiscolossal.com/2024/02/sako-architects-tokyo-office/&quot;&gt;A Rainbow Office Building Brightens Up the Tokyo Streets with Prismatic Color (article)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;A beautifully-designed office building featuring sheets of rainbow-painted glass. The details are minimal but the photos are gorgeous.&lt;/p&gt;
&lt;blockquote class=&quot;instagram-media&quot; data-instgrm-permalink=&quot;https://www.instagram.com/p/CPC21f_Mgz3/?utm_source=ig_embed&amp;amp;utm_campaign=loading&quot; data-instgrm-version=&quot;14&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:540px; min-width:326px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:16px;&quot;&gt; &lt;a href=&quot;https://www.instagram.com/p/CPC21f_Mgz3/?utm_source=ig_embed&amp;amp;utm_campaign=loading&quot; style=&quot; background:#FFFFFF; line-height:0; padding:0 0; text-align:center; text-decoration:none; width:100%;&quot; target=&quot;_blank&quot;&gt; &lt;div style=&quot; display: flex; flex-direction: row; align-items: center;&quot;&gt; &lt;div style=&quot;background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 40px; margin-right: 14px; width: 40px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;display: flex; flex-direction: column; flex-grow: 1; justify-content: center;&quot;&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 100px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 60px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;padding: 19% 0;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;display:block; height:50px; margin:0 auto 12px; width:50px;&quot;&gt;&lt;svg width=&quot;50px&quot; height=&quot;50px&quot; viewBox=&quot;0 0 60 60&quot; version=&quot;1.1&quot; xmlns=&quot;https://www.w3.org/2000/svg&quot; xmlns:xlink=&quot;https://www.w3.org/1999/xlink&quot;&gt;&lt;g stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;g transform=&quot;translate(-511.000000, -20.000000)&quot; fill=&quot;#000000&quot;&gt;&lt;g&gt;&lt;path d=&quot;M556.869,30.41 C554.814,30.41 553.148,32.076 553.148,34.131 C553.148,36.186 554.814,37.852 556.869,37.852 C558.924,37.852 560.59,36.186 560.59,34.131 C560.59,32.076 558.924,30.41 556.869,30.41 M541,60.657 C535.114,60.657 530.342,55.887 530.342,50 C530.342,44.114 535.114,39.342 541,39.342 C546.887,39.342 551.658,44.114 551.658,50 C551.658,55.887 546.887,60.657 541,60.657 M541,33.886 C532.1,33.886 524.886,41.1 524.886,50 C524.886,58.899 532.1,66.113 541,66.113 C549.9,66.113 557.115,58.899 557.115,50 C557.115,41.1 549.9,33.886 541,33.886 M565.378,62.101 C565.244,65.022 564.756,66.606 564.346,67.663 C563.803,69.06 563.154,70.057 562.106,71.106 C561.058,72.155 560.06,72.803 558.662,73.347 C557.607,73.757 556.021,74.244 553.102,74.378 C549.944,74.521 548.997,74.552 541,74.552 C533.003,74.552 532.056,74.521 528.898,74.378 C525.979,74.244 524.393,73.757 523.338,73.347 C521.94,72.803 520.942,72.155 519.894,71.106 C518.846,70.057 518.197,69.06 517.654,67.663 C517.244,66.606 516.755,65.022 516.623,62.101 C516.479,58.943 516.448,57.996 516.448,50 C516.448,42.003 516.479,41.056 516.623,37.899 C516.755,34.978 517.244,33.391 517.654,32.338 C518.197,30.938 518.846,29.942 519.894,28.894 C520.942,27.846 521.94,27.196 523.338,26.654 C524.393,26.244 525.979,25.756 528.898,25.623 C532.057,25.479 533.004,25.448 541,25.448 C548.997,25.448 549.943,25.479 553.102,25.623 C556.021,25.756 557.607,26.244 558.662,26.654 C560.06,27.196 561.058,27.846 562.106,28.894 C563.154,29.942 563.803,30.938 564.346,32.338 C564.756,33.391 565.244,34.978 565.378,37.899 C565.522,41.056 565.552,42.003 565.552,50 C565.552,57.996 565.522,58.943 565.378,62.101 M570.82,37.631 C570.674,34.438 570.167,32.258 569.425,30.349 C568.659,28.377 567.633,26.702 565.965,25.035 C564.297,23.368 562.623,22.342 560.652,21.575 C558.743,20.834 556.562,20.326 553.369,20.18 C550.169,20.033 549.148,20 541,20 C532.853,20 531.831,20.033 528.631,20.18 C525.438,20.326 523.257,20.834 521.349,21.575 C519.376,22.342 517.703,23.368 516.035,25.035 C514.368,26.702 513.342,28.377 512.574,30.349 C511.834,32.258 511.326,34.438 511.181,37.631 C511.035,40.831 511,41.851 511,50 C511,58.147 511.035,59.17 511.181,62.369 C511.326,65.562 511.834,67.743 512.574,69.651 C513.342,71.625 514.368,73.296 516.035,74.965 C517.703,76.634 519.376,77.658 521.349,78.425 C523.257,79.167 525.438,79.673 528.631,79.82 C531.831,79.965 532.853,80.001 541,80.001 C549.148,80.001 550.169,79.965 553.369,79.82 C556.562,79.673 558.743,79.167 560.652,78.425 C562.623,77.658 564.297,76.634 565.965,74.965 C567.633,73.296 568.659,71.625 569.425,69.651 C570.167,67.743 570.674,65.562 570.82,62.369 C570.966,59.17 571,58.147 571,50 C571,41.851 570.966,40.831 570.82,37.631&quot;&gt;&lt;/path&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/div&gt;&lt;div style=&quot;padding-top: 8px;&quot;&gt; &lt;div style=&quot; color:#3897f0; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:550; line-height:18px;&quot;&gt;View this post on Instagram&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;padding: 12.5% 0;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;display: flex; flex-direction: row; margin-bottom: 14px; align-items: center;&quot;&gt;&lt;div&gt; &lt;div style=&quot;background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(0px) translateY(7px);&quot;&gt;&lt;/div&gt; &lt;div style=&quot;background-color: #F4F4F4; height: 12.5px; transform: rotate(-45deg) translateX(3px) translateY(1px); width: 12.5px; flex-grow: 0; margin-right: 14px; margin-left: 2px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot;background-color: #F4F4F4; border-radius: 50%; height: 12.5px; width: 12.5px; transform: translateX(9px) translateY(-18px);&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: 8px;&quot;&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 50%; flex-grow: 0; height: 20px; width: 20px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot; width: 0; height: 0; border-top: 2px solid transparent; border-left: 6px solid #f4f4f4; border-bottom: 2px solid transparent; transform: translateX(16px) translateY(-4px) rotate(30deg)&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;margin-left: auto;&quot;&gt; &lt;div style=&quot; width: 0px; border-top: 8px solid #F4F4F4; border-right: 8px solid transparent; transform: translateY(16px);&quot;&gt;&lt;/div&gt; &lt;div style=&quot; background-color: #F4F4F4; flex-grow: 0; height: 12px; width: 16px; transform: translateY(-4px);&quot;&gt;&lt;/div&gt; &lt;div style=&quot; width: 0; height: 0; border-top: 8px solid #F4F4F4; border-left: 8px solid transparent; transform: translateY(-4px) translateX(8px);&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt; &lt;div style=&quot;display: flex; flex-direction: column; flex-grow: 1; justify-content: center; margin-bottom: 24px;&quot;&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; margin-bottom: 6px; width: 224px;&quot;&gt;&lt;/div&gt; &lt;div style=&quot; background-color: #F4F4F4; border-radius: 4px; flex-grow: 0; height: 14px; width: 144px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;/a&gt;&lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;&lt;a href=&quot;https://www.instagram.com/p/CPC21f_Mgz3/?utm_source=ig_embed&amp;amp;utm_campaign=loading&quot; style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;&quot; target=&quot;_blank&quot;&gt;A post shared by 迫 慶一郎 | SAKO Architects (@keiichiro_sako)&lt;/a&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;h4 id=&quot;bob-cassette-rewinder-hacking-detergent-drm-for-98-cost-saving-articlegit-repo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#bob-cassette-rewinder-hacking-detergent-drm-for-98-cost-saving-articlegit-repo&quot; aria-label=&quot;bob cassette rewinder hacking detergent drm for 98 cost saving articlegit repo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://github.com/dekuNukem/bob_cassette_rewinder&quot;&gt;Bob Cassette Rewinder: Hacking Detergent DRM for 98% Cost Saving (article/git repo)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I don&apos;t think I&apos;ve ever seen a README with so much detail before, it really is a blog post in itself. I&apos;ve also never heard of this Bob dishwasher before, but I really enjoy this story. Buying replacement dishwasher &quot;cassettes&quot; is expensive and wasteful, so &lt;a href=&quot;https://github.com/dekuNukem&quot;&gt;dekuNukem&lt;/a&gt;, who seems to do a lot of reverse-engineering, figured out how to refill and reset the cartridges so they can be reused. While they spend a lot of time dumping data to figure out how to manually reset the wash count on the chip, they even go as far as figuring out the diswashing detergent formula used for the cassettes. It&apos;s a fascinating read.&lt;/p&gt;
&lt;h4 id=&quot;special-6th-thing-my-post-ai-writing-blog-post&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#special-6th-thing-my-post-ai-writing-blog-post&quot; aria-label=&quot;special 6th thing my post ai writing blog post permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Special 6th thing! &lt;a href=&quot;https://www.ribbonfarm.com/2024/03/08/my-post-ai-writing/&quot;&gt;My Post-AI Writing (blog post)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;In response to being asked about the effect of AI on writing, the author explains how AI makes writing less fun and thoughtful. In a world where you can have AI gather your thoughts and polish your writing, there&apos;s something extra freeing about just letting words fall out onto the page.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;But AI has had an indirect positive and enjoyable effect on my writing: It has made me lower my craftsmanship standards, which were never very high to begin with. This is one reason I’m writing a lot more this year. The causal chain from AI is subtle, and AI is not the whole explanation for changes in my writing, so let me try to unpack the part that is.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I really enjoyed this. It mirrors my thoughts about writing and organizing thoughts publicly. There &lt;em&gt;is&lt;/em&gt; a time and place for AI-assisted writing, as the author notes. Whenever a high amount of polish is required, and you can&apos;t run it by an editor or trust your self-editing, maybe running your writing through an AI for some final touches is the way to go.&lt;/p&gt;
&lt;p&gt;However, when writing is for fun or being used as a way to gather your thoughts, AI just doesn&apos;t cut it. I&apos;ve tinkered with using AI to help spark ideas, but it always comes up clinical and flat. I come up with more genuine ideas by consuming quality content, sitting quietly with it, and &lt;em&gt;thinking&lt;/em&gt;.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[I made... carnitas tacos with fresh corn tortillas]]></title><link>https://mary.codes/blog/recipes/i_made_carnitas_tacos/</link><guid isPermaLink="false">https://mary.codes/blog/recipes/i_made_carnitas_tacos/</guid><pubDate>Wed, 13 Mar 2024 23:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Tonight, I made carnitas for the first time. I also made corn tortillas for the first time. Beginner&apos;s luck, I&apos;m sure, but they came out great.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/62616af48c69c51354ea078de0e00044/81f49/carnitas_tacos.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.08108108108109%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/62616af48c69c51354ea078de0e00044/f51c2/carnitas_tacos.webp 148w,
/static/62616af48c69c51354ea078de0e00044/66888/carnitas_tacos.webp 295w,
/static/62616af48c69c51354ea078de0e00044/bc8a3/carnitas_tacos.webp 590w,
/static/62616af48c69c51354ea078de0e00044/4ce34/carnitas_tacos.webp 885w,
/static/62616af48c69c51354ea078de0e00044/f490a/carnitas_tacos.webp 1180w,
/static/62616af48c69c51354ea078de0e00044/d182c/carnitas_tacos.webp 4032w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/62616af48c69c51354ea078de0e00044/ca928/carnitas_tacos.jpg 148w,
/static/62616af48c69c51354ea078de0e00044/278fa/carnitas_tacos.jpg 295w,
/static/62616af48c69c51354ea078de0e00044/8a7c7/carnitas_tacos.jpg 590w,
/static/62616af48c69c51354ea078de0e00044/b4485/carnitas_tacos.jpg 885w,
/static/62616af48c69c51354ea078de0e00044/096b1/carnitas_tacos.jpg 1180w,
/static/62616af48c69c51354ea078de0e00044/81f49/carnitas_tacos.jpg 4032w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/62616af48c69c51354ea078de0e00044/8a7c7/carnitas_tacos.jpg&quot;
            alt=&quot;Carnitas tacos&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;For the carnitas, I used the recipe for &lt;a href=&quot;https://www.gimmesomeoven.com/crispy-slow-cooker-carnitas/&quot;&gt;crispy slow cooker carnitas&lt;/a&gt; from Gimme Some Oven. I made a few changes to the recipe. I used a cup of pineapple juice and pineapple chunks instead of beer or chicken stock, and I also added some leftover chipotles in adobo sauce (about 4) because I needed to use them. I also used about 3 pounds of pork roast instead of 4 to 5. I&apos;d used the rest of the pork loin for porkchops.&lt;/p&gt;
&lt;p&gt;I left the pork in the slow cooker on high for about 5 hours. It came out a little bit dry, so I probably should&apos;ve turned it off an hour earlier. I also was able to get all the shredded pork on one sheet tray.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b786900bea9ca1c1a333d8a3fa9590c8/81f49/carnitas.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 56.08108108108109%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b786900bea9ca1c1a333d8a3fa9590c8/f51c2/carnitas.webp 148w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/66888/carnitas.webp 295w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/bc8a3/carnitas.webp 590w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/4ce34/carnitas.webp 885w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/f490a/carnitas.webp 1180w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/d182c/carnitas.webp 4032w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b786900bea9ca1c1a333d8a3fa9590c8/ca928/carnitas.jpg 148w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/278fa/carnitas.jpg 295w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/8a7c7/carnitas.jpg 590w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/b4485/carnitas.jpg 885w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/096b1/carnitas.jpg 1180w,
/static/b786900bea9ca1c1a333d8a3fa9590c8/81f49/carnitas.jpg 4032w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b786900bea9ca1c1a333d8a3fa9590c8/8a7c7/carnitas.jpg&quot;
            alt=&quot;Carnitas&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To make the corn tortillas, I simply used the recipe on the back of the masa harina bag, but divided it by 4. I used 1/2 cup of masa, about 3/8 cup of water, and a dash of salt. I mixed it all together and divided the dough into 4 balls of about 1.25 oz each.&lt;/p&gt;
&lt;p&gt;I don&apos;t have a tortilla press or plastic wrap (forgot to buy some), so I pressed the dough balls between two pieces of wax paper and a plate. The plate doesn&apos;t get the dough very thin, though, so I rolled out the tortillas even thinner with a rolling pin. I still think they may have been a little too thick in the center, because my tortillas began to split as I was eating the tacos.&lt;/p&gt;
&lt;p&gt;I threw the tortillas on the electric griddle heated to 300F for about 30 seconds to a minute on each side.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/83047198d93ad862877dcd456149620e/e4bf4/carnitas_taco.jpg&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 177.7027027027027%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/83047198d93ad862877dcd456149620e/f51c2/carnitas_taco.webp 148w,
/static/83047198d93ad862877dcd456149620e/66888/carnitas_taco.webp 295w,
/static/83047198d93ad862877dcd456149620e/bc8a3/carnitas_taco.webp 590w,
/static/83047198d93ad862877dcd456149620e/4ce34/carnitas_taco.webp 885w,
/static/83047198d93ad862877dcd456149620e/f490a/carnitas_taco.webp 1180w,
/static/83047198d93ad862877dcd456149620e/a552e/carnitas_taco.webp 2268w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/83047198d93ad862877dcd456149620e/ca928/carnitas_taco.jpg 148w,
/static/83047198d93ad862877dcd456149620e/278fa/carnitas_taco.jpg 295w,
/static/83047198d93ad862877dcd456149620e/8a7c7/carnitas_taco.jpg 590w,
/static/83047198d93ad862877dcd456149620e/b4485/carnitas_taco.jpg 885w,
/static/83047198d93ad862877dcd456149620e/096b1/carnitas_taco.jpg 1180w,
/static/83047198d93ad862877dcd456149620e/e4bf4/carnitas_taco.jpg 2268w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/83047198d93ad862877dcd456149620e/8a7c7/carnitas_taco.jpg&quot;
            alt=&quot;Taco&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;I dressed my tacos with some diced sweet onion, cilantro, and queso fresco. The second taco got a dollop of sour cream. I think they turned out pretty great!&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Finding the Design Engineer within the Full-Stack Developer]]></title><link>https://mary.codes/blog/programming/full_stack_dev_design_engineer/</link><guid isPermaLink="false">https://mary.codes/blog/programming/full_stack_dev_design_engineer/</guid><pubDate>Mon, 11 Mar 2024 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Have you ever heard the term &quot;design engineer&quot;? Up until recently, I didn&apos;t realize that there was a niche being carved out in the last five years for people who specialize in bridging the realms of development and design.&lt;/p&gt;
&lt;h3 id=&quot;discovering-design-engineering&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#discovering-design-engineering&quot; aria-label=&quot;discovering design engineering permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Discovering design engineering&lt;/h3&gt;
&lt;p&gt;Last month, Jim Nielsen wrote an article called &lt;a href=&quot;https://blog.jim-nielsen.com/2024/the-case-for-design-engineers-pt-ii/&quot;&gt;&quot;The Case for Design Engineers, Pt. II&quot; (2024)&lt;/a&gt;. The article gives an example of how a static design can be interpreted many different ways by a developer. There is a distance between the design and the implementation. Nielsen makes the case that designing with code makes sense.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Design engineers don’t just push pixels around in a GUI tool, they do it in a web browser — the medium of delivery — designing not just the visuals but the interactions that make sense for a living, breathing, moving interface.&lt;/p&gt;
&lt;p&gt;This approach to design — designing with code — doesn’t result in one artifact that approximates the final deliverable to drive consensus, then requires a translation to the deliverable artifact itself.&lt;/p&gt;
&lt;p&gt;Instead, the artifact is the deliverable — just in embryonic form.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a follow-up article to &lt;a href=&quot;https://blog.jim-nielsen.com/2022/the-case-for-design-engineers/&quot;&gt;&quot;The Case for Design Engineers&quot; (2022)&lt;/a&gt;. In the original article, Nielsen makes a case for having a dedicated design engineer role to reduce wasted time iterating between design and programming. The article references &lt;a href=&quot;https://cloudfour.com/thinks/traditional-web-design-process-is-fundamentally-broken/&quot;&gt;&quot;Traditional Web Design Process is Fundamentally Broken&quot; (2022)&lt;/a&gt; which explains how many wireframes and mockups, a.k.a &quot;artifacts&quot;, are now required for a responsive web design, if they are created in a static medium. According to Nielsen, &quot;design engineers are worth their weight in gold&quot; because of this problem.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;They have an understanding of the constraints of the medium, so from sketches to wireframe to high fidelity mocks, they only have to produce one or two artifacts while simultaneously keeping a picture in their head of how the elements of those designs flex and flow and change across different sizes.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In &lt;a href=&quot;https://www.trysmudford.com/blog/i-think-im-a-design-engineer/&quot;&gt;&quot;On Design Engineering: I think I might be a design engineer...&quot; (2021)&lt;/a&gt;, Trys Mudford narrows down the niche in which design engineers live. Many web developers either live in the backend or back-of-the-front-end, where design is a second-class citizen to functionality. Design engineers live in the front-of-the-front-end, and work closely with designers to bridge the gap between design and functionality. Design engineers work alongside designers and back-of-the-front-end engineers to come up with solutions that are both beautiful and functional.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;In essence, a design engineer’s goal is to be helpful. Helping UX come to sound decisions, helping research get the most useful insights from their testing, helping designers generate sound &amp;#x26; deliverable ideas, and helping engineers understand the design intention. But the primary focus is on doing anything they can to help translate the design for the engineering team.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Brad Frost writes about the divide between &lt;a href=&quot;https://bradfrost.com/blog/post/front-of-the-front-end-and-back-of-the-front-end-web-development/&quot;&gt;front-of-the-front-end and back-of-the-front-end web development (2021)&lt;/a&gt;. A front-of-the-front-end developer is an expert in semantic HTML, CSS, DOM manipulation, accessibility, and design. A back-of-the-front-end developer is an expert in business logic, routing, APIs, authentication, and data.&lt;/p&gt;
&lt;p&gt;Adactio (Jeremy Keith) has an article about consciously specializing in front-of-the-front-end development as a &lt;a href=&quot;https://adactio.com/journal/17838&quot;&gt;design engineer (2021)&lt;/a&gt;. Specializing in UX design and development allowed Keith&apos;s clients to utilize whatever backends they wanted, while Keith focused on creating optimized front-end experiences.&lt;/p&gt;
&lt;p&gt;One of the earliest articles I could find on this subject, although the term &quot;design engineer&quot; never appears, is &lt;a href=&quot;https://css-tricks.com/the-great-divide/&quot;&gt;&quot;The Great Divide&quot; (2019)&lt;/a&gt; by Chris Coyier. This article began exploring the differences in JavaScript developers that was already happening at that time. Two front-end developers could have vastly different skillsets and goals based upon whether they specialized in presentation or business logic, but they&apos;re still both called front-end developers.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Two &apos;front-end web developers&apos; can be standing right next to each other and have little, if any, skill sets in common. That’s downright bizarre to me for a job title so specific and ubiquitous. I’m sure that’s already the case with a job title like designer, but front-end web developer is a niche within a niche already.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Perhaps InVision&apos;s &lt;a href=&quot;https://marketing.invisionapp-cdn.com/www-assets.invisionapp.com/epubs/InVision_DesignEngineeringHandbook.pdf&quot;&gt;Design Engineering Handbook (2020)&lt;/a&gt; explains design engineering best:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Simply put, design engineering is where solutions are created at the intersection of design and development. It’s not only about solving problems for customers; it’s also about improving the design and engineering process, making a space for communication and collaboration, and building a great experience. Or to phrase it another way: It’s a question of building the right thing versus building the thing right.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;how-i-feel-about-design-engineering-as-a-full-stack-developer&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#how-i-feel-about-design-engineering-as-a-full-stack-developer&quot; aria-label=&quot;how i feel about design engineering as a full stack developer permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;How I feel about design engineering as a full-stack developer&lt;/h3&gt;
&lt;p&gt;I feel like the realm of design engineering is an area of development that I gravitate toward, but I have a hard time understanding it as a job title and full-time role.&lt;/p&gt;
&lt;p&gt;I started out as a front-of-the-front-end developer. I could consume an API and transform data, but my main focus was on creating HTML and CSS, with a dash of JavaScript for interactivity. I spent a lot of time creating WordPress themes, which required a bit of JavaScript and PHP, but mostly, I was focused on making things look great.&lt;/p&gt;
&lt;p&gt;Once I was hired as a professional front-end developer I had to quickly learn more about working within a full JavaScript application. I had to learn how to work within a large JavaScript app and use data from APIs. I hadn&apos;t given much mind to security when working on my own projects, so I had to learn all about XSS attacks and form validation. I started collecting skills like Pokémon badges, and each one took me further away from my safe space in front-of-the-front-end land.&lt;/p&gt;
&lt;p&gt;Eventually, I started working with PHP and databases. I mean &lt;em&gt;really&lt;/em&gt; working with them. I&apos;ve gotten to a point where I can write a pretty complex SQL query in a few minutes. Now I mostly work on a PHP monolith with a sprinkling of React frontends.&lt;/p&gt;
&lt;p&gt;On a small team, nobody has the luxury of working only on the front-of-the-front end. Part of what makes my job interesting is being able to work on a wide variety projects, and no two are alike. One week I might be working on something front-of-the-front-end, like implementing a new modal or form. The next week I might be designing email deployments. Another week, I might be working on payments.&lt;/p&gt;
&lt;p&gt;However, one of the best parts of my job is that I often get a lot of leeway in my project designs. Oftentimes, I have design guidelines that I have to follow, but I&apos;m given time to iterate on an idea and try out different designs and interactions. While my sole focus isn&apos;t on design engineering, my goal is the same, to create solutions that are accessible and easy to use.&lt;/p&gt;
&lt;h3 id=&quot;focusing-on-design-engineering-skills&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#focusing-on-design-engineering-skills&quot; aria-label=&quot;focusing on design engineering skills permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Focusing on design engineering skills&lt;/h3&gt;
&lt;p&gt;While I&apos;m a generalist by necessity, I am increasingly focusing on developing my design engineering skills in my free time. I&apos;ve been reading design books. I&apos;m learning Figma. I&apos;m working through lecture notes on &lt;a href=&quot;https://ocw.mit.edu/courses/6-831-user-interface-design-and-implementation-spring-2011/pages/lecture-notes/&quot;&gt;User Interface Design and Implementation at MIT OpenCourseWare&lt;/a&gt;. As I dig deeper I find a wide variety of sub-niches that are appealing to me.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accessibility. How can systems be designed and implemented to be accessible to the widest audience possible? How can human-computer interaction be made easier for everyone, regardless of ability?&lt;/li&gt;
&lt;li&gt;WebXR. How do we create augmented and virtual experiences that are user-friendly and accessible? How do people respond to XR experiences? In what ways can XR experiences be democratized, instead of walled behind expensive headsets and glasses?&lt;/li&gt;
&lt;li&gt;Human-centered AI (HCAI). How can AI be used to augment human capabilities? How should user interfaces be designed to best serve humans in a safe and understandable way?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are just some of the topics that I&apos;ve been thinking about lately. Do they really belong as part of design engineering? Maybe they&apos;re more on the fringes, especially WebXR and human-centered AI. However, I think they&apos;re some of the most interesting topics to research right now.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Daily practice, spinning guitars, and Eloquent Javascript]]></title><link>https://mary.codes/blog/friday_faves/daily_practice_and_eloquent_javascript/</link><guid isPermaLink="false">https://mary.codes/blog/friday_faves/daily_practice_and_eloquent_javascript/</guid><pubDate>Fri, 08 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Five-ish things that I loved this week.&lt;/p&gt;
&lt;h4 id=&quot;i-paint-daily-no-matter-what-how-one-womans-coping-mechanism-became-a-global-business-article&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#i-paint-daily-no-matter-what-how-one-womans-coping-mechanism-became-a-global-business-article&quot; aria-label=&quot;i paint daily no matter what how one womans coping mechanism became a global business article permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://www.theguardian.com/artanddesign/2024/mar/02/i-paint-daily-artist-margo-mcdaid-coping-mechanism-to-global-business&quot;&gt;‘I paint daily, no matter what’: how one woman’s coping mechanism became a global business (article)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;I found this article a little sad but very inspiring. It&apos;s about Margo McDaid finding success in art after overcoming tragedy. She turned to creating daily paintings to cope, and years later, her prolific painting has honed her craft and brought her success as an artist.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“I wanted to see how my work would change if I practised every day. As a teacher, I’d watch how kids developed, from circling around their hands to joined-up handwriting... All the Old Masters were apprentices. Trying to improve in a short space of time is tough. Doing it daily, you don’t expect outcomes quickly.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The article also discusses a few other people in other fields who use daily practice and repetition to hone their respective crafts. One of my favorite books is &lt;a href=&quot;https://jamesclear.com/atomic-habits&quot;&gt;Atomic Habits&lt;/a&gt;, which not only emphasises daily practice, but striving to be a little bit better every day. I suppose that&apos;s why this article resonated with me, it reminded me about the importance of daily habits. (I also talk about James Clear and his 1% better theory in my post &lt;a href=&quot;blog/life/streaking_into_the_new_year/&quot;&gt;&quot;Streaking into the new year&quot;&lt;/a&gt;).&lt;/p&gt;
&lt;h4 id=&quot;what-happens-when-your-art-is-used-to-train-ai-interview&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#what-happens-when-your-art-is-used-to-train-ai-interview&quot; aria-label=&quot;what happens when your art is used to train ai interview permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://themarkup.org/hello-world/2024/03/02/what-happens-when-your-art-is-used-to-train-ai&quot;&gt;What Happens When Your Art Is Used to Train AI (interview)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;Another artist, Dorothy Gambrell of &lt;a href=&quot;https://catandgirl.com/&quot;&gt;Cat and Girl&lt;/a&gt;, reacts to her name being included in a court document naming artists whose work has been used to train AI, specifically Midjourney. She created a comic called &lt;a href=&quot;https://catandgirl.com/4000-of-my-closest-friends/&quot;&gt;4,000 of my closest friends&lt;/a&gt; about the difficulty of being a small, independent artist whose work was then taken and used by others for for-profit purposes.&lt;/p&gt;
&lt;p&gt;But this interview is so much more than that. It discusses visibility on the internet, content silos, and how the wealthy have already been monetizing our work via the main avenues of communication on the internet, long before the AI age. And, now that everything is fed to us by &quot;the algorithm&quot; on social media, or hidden behind low-effort crap, finding interesting, authentic content on the internet is no longer satisfying.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;Internet users in 1999 were seeking out things to read and see. We had the internet, we wanted it to entertain us, and there just wasn’t much there. So it was really exciting to find someone’s comics! People were really excited to find your comics! And then the internet filled up, and it was hard to get anyone’s attention, because there were so many other things to see and do. And now… there are so many things, but it feels like there’s nothing. We’re all content, and content is just an infinite slog. I feel that way as a reader, too. Somehow removing the small effort of searching something out or entering a url has made everything we see feel equally worthless.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The more that I read different perspectives on AI, and the more that I think about it, the more I&apos;m convinced that AI is going to further homogenize the internet in general. AI generated content is, in my opinion, quite bland, and as it proliferates it will just make the internet more and more bland, and browsers like the Arc Browser (I touch on its summarization capabilities a bit in &lt;a href=&quot;/blog/friday_faves/javascript_sets_and_sorting_git_branches/#who-makes-money-when-ai-reads-the-internet-for-us-article&quot;&gt;a prior Friday Fave&lt;/a&gt;) will condense the blandness even further. It makes me hopeful that genuine, personal content created by humans will become increasingly valuable.&lt;/p&gt;
&lt;p&gt;...Well, this should probably be its own blog post, shouldn&apos;t it?&lt;/p&gt;
&lt;h4 id=&quot;eloquent-javascript-fourth-edition-book&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#eloquent-javascript-fourth-edition-book&quot; aria-label=&quot;eloquent javascript fourth edition book permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://eloquentjavascript.net/&quot;&gt;Eloquent JavaScript, Fourth Edition (book)&lt;/a&gt;&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://eloquentjavascript.net/&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: 309px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 129.7297297297297%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/16750435364185488273f199a83b3e56/f51c2/eloquent_js_4.webp 148w,
/static/16750435364185488273f199a83b3e56/66888/eloquent_js_4.webp 295w,
/static/16750435364185488273f199a83b3e56/669b6/eloquent_js_4.webp 309w&quot;
              sizes=&quot;(max-width: 309px) 100vw, 309px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/16750435364185488273f199a83b3e56/ca928/eloquent_js_4.jpg 148w,
/static/16750435364185488273f199a83b3e56/278fa/eloquent_js_4.jpg 295w,
/static/16750435364185488273f199a83b3e56/9a007/eloquent_js_4.jpg 309w&quot;
            sizes=&quot;(max-width: 309px) 100vw, 309px&quot;
            type=&quot;image/jpeg&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/16750435364185488273f199a83b3e56/9a007/eloquent_js_4.jpg&quot;
            alt=&quot;Eloquent JavaScript, Fourth Edition  cover&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
    &lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Eloquent JavaScript, Second Edition&lt;/em&gt; was one of the first JavaScript books I read when I was learning JavaScript. I look forward to reading through this version and seeing what&apos;s changed. I didn&apos;t read the third edition, so I assume there&apos;s going to be big changes from the second. If you&apos;re interested in learning JavaScript or you&apos;re a pro looking for a refresher (like me!), I think &lt;em&gt;Eloquent JavaScript&lt;/em&gt; is a great place to start.&lt;/p&gt;
&lt;h4 id=&quot;ansons-aggregated-feed-website&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#ansons-aggregated-feed-website&quot; aria-label=&quot;ansons aggregated feed website permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;&lt;a href=&quot;https://zine.ansonbiggs.com/&quot;&gt;Anson&apos;s Aggregated Feed (website)&lt;/a&gt;&lt;/h4&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/6460a1d60aff9f259718b6390aad9dc0/4e22f/ansons_zine.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/6460a1d60aff9f259718b6390aad9dc0/f51c2/ansons_zine.webp 148w,
/static/6460a1d60aff9f259718b6390aad9dc0/66888/ansons_zine.webp 295w,
/static/6460a1d60aff9f259718b6390aad9dc0/bc8a3/ansons_zine.webp 590w,
/static/6460a1d60aff9f259718b6390aad9dc0/4ce34/ansons_zine.webp 885w,
/static/6460a1d60aff9f259718b6390aad9dc0/f490a/ansons_zine.webp 1180w,
/static/6460a1d60aff9f259718b6390aad9dc0/b2ae9/ansons_zine.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/6460a1d60aff9f259718b6390aad9dc0/c5084/ansons_zine.png 148w,
/static/6460a1d60aff9f259718b6390aad9dc0/60cc9/ansons_zine.png 295w,
/static/6460a1d60aff9f259718b6390aad9dc0/6d370/ansons_zine.png 590w,
/static/6460a1d60aff9f259718b6390aad9dc0/540ae/ansons_zine.png 885w,
/static/6460a1d60aff9f259718b6390aad9dc0/2561a/ansons_zine.png 1180w,
/static/6460a1d60aff9f259718b6390aad9dc0/4e22f/ansons_zine.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/6460a1d60aff9f259718b6390aad9dc0/6d370/ansons_zine.png&quot;
            alt=&quot;Anson&amp;#39;s Aggregated Feed screenshot&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;This is a really cool project that takes RSS feeds and displays them card-style. It&apos;s inspired by &lt;a href=&quot;https://news.russellsaw.io/&quot;&gt;The Webpage&lt;/a&gt;, which displays feeds in a newspaper format. I really like the idea of having a publicly-available aggregation of RSS feeds that anyone can read and use as their own RSS inspiration. Of course, now this has me thinking about building my own aggregator, but I&apos;m also interested in an open source solution like &lt;a href=&quot;https://freshrss.org/&quot;&gt;FreshRSS&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id=&quot;360-spinning-guitar-video&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#360-spinning-guitar-video&quot; aria-label=&quot;360 spinning guitar video permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;360 spinning guitar (video)&lt;/h4&gt;
&lt;p&gt;I really love watching people work on ridiculous engineering projects. The more creative the better. Creative projects require creative solutions, and I love watching people come up with creative solutions that actually work. Not only is this video a great look into the build process of this seemingly impossible guitar, but it&apos;s also incredibly funny.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&quot;It&apos;s kind of flat. I see a problem here. So I cut it into six parts and you know what? Now it&apos;s broken. But now it&apos;s broken and &lt;em&gt;cylindrical&lt;/em&gt;.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;iframe width=&quot;100%&quot; style=&quot;aspect-ratio: 16/9&quot; src=&quot;https://www.youtube.com/embed/p2kJMPfFOX8?si=ygu1h1Hbq7LMxUxE&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; allowfullscreen&gt;&lt;/iframe&gt;</content:encoded></item><item><title><![CDATA[Displaying the current Git branch in my Linux terminal prompt]]></title><link>https://mary.codes/blog/programming/displaying-git-branch-in-linux-terminal/</link><guid isPermaLink="false">https://mary.codes/blog/programming/displaying-git-branch-in-linux-terminal/</guid><pubDate>Wed, 06 Mar 2024 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It wasn&apos;t until I heard about a cool, fast, new, insert-superlative-here terminal that I began thinking about how nice it would be to have the active Git branch displayed in the terminal at all times. Because this was a feature of the cool, fast, new, etc. terminal I decided to install it... and was promptly hit with a login page. Excuse me? I need an account registered on someone else&apos;s site to use a terminal installed on &lt;em&gt;my computer&lt;/em&gt;?&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
    &lt;img src=&quot;/static/61dc149cfe97ef4bfde6f7ff69aaf4cc/grandpa_simpson.gif&quot; alt=&quot;Grandpa Simpson turning right back around&quot;&gt;
&lt;/div&gt;
&lt;p&gt;As it turns out, getting and displaying the current Git branch is &lt;em&gt;easy peasy&lt;/em&gt; if you can stomach a little bash scripting.&lt;/p&gt;
&lt;p&gt;Step one, have &lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt; installed and be on a relatively recent version. I currently have 2.34.1 installed, and the latest release, as of this writing, is 2.44.0.&lt;/p&gt;
&lt;p&gt;Step two, open &lt;code class=&quot;language-text&quot;&gt;~/.bashrc&lt;/code&gt; in your text editor of choice. I&apos;m a vim girl, so&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 function&quot;&gt;vim&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Step three, add a line that begins with &lt;code class=&quot;language-text&quot;&gt;PS1=&lt;/code&gt; that will contain whatever information you want in the terminal prompt. This is where things start to get a little bit technical.&lt;/p&gt;
&lt;p&gt;This is a very simple prompt, showing the current directory, the Git branch, and a dollar sign.&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 assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PS1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;\w\&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;__git_ps1&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;\$ &quot;&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: 407px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/846d27bdd89f52da11303dadb0200ede/fc7bc/terminal-git-1.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 10.81081081081081%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/846d27bdd89f52da11303dadb0200ede/f51c2/terminal-git-1.webp 148w,
/static/846d27bdd89f52da11303dadb0200ede/66888/terminal-git-1.webp 295w,
/static/846d27bdd89f52da11303dadb0200ede/6c44f/terminal-git-1.webp 407w&quot;
              sizes=&quot;(max-width: 407px) 100vw, 407px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/846d27bdd89f52da11303dadb0200ede/c5084/terminal-git-1.png 148w,
/static/846d27bdd89f52da11303dadb0200ede/60cc9/terminal-git-1.png 295w,
/static/846d27bdd89f52da11303dadb0200ede/fc7bc/terminal-git-1.png 407w&quot;
            sizes=&quot;(max-width: 407px) 100vw, 407px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/846d27bdd89f52da11303dadb0200ede/fc7bc/terminal-git-1.png&quot;
            alt=&quot;Basic terminal&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;However, I like things to be colorful and interesting, so I&apos;ve added some colors and an emoji.&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 assign-left variable&quot;&gt;&lt;span class=&quot;token environment constant&quot;&gt;PS1&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;💀 \[&lt;span class=&quot;token entity&quot; title=&quot;\033&quot;&gt;\033&lt;/span&gt;[01;36m\]\w\[&lt;span class=&quot;token entity&quot; title=&quot;\033&quot;&gt;\033&lt;/span&gt;[01;33m\]\&lt;span class=&quot;token variable&quot;&gt;&lt;span class=&quot;token variable&quot;&gt;$(&lt;/span&gt;__git_ps1&lt;span class=&quot;token variable&quot;&gt;)&lt;/span&gt;&lt;/span&gt;\[&lt;span class=&quot;token entity&quot; title=&quot;\033&quot;&gt;\033&lt;/span&gt;[01;32m\]\$\[&lt;span class=&quot;token entity&quot; title=&quot;\033&quot;&gt;\033&lt;/span&gt;[00m\] &quot;&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: 432px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/374476dc25eff281a73b2ee68d4bb025/dc3b1/terminal-git-2.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 8.783783783783782%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/374476dc25eff281a73b2ee68d4bb025/f51c2/terminal-git-2.webp 148w,
/static/374476dc25eff281a73b2ee68d4bb025/66888/terminal-git-2.webp 295w,
/static/374476dc25eff281a73b2ee68d4bb025/e3a5e/terminal-git-2.webp 432w&quot;
              sizes=&quot;(max-width: 432px) 100vw, 432px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/374476dc25eff281a73b2ee68d4bb025/c5084/terminal-git-2.png 148w,
/static/374476dc25eff281a73b2ee68d4bb025/60cc9/terminal-git-2.png 295w,
/static/374476dc25eff281a73b2ee68d4bb025/dc3b1/terminal-git-2.png 432w&quot;
            sizes=&quot;(max-width: 432px) 100vw, 432px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/374476dc25eff281a73b2ee68d4bb025/dc3b1/terminal-git-2.png&quot;
            alt=&quot;Colorful terminal&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;To break it down:&lt;/p&gt;
&lt;p&gt;&lt;code class=&quot;language-text&quot;&gt;\[\033[01;36m\]&lt;/code&gt; is a blue color in the terminal. &lt;code class=&quot;language-text&quot;&gt;\w&lt;/code&gt; is the current directory. &lt;code class=&quot;language-text&quot;&gt;\[\033[01;33m\]&lt;/code&gt; is a yellow color in my terminal. &lt;code class=&quot;language-text&quot;&gt;\$(__git_ps1)&lt;/code&gt; appends the current Git branch. The $ is important, without it, the branch name won&apos;t update when you change branches. &lt;code class=&quot;language-text&quot;&gt;\[\033[01;32m\]&lt;/code&gt; is a green color, &lt;code class=&quot;language-text&quot;&gt;\$&lt;/code&gt; prints a dollar sign, and &lt;code class=&quot;language-text&quot;&gt;\[\033[00m\]&lt;/code&gt; returns the text following the prompt back to white, unbolded text.&lt;/p&gt;
&lt;p&gt;Step four, save and exit out of your text editor.&lt;/p&gt;
&lt;p&gt;Step five, type the following into your terminal:&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 builtin class-name&quot;&gt;source&lt;/span&gt; ~/.bashrc&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The terminal should change to reflect your new settings.&lt;/p&gt;
&lt;p&gt;I know just enough about .bashrc and bash scripting to be dangerous, so take care while following these steps, and maybe also look up some other resources if you get stuck. Here&apos;s one from the actual Git docs: &lt;a href=&quot;https://git-scm.com/book/pl/v2/Appendix-A%3A-Git-in-Other-Environments-Git-in-Bash&quot;&gt;Git in Other Environments - Git in Bash&lt;/a&gt;. These are the steps that worked for me on a Pop!_OS system, so if you&apos;re on an Ubuntu flavor of Linux, I think this will work for you too.&lt;/p&gt;</content:encoded></item><item><title><![CDATA[Generating a 3D map with OpenStreetMap and A-Frame]]></title><link>https://mary.codes/blog/programming/generating_a_vr_map_with_osm_and_aframe/</link><guid isPermaLink="false">https://mary.codes/blog/programming/generating_a_vr_map_with_osm_and_aframe/</guid><pubDate>Mon, 04 Mar 2024 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Over the weekend, I was able to work more on my Disney World wait time project that I began over at &lt;a href=&quot;/blog/programming/translating_openstreetmaps_to_HTML5_canvas_rust_wasm/&quot;&gt;Translating OpenStreetMap data to HTML5 Canvas with Rust and WebAssembly&lt;/a&gt;. This project was last left in a state where I was pulling data from the Overpass API, processing it using Rust, and then using the generated coordinates to draw to an HTML5 canvas.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/994a26e9c7ff1d0d0155d52361d5a05f/065ce/mk_canvas_map.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 66.89189189189189%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/994a26e9c7ff1d0d0155d52361d5a05f/f51c2/mk_canvas_map.webp 148w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/66888/mk_canvas_map.webp 295w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/bc8a3/mk_canvas_map.webp 590w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/4ce34/mk_canvas_map.webp 885w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/f490a/mk_canvas_map.webp 1180w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/f93c5/mk_canvas_map.webp 2680w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/994a26e9c7ff1d0d0155d52361d5a05f/c5084/mk_canvas_map.png 148w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/60cc9/mk_canvas_map.png 295w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/6d370/mk_canvas_map.png 590w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/540ae/mk_canvas_map.png 885w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/2561a/mk_canvas_map.png 1180w,
/static/994a26e9c7ff1d0d0155d52361d5a05f/065ce/mk_canvas_map.png 2680w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/994a26e9c7ff1d0d0155d52361d5a05f/6d370/mk_canvas_map.png&quot;
            alt=&quot;Canvas map&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;It&apos;s a proof-of-concept that I was really just using to see if I could (more or less) get accurate coordinates from OpenStreetMaps. However, the goal was never really to draw to a canvas. The goal is to draw the map in 3D.&lt;/p&gt;
&lt;h3 id=&quot;table-of-contents&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#table-of-contents&quot; aria-label=&quot;table of contents permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Table of Contents&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#set-up-the-3d-environment-with-a-frame&quot;&gt;Set up the 3D environment with A-Frame&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#creating-a-custom-geometry-component&quot;&gt;Creating a custom geometry component&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#generating-custom-geometries-from-osm-data&quot;&gt;Generating custom geometries from OSM data&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#rust-code-updates&quot;&gt;Rust code updates&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#drawing-the-rest-of-the-map&quot;&gt;Drawing the rest of the map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#creating-walkway-lines&quot;&gt;Creating walkway lines&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ongoing-work&quot;&gt;Ongoing work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#demo&quot;&gt;Demo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;set-up-the-3d-environment-with-a-frame&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#set-up-the-3d-environment-with-a-frame&quot; aria-label=&quot;set up the 3d environment with a frame permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Set up the 3D environment with A-Frame&lt;/h3&gt;
&lt;p&gt;As a reminder, I&apos;m sort of freestyling right now with static files. I&apos;m using &lt;a href=&quot;https://github.com/http-party/http-server&quot;&gt;http-server&lt;/a&gt;, globally installed, to serve my files. Eventually I&apos;ll probably migrate all of this into React or some other sort of framework/build system. But for now, this is freeform jazz, baby. I&apos;m also jumping right into this from &lt;a href=&quot;/blog/programming/translating_openstreetmaps_to_HTML5_canvas_rust_wasm/&quot;&gt;where I left off before&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, I&apos;m going to clean up index.html a bit. I&apos;m going to take the script that I had previously written within the body of index.html and add it to &lt;code class=&quot;language-text&quot;&gt;js/script.mjs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I&apos;m also going to add three scripts to the head of index.html. One adds &lt;a href=&quot;https://aframe.io/&quot;&gt;A-Frame&lt;/a&gt; to my project, the second adds a basic environment with &lt;a href=&quot;https://github.com/supermedium/aframe-environment-component&quot;&gt;aframe-environment-component&lt;/a&gt;, and the third adds &lt;a href=&quot;https://github.com/supermedium/superframe/tree/master/components/orbit-controls/&quot;&gt;orbit controls&lt;/a&gt;.&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;script&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;&quot;&lt;/span&gt;https://aframe.io/releases/1.5.0/aframe.min.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&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;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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 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;&quot;&lt;/span&gt;https://unpkg.com/aframe-environment-component@1.3.3/dist/aframe-environment-component.min.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&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;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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 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;&quot;&lt;/span&gt;https://unpkg.com/aframe-orbit-controls@1.3.2/dist/aframe-orbit-controls.min.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&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;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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 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;&quot;&lt;/span&gt;module&lt;span class=&quot;token punctuation&quot;&gt;&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;&quot;&lt;/span&gt;js/script.mjs&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&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;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, in the body of index.html, I&apos;m going to add a basic scene that should orbit around the origin of the scene. For the environment preset, I&apos;m going to use the &quot;contact&quot; setting, but remove the trees and create a completely flat ground. (Why? Because I think it looks cool.) I&apos;ve also added orbit controls to the camera. I commented out &lt;code class=&quot;language-text&quot;&gt;&amp;lt;script type=&quot;module&quot; src=&quot;js/script.mjs&quot;&gt;&amp;lt;/script&gt;&lt;/code&gt; for now, the lack of a canvas will make that script error out.&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;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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;a-scene&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;environment&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;&quot;&lt;/span&gt;preset: contact; dressing: none; ground: flat; fog: 0.7&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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;a-camera&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;look-controls&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;&quot;&lt;/span&gt;enabled: false&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;orbit-controls&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;&quot;&lt;/span&gt;target: 0 0 0; minDistance: 2; maxDistance: 180; initialPosition: 0 2 -5; rotateSpeed: 0.5; maxPolarAngle: 85&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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;a-camera&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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;a-scene&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&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;body&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This is a quick and easy way to create a basic scene and test that everything is working correctly.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f2782649a448355f383f9bb2b497ecb2/4e22f/aframe-basic-scene.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f2782649a448355f383f9bb2b497ecb2/f51c2/aframe-basic-scene.webp 148w,
/static/f2782649a448355f383f9bb2b497ecb2/66888/aframe-basic-scene.webp 295w,
/static/f2782649a448355f383f9bb2b497ecb2/bc8a3/aframe-basic-scene.webp 590w,
/static/f2782649a448355f383f9bb2b497ecb2/4ce34/aframe-basic-scene.webp 885w,
/static/f2782649a448355f383f9bb2b497ecb2/f490a/aframe-basic-scene.webp 1180w,
/static/f2782649a448355f383f9bb2b497ecb2/b2ae9/aframe-basic-scene.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f2782649a448355f383f9bb2b497ecb2/c5084/aframe-basic-scene.png 148w,
/static/f2782649a448355f383f9bb2b497ecb2/60cc9/aframe-basic-scene.png 295w,
/static/f2782649a448355f383f9bb2b497ecb2/6d370/aframe-basic-scene.png 590w,
/static/f2782649a448355f383f9bb2b497ecb2/540ae/aframe-basic-scene.png 885w,
/static/f2782649a448355f383f9bb2b497ecb2/2561a/aframe-basic-scene.png 1180w,
/static/f2782649a448355f383f9bb2b497ecb2/4e22f/aframe-basic-scene.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f2782649a448355f383f9bb2b497ecb2/6d370/aframe-basic-scene.png&quot;
            alt=&quot;A-Frame basic scene&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;creating-a-custom-geometry-component&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#creating-a-custom-geometry-component&quot; aria-label=&quot;creating a custom geometry component permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Creating a custom geometry component&lt;/h3&gt;
&lt;p&gt;The next step is to create a component that will &lt;a href=&quot;https://aframe.io/docs/1.5.0/components/geometry.html#register-a-custom-geometry&quot;&gt;register a custom geometry&lt;/a&gt; in A-Frame. This geometry component will use the coordinates provided by the OSM conversion and create basic 3D shapes. Once the component is created, it&apos;ll be appended to the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;a-scene&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;First, I&apos;ll create a new JavaScript file called &lt;code class=&quot;language-text&quot;&gt;geom.js&lt;/code&gt; and put that in the same &lt;code class=&quot;language-text&quot;&gt;js&lt;/code&gt; directory as &lt;code class=&quot;language-text&quot;&gt;script.mjs&lt;/code&gt;. This file will hold any custom A-Frame geometries that I want to create.&lt;/p&gt;
&lt;p&gt;Creating a custom A-Frame geometry requires a good amount of knowledge of &lt;a href=&quot;https://threejs.org/&quot;&gt;THREE.js&lt;/a&gt;. A-Frame is built with THREE.js as a base, allowing you to easily create immersive 3D scenes with basic geometries, but it&apos;s incredibly extensible by tapping into THREE.js&apos;s custom geometries.&lt;/p&gt;
&lt;p&gt;Here&apos;s the full code for the custom component:&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token constant&quot;&gt;AFRAME&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;registerGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;map-item&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;schema&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 literal-property property&quot;&gt;height&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 keyword&quot;&gt;default&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 punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token literal-property property&quot;&gt;vertices&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 keyword&quot;&gt;default&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;&apos;-2 -2&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;-2 0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;1 1&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;2 0&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
  &lt;span class=&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;init&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;data&lt;/span&gt;&lt;span class=&quot;token punctuation&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; 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;
    &lt;span class=&quot;token comment&quot;&gt;// A THREE.Shape is created by drawing lines between vertices.&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; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vertices&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;length&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;let&lt;/span&gt; vertex &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;vertices&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;
      &lt;span class=&quot;token keyword&quot;&gt;let&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 operator&quot;&gt;=&lt;/span&gt; vertex&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&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;val&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&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;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; &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;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;
      &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;
        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;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;
      &lt;span class=&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;// Adding a very small bevel to the top of each geometry.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; extrudeSettings &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 literal-property property&quot;&gt;steps&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 literal-property property&quot;&gt;depth&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; data&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 literal-property property&quot;&gt;bevelEnabled&lt;/span&gt;&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 literal-property property&quot;&gt;bevelThickness&lt;/span&gt;&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;
      &lt;span class=&quot;token literal-property property&quot;&gt;bevelSize&lt;/span&gt;&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;
      &lt;span class=&quot;token literal-property property&quot;&gt;bevelSegments&lt;/span&gt;&lt;span class=&quot;token operator&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 punctuation&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; geometry &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;ExtrudeGeometry&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; extrudeSettings&lt;span class=&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;// Geometry needs to be rotated and translated to be in the right position&lt;/span&gt;
    geometry&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;rotateX&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;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;
    geometry&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;translate&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; data&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 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;
    geometry&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;computeBoundingBox&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&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;geometry &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; geometry&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&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;A-Frame requires a schema and init function to &lt;a href=&quot;https://aframe.io/docs/1.5.0/core/component.html#register-a-component&quot;&gt;register a component&lt;/a&gt;. There are other lifecycle methods, but because I&apos;m not animating or updating the geometry, I should be able to get by with just using init.&lt;/p&gt;
&lt;p&gt;For the schema, I want to be able to set the height of the geometry and the vertices from the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;a-entity&gt;&lt;/code&gt; properties. I&apos;ve added some default vertices as a test.&lt;/p&gt;
&lt;p&gt;In the init function, I&apos;m initializing a new &lt;a href=&quot;https://threejs.org/docs/?q=shape#api/en/extras/core/Shape&quot;&gt;THREE.Shape&lt;/a&gt;. For each of the vertices, I can&apos;t pass a two-dimensional array in A-Frame, so I&apos;ll pass the vertices as &quot;x y&quot;, splitting them by the space. I&apos;m iterating over each vertex and updating the shape. Once the shape is complete, I set extrude settings for the &lt;a href=&quot;https://threejs.org/docs/index.html#api/en/geometries/ExtrudeGeometry&quot;&gt;Extrude Geometry&lt;/a&gt;. The height will be dictated by whatever height I pass in for the map type.&lt;/p&gt;
&lt;p&gt;Finally, I create a new Extrude Geometry by passing in the shape and extrude settings. Then, I&apos;m rotating the geometry by 90 degrees on the X axis and translating it up by the amount of its height. This gets the geometry in the right position. Finally, I&apos;m going to compute the bounding box (I might need that later, I&apos;m not sure) and set the geometry to &lt;code class=&quot;language-text&quot;&gt;this.geometry&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This should be enough to generate a basic shape and extrude it. I&apos;m going to write some temporary JavaScript below the new component that will generate and append a new element to the scene.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; scene &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;&apos;a-scene&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&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; mapItem &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;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a-entity&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mapItem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;geometry&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;primitive&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;map-item&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
mapItem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;material&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token literal-property property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;#bada55&apos;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&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;&lt;span class=&quot;token function&quot;&gt;appendChild&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;mapItem&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&apos;m using the default vertices and height and adding a second attribute as a material.&lt;/p&gt;
&lt;p&gt;I&apos;ll add the script to index.html with the &lt;code class=&quot;language-text&quot;&gt;defer&lt;/code&gt; attribute. That way, the script won&apos;t be executed until after the document is parsed. Otherwise, &lt;code class=&quot;language-text&quot;&gt;a-scene&lt;/code&gt; isn&apos;t available to the script.&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;script&lt;/span&gt; &lt;span class=&quot;token attr-name&quot;&gt;defer&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;&quot;&lt;/span&gt;js/geom.js&lt;span class=&quot;token punctuation&quot;&gt;&quot;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token script&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;script&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After testing this script, I can remove the &lt;code class=&quot;language-text&quot;&gt;defer&lt;/code&gt; as long as I don&apos;t try to manipulate the DOM in &lt;code class=&quot;language-text&quot;&gt;geom.js&lt;/code&gt;, which I don&apos;t plan to do. This is the result of the new geometry 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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/52f4766087da7fe10a0b6440285855a6/4e22f/basic-geom.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/52f4766087da7fe10a0b6440285855a6/f51c2/basic-geom.webp 148w,
/static/52f4766087da7fe10a0b6440285855a6/66888/basic-geom.webp 295w,
/static/52f4766087da7fe10a0b6440285855a6/bc8a3/basic-geom.webp 590w,
/static/52f4766087da7fe10a0b6440285855a6/4ce34/basic-geom.webp 885w,
/static/52f4766087da7fe10a0b6440285855a6/f490a/basic-geom.webp 1180w,
/static/52f4766087da7fe10a0b6440285855a6/b2ae9/basic-geom.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/52f4766087da7fe10a0b6440285855a6/c5084/basic-geom.png 148w,
/static/52f4766087da7fe10a0b6440285855a6/60cc9/basic-geom.png 295w,
/static/52f4766087da7fe10a0b6440285855a6/6d370/basic-geom.png 590w,
/static/52f4766087da7fe10a0b6440285855a6/540ae/basic-geom.png 885w,
/static/52f4766087da7fe10a0b6440285855a6/2561a/basic-geom.png 1180w,
/static/52f4766087da7fe10a0b6440285855a6/4e22f/basic-geom.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/52f4766087da7fe10a0b6440285855a6/6d370/basic-geom.png&quot;
            alt=&quot;Basic geometry&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;generating-custom-geometries-from-osm-data&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#generating-custom-geometries-from-osm-data&quot; aria-label=&quot;generating custom geometries from osm data permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Generating custom geometries from OSM data&lt;/h3&gt;
&lt;p&gt;Now, I want to feed the vertices supplied by OSM to my custom geometry component to create map elements. First, I&apos;m going to remove that test script from &lt;code class=&quot;language-text&quot;&gt;js/geom.js&lt;/code&gt; and remove the &lt;code class=&quot;language-text&quot;&gt;defer&lt;/code&gt; from it in index.html.&lt;/p&gt;
&lt;p&gt;I&apos;m removing all references to canvas in &lt;code class=&quot;language-text&quot;&gt;script.mjs&lt;/code&gt;, and instead querying for the &lt;code class=&quot;language-text&quot;&gt;&amp;lt;a-scene&gt;&lt;/code&gt; element.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; scene &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;&apos;a-scene&apos;&lt;/span&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, I will create a function very similar to the code that I just deleted from geom.js.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createGeometry&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 class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&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 punctuation&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;token comment&quot;&gt;// WASM returns a 3-dimensional array. Map over each element, then the points.&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; polygon &lt;span class=&quot;token keyword&quot;&gt;of&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;let&lt;/span&gt; vertices &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; polygon&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;point&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&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;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 operator&quot;&gt;=&lt;/span&gt; point&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;x&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;y&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;// Fix this in Rust to return 2D array.&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&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 element and append.&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; mapItem &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;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a-entity&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    mapItem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;geometry&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;primitive&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;map-item&apos;&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;
      vertices&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    mapItem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;material&apos;&lt;/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;
    scene&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;mapItem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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 will comment out all the calls to &lt;code class=&quot;language-text&quot;&gt;drawPolygons()&lt;/code&gt; and instead add a function call to &lt;code class=&quot;language-text&quot;&gt;createGeometry()&lt;/code&gt; for the water elements.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;createGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;water&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 string&quot;&gt;&apos;rgb(83,156,156)&apos;&lt;/span&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;Refreshing the page now displays a huge ocean of water. Scrolling out, it&apos;s larger than the A-Frame world. I&apos;m going to update the Rust code to scale down the scene and to return a 2D array instead of a 3D array. There&apos;s no reason to do the conversion in JavaScript, just return data in the correct format the first time!&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/569331323b20318211fb4fd4bf54e519/4e22f/large-geometry.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/569331323b20318211fb4fd4bf54e519/f51c2/large-geometry.webp 148w,
/static/569331323b20318211fb4fd4bf54e519/66888/large-geometry.webp 295w,
/static/569331323b20318211fb4fd4bf54e519/bc8a3/large-geometry.webp 590w,
/static/569331323b20318211fb4fd4bf54e519/4ce34/large-geometry.webp 885w,
/static/569331323b20318211fb4fd4bf54e519/f490a/large-geometry.webp 1180w,
/static/569331323b20318211fb4fd4bf54e519/b2ae9/large-geometry.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/569331323b20318211fb4fd4bf54e519/c5084/large-geometry.png 148w,
/static/569331323b20318211fb4fd4bf54e519/60cc9/large-geometry.png 295w,
/static/569331323b20318211fb4fd4bf54e519/6d370/large-geometry.png 590w,
/static/569331323b20318211fb4fd4bf54e519/540ae/large-geometry.png 885w,
/static/569331323b20318211fb4fd4bf54e519/2561a/large-geometry.png 1180w,
/static/569331323b20318211fb4fd4bf54e519/4e22f/large-geometry.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/569331323b20318211fb4fd4bf54e519/6d370/large-geometry.png&quot;
            alt=&quot;This water is too big&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;rust-code-updates&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#rust-code-updates&quot; aria-label=&quot;rust code updates permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Rust code updates&lt;/h3&gt;
&lt;p&gt;All the Rust changes take place in the &lt;code class=&quot;language-text&quot;&gt;process_points&lt;/code&gt; function.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;rust&quot;&gt;&lt;pre class=&quot;language-rust&quot;&gt;&lt;code class=&quot;language-rust&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;fn&lt;/span&gt; &lt;span class=&quot;token function-definition function&quot;&gt;process_points&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 operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;osm&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Node&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;token namespace&quot;&gt;osm&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token class-name&quot;&gt;Bounds&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 keyword&quot;&gt;f64&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 keyword&quot;&gt;f64&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;-&gt;&lt;/span&gt; &lt;span class=&quot;token class-name&quot;&gt;JsValue&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 function&quot;&gt;map_points&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;lat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minlat&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;maxlat&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 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; width &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 operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50.0&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 function&quot;&gt;map_points&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;lon&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;minlon&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; bounds&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;maxlon&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 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; height &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 operator&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;50.0&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.0&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token class-name&quot;&gt;JsValue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;from_str&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;&lt;span class=&quot;token macro property&quot;&gt;format!&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;{} {}&quot;&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;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I&apos;m dividing both points calculations by 50 in order to scale the scene to a manageable size, and I&apos;m also multiplying the x axis by -1, because my bad math is coming back to haunt me.&lt;/p&gt;
&lt;p&gt;I&apos;ve also updated the start2 and stop2 points for the &lt;code class=&quot;language-text&quot;&gt;map_points&lt;/code&gt; function to be from half the width/height in the negative direction to half the width/height in the positive direction. This is due to the fact that the HTML5 canvas considers the origin to be in the top left corner of the canvas, while A-Frame puts the origin in the middle of the scene.&lt;/p&gt;
&lt;p&gt;I&apos;m also returning a formatted &apos;x y&apos; string from this function as well, as opposed to the array that it previously returned.&lt;/p&gt;
&lt;p&gt;Finally, script.mjs is updated to remove that extra vertex parsing from &lt;code class=&quot;language-text&quot;&gt;createGeometry()&lt;/code&gt;;&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createGeometry&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 class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; height&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 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; vertices &lt;span class=&quot;token keyword&quot;&gt;of&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;let&lt;/span&gt; mapItem &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;createElement&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;a-entity&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    mapItem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;geometry&apos;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;token literal-property property&quot;&gt;primitive&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&apos;map-item&apos;&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;
      vertices&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    mapItem&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;setAttribute&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos;material&apos;&lt;/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;
    scene&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;mapItem&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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&apos;m also going to update the camera element to &lt;code class=&quot;language-text&quot;&gt;initialPosition: 0 10 -20&lt;/code&gt;, just so I can get more of the map in view.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/f936c35575dfee963cbc1d4f4bdb182a/4e22f/map-full-water.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/f936c35575dfee963cbc1d4f4bdb182a/f51c2/map-full-water.webp 148w,
/static/f936c35575dfee963cbc1d4f4bdb182a/66888/map-full-water.webp 295w,
/static/f936c35575dfee963cbc1d4f4bdb182a/bc8a3/map-full-water.webp 590w,
/static/f936c35575dfee963cbc1d4f4bdb182a/4ce34/map-full-water.webp 885w,
/static/f936c35575dfee963cbc1d4f4bdb182a/f490a/map-full-water.webp 1180w,
/static/f936c35575dfee963cbc1d4f4bdb182a/b2ae9/map-full-water.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/f936c35575dfee963cbc1d4f4bdb182a/c5084/map-full-water.png 148w,
/static/f936c35575dfee963cbc1d4f4bdb182a/60cc9/map-full-water.png 295w,
/static/f936c35575dfee963cbc1d4f4bdb182a/6d370/map-full-water.png 590w,
/static/f936c35575dfee963cbc1d4f4bdb182a/540ae/map-full-water.png 885w,
/static/f936c35575dfee963cbc1d4f4bdb182a/2561a/map-full-water.png 1180w,
/static/f936c35575dfee963cbc1d4f4bdb182a/4e22f/map-full-water.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/f936c35575dfee963cbc1d4f4bdb182a/6d370/map-full-water.png&quot;
            alt=&quot;All of the water elements on the map&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;drawing-the-rest-of-the-map&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#drawing-the-rest-of-the-map&quot; aria-label=&quot;drawing the rest of the map permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Drawing the rest of the map&lt;/h3&gt;
&lt;p&gt;Creating the rest of the map geometry is as easy as converting &lt;code class=&quot;language-text&quot;&gt;drawPolygons()&lt;/code&gt; function calls to &lt;code class=&quot;language-text&quot;&gt;createGeometry()&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token function&quot;&gt;createGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;water&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 string&quot;&gt;&apos;rgb(83,156,156)&apos;&lt;/span&gt;&lt;span class=&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;createGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;gardens&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 string&quot;&gt;&apos;rgb(136,172,140)&apos;&lt;/span&gt;&lt;span class=&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;createGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;buildings&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 string&quot;&gt;&apos;rgb(88,87,98)&apos;&lt;/span&gt;&lt;span class=&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;createGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;named_buildings&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 string&quot;&gt;&apos;rgb(88,87,98)&apos;&lt;/span&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;Buildings are now the same color but I&apos;ve made the &quot;named buildings&quot; (which should mostly be rides and attractions) twice as tall.  I plan to tweak the building heights as I go along.&lt;/p&gt;
&lt;p&gt;Here&apos;s an initial look down the center of Main Street, USA towards Cinderella Castle (which obviously does not look like a castle).&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/4e22f/mk_3d.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/f51c2/mk_3d.webp 148w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/66888/mk_3d.webp 295w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/bc8a3/mk_3d.webp 590w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/4ce34/mk_3d.webp 885w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/f490a/mk_3d.webp 1180w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/b2ae9/mk_3d.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/c5084/mk_3d.png 148w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/60cc9/mk_3d.png 295w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/6d370/mk_3d.png 590w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/540ae/mk_3d.png 885w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/2561a/mk_3d.png 1180w,
/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/4e22f/mk_3d.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/d9e22a7cd01abaa9dd4dd9d2990a61ef/6d370/mk_3d.png&quot;
            alt=&quot;Magic Kingdom initial render&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;creating-walkway-lines&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#creating-walkway-lines&quot; aria-label=&quot;creating walkway lines permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Creating walkway lines&lt;/h3&gt;
&lt;p&gt;To add the lines for walkway areas, I&apos;ve decided to skip creating a new A-Frame geometry component. Instead, I&apos;m going to add a THREE.Line directly to the scene. I figure that since the walkway won&apos;t have any interactivity, it makes more sense to just add it directly. I may end up taking the walkway lines out altogether (or have a toggle to display them).&lt;/p&gt;
&lt;div class=&quot;gatsby-highlight&quot; data-language=&quot;javascript&quot;&gt;&lt;pre class=&quot;language-javascript&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;createLineGeometry&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 punctuation&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; vertices &lt;span class=&quot;token keyword&quot;&gt;of&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;const&lt;/span&gt; points &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; vertices&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;point&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&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;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 operator&quot;&gt;=&lt;/span&gt; point&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&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;val&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;parseFloat&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;val&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&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;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;x&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; 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;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; geometry &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;BufferGeometry&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&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;setFromPoints&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 keyword&quot;&gt;const&lt;/span&gt; line &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;Line&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;geometry&lt;span class=&quot;token punctuation&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;LineBasicMaterial&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token literal-property property&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token number&quot;&gt;0x000000&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&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;object3D&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;line&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&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 function is constructed similarly to the earlier component, but instead of creating a shape, I&apos;m creating a THREE.Vector3 with the y-axis just slightly above 0. Then, the THREE.BufferGeometry is set from the array of vectors, which is then used to build the line. The THREE.js documentation has an entire page dedicated to &lt;a href=&quot;https://threejs.org/docs/#manual/en/introduction/Drawing-lines&quot;&gt;drawing lines&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;An important note is that the line is added to &lt;code class=&quot;language-text&quot;&gt;scene.object3D&lt;/code&gt;. This is the proper way to &lt;a href=&quot;https://aframe.io/docs/1.5.0/introduction/developing-with-threejs.html#accessing-the-three-js-scene&quot;&gt;access the THREE.js scene from A-Frame&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/00467feec7346da17fa01d4fbb2cb7d1/4e22f/walkway-lines.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/00467feec7346da17fa01d4fbb2cb7d1/f51c2/walkway-lines.webp 148w,
/static/00467feec7346da17fa01d4fbb2cb7d1/66888/walkway-lines.webp 295w,
/static/00467feec7346da17fa01d4fbb2cb7d1/bc8a3/walkway-lines.webp 590w,
/static/00467feec7346da17fa01d4fbb2cb7d1/4ce34/walkway-lines.webp 885w,
/static/00467feec7346da17fa01d4fbb2cb7d1/f490a/walkway-lines.webp 1180w,
/static/00467feec7346da17fa01d4fbb2cb7d1/b2ae9/walkway-lines.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/00467feec7346da17fa01d4fbb2cb7d1/c5084/walkway-lines.png 148w,
/static/00467feec7346da17fa01d4fbb2cb7d1/60cc9/walkway-lines.png 295w,
/static/00467feec7346da17fa01d4fbb2cb7d1/6d370/walkway-lines.png 590w,
/static/00467feec7346da17fa01d4fbb2cb7d1/540ae/walkway-lines.png 885w,
/static/00467feec7346da17fa01d4fbb2cb7d1/2561a/walkway-lines.png 1180w,
/static/00467feec7346da17fa01d4fbb2cb7d1/4e22f/walkway-lines.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/00467feec7346da17fa01d4fbb2cb7d1/6d370/walkway-lines.png&quot;
            alt=&quot;The scene with walkway lines&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;ongoing-work&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#ongoing-work&quot; aria-label=&quot;ongoing work permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Ongoing work&lt;/h3&gt;
&lt;p&gt;I&apos;m still working on adding more features and detail to the 3D map by querying more features. I&apos;m also looking into some problems when it comes to adding sidewalks/walkways. In some cases, relations are made of many different tiny ways, that are then stitched together to form the outline of an area. My geometry component doesn&apos;t like that very much. So, I&apos;m working on that and other optimizations to make the map look great before adding wait times.&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: 590px; box-shadow: rgb(73, 76, 103, 0.25) 0px 5px 15px 0px;&quot;
    &gt;
      &lt;a
    class=&quot;gatsby-resp-image-link&quot;
    href=&quot;/static/b29f8382fabf91aeddb5e4f4ba0a8f86/4e22f/mk-progress.png&quot;
    style=&quot;display: block&quot;
    target=&quot;_blank&quot;
    rel=&quot;noopener&quot;
  &gt;
    &lt;span
    class=&quot;gatsby-resp-image-background-image&quot;
    style=&quot;padding-bottom: 51.35135135135135%; position: relative; bottom: 0; left: 0; display: block;&quot;
  &gt;&lt;/span&gt;
  &lt;picture&gt;
          &lt;source
              srcset=&quot;/static/b29f8382fabf91aeddb5e4f4ba0a8f86/f51c2/mk-progress.webp 148w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/66888/mk-progress.webp 295w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/bc8a3/mk-progress.webp 590w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/4ce34/mk-progress.webp 885w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/f490a/mk-progress.webp 1180w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/b2ae9/mk-progress.webp 1860w&quot;
              sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
              type=&quot;image/webp&quot;
            /&gt;
          &lt;source
            srcset=&quot;/static/b29f8382fabf91aeddb5e4f4ba0a8f86/c5084/mk-progress.png 148w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/60cc9/mk-progress.png 295w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/6d370/mk-progress.png 590w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/540ae/mk-progress.png 885w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/2561a/mk-progress.png 1180w,
/static/b29f8382fabf91aeddb5e4f4ba0a8f86/4e22f/mk-progress.png 1860w&quot;
            sizes=&quot;(max-width: 590px) 100vw, 590px&quot;
            type=&quot;image/png&quot;
          /&gt;
          &lt;img
            class=&quot;gatsby-resp-image-image&quot;
            src=&quot;/static/b29f8382fabf91aeddb5e4f4ba0a8f86/6d370/mk-progress.png&quot;
            alt=&quot;Added walkways&quot;
            title=&quot;&quot;
            loading=&quot;lazy&quot;
            decoding=&quot;async&quot;
            style=&quot;width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;&quot;
          /&gt;
        &lt;/picture&gt;
  &lt;/a&gt;
    &lt;/span&gt;&lt;/p&gt;
&lt;h3 id=&quot;demo&quot; style=&quot;position:relative;&quot;&gt;&lt;a href=&quot;#demo&quot; aria-label=&quot;demo permalink&quot; class=&quot;anchor before&quot;&gt;&lt;svg aria-hidden=&quot;true&quot; focusable=&quot;false&quot; height=&quot;16&quot; version=&quot;1.1&quot; viewBox=&quot;0 0 16 16&quot; width=&quot;16&quot;&gt;&lt;path fill-rule=&quot;evenodd&quot; d=&quot;M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z&quot;&gt;&lt;/path&gt;&lt;/svg&gt;&lt;/a&gt;Demo&lt;/h3&gt;
&lt;p&gt;Click and hold to rotate, mouse wheel to zoom.&lt;/p&gt;
&lt;iframe src=&quot;/demo-pages/linebuddy-2-vr/&quot; width=100% style=&quot;aspect-ratio: 16/9; border: 0;&quot;&gt;&lt;/iframe&gt;</content:encoded></item></channel></rss>