Skip to content

Instantly share code, notes, and snippets.

@amanat361
Created August 25, 2025 20:17
Show Gist options
  • Select an option

  • Save amanat361/d10b7569fcc8c2b5695a6efd7bb677b8 to your computer and use it in GitHub Desktop.

Select an option

Save amanat361/d10b7569fcc8c2b5695a6efd7bb677b8 to your computer and use it in GitHub Desktop.
3D cube for LLM streams
import React, { useState, useEffect, useRef } from ‘react’;
const TextCube = () => {
const [faceTexts, setFaceTexts] = useState([’’, ‘’, ‘’, ‘’, ‘’, ‘’]);
const [prompt, setPrompt] = useState(’’);
const [isGenerating, setIsGenerating] = useState(false);
const streamingIntervals = useRef([]);
// Maximum characters to display per face
const maxChars = 140;
// Complete website project files
const generateCodeFiles = () => {
const htmlFile = `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Portfolio</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<nav class="navbar">
<div class="logo">
<span>&lt;dev/&gt;</span>
</div>
<ul class="nav-menu">
<li><a href="#home">Home</a></li>
<li><a href="#projects">Projects</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
```
<section class="hero">
<canvas id="particles"></canvas>
<div class="hero-content">
<h1 class="glitch" data-text="Hello World">Hello World</h1>
<p class="typing">I'm a <span id="role"></span></p>
<button class="cta">View My Work</button>
</div>
</section>
<section id="projects" class="projects">
<h2>Featured Projects</h2>
<div class="project-grid">
<div class="project-card">
<img src="project1.jpg" alt="Project">
<h3>E-commerce Platform</h3>
<p>Full-stack React application</p>
</div>
</div>
</section>
<script src="main.js"></script>
```
</body>
</html>`;
```
const cssFile = `* {
margin: 0;
padding: 0;
box-sizing: border-box;
```
}
:root {
–primary: #00ffff;
–secondary: #ff00ff;
–dark: #0a0a0a;
–text: #ffffff;
}
body {
font-family: ‘Courier New’, monospace;
background: var(–dark);
color: var(–text);
overflow-x: hidden;
}
.navbar {
position: fixed;
width: 100%;
padding: 1rem 2rem;
background: rgba(10, 10, 10, 0.9);
backdrop-filter: blur(10px);
z-index: 1000;
}
.logo {
font-size: 1.5rem;
color: var(–primary);
font-weight: bold;
}
.nav-menu {
display: flex;
list-style: none;
gap: 2rem;
float: right;
}
.nav-menu a {
color: var(–text);
text-decoration: none;
transition: color 0.3s;
}
.nav-menu a:hover {
color: var(–primary);
}
.hero {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
#particles {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
.hero-content {
text-align: center;
z-index: 10;
}
.glitch {
font-size: 4rem;
font-weight: bold;
text-transform: uppercase;
position: relative;
color: var(–text);
letter-spacing: 5px;
animation: glitch 2s infinite;
}
.glitch::before,
.glitch::after {
content: attr(data-text);
position: absolute;
top: 0;
left: 0;
}
.glitch::before {
animation: glitch-1 0.5s infinite;
color: var(–primary);
z-index: -1;
}
.glitch::after {
animation: glitch-2 0.5s infinite;
color: var(–secondary);
z-index: -2;
}
@keyframes glitch {
0%, 100% { transform: translate(0); }
20% { transform: translate(-2px, 2px); }
40% { transform: translate(-2px, -2px); }
60% { transform: translate(2px, 2px); }
80% { transform: translate(2px, -2px); }
}
@keyframes glitch-1 {
0%, 100% { clip: rect(0, 900px, 0, 0); }
25% { clip: rect(0, 900px, 20px, 0); }
50% { clip: rect(40px, 900px, 60px, 0); }
75% { clip: rect(80px, 900px, 100px, 0); }
}
.cta {
margin-top: 2rem;
padding: 1rem 2rem;
background: linear-gradient(45deg, var(–primary), var(–secondary));
border: none;
color: var(–dark);
font-weight: bold;
cursor: pointer;
transition: transform 0.3s;
}
.cta:hover {
transform: scale(1.05);
}`;
```
const jsFile = `// Particle System
```
class ParticleSystem {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext(‘2d’);
this.particles = [];
this.init();
}
```
init() {
this.canvas.width = window.innerWidth;
this.canvas.height = window.innerHeight;
for (let i = 0; i < 100; i++) {
this.particles.push({
x: Math.random() * this.canvas.width,
y: Math.random() * this.canvas.height,
vx: Math.random() * 2 - 1,
vy: Math.random() * 2 - 1,
size: Math.random() * 2 + 1
});
}
this.animate();
}
animate() {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
this.particles.forEach(p => {
p.x += p.vx;
p.y += p.vy;
if (p.x < 0 || p.x > this.canvas.width) p.vx *= -1;
if (p.y < 0 || p.y > this.canvas.height) p.vy *= -1;
this.ctx.beginPath();
this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
this.ctx.fill();
});
// Draw connections
this.particles.forEach((p1, i) => {
this.particles.slice(i + 1).forEach(p2 => {
const dist = Math.hypot(p1.x - p2.x, p1.y - p2.y);
if (dist < 100) {
this.ctx.strokeStyle = \`rgba(0, 255, 255, \${0.2 * (1 - dist/100)})\`;
this.ctx.beginPath();
this.ctx.moveTo(p1.x, p1.y);
this.ctx.lineTo(p2.x, p2.y);
this.ctx.stroke();
}
});
});
requestAnimationFrame(() => this.animate());
}
```
}
// Typing Effect
class TypeWriter {
constructor(element, words) {
this.element = element;
this.words = words;
this.wordIndex = 0;
this.charIndex = 0;
this.isDeleting = false;
this.type();
}
```
type() {
const current = this.words[this.wordIndex % this.words.length];
if (this.isDeleting) {
this.element.textContent = current.substring(0, this.charIndex--);
} else {
this.element.textContent = current.substring(0, this.charIndex++);
}
let speed = this.isDeleting ? 50 : 100;
if (!this.isDeleting && this.charIndex === current.length) {
speed = 2000;
this.isDeleting = true;
} else if (this.isDeleting && this.charIndex === 0) {
this.isDeleting = false;
this.wordIndex++;
}
setTimeout(() => this.type(), speed);
}
```
}
// Initialize when DOM loads
document.addEventListener(‘DOMContentLoaded’, () => {
const canvas = document.getElementById(‘particles’);
if (canvas) new ParticleSystem(canvas);
```
const role = document.getElementById('role');
if (role) {
new TypeWriter(role, ['Developer', 'Designer', 'Creator']);
}
// Smooth scroll
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', e => {
e.preventDefault();
const target = document.querySelector(anchor.getAttribute('href'));
if (target) target.scrollIntoView({ behavior: 'smooth' });
});
});
```
});`;
```
// Return 6 files: HTML, CSS, JS, then repeat for opposite faces
return [htmlFile, cssFile, jsFile, htmlFile, cssFile, jsFile];
```
};
const handleGenerate = () => {
if (isGenerating) return;
```
setIsGenerating(true);
setFaceTexts(['', '', '', '', '', '']);
// Clear any existing intervals
streamingIntervals.current.forEach(clearInterval);
streamingIntervals.current = [];
const codeFiles = generateCodeFiles();
// Stream each file character by character
codeFiles.forEach((file, faceIndex) => {
let charIndex = 0;
const interval = setInterval(() => {
if (charIndex < file.length) {
setFaceTexts(prev => {
const newTexts = [...prev];
newTexts[faceIndex] = (newTexts[faceIndex] + file[charIndex]).slice(-maxChars);
return newTexts;
});
charIndex++;
} else {
clearInterval(interval);
streamingIntervals.current[faceIndex] = null;
// Check if all faces are done streaming
if (streamingIntervals.current.every(int => int === null)) {
setIsGenerating(false);
}
}
}, 20); // Fast streaming for code effect
streamingIntervals.current[faceIndex] = interval;
});
```
};
// Cleanup intervals on unmount
useEffect(() => {
return () => {
streamingIntervals.current.forEach(clearInterval);
};
}, []);
const faceStyles = {
front: {
transform: ‘translateZ(100px)’,
color: ‘#0ff’,
background: ‘rgba(0, 255, 255, 0.05)’,
borderColor: ‘rgba(0, 255, 255, 0.3)’,
},
right: {
transform: ‘rotateY(90deg) translateZ(100px)’,
color: ‘#f0f’,
background: ‘rgba(255, 0, 255, 0.05)’,
borderColor: ‘rgba(255, 0, 255, 0.3)’,
},
top: {
transform: ‘rotateX(90deg) translateZ(100px)’,
color: ‘#ff0’,
background: ‘rgba(255, 255, 0, 0.05)’,
borderColor: ‘rgba(255, 255, 0, 0.3)’,
},
back: {
transform: ‘rotateY(180deg) translateZ(100px)’,
color: ‘#0f0’,
background: ‘rgba(0, 255, 0, 0.05)’,
borderColor: ‘rgba(0, 255, 0, 0.3)’,
},
left: {
transform: ‘rotateY(-90deg) translateZ(100px)’,
color: ‘#f80’,
background: ‘rgba(255, 136, 0, 0.05)’,
borderColor: ‘rgba(255, 136, 0, 0.3)’,
},
bottom: {
transform: ‘rotateX(-90deg) translateZ(100px)’,
color: ‘#88f’,
background: ‘rgba(136, 136, 255, 0.05)’,
borderColor: ‘rgba(136, 136, 255, 0.3)’,
},
};
const faceLabels = [‘index.html’, ‘styles.css’, ‘main.js’, ‘index.html’, ‘styles.css’, ‘main.js’];
const containerStyle = {
width: ‘100vw’,
height: ‘100vh’,
display: ‘flex’,
flexDirection: ‘column’,
justifyContent: ‘center’,
alignItems: ‘center’,
background: ‘#1a1a1a’,
perspective: ‘1000px’,
margin: 0,
padding: 0,
gap: ‘40px’,
};
const cubeStyle = {
width: ‘200px’,
height: ‘200px’,
position: ‘relative’,
transformStyle: ‘preserve-3d’,
animation: ‘rotate 10s infinite linear’,
};
const faceBaseStyle = {
position: ‘absolute’,
width: ‘200px’,
height: ‘200px’,
display: ‘flex’,
flexDirection: ‘column’,
fontSize: ‘11px’,
lineHeight: ‘1.2’,
overflow: ‘hidden’,
wordBreak: ‘break-all’,
padding: ‘10px’,
boxSizing: ‘border-box’,
border: ‘1px solid’,
fontFamily: ‘monospace’,
};
const labelStyle = {
fontSize: ‘10px’,
fontWeight: ‘bold’,
marginBottom: ‘5px’,
opacity: 0.8,
borderBottom: ‘1px solid rgba(255, 255, 255, 0.1)’,
paddingBottom: ‘3px’,
};
const codeStyle = {
flex: 1,
overflow: ‘hidden’,
whiteSpace: ‘pre-wrap’,
wordWrap: ‘break-word’,
margin: 0,
};
const inputContainerStyle = {
display: ‘flex’,
gap: ‘10px’,
padding: ‘20px’,
background: ‘rgba(255, 255, 255, 0.05)’,
borderRadius: ‘8px’,
border: ‘1px solid rgba(255, 255, 255, 0.1)’,
};
const inputStyle = {
padding: ‘10px 15px’,
fontSize: ‘16px’,
background: ‘rgba(255, 255, 255, 0.1)’,
border: ‘1px solid rgba(255, 255, 255, 0.2)’,
borderRadius: ‘4px’,
color: ‘#fff’,
width: ‘300px’,
fontFamily: ‘monospace’,
};
const buttonStyle = {
padding: ‘10px 20px’,
fontSize: ‘16px’,
background: isGenerating ? ‘rgba(100, 100, 100, 0.3)’ : ‘rgba(0, 255, 255, 0.2)’,
border: ‘1px solid rgba(0, 255, 255, 0.5)’,
borderRadius: ‘4px’,
color: isGenerating ? ‘#666’ : ‘#0ff’,
cursor: isGenerating ? ‘not-allowed’ : ‘pointer’,
fontFamily: ‘monospace’,
transition: ‘all 0.3s’,
};
return (
<div style={containerStyle}>
<style>{`
@keyframes rotate {
from {
transform: rotateX(-20deg) rotateY(30deg);
}
to {
transform: rotateX(-20deg) rotateY(390deg);
}
}
```
input::placeholder {
color: rgba(255, 255, 255, 0.4);
}
button:hover:not(:disabled) {
background: rgba(0, 255, 255, 0.3) !important;
box-shadow: 0 0 20px rgba(0, 255, 255, 0.5);
}
`}</style>
<div style={inputContainerStyle}>
<input
type="text"
placeholder="e.g. 'Build me a portfolio website'"
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && handleGenerate()}
style={inputStyle}
disabled={isGenerating}
/>
<button
onClick={handleGenerate}
style={buttonStyle}
disabled={isGenerating}
>
{isGenerating ? 'Generating...' : 'Generate Code'}
</button>
</div>
<div style={cubeStyle}>
{Object.entries(faceStyles).map(([face, style], index) => (
<div
key={face}
style={{
...faceBaseStyle,
...style,
borderColor: style.borderColor,
}}
>
<div style={{...labelStyle, color: style.color}}>
{faceLabels[index]}
</div>
<p style={{...codeStyle, color: style.color}}>
{faceTexts[index]}
</p>
</div>
))}
</div>
</div>
```
);
};
export default TextCube;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment