Starry Magic Cursor effect
Source code for the cursor starry effect Video.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Starry Magic Cursor</title>
<link rel="stylesheet" href="style.css">
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
<div class="min-h-screen flex items-center justify-center">
<div class="text-container text-center space-y-8">
<h1 class="text-6xl text-white font-bold text-black">
Starry Magic Cursor
</h1>
<p class="text-2xl text-gray-700">
Source code in Description
</p>
</div>
<canvas id="starCanvas"></canvas>
</div>
<script src="main.js"></script>
</body>
</html>
CSS
@tailwind base;
@tailwind components;
@tailwind utilities;
body,
html {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000; /* Dark background */
}
canvas {
position: absolute;
top: 0;
left: 0;
}
JavaScript
document.addEventListener("DOMContentLoaded", () => {
const canvas = document.getElementById("starCanvas");
const ctx = canvas.getContext("2d");
let width = (canvas.width = window.innerWidth);
let height = (canvas.height = window.innerHeight);
let stars = [];
// Adjust canvas size on window resize
window.addEventListener("resize", () => {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
});
// Helper function for random numbers within a range
const randomRange = (min, max) => Math.random() * (max - min) + min;
// Star class encapsulates star properties and behavior
class Star {
constructor(x, y, velocityX, velocityY) {
this.x = x;
this.y = y;
this.finalSize = randomRange(1, 2); // Final size of the star
this.size = this.finalSize * 2; // Start with double the size
this.alpha = 1; // Initial opacity
this.velocityX = velocityX * 0.05;
this.velocityY = 1 + randomRange(0, 1) + velocityY * 0.05;
this.gravity = 0.02;
this.drag = 0.97;
this.turbulence = () => randomRange(-0.25, 0.25);
this.timeElapsed = 0; // Time since creation
}
// Draw the star
draw() {
ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;
ctx.beginPath();
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
}
// Update the star's position and size
update(deltaTime) {
this.x += this.velocityX + this.turbulence();
this.velocityX *= this.drag;
this.y += this.velocityY;
this.velocityY += this.gravity;
// Fade out gradually
this.alpha = Math.max(0, this.alpha - 0.005);
// Adjust size based on elapsed time
this.timeElapsed += deltaTime;
if (this.timeElapsed < 2000) {
this.size = this.finalSize * 2 - (this.finalSize * this.timeElapsed) / 2000;
} else {
this.size = this.finalSize;
}
}
}
// Mouse tracking variables
let lastMouseX = 0;
let lastMouseY = 0;
let mouseVelocityX = 0;
let mouseVelocityY = 0;
// Add a star on mouse movement
function addStar(event) {
// Calculate mouse velocity
mouseVelocityX = event.clientX - lastMouseX;
mouseVelocityY = event.clientY - lastMouseY;
lastMouseX = event.clientX;
lastMouseY = event.clientY;
// Introduce randomness to the velocity
const randomOffsetX = randomRange(-50, 50);
const randomOffsetY = randomRange(-50, 50);
// Create and add a new star
stars.push(new Star(event.clientX, event.clientY, mouseVelocityX + randomOffsetX, mouseVelocityY + randomOffsetY));
}
// Attach mousemove event listener
canvas.addEventListener("mousemove", addStar);
// Animation loop
let lastTime = 0;
function update(time = 0) {
const deltaTime = time - lastTime;
lastTime = time;
// Clear the canvas
ctx.clearRect(0, 0, width, height);
// Update and draw each star
stars.forEach((star) => star.update(deltaTime));
stars.forEach((star) => star.draw());
// Remove stars that are no longer visible
stars = stars.filter((star) => star.alpha > 0 && star.y < height && star.x > 0 && star.x < width);
// Request next frame
requestAnimationFrame(update);
}
// Start the animation
update();
});

Comments
Post a Comment