スケチャ
100%
設定
ブロックをクリックして編集
\n\n
\n'+exportList(blocks)+'
\n\n'; isPreview = prevPreview; // Restore const blob=new Blob([html],{type:'text/html'});const a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download='mockup.html';a.click();showToast('HTMLを出力しました'); } function exportList(list){ return list.filter(b=>!b.hidden).map(b=>{ const tag=TAG_MAP[b.type]||'div';const wS=b.width<100?`max-width:${b.width}%`:'';const aC=b.width<100?` align-${b.align||'center'}`:''; const bg=b.bgColor?`background:${b.bgColor};`:'';const mS=boxHasValue(b.margin)?`margin:${boxToCSS(b.margin)};`:'';const pS=boxHasValue(b.padding)?`padding:${boxToCSS(b.padding)};`:'';const cS=cssToInline(b.css); let inner; if(b.type==='container')inner=b.cols[0].length?exportList(b.cols[0]):''; else if(b.type==='columns2'||b.type==='columns3'){const g=b.gap?`gap:${b.gap}px;`:'';const rt=(b.colRatio||'').split(':').map(Number);const gt=rt.length===b.cols.length&&rt.every(n=>n>0)?rt.map(r=>r+'fr').join(' '):`repeat(${b.cols.length},1fr)`;inner=`
${b.cols.map(c=>`
${c.length?exportList(c):''}
`).join('')}
`;} else inner=renderBlockContent(b); return `
<${tag}${b.cssClass?' class="'+esc(b.cssClass)+'"':''}${b.cssId?' id="'+esc(b.cssId)+'"':''} style="${bg}${pS}${cS}">${inner}
`; }).join('\n'); } function esc(s){if(s==null)return'';return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"');} // ===== Keyboard Shortcuts ===== document.addEventListener('keydown',(e)=>{ if(e.target.closest('input,textarea,[contenteditable]')){if(e.key==='Escape')e.target.blur();return;} if(e.key==='Delete'&&selectedId){deleteBlock(selectedId);e.preventDefault();} if(e.ctrlKey&&e.key==='d'&&selectedId){duplicateBlock(selectedId);e.preventDefault();} if(e.ctrlKey&&e.key==='c'&&selectedId){copyBlock();e.preventDefault();} if(e.ctrlKey&&e.key==='v'){pasteBlock();e.preventDefault();} if(e.ctrlKey&&e.key==='z'){doUndo();e.preventDefault();} if(e.ctrlKey&&e.key==='y'){doRedo();e.preventDefault();} if(e.ctrlKey&&e.key==='s'){saveToLocal();e.preventDefault();} if(e.altKey&&e.key==='ArrowUp'&&selectedId){moveBlock(selectedId,-1);e.preventDefault();} if(e.altKey&&e.key==='ArrowDown'&&selectedId){moveBlock(selectedId,1);e.preventDefault();} // Arrow key navigation if(!e.altKey&&!e.ctrlKey&&(e.key==='ArrowUp'||e.key==='ArrowDown')){ const ids=flatIds(blocks);if(!ids.length)return; e.preventDefault(); if(!selectedId){selectedId=ids[0];render();return;} const ci=ids.indexOf(selectedId); if(e.key==='ArrowUp'&&ci>0){selectedId=ids[ci-1];render();const el=document.querySelector(`[data-id="${selectedId}"]`);if(el)el.scrollIntoView({behavior:'smooth',block:'nearest'});} if(e.key==='ArrowDown'&&ci

ページ設定

`; document.body.appendChild(div); div.addEventListener('click', (e) => { if (e.target === div) closePageSettings(); }); } function closePageSettings() { const m = document.getElementById('page-settings-modal'); if (m) m.remove(); } function applyPageSettings() { pageSettings.bgColor = document.getElementById('ps-bg').value; pageSettings.fontFamily = document.getElementById('ps-font').value; pageSettings.maxWidth = parseInt(document.getElementById('ps-maxw').value) || 960; applyPageStyle(); closePageSettings(); showToast('ページ設定を反映しました'); } function applyPageStyle() { const c = document.getElementById('canvas'); c.style.background = pageSettings.bgColor; c.style.fontFamily = pageSettings.fontFamily || ''; c.style.maxWidth = pageSettings.maxWidth + 'px'; } // ===== Image Drop ===== function onImageDrop(e, bid) { e.preventDefault(); e.stopPropagation(); const file = e.dataTransfer.files[0]; if (!file || !file.type.startsWith('image/')) return; const reader = new FileReader(); reader.onload = (ev) => { const b = findBlock(blocks, bid); if (b) { pushUndo(); b.imageUrl = ev.target.result; render(); showToast('画像を追加しました'); } }; reader.readAsDataURL(file); } // ===== Zoom ===== let zoomLevel = 100; function setZoom(delta) { zoomLevel = Math.max(50, Math.min(150, zoomLevel + delta)); document.getElementById('canvas').style.transform = `scale(${zoomLevel/100})`; document.getElementById('canvas').classList.toggle('canvas-zoom', zoomLevel !== 100); document.getElementById('zoom-val').textContent = zoomLevel + '%'; } // ===== Block size display on hover ===== document.addEventListener('mouseover', (e) => { const blockEl = e.target.closest('.block-item[data-id]'); if (blockEl) { const sizeEl = blockEl.querySelector(':scope > .block-size'); if (sizeEl) { const r = blockEl.getBoundingClientRect(); sizeEl.textContent = `${Math.round(r.width)} × ${Math.round(r.height)}`; } } }); // ===== Hover sync (canvas <-> tree) ===== document.addEventListener('mouseover', (e) => { const blockEl = e.target.closest('.block-item[data-id]'); const treeEl = e.target.closest('.tree-item[data-hover-id]'); // Clear previous hovers document.querySelectorAll('.hovered').forEach(el => el.classList.remove('hovered')); if (blockEl) { const id = blockEl.dataset.id; const treeItem = document.querySelector(`.tree-item[data-hover-id="${id}"]`); if (treeItem) treeItem.classList.add('hovered'); } if (treeEl) { const id = treeEl.dataset.hoverId; const canvasItem = document.querySelector(`.block-item[data-id="${id}"]`); if (canvasItem) canvasItem.classList.add('hovered'); } }); // ===== Init ===== if(localStorage.getItem('bc_dark')==='1'){document.body.classList.add('dark');document.getElementById('btn-dark').classList.add('active');} render(); document.addEventListener('click',(e)=>{ hideCtx(); if(e.target.closest('.block-item,.sidebar,.props-panel,.topbar,.ctx-menu')) return; selectedId=null;render(); });