如何在视窗内添加自定义装饰
基本使用
Imodel.js可以在前端视窗内添加/删除用户自定义装饰(Decorator)。其类层次如下所示:
其中AccuSnap,HyperModelingDecorator是imodel.js系统预定义的装饰(Decorator),CustomDecorator是用户自定义装饰(Decorator),也就说用户至少需要实现接口Decorator中的decorate(context: DecorateContext): void方法即可实现自己的装饰(Decorator)。然后创建CustomDecorator的实例customDecorator,并调用:IModelApp.viewManager.addDecorator(customDecorator);即可将自定义装饰(Decorator)显示在视窗上,同时调用IModelApp.viewManager.dropDecorator(d)可将自定义装饰(Decorator)从视窗上删除。
示例
希望在视窗上显示一个用户自定义三角形,效果如下所示:
使用以下代码即可实现:
class CustomDecorator implements Decorator {
public decorate(context: DecorateContext) {
// draw semi-transparent polyline from top left to bottom right of vp
const overlayBuilder = context.createGraphicBuilder(
GraphicType.ViewOverlay
);
const polylineColor = ColorDef.from(0, 255, 0, 128);
overlayBuilder.setSymbology(polylineColor, polylineColor, 10);
const ps: Point3d[] = [
new Point3d(100, 0, 0),
new Point3d(100, 500, 0),
new Point3d(500, 500, 0),
new Point3d(100, 0, 0),
];
overlayBuilder.addShape(ps);
context.addDecorationFromBuilder(overlayBuilder);
}
}
const cd = new CustomDecorator();
//添加装饰
IModelApp.viewManager.addDecorator(cd);
//删除装饰
IModelApp.viewManager.dropDecorator(cd);
原理
IModelApp.viewManager维护着一个Decorator[]数组,每当显式调用:IModelApp.viewManager.addDecorator或IModelApp.viewManager.dropDecorator的时候遍历标记所有viewport中的_decorationsValid为无效(异常情况下不会触发此标记),然后主动调用IModelApp.requestNextAnimation()以更新帧,因为此时_decorationsValid已经被标记为无效,所以会将IModelApp.viewManager维护者的Decorator[]数组中的所有内容更新到窗口上。注意,通过IModelApp.viewManager.addDecorator添加的装饰(Decorator)会在所有的ViewState的视窗上出现。
其大概流程如下所示: