feat: 无限画布 — infinite canvas with generation integration
Backend: - canvases table + owner-scoped CRUD under /admin/api/canvas (list/create/get/save/delete, 50 docs/user, 4MiB cap, JSON validation) Frontend: - /canvas full-screen workspace: DOM+CSS-transform infinite pan/zoom (GPU-composited world layer, viewport culling, rAF-batched pointer moves) - nodes: image (thumb display, natural-size correction), note (uncontrolled contenteditable), generation placeholder with edges - generate on canvas: prompt from panel or selected notes, selected image nodes as references, results auto-placed + bezier edges to sources - multi-canvas management, debounced autosave + keepalive flush, snapshot undo/redo (60 steps), marquee/keyboard interactions
This commit is contained in:
@@ -35,6 +35,7 @@ const ImagesView = () => import('./views/ImagesView.vue')
|
||||
const LogsView = () => import('./views/LogsView.vue')
|
||||
const ConfigView = () => import('./views/ConfigView.vue')
|
||||
const ShowcaseView = () => import('./views/ShowcaseView.vue')
|
||||
const CanvasView = () => import('./views/CanvasView.vue')
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@@ -43,6 +44,7 @@ const routes = [
|
||||
children: [
|
||||
{ path: '', component: HomeView, meta: { label: '首页' } },
|
||||
{ path: 'user', component: PlaygroundView, meta: { label: '画图' } },
|
||||
{ path: 'canvas', component: CanvasView, meta: { label: '无限画布' } },
|
||||
{ path: 'logs', component: UserLogsView, meta: { label: '图片' } },
|
||||
{ path: 'mylogs', component: UserLogsTableView, meta: { label: '日志' } },
|
||||
{ path: 'invite', component: InviteView, meta: { label: '邀请' } },
|
||||
@@ -95,7 +97,7 @@ const router = createRouter({
|
||||
|
||||
// Pages that require a login. The home page (/) stays public; everything a
|
||||
// signed-in user touches (画图/记录/设置) and the whole admin area is gated.
|
||||
const PROTECTED = ['/user', '/logs', '/invite', '/settings', '/orders']
|
||||
const PROTECTED = ['/user', '/canvas', '/logs', '/invite', '/settings', '/orders']
|
||||
function isProtected(path) {
|
||||
return path.startsWith('/admin') || PROTECTED.includes(path)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user