21 lines
25 KiB
HTML
21 lines
25 KiB
HTML
|
|
<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>SiteForge V8.22 · 高级可视化编辑器(交互演示)</title><style>
|
|||
|
|
:root{font-family:Inter,-apple-system,BlinkMacSystemFont,"Microsoft Yahei",sans-serif;color:#2c3a4d;background:#f0f3f7}*{box-sizing:border-box}body{margin:0}.app{height:100vh;display:flex;flex-direction:column}.top{height:67px;flex-shrink:0;background:#fff;display:flex;align-items:center;padding:0 18px;gap:16px;border-bottom:1px solid #e8edf2}.logo{font-weight:900;font-size:21px;color:#e67832}.logo small{font-weight:500;font-size:11px;display:block;color:#8a97a8}.file{font-size:13px;font-weight:750;border-left:1px solid #e6e9ee;padding-left:16px}.file small{display:block;font-size:10px;color:#8793a4;font-weight:400;margin-bottom:2px}.devices{margin:auto;display:flex;gap:3px;padding:4px;border-radius:10px;background:#f3f5f8}.devices button{background:transparent;color:#65748a;border:none;border-radius:7px;padding:9px 14px;font-size:12px;cursor:pointer}.devices button.active{color:#c86425;background:#fff;box-shadow:0 2px 6px #2233}.save-state{color:#b8783e;font-size:12px;min-width:65px}.btn{border:1px solid #dde3eb;background:#fff;border-radius:9px;padding:10px 13px;color:#4c5d72;font-weight:750;cursor:pointer}.btn.orange{color:white;background:#de7636;border-color:#de7636}.top .btn{white-space:nowrap}.body{min-height:0;display:grid;grid-template-columns:260px minmax(0,1fr) 295px;flex:1}.side{background:#fff;min-height:0;overflow-y:auto;padding:17px 13px;border-right:1px solid #e5e9f0}.right{border-right:0;border-left:1px solid #e5e9f0}.eyebrow{font-size:10px;font-weight:800;color:#d57635;letter-spacing:1.5px}.side h2{font-size:17px;margin:4px 0 17px}.picker{width:100%;border:1px solid #dfe5ed;border-radius:8px;padding:10px;color:#455871;background:#f9fafc}.add{width:100%;border:0;border-radius:9px;background:#df7c3e;padding:13px;color:#fff;font-weight:800;cursor:pointer;margin:15px 0 8px}.hint{font-size:11px;color:#9aa6b3;line-height:1.7;margin:3px 0 20px}.label{font-size:12px;font-weight:750;color:#66758c;display:block;margin:12px 3px}.block{width:100%;border:1px solid #e4e9ef;border-radius:9px;display:flex;align-items:center;padding:11px;margin-bottom:7px;background:white;gap:9px;cursor:pointer;text-align:left;color:#42546c}.block.sel{border-color:#e18a52;background:#fff7f0}.block .shape{font-size:20px;color:#df8245;background:#fff4e8;border-radius:7px;padding:5px}.block strong{font-size:12px;display:block}.block small{font-size:10px;color:#99a5b4;display:block;padding-top:3px}.lib[hidden]{display:none}.lib{padding:9px;background:#fff8f2;border:1px solid #f2ddce;border-radius:11px}.lib .btn{width:100%;margin:3px 0;text-align:left;font-size:12px}.stage-area{background:#eef2f6;display:flex;flex-direction:column;min-width:0}.stagebar{height:47px;background:#f8fafc;border-bottom:1px solid #e6eaf1;display:flex;align-items:center;justify-content:space-between;padding:0 20px;color:#647388;font-size:12px}.stage{padding:19px;display:flex;justify-content:center;flex:1;min-height:0;overflow:auto}.device{width:100%;max-width:1100px;box-shadow:0 18px 45px #33455d1d;background:white;border-radius:8px;overflow:hidden;transition:max-width .2s;min-height:650px}.device.tablet{max-width:780px}.device.phone{max-width:390px;border:7px solid #263346;border-radius:18px}.device iframe{border:0;display:block;width:100%;height:100%;min-height:660px}.stagefoot{font-size:11px;color:#9aa7b7;padding:9px 18px}.tabs{display:flex;background:#f3f6fa;padding:4px;border-radius:8px;margin-bottom:16px}.tabs button{flex:1;border:0;background:transparent;padding:8px 4px;cursor:pointer;font-size:12px;color:#69788e;border-radius:7px}.tabs button.active{background:white;color:#d36b2c;font-weight:800;box-shadow:0 1px 5px #2332}.prop{margin-bottom:14px}.prop label{font-size:12px;color:#5f7187;display:block;margin-bottom:7px}.prop input,.prop textarea{width:100%;border:1px solid #dee5ed;border-radius:8px;padding:11px;font:inherit;color:#384b62;font-size:13px}.prop textarea{min-height:85px;resize:vertical}.muted{color:#97a2b1;font-size:11px;line-height:1.7}.notice{background:#fff7ed;color:#a86636;border-radius:10px;padding:13px;font-size:12px;line-height:1.65;margi
|
|||
|
|
</style></head><body><div class="app"><div class="top"><div class="logo">◆ SiteForge<small>VISUAL STUDIO</small></div><div class="file"><small>我的网站 / 首页</small>页面可视化编辑</div><div class="devices"><button class="active" data-device="desktop">▣ 电脑</button><button data-device="tablet">▤ 平板</button><button data-device="phone">▯ 手机</button></div><span class="save-state" id="status">未保存修改</span><button class="btn" id="undo">↶ 撤销</button><button class="btn" id="save">保存草稿</button><button class="btn orange" id="publish">发布设计</button></div><div class="body"><aside class="side"><div class="eyebrow">01 · 页面内容</div><h2>编辑页面</h2><select class="picker"><option>首页 / Home</option></select><button class="add" id="add">+ 添加内容区块</button><div class="lib" id="lib" hidden><button class="btn" data-type="hero">▣ 大图横幅</button><button class="btn" data-type="features">▦ 优势列表</button><button class="btn" data-type="layout">▥ 双列布局</button><button class="btn" data-type="cta">↗ 联系引导</button></div><p class="hint">直接点击中间画布,在浮动工具栏中拖动、复制、调整或新增区块。</p><span class="label">当前页面内容</span><div id="blocks"></div><div class="notice">演示环境:可以编辑和模拟保存,但不会修改任何真实网站、数据库或线上内容。</div></aside><main class="stage-area"><div class="stagebar"><span>● <b>实时画布</b> / 首页</span><span>点击区块直接编辑 · 拖动列宽</span></div><div class="stage"><div class="device" id="device"><iframe id="preview" title="真实可交互画布" sandbox="allow-scripts"></iframe></div></div><div class="stagefoot">这是本地演示数据 · 改动仅保留在当前打开的演示页面</div></main><aside class="side right"><div class="eyebrow">02 · 编辑属性</div><h2>修改选中的内容</h2><div class="tabs"><button class="active" data-tab="content">内容</button><button data-tab="style">样式</button><button data-tab="responsive">手机/平板</button></div><div id="fields"></div></aside></div></div><script>
|
|||
|
|
const CANVAS_BRIDGE="/* V8.22 trusted, sandboxed studio canvas bridge. No arbitrary user code. */\n(function(){\n 'use strict';\n const source='siteforge-studio-canvas';\n const list=()=>Array.from(document.querySelectorAll('.sf-section[data-block]')).filter(n=>!n.parentElement.closest('.sf-section[data-block]'));\n const send=(action,id,extra={})=>parent.postMessage({source,action,blockId:id,...extra},'*');\n let active='', dragging='',resize=null;\n const all=()=>Array.from(document.querySelectorAll('.sf-section[data-block]'));\n const style=document.createElement('style');\n style.textContent=`\n .sf-section[data-block]{position:relative}\n .sf-section[data-block].sf-canvas-selected{outline:2px solid #ec7c35!important;outline-offset:-2px}\n .sf-section[data-block].sf-canvas-drop{box-shadow:inset 0 4px 0 #ef8741!important}\n .sf-section[data-block]:hover{outline:1px dashed #eb995a;outline-offset:-1px}\n .sf-canvas-toolbar{position:absolute;right:7px;top:5px;z-index:2147480000;display:none;align-items:center;gap:3px;padding:5px;background:#263447;color:#fff;border-radius:9px;box-shadow:0 5px 20px #20304450;font:12px/1.4 system-ui,sans-serif;white-space:nowrap;pointer-events:auto}\n .sf-canvas-selected>.sf-canvas-toolbar,.sf-section[data-block]:hover>.sf-canvas-toolbar,.sf-canvas-toolbar:focus-within{display:flex}\n .sf-canvas-toolbar button{background:transparent;color:inherit;border:0;cursor:pointer;padding:5px 7px;border-radius:5px;font:inherit}\n .sf-canvas-toolbar button:hover,.sf-canvas-toolbar button:focus-visible{background:#52687e;outline:1px solid #fff6}\n .sf-canvas-toolbar .sf-canvas-drag{cursor:grab;background:#496174}\n .sf-canvas-toolbar .sf-canvas-danger:hover{background:#ab4d46}\n .sf-canvas-hint{position:fixed;bottom:12px;left:50%;transform:translateX(-50%);background:#1c293ee8;color:white;padding:9px 13px;border-radius:9px;z-index:2147480000;font:12px system-ui;pointer-events:none}\n .sf-layout-grid{position:relative}\n .sf-canvas-resize{position:absolute;z-index:2147480000;top:4px;bottom:4px;width:12px;transform:translateX(-50%);cursor:col-resize;touch-action:none;opacity:0;display:flex;align-items:center;justify-content:center}\n .sf-canvas-resize:after{content:'⋮';background:#e77632;color:white;box-shadow:0 2px 8px #2225;border-radius:8px;font:20px/26px system-ui;text-align:center;width:19px;min-width:19px}\n .sf-section:hover .sf-canvas-resize,.sf-canvas-resize:focus-visible,.sf-canvas-resize.sf-resizing{opacity:1}\n [contenteditable].sf-canvas-editing{outline:2px dashed #df7435!important;border-radius:3px;cursor:text!important}\n @media(max-width:820px){.sf-canvas-resize{display:none!important}}\n `;\n document.head.appendChild(style);\n const types={title:'h1,h2',description:'.sf-hero-copy p,.sf-image-text p,.sf-cta-wrap p'};\n function activate(id,notify=true){\n active=id||'';for(const el of all())el.classList.toggle('sf-canvas-selected',el.dataset.block===id);\n if(notify&&id)send('select',id);\n }\n const topSections=list();\n for(const block of topSections){\n const id=block.dataset.block;\n const bar=document.createElement('div');bar.className='sf-canvas-toolbar';bar.setAttribute('role','toolbar');bar.setAttribute('aria-label','区块快捷操作');\n const controls=[['↕','拖动区块','drag'],['✎','编辑区块','edit'],['↑','上移区块','up'],['↓','下移区块','down'],['+','在下方添加区块','add-after'],['⧉','复制区块','duplicate'],['×','删除区块','delete']];\n for(const [txt,label,action] of controls){\n const b=document.createElement('button');b.type='button';b.textContent=txt;b.title=label;b.setAttribute('aria-label',label);b.dataset.action=action;\n if(action==='drag'){b.draggable=true;b.className='sf-canvas-drag';b.addEventListener('dragstart',e=>{dragging=id;e.dataTransfer.setData('text/plain',id);e.dataTransfer.effectAllowed='move';e.stopPropagation()});b.addEventListener('dragend',()=>{dragging='';list().forEach(el=>el.classList.remove('sf-canvas-drop'))})}\n else {if(action==='dele
|
|||
|
|
let data=[{id:'b1',type:'hero',title:'连接全球汽车市场',description:'从中国采购,到全球交付。值得信赖的国际汽车贸易伙伴。',columns:null},{id:'b2',type:'features',title:'为什么选择我们',description:'',columns:null},{id:'b3',type:'layout',title:'自由组合布局',description:'',columns:[{width:1},{width:1}]},{id:'b4',type:'cta',title:'准备好开始合作了吗?',description:'联系我们,获取符合您市场需求的采购方案。',columns:null}],selected='b1',insertAfter=null,tab='content',history=[];
|
|||
|
|
const $=s=>document.querySelector(s),esc=s=>String(s??'').replace(/[&<>"']/g,ch=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[ch]));
|
|||
|
|
const id=()=>Math.random().toString(36).slice(2,11);
|
|||
|
|
function snapshot(){history.push(JSON.stringify(data));if(history.length>30)history.shift();$('#status').textContent='未保存修改'}
|
|||
|
|
function section(b){const head='<section class="sf-section" data-block="'+esc(b.id)+'"><div class="sf-container">',end='</div></section>';
|
|||
|
|
if(b.type==='hero')return head+`<div class="hero"><div><p class="kicker">CHINA SOURCING · GLOBAL DELIVERY</p><h1>${esc(b.title)}</h1><p>${esc(b.description)}</p><a href="#">探索全球业务 ↗</a></div><div class="art">🚙</div></div>`+end;
|
|||
|
|
if(b.type==='features')return head+`<div class="center"><small>OUR STRENGTHS</small><h2>${esc(b.title)}</h2></div><div class="cards"><article><b>01</b><h3>专业采购</h3><p>丰富车型供应资源</p></article><article><b>02</b><h3>全球物流</h3><p>多式联运交付保障</p></article><article><b>03</b><h3>海外服务</h3><p>本地化服务协同</p></article></div>`+end;
|
|||
|
|
if(b.type==='layout'){const cols=b.columns.map((c,i)=>`<div class="sf-layout-column"><article class="col-card"><small>模块 ${i+1}</small><h3>${i?'服务与支持':'汽车产品'}</h3><p>在画布上拖动列边界,可以调整两列的占比。</p></article></div>`).join('');return head+`<div class="center"><h2>${esc(b.title)}</h2></div><div class="sf-layout-grid" data-layout="${esc(b.id)}" style="--sf-layout-cols:${b.columns.map(x=>x.width+'fr').join(' ')}">${cols}</div>`+end}
|
|||
|
|
return head+`<div class="cta"><h2>${esc(b.title)}</h2><p>${esc(b.description)}</p><a href="#">联系我们 ↗</a></div>`+end;
|
|||
|
|
}
|
|||
|
|
function render(){const blocks=data.map(section).join('');const css=`<style>*{box-sizing:border-box}body{margin:0;color:#2e3f54;font:15px/1.6 Arial,'Microsoft Yahei',sans-serif}a{display:inline-block;background:#ed843f;border-radius:7px;color:#fff;text-decoration:none;padding:12px 18px;margin-top:8px;font-weight:bold}.site-nav{display:flex;justify-content:space-between;padding:18px 27px;border-bottom:1px solid #ebedf0}.site-nav strong{color:#df7e3f;font-size:18px}.site-nav span{color:#8795a4;font-size:12px}.sf-section{padding:62px 16px;background:white}.sf-section:nth-child(odd){background:#f8fafc}.sf-container{max-width:1050px;margin:auto}.hero{display:grid;grid-template-columns:1fr .8fr;gap:30px;align-items:center;min-height:300px}.kicker,.center small{color:#e27d38;font-weight:bold;font-size:11px;letter-spacing:2px}.hero h1{font-size:40px;line-height:1.2;margin:15px 0}.hero p{color:#617186}.art{display:grid;place-items:center;font-size:115px;background:linear-gradient(135deg,#fff2e4,#f3f7ff);height:280px;border-radius:22px}.center{text-align:center;margin-bottom:25px}.center h2{font-size:28px}.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.cards article,.col-card{background:#fff;border:1px solid #e7edf3;border-radius:12px;padding:25px}.cards b{color:#eb833b}.cards p,.col-card p{color:#728297}.sf-layout-grid{display:grid;grid-template-columns:var(--sf-layout-cols);gap:16px;position:relative}.sf-layout-column{min-width:0}.col-card{background:#f7f8fb;min-height:190px}.col-card small{color:#e18447}.cta{text-align:center;background:#263b55;padding:60px 15px;border-radius:16px;color:white}.cta p{color:#c4d3e5}footer{text-align:center;padding:35px;font-size:12px;color:#9aa9b7}@media(max-width:800px){.hero{grid-template-columns:1fr}.art{height:170px;font-size:70px}.sf-section{padding:35px 18px}.cards{grid-template-columns:1fr}.sf-layout-grid{grid-template-columns:1fr!important}.hero h1{font-size:26px}.site-nav span{display:none}}</style>`;const content='<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">'+css+'</head><body><div class="site-nav"><strong>HESU AUTO</strong><span>HOME PRODUCTS ABOUT CONTACT</span></div>'+blocks+'<footer>CHINA SOURCING. GLOBAL DELIVERY.</footer><scr'+'ipt>'+CANVAS_BRIDGE+'</scr'+'ipt></body></html>';
|
|||
|
|
$('#preview').onload=()=>$('#preview').contentWindow.postMessage({source:'siteforge-studio-host',action:'highlight',blockId:selected},'*');$('#preview').srcdoc=content;list();fields();}
|
|||
|
|
function list(){$('#blocks').innerHTML=data.map((b,i)=>`<button class="block ${b.id===selected?'sel':''}" data-select="${esc(b.id)}"><span class="shape">${({hero:'▣',features:'▦',layout:'▥',cta:'↗'})[b.type]}</span><span><strong>${esc(b.title||b.type)}</strong><small>${i+1} · 点击选中</small></span></button>`).join('');document.querySelectorAll('[data-select]').forEach(b=>b.onclick=()=>{selected=b.dataset.select;render();});}
|
|||
|
|
function fields(){const b=data.find(x=>x.id===selected);$('#fields').innerHTML= !b?'<p class="muted">点击中间画布中的区块开始。</p>':(tab==='content'?`<div class="prop"><label>标题</label><input id="title" value="${esc(b.title)}"></div><div class="prop"><label>内容描述</label><textarea id="desc">${esc(b.description)}</textarea></div><p class="muted">还可以在画布上双击标题直接编辑。</p>`:tab==='style'?'<p class="muted">本次重点演示布局交互。正式项目可通过属性面板调整颜色和间距。</p>':`<p class="muted">使用顶部设备按钮查看电脑 / 平板 / 手机效果。手机布局独立自适应;桌面列宽通过拖动调整。</p>`);const a=$('#title'),binput=$('#desc');if(a)a.onchange=()=>{snapshot();b.title=a.value;render()};if(binput)binput.onchange=()=>{snapshot();b.description=binput.value;render()};}
|
|||
|
|
window.addEventListener('message',e=>{if(e.source!==$('#preview').contentWindow||e.data?.source!=='siteforge-studio-canvas')return;const m=e.data,i=data.findIndex(b=>b.id===m.blockId);if(i<0)return;const b=data[i];selected=b.id;switch(m.action){case 'select':case 'edit':list();fields();return;case 'up':if(i===0)return;snapshot();[data[i-1],data[i]]=[data[i],data[i-1]];break;case 'down':if(i===data.length-1)return;snapshot();[data[i+1],data[i]]=[data[i],data[i+1]];break;case 'duplicate':snapshot();data.splice(i+1,0,{...structuredClone(b),id:id()});break;case 'delete':if(!confirm('删除该区块?'))return;snapshot();data.splice(i,1);selected=data[Math.max(0,i-1)]?.id||null;break;case 'add-after':insertAfter=b.id;$('#lib').hidden=false;$('#status').textContent='选一种区块插入';list();fields();return;case 'reorder':{const target=data.findIndex(x=>x.id===m.targetId);if(target<0||target===i)return;snapshot();data.splice(target,0,data.splice(i,1)[0]);break;}case 'resize-columns':if(b.type!=='layout'||!Array.isArray(m.widths)||m.widths.length!==b.columns.length||m.widths.some(x=>!Number.isFinite(x)||x<.5||x>4))return;snapshot();b.columns.forEach((x,i)=>x.width=m.widths[i]);break;case 'inline-text':if(!['title','description'].includes(m.field)||typeof m.value!=='string'||m.value.length>500)return;snapshot();b[m.field]=m.value;break;default:return;}render();});
|
|||
|
|
$('#add').onclick=()=>$('#lib').hidden=!$('#lib').hidden;document.querySelectorAll('[data-type]').forEach(btn=>btn.onclick=()=>{snapshot();const type=btn.dataset.type;const b={id:id(),type,title:({hero:'新的横幅',features:'新的优势列表',layout:'新的双列布局',cta:'新的联系区块'})[type],description:'点击修改这里的文字',columns:type==='layout'?[{width:1},{width:1}]:null};const ix=data.findIndex(x=>x.id===insertAfter);data.splice(ix<0?data.length:ix+1,0,b);insertAfter=null;selected=b.id;$('#lib').hidden=true;render();});document.querySelectorAll('[data-device]').forEach(b=>b.onclick=()=>{document.querySelectorAll('[data-device]').forEach(x=>x.classList.remove('active'));b.classList.add('active');$('#device').className='device '+(b.dataset.device==='desktop'?'':b.dataset.device)});document.querySelectorAll('[data-tab]').forEach(b=>b.onclick=()=>{tab=b.dataset.tab;document.querySelectorAll('[data-tab]').forEach(x=>x.classList.toggle('active',x===b));fields()});$('#save').onclick=()=>$('#status').textContent='演示草稿已保存';$('#publish').onclick=()=>alert('这是操作演示,不会发布到任何真实网站。正式流程:保存草稿 → 发布设计到内容库 → 静态构建 → 审批部署。');$('#undo').onclick=()=>{if(!history.length)return;data=JSON.parse(history.pop());selected=data[0]?.id;render();$('#status').textContent='已撤销';};render();
|
|||
|
|
</script></body></html>
|