0

I used this to create my dynamic component, but I found its ElementRef isn't the right "element".

Is angular injection works wrong, or just my fault? How do I fix it?

My code

@Component({
  selector: 'animator',
  template: `<svg:animate
    nowrapper
    fill="freeze"
    [attr.attributeName]="attributeName"
    begin="indefinite"
    calcMode="spline"
    keyTimes="0; 1"
    keySplines=".2 1 1 1"
    dur="200ms"
    [attr.values]="animateValues"
  ></svg:animate>`,
})
export class AnimeComponent implements AfterViewInit {
  constructor(private elRef: ElementRef) {}

  ngAfterViewInit() {
    setTimeout(() => {
      this.anime(this.size.x, this.size.x);
    }, 0);
  }

  animateValues: `${string};${string}` = '0;0';
  size = Point.zero();
  attributeName = 'r';

  start() {
    this.anime(this.size.x, this.size.y);
  }

  end() {
    this.anime(this.size.y, this.size.x);
  }

  private anime(from: number, to: number) {
    this.animateValues = `${from};${to}`;
    this.elRef.nativeElement.beginElement();    /// error: elRef is not the <animate></animate>
  }
}

@Directive({
  selector: '[animatable]',
  exportAs: 'animatable',
})
export class AnimeDirective implements OnInit, OnDestroy {
  constructor(
    private componentFactoryResolver: ComponentFactoryResolver,
    private injector: Injector,
    private viewContainerRef: ViewContainerRef,
    private _appRef: ApplicationRef
  ) {}

  @Input('anime-attribute') attribute = 'r';

  componentRef: ComponentRef<AnimeComponent> | null = null;

  ngOnInit() {
    /// create a dynamic AnimeComponent
    this.componentRef = this.componentFactoryResolver
      .resolveComponentFactory(AnimeComponent)
      .create(this.injector);
    this._appRef.attachView(this.componentRef.hostView);
    this.componentRef.instance.attributeName = this.attribute;

    this.viewContainerRef.element.nativeElement.appendChild(
      this.componentRef.location.nativeElement
    );
  }

  start() {
    this.componentRef?.instance.start();
  }

  end() {
    this.componentRef?.instance.end();
  }

  ngOnDestroy() {
    this.componentRef?.destroy();
    this.componentRef = null;
  }
}
<circle
  cx="0"
  cy="0"
  animatable
  anime-attribute="r"
  [anime-size]="[4, 8]"
  [ngStyle]="{
     strokeDasharray: '1.5, 4',
     fill: 'rgb(255,255,255)'
  }"
  #animte="animatable"
  (mouseenter)="activeAnimate(animte, true)"
  (mouseleave)="activeAnimate(animte, false)"
></circle>
AllenEyes
  • 9
  • 2

0 Answers0