File

projects/atft/src/lib/effect/dashed-draw.directive.ts

Implements

AfterViewInit OnDestroy

Metadata

Index

Properties
Methods
Inputs

Constructor

constructor(host: AbstractObject3D<any>, animationService: AnimationService)
Parameters :
Name Type Optional
host AbstractObject3D<any> No
animationService AnimationService No

Inputs

dashColor
Type : string | number
Default value : '#FF0000'
dashIncrement
Type : number
Default value : 10
hideDash
Type : boolean
Default value : false
initialOpacity
Type : number
targetOpacity
Type : number

Methods

Private animate
animate()
Returns : void
ngAfterViewInit
ngAfterViewInit()
Returns : void
ngOnDestroy
ngOnDestroy()
Returns : void
Private tryToFindGeometry
tryToFindGeometry()
Returns : void

Properties

Protected animation
Type : Subscription
Private edges
Type : any
Private material
Type : THREE.Material
Private stop
Default value : false
import {AfterViewInit, Directive, Input, OnDestroy} from '@angular/core';
import {AbstractObject3D} from '../object/abstract-object-3d';
import * as THREE from 'three';
import {AnimationService} from '../animation/animation.service';
import {Subscription} from 'rxjs';

@Directive({selector: '[atft-dashed-draw]'})
export class DashedDrawDirective implements AfterViewInit, OnDestroy {

  @Input() dashColor: string | number = '#FF0000';
  @Input() dashIncrement = 10;
  @Input() initialOpacity! : number;
  @Input() targetOpacity! : number;
  @Input() hideDash = false; // hide dash lines at the end of animation

  private edges: any;
  private material!: THREE.Material;
  private stop = false;
  protected animation!: Subscription;

  constructor(
    private host: AbstractObject3D<any>,
    private animationService: AnimationService
  ) {
  }

  ngAfterViewInit(): void {
    // console.log('DashedDrawDirective.ngAfterViewInit: Dashed draw for', this.host);
    this.tryToFindGeometry();
    this.animate = this.animate.bind(this);
    this.animation = this.animationService.animate.subscribe(this.animate);
    this.animationService.start();
  }


  private tryToFindGeometry() {
    const object = this.host.getObject() as THREE.Object3D;
    object.traverse(child => {
      const findMesh = (child instanceof THREE.Mesh ? child : child.children[0]);

      if (findMesh && findMesh instanceof THREE.Mesh && !this.edges) {
        // console.log('DashedDrawDirective.ngAfterViewInit: child', findMesh);

        const edgesGeom = new THREE.EdgesGeometry(findMesh.geometry, 8);
        this.edges = new THREE.LineSegments(edgesGeom, new THREE.LineDashedMaterial({color: this.dashColor}));
        this.edges.computeLineDistances();
        this.edges.material.dashSize = 0;
        this.edges.material.gapSize = this.edges.geometry.attributes
          .lineDistance.array[this.edges.geometry.attributes.lineDistance.count - 1];
        this.material = findMesh.material as THREE.Material;
        console.log('DashedDrawDirective.tryToFindGeometry original material', this.material);

        if (this.initialOpacity >= 0.0) {
          // console.log('initialOpacity', this.initialOpacity);
          if (!this.material.transparent) {
            this.material.transparent = true;
            this.material.depthWrite = true;
            this.material.needsUpdate = true;
          }
          this.material.opacity = this.initialOpacity;
        }
        findMesh.add(this.edges);
      } else {
        // console.log('DashedDrawDirective.ngAfterViewInit: cant find geometry yet');
      }
    });
  }

  private animate() {
    // console.log(this.host.getObject().parentScene);
    if (!this.stop) {
      if (this.edges) {
        this.edges.material.dashSize += this.dashIncrement;
        if (this.edges.material.dashSize >= this.edges.material.gapSize) {

          if (this.hideDash) {
            this.edges.parent.children = [];
          }
          if (this.targetOpacity >= 0.0) {
            this.material.opacity = this.targetOpacity;
            if (this.targetOpacity === 1) {
              this.material.transparent = false;
            }
          }
          this.stop = true;
        }
      } else {
        this.tryToFindGeometry();
      }
    }

  }

  ngOnDestroy() {
    this.animation?.unsubscribe();
  }

}

results matching ""

    No results matching ""