<!-- Prompt to Performance - Complete Single Block Version --> <style> .perf-container { font-family: Helvetica, Arial, sans-serif; max-width: 100%; margin: 20px auto; padding: 20px; background: #fff; } .perf-header { text-align: center; margin-bottom: 30px; border-bottom: 1px solid #ddd; padding-bottom: 20px; } .perf-title { font-size: 24px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; } .perf-subtitle { color: #666; margin-top: 10px; } .perf-main { display: grid; grid-template-columns: 1fr 1fr; gap: 30px; } .perf-section { padding: 20px; } .perf-input-section { border-right: 1px solid #ddd; } .perf-output-section { background: #fafafa; } .perf-section-title { font-size: 18px; font-weight: bold; margin-bottom: 15px; text-transform: uppercase; } .perf-textarea { width: 100%; height: 120px; padding: 15px; border: 1px solid #ccc; font-family: inherit; resize: vertical; } .perf-textarea:focus { outline: none; border-color: #000; } .perf-controls { margin: 20px 0; display: flex; gap: 10px; flex-wrap: wrap; } .perf-btn { background: #000; color: #fff; border: none; padding: 10px 20px; cursor: pointer; text-transform: uppercase; font-size: 12px; } .perf-btn:hover { background: #333; } .perf-btn.secondary { background: #fff; color: #000; border: 1px solid #000; } .perf-btn.secondary:hover { background: #f5f5f5; } .perf-canvas { width: 100%; height: 300px; background: #000; border: 1px solid #ccc; position: relative; overflow: hidden; } .perf-laser { position: absolute; background: #fff; opacity: 0.8; } .perf-laser.beam { height: 2px; box-shadow: 0 0 10px #fff; } .perf-laser.line { width: 1px; box-shadow: 0 0 8px #fff; } .perf-laser.dot { width: 4px; height: 4px; border-radius: 50%; box-shadow: 0 0 15px #fff; } .perf-status { margin-top: 15px; padding: 10px; background: #f0f0f0; border-left: 3px solid #000; font-size: 14px; } .perf-monologue { margin-top: 15px; padding: 15px; background: #f8f8f8; border-left: 3px solid #333; display: none; font-style: italic; line-height: 1.6; } .perf-voice-status { margin-top: 10px; text-align: center; padding: 8px; background: #f0f0f0; font-size: 12px; color: #666; } .perf-voice-status.speaking { background: #e8f5e8; color: #2d5a2d; } .perf-stats { display: flex; gap: 20px; margin: 15px 0; font-size: 14px; } .perf-stat { display: flex; flex-direction: column; } .perf-stat-label { font-size: 11px; text-transform: uppercase; color: #666; } .perf-stat-value { font-size: 18px; font-weight: bold; } @keyframes laser-pulse { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } } @keyframes laser-sweep { 0% { transform: scaleX(0); } 100% { transform: scaleX(1); } } @media (max-width: 768px) { .perf-main { grid-template-columns: 1fr; } .perf-input-section { border-right: none; border-bottom: 1px solid #ddd; padding-bottom: 20px; } } </style> <div class="perf-container"> <div class="perf-header"> <div class="perf-title">Prompt → Performance</div> <div class="perf-subtitle">Transform text into laser lighting with voice performance</div> </div> <div class="perf-main"> <div class="perf-section perf-input-section"> <div class="perf-section-title">Text Input</div> <textarea class="perf-textarea" id="perfInput" placeholder="Enter your creative prompt here... Brilliant laser beams cut through darkness, creating patterns of light and shadow..."></textarea> <div class="perf-controls"> <button class="perf-btn" onclick="createLaserShow()">Create Laser Show</button> <button class="perf-btn" onclick="createMonologue()">Create Performance</button> <button class="perf-btn secondary" onclick="stopAll()">Stop</button> </div> <div class="perf-stats"> <div class="perf-stat"> <div class="perf-stat-label">Words</div> <div class="perf-stat-value" id="perfWordCount">0</div> </div> <div class="perf-stat"> <div class="perf-stat-label">Lasers</div> <div class="perf-stat-value" id="perfLaserCount">0</div> </div> <div class="perf-stat"> <div class="perf-stat-label">Status</div> <div class="perf-stat-value" id="perfStatus">Ready</div> </div> </div> </div> <div class="perf-section perf-output-section"> <div class="perf-section-title">Performance Output</div> <div class="perf-canvas" id="perfCanvas"></div> <div class="perf-monologue" id="perfMonologue"> <strong>Generated Performance:</strong> <div id="perfMonologueText"></div> </div> <div class="perf-voice-status" id="perfVoiceStatus">Voice system ready</div> <div class="perf-status" id="perfStatusDisplay">Ready for input. Enter text to generate performance.</div> </div> </div> </div> <script> let perfCurrentSpeech = null; let perfVoices = []; let perfSelectedVoice = null; let perfProcessing = false; // Initialize voices if (window.speechSynthesis) { speechSynthesis.onvoiceschanged = function() { perfVoices = speechSynthesis.getVoices(); perfSelectedVoice = perfVoices.find(v => v.lang.startsWith('en')) || perfVoices[0]; }; } // Update word count document.getElementById('perfInput').addEventListener('input', function() { const words = this.value.trim().split(/\s+/).filter(w => w.length > 0); document.getElementById('perfWordCount').textContent = words.length; document.getElementById('perfStatusDisplay').textContent = words.length > 0 ? 'Text ready for performance.' : 'Ready for input.'; }); // Create laser effects function createPerfLasers(text) { const canvas = document.getElementById('perfCanvas'); canvas.innerHTML = ''; const words = text.split(/\s+/).filter(w => w.length > 0); const laserCount = Math.min(12, Math.max(3, words.length)); for (let i = 0; i < laserCount; i++) { const laser = document.createElement('div'); laser.className = 'perf-laser'; const types = ['beam', 'line', 'dot']; const type = types[Math.floor(Math.random() * types.length)]; laser.classList.add(type); const x = Math.random() * (canvas.offsetWidth - 50); const y = Math.random() * (canvas.offsetHeight - 50); laser.style.left = x + 'px'; laser.style.top = y + 'px'; if (type === 'beam') { laser.style.width = (60 + Math.random() * 120) + 'px'; } else if (type === 'line') { laser.style.height = (40 + Math.random() * 80) + 'px'; } const hue = Math.random() * 360; laser.style.filter = `hue-rotate(${hue}deg)`; laser.style.animation = `laser-pulse ${2 + Math.random() * 2}s ease-in-out infinite`; laser.style.animationDelay = (Math.random() * 2) + 's'; canvas.appendChild(laser); } return laserCount; } // Generate simple monologue function generatePerfMonologue(text) { const words = text.toLowerCase().split(/\s+/); const keyWords = words.filter(w => w.length > 4).slice(0, 3); let monologue = "In this moment of creation, I witness "; if (keyWords.length > 0) { monologue += `the essence of ${keyWords[0]}. `; } else { monologue += "the power of imagination. "; } monologue += "Light and shadow dance together, creating patterns that speak to the soul. "; if (keyWords.length > 1) { monologue += `Each ${keyWords[1]} becomes a messenger of deeper meaning, `; } monologue += "weaving together the visible and invisible into one magnificent performance. "; if (keyWords.length > 2) { monologue += `The ${keyWords[2]} reminds us that beauty exists in the spaces between certainty and mystery. `; } monologue += "This performance speaks to the very essence of what it means to create, to express, to exist in this universe of infinite possibility."; return monologue; } // Speech function function perfSpeak(text) { if (!window.speechSynthesis) return; if (perfCurrentSpeech) { speechSynthesis.cancel(); } const processedText = text.replace(/\./g, '... ').replace(/,/g, ', '); perfCurrentSpeech = new SpeechSynthesisUtterance(processedText); if (perfSelectedVoice) { perfCurrentSpeech.voice = perfSelectedVoice; } perfCurrentSpeech.volume = 0.8; perfCurrentSpeech.rate = 0.7; perfCurrentSpeech.pitch = 1.0; perfCurrentSpeech.onstart = function() { document.getElementById('perfVoiceStatus').textContent = 'Speaking performance...'; document.getElementById('perfVoiceStatus').className = 'perf-voice-status speaking'; }; perfCurrentSpeech.onend = function() { document.getElementById('perfVoiceStatus').textContent = 'Performance complete'; document.getElementById('perfVoiceStatus').className = 'perf-voice-status'; perfCurrentSpeech = null; }; speechSynthesis.speak(perfCurrentSpeech); } // Create laser show (no voice) function createLaserShow() { const text = document.getElementById('perfInput').value.trim(); if (!text || perfProcessing) return; perfProcessing = true; document.getElementById('perfStatus').textContent = 'Creating'; document.getElementById('perfMonologue').style.display = 'none'; if (perfCurrentSpeech) { speechSynthesis.cancel(); perfCurrentSpeech = null; } const laserCount = createPerfLasers(text); document.getElementById('perfLaserCount').textContent = laserCount; setTimeout(function() { document.getElementById('perfStatus').textContent = 'Active'; document.getElementById('perfStatusDisplay').textContent = `Silent laser show with ${laserCount} effects.`; document.getElementById('perfVoiceStatus').textContent = 'Laser show - visual only'; perfProcessing = false; }, 1000); } // Create full performance function createMonologue() { const text = document.getElementById('perfInput').value.trim(); if (!text || perfProcessing) return; perfProcessing = true; document.getElementById('perfStatus').textContent = 'Creating'; const monologue = generatePerfMonologue(text); document.getElementById('perfMonologueText').textContent = monologue; document.getElementById('perfMonologue').style.display = 'block'; const laserCount = createPerfLasers(text); document.getElementById('perfLaserCount').textContent = laserCount; setTimeout(function() { perfSpeak(monologue); document.getElementById('perfStatus').textContent = 'Active'; document.getElementById('perfStatusDisplay').textContent = `Performance created with ${laserCount} laser effects and voice.`; perfProcessing = false; }, 1500); } // Stop all function stopAll() { if (perfCurrentSpeech) { speechSynthesis.cancel(); perfCurrentSpeech = null; } document.getElementById('perfStatus').textContent = 'Stopped'; document.getElementById('perfVoiceStatus').textContent = 'Stopped'; document.getElementById('perfVoiceStatus').className = 'perf-voice-status'; document.getElementById('perfMonologue').style.display = 'none'; perfProcessing = false; } // Initialize word count document.getElementById('perfInput').dispatchEvent(new Event('input')); </script>