// 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 variables
const colors = SETTINGS.colors;
let currentUnit = '%';
let selectedDiv = null;
const divProperties = new Map();
function initColorGrid() {
const colorGrid = document.getElementById('colorGrid');
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) {
currentUnit = unit;
document.getElementById('pxBtn').classList.toggle('active', unit === 'px');
document.getElementById('percentBtn').classList.toggle('active', unit === '%');
updateSliderRanges();
if (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 (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 (!selectedDiv) return;
const divId = selectedDiv.id;
const props = divProperties.get(divId);
if (!props) return;
let widthValue, heightValue, paddingValue;
if (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 + currentUnit;
document.getElementById('heightDisplay').textContent = Math.round(heightValue * 10) / 10 + currentUnit;
document.getElementById('paddingDisplay').textContent = Math.round(paddingValue * 10) / 10 + currentUnit;
document.getElementById('divNameInput').value = props.name || '';
if (props.positioning === 'absolute') {
updatePositionSliders();
}
}
function updatePositionSliders() {
if (!selectedDiv || !selectedDiv.classList.contains('absolute')) return;
const divId = selectedDiv.id;
const props = divProperties.get(divId);
let xValue, yValue;
if (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 + currentUnit;
document.getElementById('yDisplay').textContent = Math.round(yValue * 10) / 10 + currentUnit;
}
function closeProperties() {
if (selectedDiv) {
selectedDiv.classList.remove('selected');
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;
colors.forEach((color, index) => {
if (currentBg === color) {
colorOptions[index].classList.add('selected');
}
});
}
function updateDivName() {
if (!selectedDiv) return;
const newName = document.getElementById('divNameInput').value;
const divId = selectedDiv.id;
const props = divProperties.get(divId);
props.name = newName;
const textSpan = selectedDiv.querySelector('span');
if (textSpan) {
if (newName.trim()) {
textSpan.textContent = newName;
} else {
const divNumber = divId.split('-')[1];
textSpan.textContent = `Div ${divNumber}`;
}
}
}
function updatePadding() {
if (!selectedDiv) return;
const padding = parseFloat(document.getElementById('paddingSlider').value);
const divId = selectedDiv.id;
const props = divProperties.get(divId);
let actualPadding;
if (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;
}
selectedDiv.style.padding = actualPadding + 'px';
document.getElementById('paddingDisplay').textContent = Math.round(padding * 10) / 10 + currentUnit;
}
function updateSize() {
if (!selectedDiv) return;
const width = parseFloat(document.getElementById('widthSlider').value);
const height = parseFloat(document.getElementById('heightSlider').value);
const divId = selectedDiv.id;
const props = divProperties.get(divId);
let actualWidth, actualHeight;
if (currentUnit === 'px') {
actualWidth = width;
actualHeight = height;
props.width.px = width;
props.width.percent = (width / window.innerWidth) * 100;
props.height.px = height;
props.height.percent = (height / window.innerHeight) * 100;
} else {
actualWidth = (width / 100) * window.innerWidth;
actualHeight = (height / 100) * window.innerHeight;
props.width.percent = width;
props.width.px = actualWidth;
props.height.percent = height;
props.height.px = actualHeight;
}
selectedDiv.style.width = actualWidth + 'px';
selectedDiv.style.height = actualHeight + 'px';
document.getElementById('widthDisplay').textContent = Math.round(width * 10) / 10 + currentUnit;
document.getElementById('heightDisplay').textContent = Math.round(height * 10) / 10 + currentUnit;
}
function updatePosition() {
if (!selectedDiv || !selectedDiv.classList.contains('absolute')) return;
const x = parseFloat(document.getElementById('xSlider').value);
const y = parseFloat(document.getElementById('ySlider').value);
const divId = selectedDiv.id;
const props = divProperties.get(divId);
let actualX, actualY;
if (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;
}
selectedDiv.style.left = actualX + 'px';
selectedDiv.style.top = actualY + 'px';
document.getElementById('xDisplay').textContent = Math.round(x * 10) / 10 + currentUnit;
document.getElementById('yDisplay').textContent = Math.round(y * 10) / 10 + currentUnit;
}
function changeColor(colorIndex) {
if (!selectedDiv) return;
selectedDiv.style.background = colors[colorIndex];
const colorOptions = document.querySelectorAll('.color-option');
colorOptions.forEach(option => option.classList.remove('selected'));
colorOptions[colorIndex].classList.add('selected');
}
// Expose necessary functions and variables 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.divProperties = divProperties;
window.currentUnit = currentUnit;
window.selectedDiv = selectedDiv;
window.initColorGrid = initColorGrid;
window.updateColorSelection = updateColorSelection;