Skip to content
CoDdleCoDoodle home
Fan Art PracticeIntermediateSVG + CSS

Avatar: Seven Havens

A floating island of layered rock and waterfalls hovers above a calm sea, ringed by seven small biome portals and a tiny winged traveler. A dreamy fan-art study inspired by floating-world fantasy films — no logos, no characters, just sky, stone, and worlds within worlds.

This coded drawing is a fan-art practice example created for educational purposes only. It is a generic fantasy floating-island scene inspired by popular animated world-travel stories; it does not reproduce any character, logo, creature, likeness, or copyrighted imagery. Avatar and related properties belong to their respective owners. CoDoodle is not affiliated with, endorsed by, or sponsored by those owners.

← you, in 35 minutes.

what you'll build

Here's the plan

A floating island made of layered rock, waterfalls, tiny buildings, and seven glowing biome portals. A winged traveler hovers nearby while the island bobs, waterfalls fall, and portals pulse in a slow fantasy loop.

You’ll learn

  • Layering stacked rock shapes to create a floating island silhouette
  • Drawing multiple waterfall strands with translucent white strokes
  • Building seven tiny circular portals with distinct biome colors
  • Adding a small winged traveler with simple wing arcs
  • Animating float, fall, pulse, and sway on separate timelines
Skill level
Intermediate
Time
~35 min
Tools
Just a browser
Code type
SVG + CSS
Lines
~130

the steps

Build it, one change at a time

  1. Paint the sky and sea

    Start with a soft dusk gradient from warm peach at the bottom to deep blue at the top. Add a few distant cloud shapes so the island has somewhere to float.

    <svg class="av7" viewBox="0 0 200 200" width="200" height="200">
      <defs>
        <linearGradient id="av7-sky" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stop-color="#4B5D8C" />
          <stop offset="100%" stop-color="#F5C98C" />
        </linearGradient>
      </defs>
      <rect x="0" y="0" width="200" height="200" rx="18" fill="url(#av7-sky)" />
      <path d="M30 120 Q50 110 70 120" fill="none" stroke="#FFFDF7" stroke-width="2" opacity="0.3" />
    </svg>
    

    a calm dusk sky waiting for the island.

  2. Shape the floating island

    Stack three rock layers with rounded tops and rough bottoms. The widest layer sits at the top as grassy ground, with smaller rocky tiers hanging beneath it.

    <g class="av7-island" stroke-linecap="round" stroke-linejoin="round">
      <path d="M50 92 Q70 72 100 72 Q130 72 150 92 L140 108 Q100 118 60 108 Z" fill="#7BA05B" stroke="#2B3A55" stroke-width="2.6" />
      <path d="M60 108 Q80 132 100 132 Q120 132 140 108 L130 142 Q100 154 70 142 Z" fill="#A98C6A" stroke="#2B3A55" stroke-width="2.4" />
      <path d="M75 142 Q90 158 100 158 Q110 158 125 142 L115 162 Q100 170 85 162 Z" fill="#8C7355" stroke="#2B3A55" stroke-width="2.2" />
    </g>
    

    a layered rock island floats in the dusk sky.

  3. Add waterfalls, portals, and a traveler

    Draw translucent waterfall strands falling from the island edges. Add seven small circles around the island, each with a different biome fill. Place a tiny winged traveler near the portals.

    <!-- waterfalls -->
    <path class="av7-fall" d="M70 100 Q68 124 72 146" fill="none" stroke="#D6EFFF" stroke-width="2.2" opacity="0.65" />
    <path class="av7-fall" d="M130 100 Q132 124 128 146" fill="none" stroke="#D6EFFF" stroke-width="2.2" opacity="0.65" />
    
    <!-- seven biome portals -->
    <circle class="av7-portal" cx="42" cy="96" r="9" fill="#7BA05B" stroke="#2B3A55" stroke-width="1.6" />
    <circle class="av7-portal" cx="158" cy="96" r="9" fill="#E89B6E" stroke="#2B3A55" stroke-width="1.6" />
    <circle class="av7-portal" cx="100" cy="54" r="9" fill="#6FA8FF" stroke="#2B3A55" stroke-width="1.6" />
    

    waterfalls fall and seven portals glow.

  4. Animate the floating world

    Add CSS keyframes that bob the whole island, fall the waterfalls, pulse the portals, hover the traveler, and sway the vines. Each animation uses its own duration so the motion feels layered and alive.

    @media (prefers-reduced-motion: no-preference) {
      .av7 .av7-island { transform-box: fill-box; transform-origin: center; animation: av7-bob 5s ease-in-out infinite; }
      .av7 .av7-fall { animation: av7-fall 1.8s linear infinite; }
      .av7 .av7-portal { transform-box: fill-box; transform-origin: center; animation: av7-pulse 3s ease-in-out infinite; }
      .av7 .av7-traveler { animation: av7-hover 4s ease-in-out infinite; }
    }
    @keyframes av7-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
    @keyframes av7-fall { 0% { stroke-dashoffset: 0; opacity: 0.4; } 50% { opacity: 0.85; } 100% { stroke-dashoffset: 18; opacity: 0.4; } }
    @keyframes av7-pulse { 0%, 100% { transform: scale(1); opacity: 0.75; } 50% { transform: scale(1.1); opacity: 1; } }
    

    the island bobs, waterfalls fall, portals pulse, and the traveler hovers.

