首页 文章

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

提问于
浏览
2

目前正在开发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();
    }());
  }
}

谢谢,干杯!

Edit: 问题似乎也发生在@ angular / material的 mat-tab-groups 中 . 还在那里测试了固定高度 .

1 回答

  • 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);
        [...]
    }
    

相关问题