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>