Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="https://cdn.tailwindcss.com"> | |
| <title>Code as Art Generator</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Space+Mono:wght@400;700&family=VT323&display=swap'); | |
| body { | |
| font-family: 'Space Mono', monospace; | |
| background-color: #0f172a; | |
| color: #e2e8f0; | |
| overflow-x: hidden; | |
| } | |
| .code-art { | |
| background-color: #1e293b; | |
| border: 1px solid #334155; | |
| border-radius: 0.5rem; | |
| font-family: 'VT323', monospace; | |
| white-space: pre; | |
| overflow-x: auto; | |
| tab-size: 2; | |
| } | |
| .pulse { | |
| animation: pulse 2s infinite; | |
| } | |
| @keyframes pulse { | |
| 0% { opacity: 0.7; } | |
| 50% { opacity: 1; } | |
| 100% { opacity: 0.7; } | |
| } | |
| .glow { | |
| text-shadow: 0 0 5px #38bdf8, 0 0 10px #38bdf8; | |
| } | |
| .gradient-text { | |
| background: linear-gradient(90deg, #38bdf8, #818cf8, #c084fc); | |
| -webkit-background-clip: text; | |
| background-clip: text; | |
| color: transparent; | |
| } | |
| .typing-cursor { | |
| display: inline-block; | |
| width: 10px; | |
| height: 24px; | |
| background: #38bdf8; | |
| margin-left: 5px; | |
| animation: blink 1s step-end infinite; | |
| } | |
| @keyframes blink { | |
| from, to { opacity: 1; } | |
| 50% { opacity: 0; } | |
| } | |
| </style> | |
| </head> | |
| <body class="min-h-screen flex flex-col"> | |
| <header class="py-6 px-4 sm:px-6 lg:px-8 border-b border-slate-700"> | |
| <div class="max-w-7xl mx-auto flex justify-between items-center"> | |
| <h1 class="text-3xl font-bold gradient-text">Code as Art Generator</h1> | |
| <div class="flex items-center space-x-4"> | |
| <button id="recordBtn" class="px-4 py-2 bg-sky-600 hover:bg-sky-700 rounded-md font-medium flex items-center"> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fill-rule="evenodd" d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z" clip-rule="evenodd" /> | |
| </svg> | |
| Start Recording | |
| </button> | |
| <button id="generateBtn" class="px-4 py-2 bg-purple-600 hover:bg-purple-700 rounded-md font-medium flex items-center" disabled> | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fill-rule="evenodd" d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z" clip-rule="evenodd" /> | |
| </svg> | |
| Generate Art | |
| </button> | |
| </div> | |
| </div> | |
| </header> | |
| <main class="flex-grow p-4 sm:p-6 lg:p-8"> | |
| <div class="max-w-7xl mx-auto grid grid-cols-1 lg:grid-cols-2 gap-8"> | |
| <div class="space-y-6"> | |
| <div class="bg-slate-800 rounded-xl p-6 shadow-lg"> | |
| <h2 class="text-xl font-semibold mb-4 text-sky-400">Your Spoken Words</h2> | |
| <div id="transcriptContainer" class="min-h-48 p-4 bg-slate-900 rounded-lg border border-slate-700"> | |
| <p id="transcript" class="text-slate-300">Press "Start Recording" to begin capturing your words...</p> | |
| <div id="status" class="mt-2 text-sm text-slate-500 flex items-center"> | |
| <div id="recordingIndicator" class="hidden items-center"> | |
| <span class="relative flex h-3 w-3 mr-2"> | |
| <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-red-500 opacity-75"></span> | |
| <span class="relative inline-flex rounded-full h-3 w-3 bg-red-500"></span> | |
| </span> | |
| <span>Recording...</span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-slate-800 rounded-xl p-6 shadow-lg"> | |
| <h2 class="text-xl font-semibold mb-4 text-purple-400">Code Transformation</h2> | |
| <div class="min-h-48 p-4 bg-slate-900 rounded-lg border border-slate-700 code-art"> | |
| <div id="codePreview"> | |
| <span class="text-slate-500">// Your words will be transformed into code here</span> | |
| <span class="typing-cursor"></span> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="bg-slate-800 rounded-xl p-6 shadow-lg"> | |
| <div class="flex justify-between items-center mb-4"> | |
| <h2 class="text-xl font-semibold text-emerald-400">Generated Art</h2> | |
| <button id="downloadBtn" class="px-3 py-1 bg-emerald-600 hover:bg-emerald-700 rounded-md text-sm" disabled> | |
| Download Art | |
| </button> | |
| </div> | |
| <div id="artContainer" class="min-h-[500px] bg-slate-900 rounded-lg border border-slate-700 flex items-center justify-center overflow-hidden relative"> | |
| <div id="artDisplay" class="w-full h-full p-4 flex items-center justify-center"> | |
| <p class="text-slate-600 text-center">Your code-generated art will appear here<br>after you click "Generate Art"</p> | |
| </div> | |
| <div id="loadingOverlay" class="absolute inset-0 bg-slate-900/80 flex items-center justify-center hidden"> | |
| <div class="text-center"> | |
| <div class="inline-block animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-emerald-500 mb-4"></div> | |
| <p class="text-emerald-400 font-mono">Generating artistic code...</p> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </main> | |
| <footer class="py-4 px-4 sm:px-6 lg:px-8 border-t border-slate-700 text-center text-sm text-slate-500"> | |
| <p>Code as Art Generator - Transform your spoken words into visual code art</p> | |
| </footer> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const recordBtn = document.getElementById('recordBtn'); | |
| const generateBtn = document.getElementById('generateBtn'); | |
| const downloadBtn = document.getElementById('downloadBtn'); | |
| const transcript = document.getElementById('transcript'); | |
| const codePreview = document.getElementById('codePreview'); | |
| const artDisplay = document.getElementById('artDisplay'); | |
| const recordingIndicator = document.getElementById('recordingIndicator'); | |
| const loadingOverlay = document.getElementById('loadingOverlay'); | |
| let recognition; | |
| let isRecording = false; | |
| let capturedText = ''; | |
| // Check if browser supports speech recognition | |
| if ('webkitSpeechRecognition' in window) { | |
| recognition = new webkitSpeechRecognition(); | |
| recognition.continuous = true; | |
| recognition.interimResults = true; | |
| recognition.onstart = () => { | |
| isRecording = true; | |
| recordBtn.innerHTML = ` | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fill-rule="evenodd" d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z" clip-rule="evenodd" /> | |
| </svg> | |
| Stop Recording | |
| `; | |
| recordBtn.classList.remove('bg-sky-600', 'hover:bg-sky-700'); | |
| recordBtn.classList.add('bg-red-600', 'hover:bg-red-700'); | |
| recordingIndicator.classList.remove('hidden'); | |
| }; | |
| recognition.onend = () => { | |
| isRecording = false; | |
| recordBtn.innerHTML = ` | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fill-rule="evenodd" d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z" clip-rule="evenodd" /> | |
| </svg> | |
| Start Recording | |
| `; | |
| recordBtn.classList.remove('bg-red-600', 'hover:bg-red-700'); | |
| recordBtn.classList.add('bg-sky-600', 'hover:bg-sky-700'); | |
| recordingIndicator.classList.add('hidden'); | |
| if (capturedText.trim().length > 0) { | |
| generateBtn.disabled = false; | |
| } | |
| }; | |
| recognition.onresult = (event) => { | |
| let interimTranscript = ''; | |
| let finalTranscript = ''; | |
| for (let i = event.resultIndex; i < event.results.length; i++) { | |
| const transcript = event.results[i][0].transcript; | |
| if (event.results[i].isFinal) { | |
| finalTranscript += transcript; | |
| } else { | |
| interimTranscript += transcript; | |
| } | |
| } | |
| if (finalTranscript) { | |
| capturedText += finalTranscript + ' '; | |
| transcript.textContent = capturedText; | |
| updateCodePreview(capturedText); | |
| } | |
| // Show interim results | |
| if (interimTranscript) { | |
| transcript.textContent = capturedText + interimTranscript; | |
| } | |
| }; | |
| recognition.onerror = (event) => { | |
| console.error('Speech recognition error', event.error); | |
| transcript.textContent = 'Error: ' + event.error; | |
| isRecording = false; | |
| recordBtn.innerHTML = ` | |
| <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" viewBox="0 0 20 20" fill="currentColor"> | |
| <path fill-rule="evenodd" d="M7 4a3 3 0 016 0v4a3 3 0 11-6 0V4zm4 10.93A7.001 7.001 0 0017 8a1 1 0 10-2 0A5 5 0 015 8a1 1 0 00-2 0 7.001 7.001 0 006 6.93V17H6a1 1 0 100 2h8a1 1 0 100-2h-3v-2.07z" clip-rule="evenodd" /> | |
| </svg> | |
| Start Recording | |
| `; | |
| recordBtn.classList.remove('bg-red-600', 'hover:bg-red-700'); | |
| recordBtn.classList.add('bg-sky-600', 'hover:bg-sky-700'); | |
| recordingIndicator.classList.add('hidden'); | |
| }; | |
| } else { | |
| recordBtn.disabled = true; | |
| transcript.textContent = 'Speech recognition not supported in this browser. Try Chrome or Edge.'; | |
| } | |
| // Toggle recording | |
| recordBtn.addEventListener('click', () => { | |
| if (isRecording) { | |
| recognition.stop(); | |
| } else { | |
| capturedText = ''; | |
| transcript.textContent = 'Listening...'; | |
| recognition.start(); | |
| } | |
| }); | |
| // Generate code art | |
| generateBtn.addEventListener('click', () => { | |
| if (capturedText.trim().length === 0) return; | |
| loadingOverlay.classList.remove('hidden'); | |
| downloadBtn.disabled = true; | |
| // Simulate processing delay | |
| setTimeout(() => { | |
| generateCodeArt(capturedText); | |
| loadingOverlay.classList.add('hidden'); | |
| downloadBtn.disabled = false; | |
| }, 2000); | |
| }); | |
| // Download art | |
| downloadBtn.addEventListener('click', () => { | |
| if (!artDisplay.innerHTML.includes('canvas')) return; | |
| const canvas = document.querySelector('canvas'); | |
| const dataURL = canvas.toDataURL('image/png'); | |
| const link = document.createElement('a'); | |
| link.download = 'code-art.png'; | |
| link.href = dataURL; | |
| link.click(); | |
| }); | |
| // Transform text into code preview | |
| function updateCodePreview(text) { | |
| // Simple transformation for demo purposes | |
| const words = text.split(' '); | |
| let code = ''; | |
| // Create a function declaration | |
| code += `function createArt() {\n`; | |
| code += ` // Generated from your words\n`; | |
| code += ` let art = [];\n\n`; | |
| // Add words as comments or code | |
| words.forEach((word, i) => { | |
| if (word.trim() === '') return; | |
| if (i % 3 === 0) { | |
| code += ` art.push("${word.trim()}");\n`; | |
| } else if (i % 5 === 0) { | |
| code += ` // ${word.trim()}\n`; | |
| } else { | |
| code += ` art.push(${Math.floor(Math.random() * 100)}); // ${word.trim()}\n`; | |
| } | |
| }); | |
| code += `\n return art;\n`; | |
| code += `}\n\n`; | |
| code += `// Execute the art generator\n`; | |
| code += `const masterpiece = createArt();\n`; | |
| code += `render(masterpiece);`; | |
| codePreview.innerHTML = syntaxHighlight(code); | |
| } | |
| // Simple syntax highlighting | |
| function syntaxHighlight(code) { | |
| // Keywords | |
| code = code.replace(/(function|return|let|const|var|if|else|for|while|push)\b/g, '<span class="text-purple-400">$1</span>'); | |
| // Strings | |
| code = code.replace(/(".*?"|'.*?')/g, '<span class="text-emerald-400">$1</span>'); | |
| // Numbers | |
| code = code.replace(/\b(\d+)\b/g, '<span class="text-amber-400">$1</span>'); | |
| // Comments | |
| code = code.replace(/\/\/.*$/gm, '<span class="text-slate-500">$&</span>'); | |
| // Function calls | |
| code = code.replace(/(\w+)\(/g, '<span class="text-sky-400">$1</span>('); | |
| return code; | |
| } | |
| // Generate visual art from code | |
| function generateCodeArt(text) { | |
| // Clear previous art | |
| artDisplay.innerHTML = ''; | |
| // Create canvas | |
| const canvas = document.createElement('canvas'); | |
| canvas.width = artDisplay.clientWidth; | |
| canvas.height = artDisplay.clientHeight; | |
| artDisplay.appendChild(canvas); | |
| const ctx = canvas.getContext('2d'); | |
| // Generate art based on text | |
| const words = text.split(' '); | |
| const colors = ['#38bdf8', '#818cf8', '#c084fc', '#f472b6', '#f97316']; | |
| // Background gradient | |
| const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height); | |
| gradient.addColorStop(0, '#0f172a'); | |
| gradient.addColorStop(1, '#1e293b'); | |
| ctx.fillStyle = gradient; | |
| ctx.fillRect(0, 0, canvas.width, canvas.height); | |
| // Draw elements based on words | |
| words.forEach((word, i) => { | |
| if (word.trim() === '') return; | |
| const x = Math.random() * canvas.width; | |
| const y = Math.random() * canvas.height; | |
| const size = 10 + (word.length * 2); | |
| const color = colors[i % colors.length]; | |
| const rotation = Math.random() * 360; | |
| ctx.save(); | |
| ctx.translate(x, y); | |
| ctx.rotate(rotation * Math.PI / 180); | |
| // Alternate between shapes | |
| if (i % 3 === 0) { | |
| // Rectangle | |
| ctx.fillStyle = color; | |
| ctx.globalAlpha = 0.7; | |
| ctx.fillRect(-size/2, -size/2, size, size); | |
| } else if (i % 5 === 0) { | |
| // Circle | |
| ctx.beginPath(); | |
| ctx.fillStyle = color; | |
| ctx.globalAlpha = 0.5; | |
| ctx.arc(0, 0, size/2, 0, Math.PI * 2); | |
| ctx.fill(); | |
| } else { | |
| // Text | |
| ctx.font = `${size/2}px 'VT323', monospace`; | |
| ctx.fillStyle = color; | |
| ctx.globalAlpha = 0.9; | |
| ctx.fillText(word, 0, 0); | |
| } | |
| ctx.restore(); | |
| }); | |
| // Add connecting lines | |
| ctx.strokeStyle = 'rgba(124, 58, 237, 0.3)'; | |
| ctx.lineWidth = 1; | |
| for (let i = 0; i < words.length - 1; i++) { | |
| if (i % 2 === 0 && i < words.length - 2) { | |
| const x1 = (i / words.length) * canvas.width + (Math.random() * 50 - 25); | |
| const y1 = (Math.sin(i) * canvas.height/3) + canvas.height/2 + (Math.random() * 50 - 25); | |
| const x2 = ((i+2) / words.length) * canvas.width + (Math.random() * 50 - 25); | |
| const y2 = (Math.sin(i+2) * canvas.height/3) + canvas.height/2 + (Math.random() * 50 - 25); | |
| ctx.beginPath(); | |
| ctx.moveTo(x1, y1); | |
| ctx.bezierCurveTo( | |
| x1 + 100, y1 + 50, | |
| x2 - 100, y2 - 50, | |
| x2, y2 | |
| ); | |
| ctx.stroke(); | |
| } | |
| } | |
| } | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Boobs00/code-as-art-generator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |