You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

4.7 KiB

项目面板自动收起与动画

任务背景

在项目面板中点击项目后,需要自动收起项目面板,并且项目面板的打开/收起需要添加过渡动画效果。

实现方案

方案选择

采用方案3:灵活的参数控制 + CSS 过渡动画

优点

  • 灵活性高,可以根据场景决定是否关闭面板
  • 保持向后兼容性
  • 动画效果集中管理,易于维护

实现步骤

1. 修改 uiStore.ts - 添加自动关闭项目面板的逻辑

文件client/src/stores/uiStore.ts

修改内容

  • selectProject 方法签名中添加参数 autoCloseProjectPanel?: boolean(默认为 true
  • 当参数为 true 且选择了项目时,自动将 projectPanelOpen 设置为 false

代码变更

selectProject: (projectId: string | null, projectName?: string, autoCloseProjectPanel: boolean = true) => {
  const updates: Partial<UIState> = { selectedProjectId: projectId };
  
  // 如果需要自动关闭项目面板,且选择了项目
  if (autoCloseProjectPanel && projectId) {
    updates.projectPanelOpen = false;
  }
  
  set(updates);
  // ... 其他逻辑
}

2. 修改 ProjectTreeNode.tsx - 点击项目时关闭面板

文件client/src/components/features/project/ProjectTreeNode.tsx

修改内容

  • handleClick 中调用 selectProject 时,传递 autoCloseProjectPanel: true

代码变更

const handleClick = () => {
  if (isFolder && (hasChildren || isRootFolder)) {
    onToggleExpand(node.id);
  } else if (isProject && node.projectId) {
    // 选择项目:更新全局状态,并自动关闭项目面板
    selectProject(node.projectId.toString(), node.name, true);
  }
};

3. 修改 LeftSidebar.tsx - 保持项目面板打开

文件client/src/components/layout/LeftSidebar.tsx

修改内容

  • 在左侧边栏的搜索框选择项目时,传递 autoCloseProjectPanel: false
  • 这样用户从搜索框选择项目时,项目面板不会被自动关闭

代码变更

const handleProjectSelect = (projectId: string, projectName: string) => {
  // 从左侧边栏选择项目时,不自动关闭项目面板
  selectProject(projectId, projectName, false);
  setInputValue(projectName);
};

4. 修改 AppLayout.tsx - 添加项目面板过渡动画

文件client/src/components/layout/AppLayout.tsx

修改内容

  • 将条件渲染改为始终渲染,通过 CSS 控制显示/隐藏
  • 添加 transition-all duration-300 ease-in-out 实现平滑过渡
  • 通过 widthopacity 控制显示效果

代码变更

<div 
  className="shrink-0 border-r border-border bg-card flex flex-col overflow-hidden transition-all duration-300 ease-in-out"
  style={{
    width: projectPanelOpen ? '320px' : '0px',
    opacity: projectPanelOpen ? 1 : 0,
  }}
>
  {projectPanelOpen && <ProjectPanel />}
</div>

技术细节

动画实现

使用 CSS transition 实现平滑动画:

  • transition-all:所有属性都参与过渡
  • duration-300:动画时长 300ms
  • ease-in-out:缓入缓出效果

同时控制两个属性:

  • width:从 0px 到 320px,实现滑入滑出效果
  • opacity:从 0 到 1,实现淡入淡出效果

条件渲染优化

保留 {projectPanelOpen && <ProjectPanel />} 条件渲染,在面板关闭时不渲染内部组件,节省性能。

预期效果

功能效果

  1. 在项目面板中点击项目后,项目面板自动收起
  2. 在左侧边栏搜索框选择项目时,项目面板保持打开状态(不影响用户后续操作)
  3. 项目面板打开/收起时,有流畅的滑入滑出和淡入淡出动画

用户体验

  • 点击项目后视野更宽敞,可以直接查看素材库和分镜列表
  • 平滑的动画过渡,避免突兀的显示/隐藏
  • 不同场景下的智能行为,提升操作效率

测试要点

  1. 项目面板点击测试

    • 点击项目后,面板应自动收起
    • 动画应流畅,无卡顿
  2. 左侧边栏搜索测试

    • 从搜索框选择项目后,项目面板应保持打开
    • 可以继续在项目面板中操作
  3. 菜单按钮测试

    • 点击 TopBar 的菜单按钮,项目面板应正常打开/关闭
    • 动画效果一致
  4. 性能测试

    • 快速切换项目时,动画不应堆叠或错乱

后续优化建议

  1. 可以考虑添加 transform: translateX() 替代 width 动画,性能更好
  2. 可以添加用户偏好设置,允许用户选择是否自动关闭项目面板
  3. 可以添加键盘快捷键快速打开/关闭项目面板

实施日期:2026-01-14
实施状态 已完成