<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Eric</title>
    <description>The latest articles on Forem by Eric (@ev17).</description>
    <link>https://forem.com/ev17</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3727139%2F3d07fea9-38cd-4831-a2ee-abcf44917de8.png</url>
      <title>Forem: Eric</title>
      <link>https://forem.com/ev17</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ev17"/>
    <language>en</language>
    <item>
      <title>Stop Using Math.random(): The Art of Deterministic Chaos</title>
      <dc:creator>Eric</dc:creator>
      <pubDate>Thu, 22 Jan 2026 22:52:11 +0000</pubDate>
      <link>https://forem.com/ev17/stop-using-mathrandom-the-art-of-deterministic-chaos-4bcm</link>
      <guid>https://forem.com/ev17/stop-using-mathrandom-the-art-of-deterministic-chaos-4bcm</guid>
      <description>&lt;p&gt;We are all addicted to randomness. But in generative art, true chaos is actually the enemy.&lt;/p&gt;

&lt;p&gt;As a developer, my first instinct when building anything visual is always &lt;code&gt;Math.random()&lt;/code&gt;. Need a particle position? Random. Need a color? Random. It’s quick, it’s messy, and it feels "organic."&lt;/p&gt;

&lt;p&gt;But recently, I fell down the rabbit hole of &lt;strong&gt;Deterministic Generative Art&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal was simple: Could I build a system that takes a string of text (like a name or a date) and outputs a unique, high-fidelity visual that looks exactly the same every single time, without storing the image in a database?&lt;/p&gt;

&lt;p&gt;Here is what I learned about moving from chaos to "controlled seeds."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem with Pure Randomness
&lt;/h2&gt;

&lt;p&gt;If you use &lt;code&gt;Math.random()&lt;/code&gt;, your art is ephemeral. If a user refreshes the page, their cool design is gone forever. To keep it, you'd have to save a massive PNG to your server. That’s heavy and expensive.&lt;/p&gt;

&lt;p&gt;The solution is &lt;strong&gt;Seeding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of asking the browser for a random number, you create a "Pseudo-Random Number Generator" (PRNG). You feed it a "seed" (the user's input), and it gives you a sequence of numbers that &lt;em&gt;look&lt;/em&gt; random but are mathematically fixed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The "Poor Man's" Hash Function
&lt;/h2&gt;

&lt;p&gt;To make this work, you first need to turn a string (e.g., "User123") into a usable number. I started using a simple string-to-hash function. It’s not crypto-secure (don't use this for passwords!), but for art, it’s fast and effective.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function cyrb128(str) {
    let h1 = 1779033703, h2 = 3144134277,
        h3 = 1013904242, h4 = 2773480762;
    for (let i = 0, k; i &amp;lt; str.length; i++) {
        k = str.charCodeAt(i);
        h1 = h2 ^ Math.imul(h1 ^ k, 597399067);
        h2 = h3 ^ Math.imul(h2 ^ k, 2869860233);
        h3 = h4 ^ Math.imul(h3 ^ k, 951274213);
        h4 = h1 ^ Math.imul(h4 ^ k, 2716044179);
    }
    // ... bitwise shifts to mix the state ...
    return [(h1&amp;gt;&amp;gt;&amp;gt;0) / 4294967296, (h2&amp;gt;&amp;gt;&amp;gt;0) / 4294967296, (h3&amp;gt;&amp;gt;&amp;gt;0) / 4294967296, (h4&amp;gt;&amp;gt;&amp;gt;0) / 4294967296];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This little function is the engine. It ingests text and spits out four distinct, float-point numbers between 0 and 1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mapping Math to Colors (HSL vs RGB)
&lt;/h2&gt;

&lt;p&gt;Once I had my deterministic numbers, &lt;code&gt;RGB&lt;/code&gt; proved too difficult to control. Random RGB values often result in "muddy" browns and grays.&lt;/p&gt;

&lt;p&gt;I switched to &lt;strong&gt;HSL (Hue, Saturation, Lightness)&lt;/strong&gt;. This changed everything.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hue:&lt;/strong&gt; Mapped to the seed (0 - 360).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saturation:&lt;/strong&gt; Locked between 60% and 100% (to ensure vibrancy).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightness:&lt;/strong&gt; Modulated by a sine wave based on the cursor position or time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By constraining the chaos, the results started looking less like "TV static" and more like "Energy Signatures."&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance at 4K Resolution
&lt;/h2&gt;

&lt;p&gt;The real challenge came when trying to render this on a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; at 4K resolution (3840x2160).&lt;/p&gt;

&lt;p&gt;Looping through millions of pixels in JavaScript is a death sentence for the main thread. I had to optimize using &lt;strong&gt;OffscreenCanvas&lt;/strong&gt; and transferring control to a Web Worker. This keeps the UI buttery smooth even while the CPU is crunching complex gradients.&lt;/p&gt;

&lt;p&gt;I recently pushed this logic to production in a project called &lt;a href="https://hedmo.com" rel="noopener noreferrer"&gt;HEDMO&lt;/a&gt;, where the algorithm translates birth dates into 4K wallpapers. The interesting part wasn't the UI, but realizing that users feel a deeper connection to the image simply because they know the math behind it is unique to &lt;em&gt;them&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;If you are building creative web projects, stop reaching for &lt;code&gt;Math.random()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Build a seed function. Create rules. Let the data drive the art. The result is something that feels magical to the user, but is purely logical to the machine.&lt;/p&gt;

&lt;p&gt;What are your favorite libraries for generative art? p5.js? Three.js? Or do you prefer vanilla Canvas API like me? Let me know in the comments.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>generativeart</category>
      <category>webdev</category>
      <category>algorithms</category>
    </item>
  </channel>
</rss>
