📜
properties.js
Back
📝 Javascript ⚡ Executable Ctrl+S: Save • Ctrl+R: Run • Ctrl+F: Find
// Settings Configuration const SETTINGS = { animations: { panelTransition: 400, selectionDelay: 200, deleteAnimation: 300, slideInDuration: 400, hoverTransition: 300 }, panel: { width: 400, headerHeight: 85, contentPadding: 30, scrollbarWidth: 8 }, sliders: { width: { px: { min: 80, max: 800, default: 120 }, percent: { min: 5, max: 100, default: 100 } }, height: { px: { min: 60, max: 600, default: 80 }, percent: { min: 5, max: 100, default: 15 } }, padding: { px: { min: 0, max: 100, default: 20 }, percent: { min: 0, max: 10, default: 2 } }, position: { px: { min: 0, maxOffset: 80, default: 100 }, percent: { min: 0, max: 95, default: 10 } } }, visual: { borderRadius: 12, blurIntensity: 10, shadowIntensity: 0.2, hoverLift: 2, selectionGlow: 20 }, colors: [ 'linear-gradient(135deg, #667eea, #764ba2)', 'linear-gradient(135deg, #f093fb, #f5576c)', 'linear-gradient(135deg, #4facfe, #00f2fe)', 'linear-gradient(135deg, #43e97b, #38f9d7)', 'linear-gradient(135deg, #fa709a, #fee140)', 'linear-gradient(135deg, #a8edea, #fed6e3)', 'linear-gradient(135deg, #ff9a9e, #fecfef)', 'linear-gradient(135deg, #ffecd2, #fcb69f)', 'linear-gradient(135deg, #89f7fe, #66a6ff)', 'linear-gradient(135deg, #fdbb2d, #22c1c3)', 'linear-gradient(135deg, #ff758c, #ff7eb3)', 'linear-gradient(135deg, #84fab0, #8fd3f4)', 'linear-gradient(135deg, #a18cd1, #fbc2eb)', 'linear-gradient(135deg, #fad0c4, #ffd1ff)', 'linear-gradient(135deg, #ff9a8b, #a8e6cf)', 'linear-gradient(135deg, #d299c2, #fef9d7)' ], sortable: { animation: 150, delay: 100, delayOnTouchStart: true, ghostOpacity: 0.4, dragRotation: 5, dragShadow: '0 10px 30px rgba(0, 0, 0, 0.3)' }, drag: { threshold: 5, timeThreshold: 150, clickTimeLimit: 200, zIndexActive: 1001 }, typography: { headerSize: 18, sectionSize: 15, labelSize: 13, inputSize: 14, displaySize: 11 }, layout: { toolbarSpacing: 20, canvasPadding: 20, flowGap: 15, controlsMaxWidth: 280, minDivWidth: 120, minDivHeight: 80 } }; // Export settings globally window.LAYOUT_SETTINGS = SETTINGS; // Global state variables - shared across files window.AppState = { currentUnit: '%', selectedDiv: null, divProperties: new Map(), colors: SETTINGS.colors }; function initColorGrid() { const colorGrid = document.getElementById('colorGrid'); if (!colorGrid) { console.error('Color grid element not found!'); return; } colorGrid.innerHTML = ''; window.AppState.colors.forEach((color, index) => { const colorOption = document.createElement('div'); colorOption.className = 'color-option'; colorOption.style.background = color; colorOption.onclick = () => changeColor(index); colorGrid.appendChild(colorOption); }); } function setUnit(unit) { window.AppState.currentUnit = unit; document.getElementById('pxBtn').classList.toggle('active', unit === 'px'); document.getElementById('percentBtn').classList.toggle('active', unit === '%'); updateSliderRanges(); if (window.AppState.selectedDiv) { updateSliderValues(); } } function updateSliderRanges() { const widthSlider = document.getElementById('widthSlider'); const heightSlider = document.getElementById('heightSlider'); const xSlider = document.getElementById('xSlider'); const ySlider = document.getElementById('ySlider'); const paddingSlider = document.getElementById('paddingSlider'); if (window.AppState.currentUnit === 'px') { const w = SETTINGS.sliders.width.px; const h = SETTINGS.sliders.height.px; const p = SETTINGS.sliders.padding.px; const pos = SETTINGS.sliders.position.px; widthSlider.min = w.min; widthSlider.max = w.max; heightSlider.min = h.min; heightSlider.max = h.max; xSlider.min = pos.min; xSlider.max = window.innerWidth - pos.maxOffset; ySlider.min = pos.min; ySlider.max = window.innerHeight - pos.maxOffset; paddingSlider.min = p.min; paddingSlider.max = p.max; } else { const w = SETTINGS.sliders.width.percent; const h = SETTINGS.sliders.height.percent; const p = SETTINGS.sliders.padding.percent; const pos = SETTINGS.sliders.position.percent; widthSlider.min = w.min; widthSlider.max = w.max; heightSlider.min = h.min; heightSlider.max = h.max; xSlider.min = pos.min; xSlider.max = pos.max; ySlider.min = pos.min; ySlider.max = pos.max; paddingSlider.min = p.min; paddingSlider.max = p.max; } } function updateSliderValues() { if (!window.AppState.selectedDiv) return; const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); if (!props) return; let widthValue, heightValue, paddingValue; if (window.AppState.currentUnit === 'px') { widthValue = props.width.px; heightValue = props.height.px; paddingValue = props.padding.px; } else { widthValue = props.width.percent; heightValue = props.height.percent; paddingValue = props.padding.percent; } document.getElementById('widthSlider').value = widthValue; document.getElementById('heightSlider').value = heightValue; document.getElementById('paddingSlider').value = paddingValue; document.getElementById('widthDisplay').textContent = Math.round(widthValue * 10) / 10 + window.AppState.currentUnit; document.getElementById('heightDisplay').textContent = Math.round(heightValue * 10) / 10 + window.AppState.currentUnit; document.getElementById('paddingDisplay').textContent = Math.round(paddingValue * 10) / 10 + window.AppState.currentUnit; document.getElementById('divNameInput').value = props.name || ''; if (props.positioning === 'absolute') { updatePositionSliders(); } } function updatePositionSliders() { if (!window.AppState.selectedDiv || !window.AppState.selectedDiv.classList.contains('absolute')) return; const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); let xValue, yValue; if (window.AppState.currentUnit === 'px') { xValue = props.x.px; yValue = props.y.px; } else { xValue = props.x.percent; yValue = props.y.percent; } document.getElementById('xSlider').value = xValue; document.getElementById('ySlider').value = yValue; document.getElementById('xDisplay').textContent = Math.round(xValue * 10) / 10 + window.AppState.currentUnit; document.getElementById('yDisplay').textContent = Math.round(yValue * 10) / 10 + window.AppState.currentUnit; } function closeProperties() { if (window.AppState.selectedDiv) { window.AppState.selectedDiv.classList.remove('selected'); window.AppState.selectedDiv = null; } document.getElementById('propertiesPanel').classList.remove('visible'); } function updateColorSelection(div) { const colorOptions = document.querySelectorAll('.color-option'); colorOptions.forEach(option => option.classList.remove('selected')); const currentBg = div.style.background; window.AppState.colors.forEach((color, index) => { if (currentBg === color) { colorOptions[index].classList.add('selected'); } }); } function updateDivName() { if (!window.AppState.selectedDiv) return; const newName = document.getElementById('divNameInput').value; const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); props.name = newName; const textSpan = window.AppState.selectedDiv.querySelector('span'); if (textSpan) { if (newName.trim()) { textSpan.textContent = newName; } else { const divNumber = divId.split('-')[1]; textSpan.textContent = `Div ${divNumber}`; } } } function updatePadding() { if (!window.AppState.selectedDiv) return; const padding = parseFloat(document.getElementById('paddingSlider').value); const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); let actualPadding; if (window.AppState.currentUnit === 'px') { actualPadding = padding; props.padding.px = padding; props.padding.percent = (padding / Math.min(window.innerWidth, window.innerHeight)) * 100; } else { actualPadding = (padding / 100) * Math.min(window.innerWidth, window.innerHeight); props.padding.percent = padding; props.padding.px = actualPadding; } window.AppState.selectedDiv.style.padding = actualPadding + 'px'; document.getElementById('paddingDisplay').textContent = Math.round(padding * 10) / 10 + window.AppState.currentUnit; } function updateSize() { if (!window.AppState.selectedDiv) return; const width = parseFloat(document.getElementById('widthSlider').value); const height = parseFloat(document.getElementById('heightSlider').value); const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); let actualWidth, actualHeight; if (window.AppState.currentUnit === 'px') { actualWidth = width; actualHeight = height; const availableWidth = window.innerWidth - 40; props.width.px = width; props.width.percent = (width / availableWidth) * 100; props.height.px = height; props.height.percent = (height / window.innerHeight) * 100; } else { const availableWidth = window.innerWidth - 40; actualWidth = (width / 100) * availableWidth; actualHeight = (height / 100) * window.innerHeight; props.width.percent = width; props.width.px = actualWidth; props.height.percent = height; props.height.px = actualHeight; } window.AppState.selectedDiv.style.width = actualWidth + 'px'; window.AppState.selectedDiv.style.height = actualHeight + 'px'; document.getElementById('widthDisplay').textContent = Math.round(width * 10) / 10 + window.AppState.currentUnit; document.getElementById('heightDisplay').textContent = Math.round(height * 10) / 10 + window.AppState.currentUnit; } function updatePosition() { if (!window.AppState.selectedDiv || !window.AppState.selectedDiv.classList.contains('absolute')) return; const x = parseFloat(document.getElementById('xSlider').value); const y = parseFloat(document.getElementById('ySlider').value); const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); let actualX, actualY; if (window.AppState.currentUnit === 'px') { actualX = x; actualY = y; props.x.px = x; props.x.percent = (x / window.innerWidth) * 100; props.y.px = y; props.y.percent = (y / window.innerHeight) * 100; } else { actualX = (x / 100) * window.innerWidth; actualY = (y / 100) * window.innerHeight; props.x.percent = x; props.x.px = actualX; props.y.percent = y; props.y.px = actualY; } window.AppState.selectedDiv.style.left = actualX + 'px'; window.AppState.selectedDiv.style.top = actualY + 'px'; document.getElementById('xDisplay').textContent = Math.round(x * 10) / 10 + window.AppState.currentUnit; document.getElementById('yDisplay').textContent = Math.round(y * 10) / 10 + window.AppState.currentUnit; } function setLayoutType(type) { if (!window.AppState.selectedDiv) return; const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); const layoutControls = document.getElementById('layoutControls'); const layoutLabel = document.getElementById('layoutLabel'); // Update button states document.getElementById('noneBtn').classList.toggle('active', type === 'none'); document.getElementById('columnsBtn').classList.toggle('active', type === 'columns'); document.getElementById('rowsBtn').classList.toggle('active', type === 'rows'); if (type === 'none') { layoutControls.style.display = 'none'; clearLayout(); props.layoutType = 'none'; props.layoutCount = 0; } else { layoutControls.style.display = 'block'; layoutLabel.textContent = type === 'columns' ? 'Columns' : 'Rows'; props.layoutType = type; props.layoutCount = parseInt(document.getElementById('layoutSlider').value); updateLayout(); } } function clearLayout() { if (!window.AppState.selectedDiv) return; // Remove all layout children const layoutChildren = window.AppState.selectedDiv.querySelectorAll('.layout-child'); layoutChildren.forEach(child => child.remove()); // Reset div styles window.AppState.selectedDiv.style.display = 'flex'; window.AppState.selectedDiv.style.flexDirection = ''; window.AppState.selectedDiv.style.gap = ''; // Restore original content const span = window.AppState.selectedDiv.querySelector('span'); if (span) { span.style.display = 'block'; } } function updateLayout() { if (!window.AppState.selectedDiv) return; const divId = window.AppState.selectedDiv.id; const props = window.AppState.divProperties.get(divId); const count = parseInt(document.getElementById('layoutSlider').value); const type = props.layoutType; if (!type || type === 'none') return; // Update display document.getElementById('layoutDisplay').textContent = count; props.layoutCount = count; // Clear existing layout children const existingChildren = window.AppState.selectedDiv.querySelectorAll('.layout-child'); existingChildren.forEach(child => child.remove()); // Hide the original span content when we have layout const span = window.AppState.selectedDiv.querySelector('span'); if (span) { span.style.display = 'none'; } // Set up container styles window.AppState.selectedDiv.style.display = 'flex'; window.AppState.selectedDiv.style.flexDirection = type === 'columns' ? 'row' : 'column'; window.AppState.selectedDiv.style.gap = '2px'; window.AppState.selectedDiv.style.padding = '2px'; // Create layout children for (let i = 0; i < count; i++) { const child = document.createElement('div'); child.className = 'layout-child'; child.style.flex = '1'; child.style.border = '1px solid rgba(255, 255, 255, 0.3)'; child.style.borderRadius = '4px'; child.style.minHeight = type === 'columns' ? '30px' : '20px'; child.style.minWidth = type === 'rows' ? '30px' : '20px'; child.style.background = 'transparent'; child.style.display = 'flex'; child.style.alignItems = 'center'; child.style.justifyContent = 'center'; child.style.fontSize = '10px'; child.style.color = 'rgba(255, 255, 255, 0.5)'; child.textContent = `${type === 'columns' ? 'Col' : 'Row'} ${i + 1}`; window.AppState.selectedDiv.appendChild(child); } } function changeColor(colorIndex) { if (!window.AppState.selectedDiv) return; window.AppState.selectedDiv.style.background = window.AppState.colors[colorIndex]; const colorOptions = document.querySelectorAll('.color-option'); colorOptions.forEach(option => option.classList.remove('selected')); colorOptions[colorIndex].classList.add('selected'); } // Export functions to global scope window.setUnit = setUnit; window.closeProperties = closeProperties; window.updateDivName = updateDivName; window.updatePadding = updatePadding; window.updateSize = updateSize; window.updatePosition = updatePosition; window.changeColor = changeColor; window.initColorGrid = initColorGrid; window.updateColorSelection = updateColorSelection; window.updateSliderRanges = updateSliderRanges; window.updateSliderValues = updateSliderValues; window.updatePositionSliders = updatePositionSliders; window.setLayoutType = setLayoutType; window.updateLayout = updateLayout;