Skip to content

[Bug]: 画折线(polyline)过程中按 Ctrl 切换 drawlineH(先横后竖 ↔ 先竖后横), **只对前两段生效;从第三段起按键被静默忽略**,当前段走向始终由 "与上一段正交续接"强制决定。 #293

Description

@CMRdev

Code Sanbox异常重现

No response

bug描述

问题描述

画折线(polyline)过程中按 Ctrl 切换 drawlineH(先横后竖 ↔ 先竖后横),
只对前两段生效;从第三段起按键被静默忽略,当前段走向始终由
"与上一段正交续接"强制决定。

环境

  • @meta2d/core 1.1.19(npm 包,src 源码定位)
  • Chrome / macOS(与平台无关,纯逻辑问题)
  • 使用原生 meta2d 即可复现,无需特定编辑器封装

复现步骤

  1. meta2d.drawLine('polyline') 进入折线绘制(或编辑器连线选"折线");
  2. 落第 1 个锚点 → 移动鼠标 → 按 Ctrl:走向翻转,生效 ✓;
  3. 落第 2 个锚点(第 2 段)→ 按 Ctrl:生效 ✓;
  4. 落第 3 个锚点(第 3 段起)→ 按 Ctrl:无任何效果 ✗,
    走向永远是"垂直于上一段",无论按多少次。

根因分析

三个代码位置(以 1.1.19 src 为准):

1. 键盘层无段数限制 —— canvas.js onkeydown:

case 'Control':
    if (this.drawingLine) {
        this.drawingLine.calculative.drawlineH =
            !this.drawingLine.calculative.drawlineH;
    }

2. 每段落点后重置 —— canvas.js(落锚点处):

this.drawingLine.calculative.drawlineH = undefined;

3. 渲染层提前 return —— polyline.js getNextPoints:

function getNextPoints(pen, from, to) {
    const pts = [];
    // ① 自动赋值先于正交分支执行:把 undefined(未定)覆盖为位移判定值
    if (pen.calculative.drawlineH == undefined) {
        pen.calculative.drawlineH =
            Math.abs(to.x - from.x) > Math.abs(to.y - from.y);
    }
    let index = pen.calculative.worldAnchors.findIndex(
        (anchor) => anchor.id == from.id
    );
    if (index > 1) {                                  // ② 第三段起(from 下标 ≥ 2)
        let prev = pen.calculative.worldAnchors[index - 1];
        if (prev.x === from.x && prev.y !== from.y) {
            pts.push({ x: to.x, y: from.y });
            return pts;                               // ③ 直接返回,drawlineH 不再被消费
        } else if (prev.y === from.y && prev.x !== from.x) {
            pts.push({ x: from.x, y: to.y });
            return pts;
        }
    }
    // drawlineH 分支只在前两段可达
    ...
}

由此产生三个问题:

# 问题 说明
1 交互承诺与渲染兑现不一致 键盘层对任意段都翻转字段,渲染层第三段起忽略
2 死写入 ①的自动赋值在第三段起照常执行,随后被 ③ 绕过,字段被维护但永不参与计算
3 数据模型无法自愈 drawlineH 同时承载"自动判定值"和"手动覆盖值",且自动赋值在正交分支之前执行——即使想在 ③ 处优先尊重手动值,也无法区分当前值是鼠标位移算的还是用户按 Ctrl 设的

其中第 3 点是根因:这不是调一个分支就能修的,需要数据模型上区分手动/自动。

修复建议

方案 A(推荐):独立手动标记

// keydown:
case 'Control':
    if (this.drawingLine) {
        this.drawingLine.calculative.drawlineH =
            !this.drawingLine.calculative.drawlineH;
        this.drawingLine.calculative.drawlineHManual = true;  // 新增
    }

getNextPoints 中 index > 1 分支改为:手动标记存在 → 按 drawlineH 路由;
否则按现有正交续接。落锚点时只清 drawlineHManual 与 drawlineH。
calculative 不参与序列化,无存量数据兼容风险。

方案 B(最小改动):自动赋值惰性化

把 ①的自动赋值移入 index <= 1 的路径;index > 1 分支改为
drawlineH !== undefined ? 按 drawlineH : 正交续接。需要注意 keydown
对 undefined 翻转得 true 的时序语义(按键发生在本段首次 mousemove
之前还是之后结果不同),建议配合"手动即视为已定义"的赋值方式。

临时规避

在修复前,使用方只能按"前两段可 Ctrl、第三段起由锚点位置决定走向"
的真实行为引导用户(我们已在产品提示文案中如实描述)。

若新版本已修复此问题,请忽略并告知版本号,谢谢!

期待效果

画线全程按 Ctrl 均可切换当前段横竖顺序(官方教程对折线 Ctrl 的描述
是通用的"切换横竖方向",未提段数限制)。若"第三段起强制正交"是有意
设计,也应在文档中说明,且按键不应表现为"无响应"。

发生频率

每次

核心库版本

1.1.19

浏览器版本

No response

其他需要补充的

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions