diff --git a/public/index.html b/public/index.html index 5a0ecbb..6723d81 100644 --- a/public/index.html +++ b/public/index.html @@ -289,7 +289,7 @@ window.dispatchEvent(new Event('tiptap-loaded')); .list-item-expand { font-size: 12px; color: var(--text-hint); cursor: pointer; margin-left: 8px; white-space: nowrap; } .list-item-expand:hover { color: var(--accent); } - .mood-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 16px; } + .mood-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px; } .mood-card { position: relative; border-radius: 10px; overflow: hidden; background: var(--bg-alt); border: 1px solid var(--border); } .mood-card-img { width: 100%; aspect-ratio: 1; background-size: cover; background-position: center; cursor: pointer; background-color: var(--bg-alt); display: flex; align-items: center; justify-content: center; user-select: none; } .mood-card-img.has-image { cursor: grab; } @@ -1222,7 +1222,9 @@ function renderMoodboard() { const hasImg = !!item.image; imgDiv.className = 'mood-card-img' + (hasImg ? ' has-image' : ' empty'); if (hasImg) { + const zoom = item.zoom ?? 100; imgDiv.style.backgroundImage = `url(${item.image})`; + imgDiv.style.backgroundSize = `${zoom}%`; imgDiv.style.backgroundPosition = `${item.posX ?? 50}% ${item.posY ?? 50}%`; } if (!hasImg) { @@ -1235,8 +1237,9 @@ function renderMoodboard() { if (!didDrag && Math.abs(dx) < 4 && Math.abs(dy) < 4) return; didDrag = true; const rect = imgDiv.getBoundingClientRect(); - item.posX = Math.max(0, Math.min(100, startPosX + (dx / rect.width) * -80)); - item.posY = Math.max(0, Math.min(100, startPosY + (dy / rect.height) * -80)); + const scale = (item.zoom ?? 100) / 100; + item.posX = Math.max(0, Math.min(100, startPosX + (dx / rect.width) * -80 / scale)); + item.posY = Math.max(0, Math.min(100, startPosY + (dy / rect.height) * -80 / scale)); imgDiv.style.backgroundPosition = `${item.posX}% ${item.posY}%`; }; const onUp = () => { @@ -1255,6 +1258,14 @@ function renderMoodboard() { window.addEventListener('mousemove', onMove); window.addEventListener('mouseup', onUp); }); + // Scroll to zoom + imgDiv.addEventListener('wheel', (e) => { + e.preventDefault(); + const delta = e.deltaY > 0 ? -10 : 10; + item.zoom = Math.max(100, Math.min(400, (item.zoom ?? 100) + delta)); + imgDiv.style.backgroundSize = `${item.zoom}%`; + saveVisionSection('moodboard', JSON.stringify(items)); + }, { passive: false }); imgDiv.addEventListener('dblclick', () => { moodUploadTarget = i; document.getElementById('mood-file-input').click(); }); } @@ -1326,6 +1337,7 @@ document.addEventListener('DOMContentLoaded', () => { items[moodUploadTarget].image = data.path; items[moodUploadTarget].posX = 50; items[moodUploadTarget].posY = 50; + items[moodUploadTarget].zoom = 100; saveVisionSection('moodboard', JSON.stringify(items)); renderMoodboard(); }