Creating a Fun, Interactive Kaleidoscope with Claude AI: A Beginner’s Guide

UknOwWho_Ab1r
6 min readJul 2, 2024

--

Kaleidoscope

Have you ever wanted to make your own digital kaleidoscope? Something you can play with on your computer screen? Well, you’re in luck! This guide will show you how to create a colorful, moving kaleidoscope using a popular web technology called React and Claude AI. Don’t worry if you’re not a tech expert — we’ll explain everything in simple terms.

What We’re Making:

We’re going to build a digital kaleidoscope that changes when you move your mouse. You’ll also be able to zoom in and out. It’ll be like having your own little light show on your computer!

What You Need to Know:

  • Basic computer skills
  • A little bit of experience with coding (but don’t worry, we’ll guide you through it)
  • Claude AI (https://claude.ai)

Let’s Get Started!

Step 1: Setting Up Your Project

Think of this step like setting up an art studio. We’re getting all our tools ready:

  1. Open your computer’s command prompt or terminal.

2. In your command prompt, type :


npx create-react-app interactive-kaleidoscope
cd interactive-kaleidoscope
npm start

This creates a new folder for our project and starts it up.

Step 2: Adding Some Extra Tools

We need one more tool to make our kaleidoscope even cooler:

  1. In your command prompt, type:
npm install lucide-react

This installs some nice-looking icons we’ll use later.

Step 3: Creating the Kaleidoscope

Now for the fun part! We’re going to create the main piece of our kaleidoscope:

  1. In your project folder, find the “src” folder.
  2. Create a new file called `InteractiveKaleidoscope.js`.
import React, { useState, useEffect, useRef } from 'react';
import { ZoomIn, ZoomOut } from 'lucide-react';

// Main component for the interactive kaleidoscope
const InteractiveKaleidoscope = () => {
// State for the rotation angle of the kaleidoscope
const [angle, setAngle] = useState(0);
// State for the scale of the kaleidoscope
const [scale, setScale] = useState(1);
// Ref to the SVG element
const svgRef = useRef(null);

useEffect(() => {
// Mouse move handler to update the angle of the kaleidoscope based on mouse position
const handleMouseMove = (event) => {
if (!svgRef.current) return;
const rect = svgRef.current.getBoundingClientRect();
const centerX = rect.left + rect.width / 2;
const centerY = rect.top + rect.height / 2;
const deltaX = event.clientX - centerX;
const deltaY = event.clientY - centerY;
const newAngle = Math.atan2(deltaY, deltaX) * (180 / Math.PI);
setAngle(newAngle);
};

// Wheel event handler to update the scale of the kaleidoscope
const handleWheel = (event) => {
event.preventDefault();
setScale(prevScale => {
const newScale = prevScale - event.deltaY * 0.001;
return Math.min(Math.max(newScale, 0.5), 2);
});
};

// Add event listeners for mouse move and wheel events
window.addEventListener('mousemove', handleMouseMove);
svgRef.current.addEventListener('wheel', handleWheel, { passive: false });

// Cleanup event listeners on component unmount
return () => {
window.removeEventListener('mousemove', handleMouseMove);
svgRef.current?.removeEventListener('wheel', handleWheel);
};
}, []);

// Handler for zoom buttons to adjust the scale
const handleZoom = (direction) => {
setScale(prevScale => {
const newScale = prevScale + direction * 0.1;
return Math.min(Math.max(newScale, 0.5), 2);
});
};

return (
<div className="w-full h-full flex flex-col items-center justify-center bg-gray-900">
<svg
ref={svgRef}
viewBox="0 0 400 400"
className="w-full h-full max-w-[400px] max-h-[400px]"
>
<defs>
<radialGradient id="bgGradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style={{ stopColor: '#1a001a', stopOpacity: 1 }} />
<stop offset="100%" style={{ stopColor: '#000033', stopOpacity: 1 }} />
</radialGradient>
<filter id="glow">
<feGaussianBlur stdDeviation="2.5" result="coloredBlur" />
<feMerge>
<feMergeNode in="coloredBlur" />
<feMergeNode in="SourceGraphic" />
</feMerge>
</filter>
</defs>

<rect width="100%" height="100%" fill="url(#bgGradient)" />

<g transform={`translate(200,200) rotate(${angle}) scale(${scale})`}>
<g filter="url(#glow)">
<path d="M0,-100 C-40,-50 40,-50 0,0 C-40,50 40,50 0,100" fill="none" stroke="#00ffff" strokeWidth="2" opacity="0.6">
<animate attributeName="d" dur="10s" repeatCount="indefinite"
values="
M0,-100 C-40,-50 40,-50 0,0 C-40,50 40,50 0,100;
M0,-100 C-60,-30 60,-30 0,0 C-60,30 60,30 0,100;
M0,-100 C-40,-50 40,-50 0,0 C-40,50 40,50 0,100"
/>
</path>
<path d="M0,-100 C40,-50 -40,-50 0,0 C40,50 -40,50 0,100" fill="none" stroke="#ff00ff" strokeWidth="2" opacity="0.6">
<animate attributeName="d" dur="10s" repeatCount="indefinite"
values="
M0,-100 C40,-50 -40,-50 0,0 C40,50 -40,50 0,100;
M0,-100 C60,-30 -60,-30 0,0 C60,30 -60,30 0,100;
M0,-100 C40,-50 -40,-50 0,0 C40,50 -40,50 0,100"
/>
</path>
</g>

<g filter="url(#glow)">
<circle cx="0" cy="0" r="10" fill="#ffcc00" opacity="0.8">
<animate attributeName="r" dur="4s" repeatCount="indefinite" values="10;15;10" />
<animate attributeName="opacity" dur="4s" repeatCount="indefinite" values="0.8;1;0.8" />
</circle>
</g>

{[0, 120, 240].map((rotation) => (
<g key={rotation} transform={`rotate(${rotation})`}>
<g filter="url(#glow)">
<path d="M0,0 Q60,-80 120,-60 T180,-90" fill="none" stroke="#ff3366" strokeWidth="2" opacity="0.6">
<animate attributeName="d" dur="12s" repeatCount="indefinite"
values="
M0,0 Q60,-80 120,-60 T180,-90;
M0,0 Q70,-70 130,-50 T190,-80;
M0,0 Q60,-80 120,-60 T180,-90"
/>
</path>
<circle cx="120" cy="-60" r="6" fill="#3366ff" opacity="0.8">
<animate attributeName="cy" dur="6s" repeatCount="indefinite" values="-60;-55;-60" />
<animate attributeName="r" dur="6s" repeatCount="indefinite" values="6;8;6" />
</circle>
<circle cx="180" cy="-90" r="4" fill="#33ccff" opacity="0.8">
<animate attributeName="cy" dur="6s" repeatCount="indefinite" values="-90;-85;-90" />
<animate attributeName="r" dur="6s" repeatCount="indefinite" values="4;6;4" />
</circle>
</g>
</g>
))}

<g filter="url(#glow)">
<circle cx="0" cy="0" r="150" fill="none" stroke="#ffffff" strokeWidth="0.5" opacity="0.2" />
<circle cx="0" cy="0" r="100" fill="none" stroke="#ffffff" strokeWidth="0.5" opacity="0.2" />
<circle cx="0" cy="0" r="50" fill="none" stroke="#ffffff" strokeWidth="0.5" opacity="0.2" />
</g>

<g>
{[0, 60, 120, 180, 240, 300].map((angle, index) => (
<circle
key={angle}
cx={Math.cos(angle * Math.PI / 180) * 100}
cy={Math.sin(angle * Math.PI / 180) * 100}
r="2"
fill="#ffffff"
opacity={0.8 - index * 0.1}
/>
))}
<animateTransform attributeName="transform" type="rotate" from="0 0 0" to="360 0 0" dur="60s" repeatCount="indefinite" />
</g>
</g>
</svg>
<div className="mt-4 flex space-x-4">
<button
onClick={() => handleZoom(-1)}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
<ZoomOut size={24} />
</button>
<button
onClick={() => handleZoom(1)}
className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
>
<ZoomIn size={24} />
</button>
</div>
</div>
);
};

export default InteractiveKaleidoscope;

3. Copy the code we provide into this file.

This code is like a recipe for our kaleidoscope. It tells the computer how to draw the shapes and make them move.

Step 4: Putting It All Together

Now we need to tell our project to use the kaleidoscope we just made:

  1. Find the file called “App.js” in your “src” folder.
  2. Replace everything in it with this code :
import React from 'react';
import './App.css';
import InteractiveKaleidoscope from './InteractiveKaleidoscope';

function App() {
return (
<div className="App">
<header className="App-header">
<InteractiveKaleidoscope />
</header>
</div>
);
}

export default App;

This step is like hanging our artwork on the wall — it makes our kaleidoscope visible in the app.

Step 5: Making It Look Good

Let’s add some style to make our kaleidoscope look even better:

  1. Create a new file called “App.css” in your “src” folder.
  2. Copy the CSS code we provide into this file.
.App {
text-align: center;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #282c34;
}

.App-header {
background-color: #282c34;
padding: 20px;
color: white;
width: 100%;
max-width: 800px;
margin: 0 auto;
}

This is like choosing the perfect frame for our artwork.

Step 6: See It in Action!

Time to see what we’ve created:

  1. If your project isn’t already running, type npm start in your command prompt.
  2. Open your web browser and go to “http://localhost:3000".

You should see your kaleidoscope! Move your mouse around to see it change. Use the zoom buttons to get a closer or farther view.

Congratulations!

You’ve just created your very own interactive kaleidoscope! It’s a colorful, moving display that responds to your actions. Pretty cool, right?

What You’ve Learned:

  • How to set up a React project
  • How to create interactive graphics on a webpage
  • Basic concepts of web development

Next Steps:

Why not try changing some colors or shapes in the code? See what happens when you tweak things. That’s how you learn and make it your own!

Remember, every expert started as a beginner. Keep exploring, keep learning, and most importantly, have fun with your new digital creation!

For more tutorials and guides on React, SVG, and AI development topics, be sure to check out our writings here :

Happy coding!

#CreativeCoding#LLM#Claude#AI#React#SVG#Kaleidescope

--

--

UknOwWho_Ab1r

Creative Tech Innovator | Rust | Mechanical Engineer | Redis Side Quest Hackathon Winner | Gen AI Enthusiast