[SAVE] Export
[DEL] Clear
[RND] Random
[VIEW] Preview
[GRID] Grid
[DISK] Save
[LOAD] Load
-= DRAG ELEMENTS FROM THE SIDEBAR TO BUILD YOUR DIGITAL SHRINE =-

Welcome to the infinite canvas of cyber-expression...
[PROP] ELEMENT PROPERTIES
_
[]

-= SELECT AN ELEMENT TO EDIT ITS PROPERTIES =-

PAGE SETTINGS

Title:
BG Color:
BG Image:
BG Pattern:
Cursor:
-= Digital reality matrix loaded - begin your cyber-creation ritual =- Elements: 0 | Canvas: ∞
Cut
Copy
Paste
Duplicate
Bring to Front
Send to Back
Delete
`; // Create and download file const blob = new Blob([html], { type: 'text/html' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}.html`; a.click(); URL.revokeObjectURL(url); updateStatus('-= Page exported to the physical realm =-'); } function clearCanvas() { if (confirm('-= Are you sure you want to dissolve all elements back into the digital void? This ritual cannot be undone. =-')) { canvas.innerHTML = '
-= DRAG ELEMENTS FROM THE SIDEBAR TO BUILD YOUR DIGITAL SHRINE =-

Welcome to the infinite canvas of cyber-expression...
'; selectedElement = null; document.getElementById('properties-content').innerHTML = '

-= SELECT AN ELEMENT TO EDIT ITS PROPERTIES =-

'; updateElementCount(); updateStatus('-= Canvas purged - reality matrix reset =-'); } } function randomizeElements() { const elements = canvas.querySelectorAll('.dropped-element'); const colors = ['#ff6b6b', '#4ecdc4', '#45b7d1', '#f9ca24', '#f0932b', '#eb4d4b', '#6c5ce7', '#a29bfe', '#fd79a8', '#fdcb6e']; elements.forEach(element => { const maxX = Math.max(0, canvas.clientWidth - parseInt(element.style.width) - 40); const maxY = Math.max(0, canvas.clientHeight - parseInt(element.style.height) - 40); element.style.left = Math.random() * maxX + 'px'; element.style.top = Math.random() * maxY + 'px'; element.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; element.style.transform = `rotate(${(Math.random() - 0.5) * 30}deg)`; }); updateStatus('-= Elements scattered through the digital chaos field =-'); } function showPreview() { const previewWindow = window.open('', '_blank', 'width=1024,height=768'); previewWindow.document.write(generatePreviewHTML()); previewWindow.document.close(); } function generatePreviewHTML() { const title = document.getElementById('page-title').value; const bgColor = document.getElementById('page-bg').value; const bgImage = document.getElementById('page-bg-image').value; let html = ` ${title}
`; const elements = canvas.querySelectorAll('.dropped-element'); elements.forEach(element => { let content = element.innerHTML.replace(/
<\/div>/, ''); const styles = `position: absolute; left: ${element.style.left}; top: ${element.style.top}; width: ${element.style.width}; height: ${element.style.height}; background-color: ${element.style.backgroundColor}; color: ${element.style.color}; font-family: ${element.style.fontFamily}; font-size: ${element.style.fontSize}; border: ${element.style.border}; opacity: ${element.style.opacity}; transform: ${element.style.transform}; box-shadow: ${element.style.boxShadow}; z-index: ${element.style.zIndex};`; html += `
${content}
`; }); html += '
'; return html; } function saveProject() { const projectData = { title: document.getElementById('page-title').value, background: { color: document.getElementById('page-bg').value, image: document.getElementById('page-bg-image').value, pattern: document.getElementById('page-bg-pattern').value }, cursor: document.getElementById('page-cursor').value, elements: [] }; const elements = canvas.querySelectorAll('.dropped-element'); elements.forEach(element => { const elementData = { id: element.id, type: element.dataset.type, position: { x: element.style.left, y: element.style.top }, size: { width: element.style.width, height: element.style.height }, styles: { backgroundColor: element.style.backgroundColor, color: element.style.color, fontFamily: element.style.fontFamily, fontSize: element.style.fontSize, border: element.style.border, opacity: element.style.opacity, transform: element.style.transform, boxShadow: element.style.boxShadow, zIndex: element.style.zIndex }, content: element.innerHTML.replace(/
<\/div>/, ''), classes: Array.from(element.classList) }; projectData.elements.push(elementData); }); const blob = new Blob([JSON.stringify(projectData, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `${projectData.title.replace(/[^a-z0-9]/gi, '_').toLowerCase()}_project.json`; a.click(); URL.revokeObjectURL(url); updateStatus('-= Project saved to the data archives =-'); } function loadProject() { const input = document.createElement('input'); input.type = 'file'; input.accept = '.json'; input.onchange = (e) => { const file = e.target.files[0]; if (file) { const reader = new FileReader(); reader.onload = (e) => { try { const projectData = JSON.parse(e.target.result); loadProjectData(projectData); } catch (error) { alert('-= Error loading project file: ' + error.message + ' =-'); } }; reader.readAsText(file); } }; input.click(); } function loadProjectData(projectData) { // Clear current canvas clearCanvas(); // Load page settings document.getElementById('page-title').value = projectData.title || 'Loaded Project'; document.getElementById('page-bg').value = projectData.background?.color || '#ffffff'; document.getElementById('page-bg-image').value = projectData.background?.image || ''; document.getElementById('page-bg-pattern').value = projectData.background?.pattern || 'none'; document.getElementById('page-cursor').value = projectData.cursor || 'default'; updatePageTitle(); updatePageBackground(); updatePageCursor(); // Load elements projectData.elements.forEach(elementData => { const element = document.createElement('div'); element.className = 'dropped-element'; element.id = elementData.id || `element-${++elementCounter}`; element.dataset.type = elementData.type; // Set position and size element.style.left = elementData.position.x; element.style.top = elementData.position.y; element.style.width = elementData.size.width; element.style.height = elementData.size.height; // Apply styles Object.assign(element.style, elementData.styles); // Set content element.innerHTML = elementData.content; // Add resize handle const resizeHandle = document.createElement('div'); resizeHandle.className = 'resize-handle'; element.appendChild(resizeHandle); // Add classes elementData.classes.forEach(cls => { if (cls !== 'dropped-element') { element.classList.add(cls); } }); // Add event listeners element.addEventListener('click', (e) => { e.stopPropagation(); selectElement(element); }); element.addEventListener('contextmenu', (e) => { e.preventDefault(); selectElement(element); showContextMenu(e.clientX, e.clientY); }); element.addEventListener('mousedown', startDrag); resizeHandle.addEventListener('mousedown', startResize); canvas.appendChild(element); }); updateElementCount(); updateStatus('-= Project materialized from the data archives =-'); } function loadTemplate(templateName) { // Use the confirm-less version for templates canvas.innerHTML = '
-= DRAG ELEMENTS FROM THE SIDEBAR TO BUILD YOUR DIGITAL SHRINE =-

Welcome to the infinite canvas of cyber-expression...
'; selectedElement = null; document.getElementById('properties-content').innerHTML = '

-= SELECT AN ELEMENT TO EDIT ITS PROPERTIES =-

'; switch(templateName) { case 'personal': createElement('header', 200, 50); createElement('profile', 450, 50); createElement('navbar', 50, 20); createElement('paragraph', 50, 150); createElement('social-link', 50, 280); break; case 'portfolio': createElement('header', 250, 30); createElement('navbar', 50, 80); createElement('gallery', 50, 150); createElement('sidebar', 300, 150); createElement('contact-form', 520, 150); break; case 'blog': createElement('header', 200, 30); createElement('navbar', 50, 80); createElement('paragraph', 50, 130); createElement('quote', 50, 280); createElement('sidebar', 500, 130); break; case 'retro': createElement('marquee', 50, 20); createElement('header', 50, 80); createElement('gif-box', 50, 140); createElement('visitor-counter', 250, 140); createElement('guestbook', 400, 140); createElement('divider', 50, 320); break; case 'geocities': createElement('marquee', 50, 20); createElement('header', 50, 70); createElement('gif-box', 50, 130); createElement('visitor-counter', 250, 130); createElement('ascii-art', 400, 130); createElement('link', 50, 250); createElement('email-link', 200, 250); break; case 'cyberpunk': createElement('typewriter', 50, 50); createElement('clock', 500, 50); createElement('ascii-art', 50, 120); createElement('container', 200, 120); createElement('pattern-bg', 50, 280); break; case 'academic': createElement('header', 200, 40); createElement('navbar', 50, 90); createElement('paragraph', 50, 140); createElement('quote', 50, 260); createElement('contact-form', 400, 140); break; case 'creative': createElement('ascii-art', 50, 50); createElement('gif-box', 200, 50); createElement('pattern-bg', 350, 50); createElement('border-box', 50, 200); createElement('marquee', 300, 200); break; } updateStatus(`-= ${templateName.toUpperCase()} template manifested =-`); } // Click outside to deselect canvas.addEventListener('click', (e) => { if (e.target === canvas) { if (selectedElement) { selectedElement.classList.remove('selected'); selectedElement = null; document.getElementById('properties-content').innerHTML = '

-= SELECT AN ELEMENT TO EDIT ITS PROPERTIES =-

'; } hideContextMenu(); } }); // Hide context menu on scroll or resize document.addEventListener('scroll', hideContextMenu); window.addEventListener('resize', hideContextMenu); // Initialize drag and drop for dynamically created elements function initializeElementDragDrop() { document.querySelectorAll('.element-item').forEach(item => { item.addEventListener('dragstart', (e) => { e.dataTransfer.setData('text/plain', e.target.dataset.type); e.target.classList.add('dragging'); }); item.addEventListener('dragend', (e) => { e.target.classList.remove('dragging'); }); }); } // Initialize updateElementCount(); updateStatus('-= DragKit reality matrix loaded - begin your digital manifestation ritual =-'); initializeElementDragDrop();