Code Playground

Live HTML/CSS/JS editor with instant preview. Write code, see results immediately.

HTML
CSS
JavaScript
Preview Auto-updates on edit
Console

Get All 40+ Tools — $9.99

Instant access to every premium tool. Or resell them all for $49.99 under your brand.

Get the Bundle — $9.99
SPUNK.CODES

Like this? Get 30 more free tools in your inbox.

'; var frame = previewFrame; frame.srcdoc = doc; // Autosave autosave(); }; // --- Debounced auto-run --- function scheduleRun() { clearTimeout(debounceTimer); debounceTimer = setTimeout(function() { runCode(); }, 400); } editorHtml.addEventListener('input', scheduleRun); editorCss.addEventListener('input', scheduleRun); editorJs.addEventListener('input', scheduleRun); // Ctrl+Enter to run immediately document.addEventListener('keydown', function(e) { if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { e.preventDefault(); runCode(); } }); // Tab key in editors [editorHtml, editorCss, editorJs].forEach(function(el) { el.addEventListener('keydown', function(e) { if (e.key === 'Tab') { e.preventDefault(); var s = el.selectionStart, end = el.selectionEnd; el.value = el.value.substring(0, s) + ' ' + el.value.substring(end); el.selectionStart = el.selectionEnd = s + 2; } }); }); // --- Console --- window.addEventListener('message', function(e) { if (e.data && e.data.type === 'console') { var level = e.data.level || 'log'; var text = (e.data.args || []).join(' '); appendConsole(text, level); } }); function appendConsole(text, level) { var div = document.createElement('div'); div.className = 'log-line ' + (level || 'log'); var prefix = ''; if (level === 'error') prefix = '[error] '; else if (level === 'warn') prefix = '[warn] '; else if (level === 'info') prefix = '[info] '; div.textContent = prefix + text; consoleOutput.appendChild(div); consoleOutput.scrollTop = consoleOutput.scrollHeight; logCount++; consoleBadge.textContent = logCount; consoleBadge.style.display = 'inline'; // Expand console if collapsed consoleArea.classList.remove('console-collapsed'); } function clearConsoleInternal() { consoleOutput.innerHTML = ''; logCount = 0; consoleBadge.style.display = 'none'; } window.clearConsole = function() { clearConsoleInternal(); }; window.toggleConsole = function() { consoleArea.classList.toggle('console-collapsed'); }; // --- Reset --- window.resetEditors = function() { if ((editorHtml.value.trim() || editorCss.value.trim() || editorJs.value.trim()) && !confirm('Reset all editors? This cannot be undone.')) return; editorHtml.value = ''; editorCss.value = ''; editorJs.value = ''; clearConsoleInternal(); previewFrame.srcdoc = ''; localStorage.removeItem('playground_html'); localStorage.removeItem('playground_css'); localStorage.removeItem('playground_js'); switchTab('html'); showToast('Editors reset'); gtag('event', 'editor_reset', { event_category: 'playground' }); }; // --- Copy all code --- window.copyAllCode = function() { var combined = buildFullHTML(); navigator.clipboard.writeText(combined).then(function() { showToast('Code copied to clipboard'); incrementUsage(); }).catch(function() { showToast('Failed to copy'); }); gtag('event', 'copy_code', { event_category: 'playground' }); }; // --- Download as HTML --- window.downloadAsHTML = function() { var combined = buildFullHTML(); var blob = new Blob([combined], { type: 'text/html' }); var url = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = url; a.download = 'playground-export.html'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); showToast('Downloaded playground-export.html'); incrementUsage(); gtag('event', 'download_html', { event_category: 'playground' }); }; function buildFullHTML() { return '\n\n\n\n\nCode Playground Export\n\n\n\n' + editorHtml.value + '\n \n'; } // --- Autosave / restore --- function autosave() { localStorage.setItem('playground_html', editorHtml.value); localStorage.setItem('playground_css', editorCss.value); localStorage.setItem('playground_js', editorJs.value); } function restoreDraft() { var h = localStorage.getItem('playground_html'); var c = localStorage.getItem('playground_css'); var j = localStorage.getItem('playground_js'); if (h !== null || c !== null || j !== null) { editorHtml.value = h || ''; editorCss.value = c || ''; editorJs.value = j || ''; if ((h && h.trim()) || (c && c.trim()) || (j && j.trim())) { runCode(); } } } restoreDraft(); // --- Resizable panels --- (function() { var dragging = false; var startPos = 0; var startSize = 0; resizeHandle.addEventListener('mousedown', function(e) { e.preventDefault(); dragging = true; resizeHandle.classList.add('dragging'); if (currentLayout === 'vertical') { startPos = e.clientX; startSize = editorsPane.offsetWidth; } else { startPos = e.clientY; startSize = editorsPane.offsetHeight; } document.body.style.cursor = currentLayout === 'vertical' ? 'col-resize' : 'row-resize'; document.body.style.userSelect = 'none'; }); document.addEventListener('mousemove', function(e) { if (!dragging) return; if (currentLayout === 'vertical') { var delta = e.clientX - startPos; var newW = Math.max(200, Math.min(startSize + delta, playgroundWrap.offsetWidth - 200)); editorsPane.style.width = newW + 'px'; editorsPane.style.flexShrink = '0'; } else { var delta = e.clientY - startPos; var newH = Math.max(120, Math.min(startSize + delta, playgroundWrap.offsetHeight - 120)); editorsPane.style.height = newH + 'px'; editorsPane.style.flexShrink = '0'; } }); document.addEventListener('mouseup', function() { if (dragging) { dragging = false; resizeHandle.classList.remove('dragging'); document.body.style.cursor = ''; document.body.style.userSelect = ''; } }); // Touch support resizeHandle.addEventListener('touchstart', function(e) { var touch = e.touches[0]; dragging = true; resizeHandle.classList.add('dragging'); if (currentLayout === 'vertical') { startPos = touch.clientX; startSize = editorsPane.offsetWidth; } else { startPos = touch.clientY; startSize = editorsPane.offsetHeight; } }, { passive: true }); document.addEventListener('touchmove', function(e) { if (!dragging) return; var touch = e.touches[0]; if (currentLayout === 'vertical') { var delta = touch.clientX - startPos; var newW = Math.max(200, Math.min(startSize + delta, playgroundWrap.offsetWidth - 200)); editorsPane.style.width = newW + 'px'; editorsPane.style.flexShrink = '0'; } else { var delta = touch.clientY - startPos; var newH = Math.max(120, Math.min(startSize + delta, playgroundWrap.offsetHeight - 120)); editorsPane.style.height = newH + 'px'; editorsPane.style.flexShrink = '0'; } }, { passive: true }); document.addEventListener('touchend', function() { if (dragging) { dragging = false; resizeHandle.classList.remove('dragging'); } }); })(); // --- Toast --- window.showToast = function(msg) { var toast = document.getElementById('toast'); toast.textContent = msg; toast.classList.add('show'); setTimeout(function() { toast.classList.remove('show'); }, 2500); }; // --- Usage counter & email bar --- var TOOL_KEY = 'spunkart_playground_uses'; var BAR_KEY = 'sa_bar_dismissed_code-playground'; var usageCount = parseInt(localStorage.getItem(TOOL_KEY)) || 0; var badge = document.getElementById('usageBadge'); function updateBadge() { badge.textContent = '\uD83D\uDD25 ' + usageCount + ' project' + (usageCount !== 1 ? 's' : '') + ' created'; } updateBadge(); function incrementUsage() { usageCount++; localStorage.setItem(TOOL_KEY, usageCount); updateBadge(); if (usageCount >= 2 && !localStorage.getItem(BAR_KEY)) { document.getElementById('saEmailBar').classList.add('show'); } } window.saDismissBar = function() { document.getElementById('saEmailBar').classList.remove('show'); localStorage.setItem(BAR_KEY, '1'); }; window.saSubmitEmail = function() { var email = document.getElementById('saBarEmail').value; if (!email || email.indexOf('@') === -1) { alert('Please enter a valid email.'); return; } localStorage.setItem('sa_subscriber_email', email); localStorage.setItem(BAR_KEY, '1'); window.open('https://embeds.beehiiv.com/cae41704-7588-4c50-83f1-11f5b4a0585f?email=' + encodeURIComponent(email), '_blank'); document.getElementById('saEmailBar').classList.remove('show'); var btn = document.querySelector('.sa-sub-btn'); btn.textContent = 'Subscribed!'; btn.style.background = '#10b981'; }; // Show email bar if already past threshold and not dismissed if (usageCount >= 2 && !localStorage.getItem(BAR_KEY)) { document.getElementById('saEmailBar').classList.add('show'); } })();