<?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: Easywise</title>
    <description>The latest articles on DEV Community by Easywise (@easywise).</description>
    <link>https://dev.to/easywise</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%2F4026881%2F3dd730b9-ca05-4d7d-9fa8-2b1b2d7fd8e9.png</url>
      <title>DEV Community: Easywise</title>
      <link>https://dev.to/easywise</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/easywise"/>
    <language>en</language>
    <item>
      <title>I Built an Interactive 3D Tilt Card with Canvas Particles (No Libraries)</title>
      <dc:creator>Easywise</dc:creator>
      <pubDate>Sun, 19 Jul 2026 04:14:31 +0000</pubDate>
      <link>https://dev.to/easywise/i-built-an-interactive-3d-tilt-card-with-canvas-particles-no-libraries-23id</link>
      <guid>https://dev.to/easywise/i-built-an-interactive-3d-tilt-card-with-canvas-particles-no-libraries-23id</guid>
      <description>&lt;p&gt;I wanted a small, self-contained demo for my dev profile that actually &lt;br&gt;
shows some interactive skill — not just another static card. So I &lt;br&gt;
built one combining three techniques, all in vanilla JS with zero &lt;br&gt;
dependencies:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A canvas-based particle network background&lt;/li&gt;
&lt;li&gt;A glassmorphic card that tilts in 3D based on mouse position&lt;/li&gt;
&lt;li&gt;A typewriter effect cycling through role text&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here's how each piece works.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The particle network&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The background is a &lt;code&gt;&amp;lt;canvas&amp;gt;&lt;/code&gt; with ~70 particles drifting slowly &lt;br&gt;
across the screen. Each particle bounces off the edges, and any two &lt;br&gt;
particles within 120px of each other get a connecting line, with &lt;br&gt;
opacity fading based on distance:&lt;/p&gt;

&lt;p&gt;​&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;strokeStyle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`rgba(91,140,255,&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;dist&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;beginPath&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;moveTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lineTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stroke&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;&lt;span class="s2"&gt;```



Nothing fancy — just `&lt;/span&gt;&lt;span class="nx"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="s2"&gt;` and basic distance checks — 
but it reads as a lot more polished than it is to build.

   2. The 3D tilt effect

This is pure CSS `&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;rotateX&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;rotateY&lt;/span&gt;&lt;span class="s2"&gt;`, driven by mouse position:

​

```&lt;/span&gt;&lt;span class="nx"&gt;javascript&lt;/span&gt;
&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mousemove&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientY&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHeight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clientX&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerWidth&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;card&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`rotateX(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;rx&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;deg) rotateY(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;ry&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;deg)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt;​&lt;/span&gt;&lt;span class="s2"&gt;```



The key CSS property making this look 3D (not just skewed) is 
`&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;preserve&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="s2"&gt;` on the card, plus a `&lt;/span&gt;&lt;span class="nx"&gt;perspective&lt;/span&gt;&lt;span class="s2"&gt;` value 
on its parent container. Without perspective set on the parent, the 
rotation just looks flat and wrong.

   3. The typewriter effect

A small state machine that types out a string, pauses, deletes it, 
and moves to the next one in a list — no library, just `&lt;/span&gt;&lt;span class="nx"&gt;setTimeout&lt;/span&gt;&lt;span class="s2"&gt;` 
and two counters (`&lt;/span&gt;&lt;span class="nx"&gt;charIndex&lt;/span&gt;&lt;span class="s2"&gt;`, `&lt;/span&gt;&lt;span class="nx"&gt;roleIndex&lt;/span&gt;&lt;span class="s2"&gt;`) tracking position and 
direction.

## Why build this instead of just... not

Small interactive demos like this are genuinely useful to have on hand 
— for a portfolio, a personal site hero section, or just proving to 
yourself you understand the fundamentals (canvas rendering, CSS 3D 
transforms, animation timing) without pulling in GSAP or Three.js for 
something this simple.

Total size: one HTML file, ~60 lines of CSS, ~60 lines of JS. No 
dependencies.



I'm a full-stack developer based in Lagos, Nigeria, building products 
under the Easywise brand — you can see more of my work at 
[easywise.com.ng](https://easywise.com.ng).
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>showdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hey DEV, I'm Easywise, building full-stack products solo out of Lagos 👋</title>
      <dc:creator>Easywise</dc:creator>
      <pubDate>Mon, 13 Jul 2026 08:20:20 +0000</pubDate>
      <link>https://dev.to/easywise/hey-dev-im-easywise-building-full-stack-products-solo-out-of-lagos-2pn1</link>
      <guid>https://dev.to/easywise/hey-dev-im-easywise-building-full-stack-products-solo-out-of-lagos-2pn1</guid>
      <description>&lt;p&gt;I'm a self-taught full-stack developer based in Lagos, Nigeria, building &lt;br&gt;
products under the Easywise brand — handling everything from backend &lt;br&gt;
and database design to polished frontend UI, solo, end to end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What I work with:&lt;/strong&gt; React, React Native, Supabase, PostgreSQL, Expo, Next.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A few things I've built recently:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛒 EasyGet — a multi-role marketplace app (customers, shop owners, 
riders) with real-time orders, chat, and even a diaspora feature so 
Nigerians abroad can send groceries home&lt;/li&gt;
&lt;li&gt;🏠 EasyHomes — a property discovery platform for Lagos, with an 
interactive map and agent dashboards&lt;/li&gt;
&lt;li&gt;💱 EasyRates — a live currency tracker comparing official vs black 
market exchange rates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also take on freelance web and mobile work. You can check out &lt;br&gt;
everything I'm building at &lt;a href="https://easywise.com.ng" rel="noopener noreferrer"&gt;easywise.com.ng&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Would love to connect with other devs building in Nigeria/Africa, or &lt;br&gt;
anyone working on marketplace/fintech products. Say hi! 👋&lt;/p&gt;

</description>
      <category>introduction</category>
      <category>webdev</category>
      <category>react</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
