feat(canvas): adjust side panel element selection to center without exceeding 100% zoom

This commit is contained in:
HouYunFei
2026-08-06 11:46:28 +08:00
parent feb582bba8
commit a10f16d983
4 changed files with 4 additions and 2 deletions
+1
View File
@@ -3,6 +3,7 @@
## Unreleased ## Unreleased
+ [优化] 画布多图生成结果合并为单个图片节点,生成期间可展开查看每张图片的实时状态,优先展示最先成功的结果,并以紧凑堆叠展示已有图片。 + [优化] 画布多图生成结果合并为单个图片节点,生成期间可展开查看每张图片的实时状态,优先展示最先成功的结果,并以紧凑堆叠展示已有图片。
+ [优化] 从左侧元素列表定位画布节点时,自动缩放上限调整为 100%。
## v0.14.0 - 2026-08-05 ## v0.14.0 - 2026-08-05
@@ -10,6 +10,7 @@ The current release needs manual verification in these areas:
- English and Simplified Chinese switching across navigation, settings, titles, descriptions, Ant Design components, and persisted preferences. - English and Simplified Chinese switching across navigation, settings, titles, descriptions, Ant Design components, and persisted preferences.
- Global Dropdown, Menu, Select, Cascader, and TreeSelect popup backgrounds, hover states, and selected states in both light and dark themes. - Global Dropdown, Menu, Select, Cascader, and TreeSelect popup backgrounds, hover states, and selected states in both light and dark themes.
- Canvas node resize stability, prompt scrolling, generated-prompt restoration, image editing, drag-and-drop references, and generation configuration. - Canvas node resize stability, prompt scrolling, generated-prompt restoration, image editing, drag-and-drop references, and generation configuration.
- Canvas side panel: clicking an element row should smoothly center and select its node without zooming above 100%; image elements with content should still open the large preview without triggering canvas focus.
- Multi-image canvas generation: starting N images should immediately create one image node with N expandable slots and one incoming connection; each empty slot should independently show generating or failure while requests are running, every slot with image content should always display that image, and the first successful image should appear as the primary image immediately. The collapsed state should use a compact stack with at most three closely spaced backplates and a clearly legible count control; clicking the control should hide the floating toolbar and expand the slots upward and to the right. Every completed secondary image should keep a clearly legible primary-image action visible in both themes, and clicking the empty canvas should collapse the group. - Multi-image canvas generation: starting N images should immediately create one image node with N expandable slots and one incoming connection; each empty slot should independently show generating or failure while requests are running, every slot with image content should always display that image, and the first successful image should appear as the primary image immediately. The collapsed state should use a compact stack with at most three closely spaced backplates and a clearly legible count control; clicking the control should hide the floating toolbar and expand the slots upward and to the right. Every completed secondary image should keep a clearly legible primary-image action visible in both themes, and clicking the empty canvas should collapse the group.
- Canvas Agent startup, MCP status, model and permission controls, approvals, version reporting, diagnostics, streaming responses, history consistency, multi-tab isolation, and local Skill management. - Canvas Agent startup, MCP status, model and permission controls, approvals, version reporting, diagnostics, streaming responses, history consistency, multi-tab isolation, and local Skill management.
- Agent header tabs in English and Chinese at different panel widths; labels should collapse to icons and counts before either edge is clipped. - Agent header tabs in English and Chinese at different panel widths; labels should collapse to icons and counts before either edge is clipped.
@@ -49,7 +49,7 @@ description: 当前版本已实现但仍需人工验证的变更项
- 画布节点提示词回显:单图或多图生成完成后,切换选择生成结果的根节点及任一子节点,下方输入区域都应继续显示生成时的提示词;切换到其他节点再选回来后也不应清空。 - 画布节点提示词回显:单图或多图生成完成后,切换选择生成结果的根节点及任一子节点,下方输入区域都应继续显示生成时的提示词;切换到其他节点再选回来后也不应清空。
- 画布生成配置:连接文本节点后连续点击生成(包含失败重试),组装提示词不应重复追加上游文本;在生图、文本、视频、音频之间切换时,实际请求应始终使用当前面板展示的对应类型模型。 - 画布生成配置:连接文本节点后连续点击生成(包含失败重试),组装提示词不应重复追加上游文本;在生图、文本、视频、音频之间切换时,实际请求应始终使用当前面板展示的对应类型模型。
- 画布多图生成:开始生成 N 张图片后应立即创建一个包含 N 个可展开槽位的图片节点,并且来源到结果只保留一条连线;生成期间空槽位应独立显示生成中或失败,任何已有图片内容的槽位都必须始终显示图片,任意图片率先成功后应立即成为主图并展示,不等待其他请求完成;收起状态应最多显示三层紧密错开的背板,避免占用过多画布空间,右上角应显示醒目的「N 张」数量提示;点击数量后,浮动工具条应暂时隐藏,各图片槽位应从当前节点向右上方整齐展开;已成功图片的「设为主图」应常驻显示,并在亮色、深色主题及不同图片背景上保持清晰;点击画布空白处应自动收起并恢复工具条。 - 画布多图生成:开始生成 N 张图片后应立即创建一个包含 N 个可展开槽位的图片节点,并且来源到结果只保留一条连线;生成期间空槽位应独立显示生成中或失败,任何已有图片内容的槽位都必须始终显示图片,任意图片率先成功后应立即成为主图并展示,不等待其他请求完成;收起状态应最多显示三层紧密错开的背板,避免占用过多画布空间,右上角应显示醒目的「N 张」数量提示;点击数量后,浮动工具条应暂时隐藏,各图片槽位应从当前节点向右上方整齐展开;已成功图片的「设为主图」应常驻显示,并在亮色、深色主题及不同图片背景上保持清晰;点击画布空白处应自动收起并恢复工具条。
- 画布左侧元素列表:点击元素整行应平滑定位并选中对应节点;有内容的图片元素应显示预览按钮,点击后打开大图弹窗且不触发画布定位。 - 画布左侧元素列表:点击元素整行应平滑定位并选中对应节点,自动缩放不得超过 100%;有内容的图片元素应显示预览按钮,点击后打开大图弹窗且不触发画布定位。
- 配置与用户偏好:导出 JSON 后应包含渠道、默认模型、生成偏好、提示词来源和 WebDAV 配置;在修改当前配置后重新导入该文件,应恢复导出时的设置,错误 JSON 文件应提示格式不正确。配置文件包含 API Key 和 WebDAV 凭据,不应公开分享。 - 配置与用户偏好:导出 JSON 后应包含渠道、默认模型、生成偏好、提示词来源和 WebDAV 配置;在修改当前配置后重新导入该文件,应恢复导出时的设置,错误 JSON 文件应提示格式不正确。配置文件包含 API Key 和 WebDAV 凭据,不应公开分享。
- 模型渠道协议:渠道编辑可选择「火山方舟」并自动填入方舟接口地址;任意名称的生图模型应按方舟 JSON 格式提交参考图,任意名称的视频模型应按方舟任务格式提交和查询,不再依赖模型名包含 `doubao`、`seedream` 或 `seedance`1080p 不应再因模型名包含 `fast` 被禁用,参考视频应允许最大 200MB、总像素 409600-8295044,并继续校验官方宽高、比例和时长限制。 - 模型渠道协议:渠道编辑可选择「火山方舟」并自动填入方舟接口地址;任意名称的生图模型应按方舟 JSON 格式提交参考图,任意名称的视频模型应按方舟任务格式提交和查询,不再依赖模型名包含 `doubao`、`seedream` 或 `seedance`1080p 不应再因模型名包含 `fast` 被禁用,参考视频应允许最大 200MB、总像素 409600-8295044,并继续校验官方宽高、比例和时长限制。
- 图片编辑弹窗:遮罩、切图和裁剪连续滚轮缩放时,图片与遮罩应保持同步且不再闪烁、短暂消失或跳动;遮罩画笔圆心应始终固定在鼠标位置,仅直径随缩放变化,缩放后仍可准确涂抹、拖动切分线和调整裁剪框。 - 图片编辑弹窗:遮罩、切图和裁剪连续滚轮缩放时,图片与遮罩应保持同步且不再闪烁、短暂消失或跳动;遮罩画笔圆心应始终固定在鼠标位置,仅直径随缩放变化,缩放后仍可准确涂抹、拖动切分线和调整裁剪框。
+1 -1
View File
@@ -867,7 +867,7 @@ function InfiniteCanvasPage() {
if (!node) return; if (!node) return;
const worldX = node.position.x + node.width / 2; const worldX = node.position.x + node.width / 2;
const worldY = node.position.y + node.height / 2; const worldY = node.position.y + node.height / 2;
const k = Math.min(Math.max(Math.min((size.width * 0.6) / node.width, (size.height * 0.6) / node.height), 0.05), 1.5); const k = Math.min(Math.max(Math.min((size.width * 0.6) / node.width, (size.height * 0.6) / node.height), 0.05), 1);
const target = { x: size.width / 2 - worldX * k, y: size.height / 2 - worldY * k, k }; const target = { x: size.width / 2 - worldX * k, y: size.height / 2 - worldY * k, k };
setSelectedNodeIds(new Set([nodeId])); setSelectedNodeIds(new Set([nodeId]));
setSelectedConnectionId(null); setSelectedConnectionId(null);