Skip to main content
<CodeWithBhurtel/>
HomeLearnProjectsChallengesBlogAboutContactLogin
<CodeWithBhurtel/>

Learn through structured lessons, real projects, and live challenges. Free tutorials for HTML, CSS, JavaScript, and more.

Pages

  • Home
  • Learn
  • Blog
  • Projects
  • Challenges
  • About
  • Contact

Lessons

  • HTML
  • CSS
  • JavaScript

© 2026 CodeWithBhurtel. All rights reserved.

Privacy PolicyTerms & Conditions
Projects

Heart Animation

IntermediateHTML, CSS, JavaScript

Intermediate — you need a working understanding of both the Three.js scene graph and GSAP

Heart Animation – project preview
Share this project
Follow me on social media

About this project

This project builds a 3D heart animation using Three.js, GSAP, and SVG path data. An SVG heart shape lives hidden in the DOM and acts as the source of truth for particle positions. The browser reads thousands of points along the path, converts them into 3D coordinates with slight randomness applied to each axis, and hands them to Three.js as a particle system. GSAP then animates every particle from a central origin point outward to its final position, with the scene slowly rocking back and forth on the Y axis to give the heart a breathing, floating quality.

What you will learn

You will learn how to extract point coordinates from an SVG path using getTotalLength and getPointAtLength, and how to convert those 2D coordinates into 3D space with THREE.Vector3. From there you will build a particle system using THREE.BufferGeometry and THREE.Points, then drive each vertex with a staggered GSAP timeline so the particles burst outward from a single origin. You will also learn how to sync geometry updates inside the render loop so animated positions reflect in real time, and how additive blending makes overlapping particles glow rather than stack into flat color.

Understand with AI

Get an AI-generated overview or a file-by-file code breakdown. Ask questions about the project below the overview.

AI Overview: Heart Animation Project

This web project creates a dynamic and interactive 3D heart animation using a cloud of particles. It leverages the Three.js library for 3D rendering and the GSAP library for sophisticated animations, bringing the heart shape to life through forming and dispersing particles. The entire scene also features a subtle rotational movement, and users can interact with the 3D view.

The foundation of the heart shape is defined by an SVG <path> element directly embedded in the index.html. Although visually hidden by CSS, its geometric data is crucial. The script.js then initializes a Three.js scene, camera, and WebGL renderer. It reads the SVG path's outline, sampling numerous points along its length to generate the initial 3D coordinates (vertices) for the particles, adding a slight random offset to create a "cloud" effect.

<svg viewBox="0 0 600 552">
  <path d="M300,107.77C284.68,55.67,239.76,0,162.31,0,64.83,0,0,82.08,0,171.71c0,.48,0,.95,0,1.43-.52,19.5,0,217.94,299.87,379.69v0l0,0,.05,0,0,0,0,0v0C600,391.08,600.48,192.64,600,173.14c0-.48,0-.95,0-1.43C600,82.08,535.17,0,437.69,0,360.24,0,315.32,55.67,300,107.77" fill="#ee5282"/>
</svg>

This SVG path defines the heart shape, which is then used by JavaScript to generate particle positions.

After setting up the 3D environment, the JavaScript code iterates along the SVG path to create a collection of THREE.Vector3 objects, each representing a particle. These vectors are then used to create a THREE.Points object, which is added to the scene. The GSAP animation library is central to the particle movement; it creates a timeline that animates each particle from a central starting point to its final position on the heart, giving the illusion of the heart forming.

const path = document.querySelector("path");
const length = path.getTotalLength();
const vertices = [];
for (let i = 0; i < length; i += 0.1) {
  const point = path.getPointAtLength(i);
  const vector = new THREE.Vector3(point.x, -point.y, 0);
  vector.x += (Math.random() - 0.5) * 30;
  vector.y += (Math.random() - 0.5) * 30;
  vector.z += (Math.random() - 0.5) * 70;
  vertices.push(vector);
  tl.from(vector, {
      x: 600 / 2,
      y: -552 / 2,
      z: 0,
      ease: "power2.inOut",
      duration: "random(2, 5)"
    },
    i * 0.002
  );
}

This code samples points from the SVG path, creates 3D vectors for particles, adds random offsets, and then uses GSAP to animate each particle from a central point to its final position on the heart.

The animation is maintained by a continuous render function, which is called repeatedly using requestAnimationFrame. Inside this loop, the particle geometry is updated to reflect the ongoing GSAP animations, and the Three.js renderer redraws the scene. Additionally, GSAP is used to animate the entire 3D scene's rotation, creating a gentle, repeating sway. The OrbitControls library is also included, allowing users to manually rotate and zoom the heart with their mouse, adding an interactive element to the visualization.

function render() {
  requestAnimationFrame(render);
  // Update the geometry from the animated vertices
  geometry.setFromPoints(vertices);
  renderer.render(scene, camera);
}

The render function continuously updates the particle positions based on the GSAP animations and redraws the 3D scene.

Ask about this project

Have a question about how this project works? Ask below and get an answer based on the project code.

Code Breakdown

Structured technical breakdown for beginners. Anyone can generate or regenerate; your version is saved in this browser (local storage).

No breakdown yet. Generate one to see a file-by-file explanation. Your version is saved in this browser.

Comments

No comments yet. Sign in to leave a comment.

Sign in to leave a comment.