the complete code

Everything, in one place

Skipped straight to the end? Welcome. Copy the whole thing, download it, or open it in the Playground to start remixing.

<svg class="ava" viewBox="0 0 200 200" width="200" height="200" role="img" aria-label="A floating island with seven glowing biome portals, falling waterfalls, and a winged traveler framed by blue vines">
  <rect x="0" y="0" width="200" height="200" rx="18" fill="#FBF2E5" stroke="none"/>
  <g class="ava-island" stroke="#2B3A55" stroke-width="2.4" stroke-linejoin="round">
    <path d="M60 122 C60 122 72 94 100 90 C128 94 140 122 140 122 C140 130 124 138 100 138 C76 138 60 130 60 122 Z" fill="#4E6E58"/>
    <path d="M66 122 C66 122 76 108 100 106 C124 108 134 122 134 122" fill="none" stroke="#2B3A55" stroke-width="1.4" opacity="0.25"/>
    <path d="M70 128 C70 128 78 116 100 114 C122 116 130 128 130 128" fill="#6EF4A2" opacity="0.35" stroke="none"/>
    <path d="M90 118 L90 104 L98 100 L106 104 L106 118" fill="#C77A57" stroke="#2B3A55" stroke-width="1.8"/>
    <path d="M90 104 L98 98 L106 104" fill="none" stroke="#2B3A55" stroke-width="1.6"/>
    <rect x="92" y="108" width="5" height="5" fill="#FFFDF7" stroke="#2B3A55" stroke-width="1.2"/>
    <rect x="100" y="108" width="4" height="5" fill="#FFFDF7" stroke="#2B3A55" stroke-width="1.2"/>
    <path d="M78 124 L78 114 L84 110 L90 114 L90 124" fill="#6FA8FF" stroke="#2B3A55" stroke-width="1.6"/>
    <path d="M110 124 L110 116 L116 112 L122 116 L122 124" fill="#6FA8FF" stroke="#2B3A55" stroke-width="1.6"/>
  </g>
  <path class="ava-water" d="M118 126 C118 126 122 146 118 164 C116 174 110 184 110 184 C110 184 104 174 102 164 C98 146 102 126 102 126" fill="#6FA8FF" stroke="#FFFDF7" stroke-width="2" stroke-linejoin="round" opacity="0.8"/>
  <path class="ava-water" d="M82 128 C82 128 86 144 82 158 C80 166 76 172 76 172 C76 172 72 166 70 158 C66 144 70 128 70 128" fill="#6FA8FF" stroke="#FFFDF7" stroke-width="1.8" stroke-linejoin="round" opacity="0.7"/>
  <g class="ava-portal" style="animation-delay: 0s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="100" cy="42" r="16" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.6"/>
    <path d="M94 50 L100 34 L106 50" fill="none" stroke="#C77A57" stroke-width="2"/>
    <circle cx="100" cy="48" r="3" fill="#6FA8FF"/>
  </g>
  <g class="ava-portal" style="animation-delay: 0.4s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="46" cy="64" r="14" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.4"/>
    <path d="M40 70 C40 62 46 56 52 56 C58 56 60 64 60 70" fill="none" stroke="#4E6E58" stroke-width="1.6"/>
    <path d="M42 70 L42 58 L48 58 L48 70" fill="#C77A57" stroke="#2B3A55" stroke-width="1.4"/>
    <path d="M50 70 L50 60 L56 60 L56 70" fill="#C77A57" stroke="#2B3A55" stroke-width="1.4"/>
  </g>
  <g class="ava-portal" style="animation-delay: 0.8s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="154" cy="64" r="14" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.4"/>
    <path d="M148 72 C148 64 150 58 154 54 C158 58 160 64 160 72" fill="none" stroke="#6FA8FF" stroke-width="1.6"/>
    <path d="M146 72 L154 50 L162 72" fill="none" stroke="#2B3A55" stroke-width="1.4"/>
  </g>
  <g class="ava-portal" style="animation-delay: 1.2s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="36" cy="116" r="14" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.4"/>
    <path d="M30 120 L30 108 L36 104 L42 108 L42 120" fill="#C77A57" stroke="#2B3A55" stroke-width="1.4"/>
    <path d="M36 104 L32 100 L40 100" fill="none" stroke="#2B3A55" stroke-width="1.2"/>
    <circle cx="36" cy="112" r="2" fill="#FFD84D"/>
  </g>
  <g class="ava-portal" style="animation-delay: 1.6s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="164" cy="116" r="14" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.4"/>
    <path d="M156 120 C156 112 160 108 164 108 C168 108 172 112 172 120" fill="none" stroke="#4E6E58" stroke-width="1.6"/>
    <path d="M158 120 L158 110 L162 110 L162 120" fill="#4E6E58" stroke="#2B3A55" stroke-width="1.2"/>
    <path d="M166 120 L166 112 L170 112 L170 120" fill="#4E6E58" stroke="#2B3A55" stroke-width="1.2"/>
  </g>
  <g class="ava-portal" style="animation-delay: 2s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="50" cy="162" r="13" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.4"/>
    <path d="M44 166 C44 160 48 156 52 156 C56 156 58 160 58 166" fill="none" stroke="#C77A57" stroke-width="1.4"/>
    <circle cx="54" cy="158" r="2" fill="#FFD84D"/>
  </g>
  <g class="ava-portal" style="animation-delay: 2.4s" stroke="#2B3A55" stroke-width="1.8" stroke-linejoin="round">
    <circle cx="150" cy="162" r="13" fill="#E8F4FF" stroke="#6FA8FF" stroke-width="2.4"/>
    <path d="M144 160 C144 154 148 150 152 150 C156 150 158 154 158 160" fill="none" stroke="#6FA8FF" stroke-width="1.4"/>
    <path d="M142 166 L158 166" fill="none" stroke="#C77A57" stroke-width="1.4"/>
  </g>
  <g class="ava-figure" fill="#2B3A55" stroke="#2B3A55" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round">
    <path d="M100 184 C100 184 94 176 96 170 C98 166 102 166 104 170 C106 176 100 184 100 184 Z"/>
    <path d="M96 172 L84 166 L88 160" fill="none" stroke="#2B3A55" stroke-width="1.6"/>
    <path d="M104 172 L116 166 L112 160" fill="none" stroke="#2B3A55" stroke-width="1.6"/>
    <path d="M94 178 L86 182" fill="none" stroke="#2B3A55" stroke-width="1.4"/>
    <path d="M106 178 L114 182" fill="none" stroke="#2B3A55" stroke-width="1.4"/>
    <path d="M92 168 C88 162 90 156 96 154 C100 152 104 156 104 160" fill="none" stroke="#2B3A55" stroke-width="1.4"/>
  </g>
  <g class="ava-vine" fill="none" stroke="#6FA8FF" stroke-width="1.6" stroke-linecap="round" opacity="0.35">
    <path d="M8 100 C20 80 30 120 40 100"/>
    <path d="M192 100 C180 80 170 120 160 100"/>
    <ellipse cx="20" cy="88" rx="3" ry="1.8" fill="#6FA8FF" stroke="none"/>
    <ellipse cx="180" cy="88" rx="3" ry="1.8" fill="#6FA8FF" stroke="none"/>
  </g>
</svg>
Open in Playground

tips & gotchas

Mistakes we actually made

I keep the island as three stacked layers so the floating mass reads as solid rock rather than one flat shape.

Waterfalls use low-opacity white strokes with a dash offset animation so the water appears to move downward.

Each portal gets a distinct fill color to suggest different biomes without drawing detailed scenes inside them.

The winged traveler is tiny — a small body plus two arcs for wings — so it does not compete with the island.

Long bob loops (5s) and shorter portal pulses (3s) keep the animation calm but never static.

make it yours

Remix it

  • Vine bridgesmedium

    Connect the portals with thin green vine paths that sway on a slow loop.

  • Night modeeasy

    Darken the sky gradient and turn the waterfall strokes into pale blue glow lines.

  • Portal travelersmedium

    Add tiny silhouettes stepping out of two portals on alternating pulse beats.

challenge extension

Make the seven portals cycle through all seven colors on a shared timeline, so each one glows in sequence like a ring of worlds.

keep sketching

Pick another small recipe and borrow one technique for your next doodle.