在动态Angular组件中进行Three.js渲染

时间:2018-07-21 12:02:12

标签: javascript angular typescript three.js rendering

当前正在Angular中动态创建的three.js组件上工作。静态(通过选择器)创建的 Plot3dComponent 效果很好。但是,当通过ComponentFactoryResolver动态创建它时,该组件不会呈现任何内容。还尝试使用setTimeout添加一些延迟,但是我无法渲染任何内容。 save函数的图像输出只是一个具有所需宽度和高度的白色矩形,就像canvas元素一样。你有什么想法吗?

我用来渲染组件的模板

<ng-container #plot3dref></ng-container>

缩小的组件类如下

@ViewChild('plot3dref', {read: ViewContainerRef}) plot3dref: ViewContainerRef;

save(geometry: Geometry) {
  const componentFactory = this.componentFactoryResolver.resolveComponentFactory(Plot3dComponent);
  const componentRef = this.plot3dref.createComponent(componentFactory);
  const instance = (<Plot3dComponent>componentRef.instance);

  instance.geometry = geometry;
  instance.materials = this.materials;
  instance.selectedBlock = -1;

  console.log(instance.save());
}, 100);

缩小的 Plot3dComponent 看起来像这样

@Component({
  selector: 'app-plot-3d',
  template: '<canvas #canvas></canvas>',
  styles: [`:host { width: 100%; } canvas { width: 100%; }`],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class Plot3dComponent implements OnInit, AfterViewInit, OnDestroy {
  @ViewChild('canvas') private canvasRef: ElementRef;
  @Input() geometry: Geometry;
  @Input() selectedBlock: number;
  @Input() materials: Material[];
  [...]

  ngOnInit() { this.render = this.render.bind(this); }
  save() { return this.canvasRef.nativeElement.toDataURL(); }

  ngAfterViewInit() {
    this.startRendering();
  }

  private startRendering() {
    this.renderer = new THREE.WebGLRenderer({
      canvas: this.canvas,
      antialias: true,
      preserveDrawingBuffer: true
    });

    const component: Plot3dComponent = this;

    (function render() {
      component.render();
    }());
  }
}

谢谢,加油!

编辑:该问题似乎也出现在 @ angular / material mat-tab-groups中。还在那里测试了固定高度。

1 个答案:

答案 0 :(得分:0)

实际上使它可以同时用于静态和动态组件创建。使用工作示例创建了最小的stackblitz。这是相关的代码段。

export class DynamicComponent {
  @ViewChild('canvas') private canvasRef: ElementRef;
  [...]

  ngOnInit() {
    const renderer = new WebGLRenderer();
    renderer.setSize(200, 150);
    this.canvasRef.nativeElement.append(renderer.domElement);
    [...]
}