ui: center canvas and refine project layout
Verify and deploy production / verify-and-deploy (push) Successful in 2m50s
Verify and deploy production / verify-and-deploy (push) Successful in 2m50s
This commit is contained in:
@@ -107,6 +107,7 @@ export default function ImageEditor({ projectId }: { projectId: string }) {
|
||||
borderRadius: `${selected.settings.borderRadius}px`,
|
||||
} as CSSProperties;
|
||||
const ratioStyle = { "--canvas-ratio": `${project.canvas.width} / ${project.canvas.height}`, background: project.canvas.background } as CSSProperties;
|
||||
const selectedIndex = project.slides.findIndex((item) => item.id === selected.id);
|
||||
|
||||
return <main className="image-editor-shell">
|
||||
<header className="editor-topbar">
|
||||
@@ -116,21 +117,22 @@ export default function ImageEditor({ projectId }: { projectId: string }) {
|
||||
<input ref={fileInput} hidden type="file" accept="image/png,image/jpeg,image/webp" multiple onChange={(event) => void addImages(event.target.files)} />
|
||||
</header>
|
||||
|
||||
<aside className="editor-filmstrip">
|
||||
<div className="filmstrip-title"><span>页面</span><small>{project.slides.length}</small></div>
|
||||
<div className="filmstrip-list">{project.slides.map((slide, index) => <button key={slide.id} className={`filmstrip-item ${selected.id === slide.id ? "active" : ""}`} onClick={() => setSelectedId(slide.id)}><span>{index + 1}</span><img src={imageUrl(project.id, slide.fileName)} alt={slide.originalName} /></button>)}</div>
|
||||
<button className="filmstrip-add" onClick={() => fileInput.current?.click()}>+</button>
|
||||
</aside>
|
||||
|
||||
<section className="editor-workspace">
|
||||
<div className="canvas-toolbar"><button>↖ 选择</button><button>✋ 移动</button><i /><span>{project.canvas.width} × {project.canvas.height}</span><button onClick={() => updateSettings({ scale: 100, offsetX: 0, offsetY: 0, rotation: 0 })}>重置视图</button></div>
|
||||
<div className="canvas-viewport">
|
||||
<div className="canvas-page" style={ratioStyle} onPointerDown={onPointerDown} onPointerMove={onPointerMove} onPointerUp={onPointerUp}>
|
||||
<img draggable={false} src={imageUrl(project.id, selected.fileName)} alt={selected.originalName} style={style} />
|
||||
<div className="canvas-selection"><i className="handle nw"/><i className="handle ne"/><i className="handle sw"/><i className="handle se"/></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="editor-pagination"><button disabled={project.slides[0].id === selected.id} onClick={() => setSelectedId(project.slides[Math.max(0, project.slides.findIndex((item) => item.id === selected.id) - 1)].id)}>‹</button><span>{project.slides.findIndex((item) => item.id === selected.id) + 1} / {project.slides.length}</span><button disabled={project.slides.at(-1)?.id === selected.id} onClick={() => setSelectedId(project.slides[Math.min(project.slides.length - 1, project.slides.findIndex((item) => item.id === selected.id) + 1)].id)}>›</button></div>
|
||||
<div className="editor-carousel">
|
||||
<button className="carousel-arrow" disabled={selectedIndex === 0} onClick={() => setSelectedId(project.slides[Math.max(0, selectedIndex - 1)].id)}>‹</button>
|
||||
<div className="carousel-track">{project.slides.map((slide, index) => {
|
||||
const offset = index - selectedIndex;
|
||||
if (Math.abs(offset) > 2) return null;
|
||||
return <button key={slide.id} className={`carousel-slide ${offset === 0 ? "active" : offset < 0 ? "left" : "right"} ${Math.abs(offset) === 2 ? "far" : ""}`} onClick={() => setSelectedId(slide.id)}><img src={imageUrl(project.id, slide.fileName)} alt={slide.originalName} /><span>{index + 1}</span></button>;
|
||||
})}<button className="carousel-add" onClick={() => fileInput.current?.click()}>+</button></div>
|
||||
<button className="carousel-arrow" disabled={selectedIndex === project.slides.length - 1} onClick={() => setSelectedId(project.slides[Math.min(project.slides.length - 1, selectedIndex + 1)].id)}>›</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<aside className="editor-inspector">
|
||||
|
||||
@@ -63,7 +63,6 @@ export default function Studio() {
|
||||
const visibleProjects = projects.filter((project) => project.name.toLowerCase().includes(query.trim().toLowerCase()));
|
||||
|
||||
return <main className="kling-shell">
|
||||
<header className="kling-windowbar"><strong>首页</strong><button aria-label="新建"><Icon name="plus" size={18} /></button></header>
|
||||
<aside className="kling-sidebar">
|
||||
<div className="kling-logo">R</div>
|
||||
<nav>
|
||||
|
||||
Reference in New Issue
Block a user