<?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>DEV Community: Alexandru Pavelescu </title>
    <description>The latest articles on DEV Community by Alexandru Pavelescu  (@idlecyrex).</description>
    <link>https://dev.to/idlecyrex</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4045584%2F1e3171d0-5b62-4548-aa5a-edf38effe048.jpg</url>
      <title>DEV Community: Alexandru Pavelescu </title>
      <link>https://dev.to/idlecyrex</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/idlecyrex"/>
    <language>en</language>
    <item>
      <title>I built topolines, an animated topographic contour background for React</title>
      <dc:creator>Alexandru Pavelescu </dc:creator>
      <pubDate>Fri, 24 Jul 2026 12:33:00 +0000</pubDate>
      <link>https://dev.to/idlecyrex/topolines-animated-topographic-contour-backgrounds-for-react-5dh0</link>
      <guid>https://dev.to/idlecyrex/topolines-animated-topographic-contour-backgrounds-for-react-5dh0</guid>
      <description>&lt;p&gt;Every couple of projects I ended up rebuilding the same effect: an animated topographic map background, the kind with slowly drifting contour lines. After copy pasting the same WebGL shader for the third time I gave up and turned it into a proper library.&lt;/p&gt;

&lt;p&gt;It's called &lt;strong&gt;topolines&lt;/strong&gt;. One React component, zero dependencies, everything drawn on the GPU.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/idleCyrex/topolines" rel="noopener noreferrer"&gt;https://github.com/idleCyrex/topolines&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Playground: &lt;a href="https://topolines.idlee.xyz/playground" rel="noopener noreferrer"&gt;https://topolines.idlee.xyz/playground&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The lines are not an image or SVG. A small fragment shader generates a noise field (simplex noise + fbm) and draws contour bands from it, so it animates smoothly at any resolution for basically no CPU cost. The component just manages a canvas and the WebGL state around it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i topolines
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Topolines&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;topolines/react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Hero&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Topolines&lt;/span&gt; &lt;span class="na"&gt;seed&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"hello"&lt;/span&gt; &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#F2EFE6"&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fixed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;inset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same seed always renders the same field, so your background is stable between visits. There are props for speed, scale, line width, colors, drift, and an interactive mode where contour rings bloom around the cursor.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things I cared about
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Zero dependencies, the whole thing is one shader and some glue code&lt;/li&gt;
&lt;li&gt;SSR safe, works in a Next.js server component tree&lt;/li&gt;
&lt;li&gt;Pauses when offscreen or when the tab is hidden&lt;/li&gt;
&lt;li&gt;Respects prefers-reduced-motion (renders one static frame)&lt;/li&gt;
&lt;li&gt;Clean fallback when WebGL is not available&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The playground lets you tweak every knob and copy the resulting code out: &lt;a href="https://topolines.idlee.xyz/playground" rel="noopener noreferrer"&gt;https://topolines.idlee.xyz/playground&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's v0.1 and my first published library, so feedback and feature ideas are very welcome.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webgl</category>
      <category>showdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
