如何在视窗内添加自定义装饰
基本使用
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的视窗上出现。
其大概流程如下所示: