Skip to content

.2869047221311500:d1605857934ecebd3b1e7bba0941d126_69e614bbf51efcfb0ecaa3bf.69e619e0f51efcfb0ecaa3c3.69e619e0d90ca3ecca53d178:Trae CN.T(2026/4/20 20:19:44)#372

Open
Juebandoctor wants to merge 1 commit into
1j01:masterfrom
Juebandoctor:Trae_2

Conversation

@Juebandoctor
Copy link
Copy Markdown

实现参考图片功能,包括加载、显示/隐藏、调整透明度和移除参考图片
添加相关CSS样式和菜单选项
创建ReferenceImage类处理参考图片的显示和交互

实现参考图片功能,包括加载、显示/隐藏、调整透明度和移除参考图片
添加相关CSS样式和菜单选项
创建ReferenceImage类处理参考图片的显示和交互
Copilot AI review requested due to automatic review settings April 20, 2026 12:48
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

该 PR 为应用加入“参考图片”功能,用于在画布上加载并显示一张可调整透明度、可显示/隐藏、可移除且可拖拽/缩放的覆盖图片,以便临摹/对照绘制。

Changes:

  • 新增 ReferenceImage 画布对象类,处理参考图片的显示、拖拽与缩放交互
  • 在 View 菜单中加入“Reference Image”子菜单(加载/显示隐藏/透明度/移除)
  • 增加参考图片相关 CSS(层级、渲染与指针事件)

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
styles/layout.css 添加 .reference-image 样式(层级、canvas 渲染、指针事件)
styles/layout.rtl.css RTL 版本对应样式更新
src/menus.js View 菜单新增 Reference Image 子菜单入口
src/functions.js 增加参考图片加载/显示隐藏/透明度/移除等函数并导出
src/ReferenceImage.js 新增 ReferenceImage 类(OnCanvasObject + Handles + 拖拽手柄)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread styles/layout.css
Comment on lines +135 to +141
.reference-image {
z-index: 2.5;
display: block !important;
box-sizing: border-box;
-moz-box-sizing: border-box;
pointer-events: none;
}
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.reference-image sets display: block !important;, which will override jQuery .hide()/.show() (inline display: none without !important). As a result, ReferenceImage.hide()/toggle() may not actually hide the element. Remove the !important (or use visibility/opacity for toggling) so runtime show/hide works.

Copilot uses AI. Check for mistakes.
Comment thread styles/layout.css
z-index: 3;
}
.reference-image {
z-index: 2.5;
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

z-index only accepts integers; z-index: 2.5; is invalid and will be ignored by the browser, which can break layering (e.g., reference image may appear above selections/handles depending on DOM order). Use an integer z-index that fits the existing stacking scheme.

Suggested change
z-index: 2.5;
z-index: 2;

Copilot uses AI. Check for mistakes.
Comment thread src/functions.js
Comment on lines +1827 to +1830
if (reference_image) {
reference_image.destroy();
}

Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reference_image is used as a writable global, but there’s no definition/initialization for it anywhere else in the repo (search only finds it in this PR). In an ES module this will throw a ReferenceError the first time load_reference_image() evaluates if (reference_image). Define it (e.g., module-scoped let reference_image = null; in this file, or initialize window.reference_image with a corresponding global binding at startup).

Copilot uses AI. Check for mistakes.
Comment thread src/functions.js
Comment on lines +1818 to +1820
const { file } = await systemHooks.showOpenFileDialog({ formats: image_formats });
if (file.type.match(/^image|application\/pdf/)) {
read_image_file(file, (error, info) => {
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

systemHooks.showOpenFileDialog can throw on user cancel (e.g., Electron implementation throws "user canceled", and showOpenFilePicker rejects with an AbortError). load_reference_image() doesn’t handle this, so canceling can surface as an unhandled rejection / internal error. Wrap the dialog call in try/catch and return early on cancel (and/or guard file before reading file.type).

Copilot uses AI. Check for mistakes.
Comment thread src/ReferenceImage.js
Comment on lines +68 to +72
const rect = this.canvas.getBoundingClientRect();
const cx = e.clientX - rect.left;
const cy = e.clientY - rect.top;
mox = ~~(cx / rect.width * this.canvas.width);
moy = ~~(cy / rect.height * this.canvas.height);
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The move-handle drag offset is computed from this.canvas.getBoundingClientRect(), but the handle is positioned outside the canvas bounds (negative left). Clicking the handle will produce negative cx/cy, causing mox/moy to be wrong and the reference image to jump when dragging starts. Compute the offset from the object position (e.g., using to_canvas_coords(e) relative to this.x/this.y) instead of using the canvas rect.

Suggested change
const rect = this.canvas.getBoundingClientRect();
const cx = e.clientX - rect.left;
const cy = e.clientY - rect.top;
mox = ~~(cx / rect.width * this.canvas.width);
moy = ~~(cy / rect.height * this.canvas.height);
const m = to_canvas_coords(e);
mox = m.x - this.x;
moy = m.y - this.y;

Copilot uses AI. Check for mistakes.
Comment thread src/ReferenceImage.js
height = Math.max(1, height);

const new_canvas = make_canvas(width, height);
new_canvas.ctx.imageSmoothingEnabled = true;
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_resize() sets new_canvas.ctx.imageSmoothingEnabled = true, which conflicts with the CSS image-rendering: pixelated intent and with make_canvas() defaulting to smoothing disabled. Resizing the reference image will likely blur it. Use disable_image_smoothing() (or set imageSmoothingEnabled = false) when scaling if you want crisp/pixelated results.

Suggested change
new_canvas.ctx.imageSmoothingEnabled = true;
new_canvas.ctx.imageSmoothingEnabled = false;

Copilot uses AI. Check for mistakes.
Comment thread src/ReferenceImage.js
Comment on lines +120 to +133
_update_canvas_opacity() {
this.canvas.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.canvas.ctx.globalAlpha = this._opacity;
this.canvas.ctx.drawImage(this._original_canvas, 0, 0, this.width, this.height);
this.canvas.ctx.globalAlpha = 1;
}

/**
* @param {number} opacity - 0 to 1
*/
set_opacity(opacity) {
this._opacity = Math.max(0, Math.min(1, opacity));
this._update_canvas_opacity();
}
Copy link

Copilot AI Apr 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_opacity() redraws the entire reference image bitmap on every slider input event via _update_canvas_opacity(). For large images this can cause noticeable CPU usage/lag while dragging the slider. Consider applying opacity via CSS on the canvas/element (and only redrawing on resize) to make opacity changes cheap.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants