唯杰地图 logo唯杰地图
VJMAP
EN

preview

vjmapext/references/drawing/preview.md 5.0 KB146 行
原文

本文回答:PreviewManager.setPreviewEntities / clear —— 绘制命令里的橡皮筋实时预览。

一、是什么

用户在点第二个点之前,鼠标在动 → 实时显示一条"临时直线",跟随鼠标 → 点击确认才落地成真实实体。

这条"临时直线"就是 预览实体,由 PreviewManager 管。

二、API

ctx.previewManager.setPreviewEntities(entities: EntityBase[]): void
ctx.previewManager.setPreviewFeatures(features: GeoJSON.Feature[]): void
ctx.previewManager.setPolylineVertices(points: Point2D[]): void  // 折线绘制中记录已确认顶点
ctx.previewManager.clearPolylineVertices(): void
ctx.previewManager.clear(): void        // 注意:方法名是 clear(),不是 clearPreview()
ctx.previewManager.getFeatures(): GeoJSON.Feature[]
ctx.previewManager.setPreviewColor(hex: string | null): void  // 覆盖预览色(默认跟 drawingDefaults.color)

三、和 getPoint 的 callback 搭配

PointInputOptions.callback(字段名是 callback,不是 onMouseMove)在光标移动时触发,参数是当前 CAD 坐标点:

class PreviewLineCmd {
  async main(ctx) {   // 实例方法,不能写 static
    const { inputManager: im, previewManager: pm, store, drawingDefaults: defaults } = ctx;

    const p1 = await im.getPoint({ message: '指定起点' });
    if (p1.status !== 'ok') return;

    const p2 = await im.getPoint({
      message: '指定终点',
      useBasePoint: true,            // 橡皮筋开关是 useBasePoint,不是 rubberBand
      basePoint: p1.value,           // 点结果在 .value,不是 .point
      callback: cur => {
        const preview = new vjmapext.LineEnt(p1.value, cur);   // 预览色由 pm 统一覆盖,设 color 无效
        pm.setPreviewEntities([preview]);
      }
    });

    pm.clear();              // 无论成功取消都清
    if (p2.status !== 'ok') return;

    const line = new vjmapext.LineEnt(p1.value, p2.value);
    line.color = defaults.color;
    store.add(line);
  }
}

四、多预览实体

callback: cur => {
  const line1 = new vjmapext.LineEnt(p1.value, cur);
  const line2 = new vjmapext.LineEnt(p2.value, cur);
  const marker = new vjmapext.CircleEnt(cur, 5);
  pm.setPreviewEntities([line1, line2, marker]);
}

内部会把整组合并一次绘制,不闪。

五、getFeatures(序列化用)

const feats = pm.getFeatures();
// GeoJSON.Feature[],可叠加到其他图层或调试打印

六、与内置橡皮筋的区别

对象 内置橡皮筋 setPreviewEntities
触发 getPoint({ useBasePoint: true, basePoint }) 显式 set
形状 只能一条直线 任意实体数组
样式 系统虚线 不继承实体颜色/线宽:color 被预览色覆盖(默认 = drawingDefaults.color),线一律 1px 虚线、点 4px;只保留多边形的 fillColor/fillOpacity
用途 标准距离 / 方向显示 复杂形状 / 多对象预览

一般:

  • 画 LINE → 只用橡皮筋够了
  • 画 RECTPOLY / CIRCLE / 带文字的标注 → 用 setPreviewEntities

七、性能

setPreviewEntities 每次调用替换上一次内容;内部做了重绘合并,不需要手动 RAF。

但 callback 每帧都 fire → 如果每帧生成 100+ 预览实体可能卡;建议复用同一个实体对象:

const preview = new vjmapext.LineEnt(p1.value, p1.value);
callback: cur => {
  preview.endPoint = cur;
  pm.setPreviewEntities([preview]);
}

八、预览 Hatch 填充

callback: cur => {
  const loop = [
    p1.value,
    [cur.x, p1.value.y],   // 环用 [x,y] 数组(Point2DLike)
    cur,
    [p1.value.x, cur.y],
    p1.value
  ];
  const hatch = new vjmapext.HatchEnt(loop);   // 构造收扁平点数组(>=3 点成 1 个 outer 环)
  hatch.fillColor = 0xff0000;
  hatch.fillOpacity = 0.3;
  pm.setPreviewEntities([hatch]);
}

画矩形填充时的预览。

九、命令取消时的清理

try {
  const p = await im.getPoint({ message: '...', callback: cur => { ... } });
  ...
} finally {
  pm.clear();   // 无论 OK / Cancel 都清
}

或用 CommandContext 的生命周期:命令流程自然结束时 PreviewManager 会清掉,但显式 clear 更保险。

十、常见坑

  1. 忘 pm.clear():预览实体残留画面上(注意不是 clearPreview(),那个方法不存在)。
  2. 预览实体被加到 store:预览不是 store 里的;不要 store.add(preview);只 setPreviewEntities。
  3. 每帧 new 100 次 Entity:GC 压力大;复用同一个实体对象。
  4. 预览颜色 = drawingDefaults.color 看不清:给预览实体设 color 没用(会被统一覆盖);改用 pm.setPreviewColor('#ff00ff') 换预览色(注意 setDrawingDefaults 会把它同步回默认色)。

相关