Issue
I created a header that reveals a shape while scrolling down the page. This worked exactly as planned however when using multiple instances of the same component (for multiple headers) all instances take on the values of the first instance.
Presumably this is because I am using GetElementById()
and with multiple instances there are now multiple div
s with the same ID. The way I am binding the style may also be causing similar issues.
How can I get each script to access only the DOM element within its own component and how can I dynamically set the style for those elements?
app.comonent.html
<div class="columns mt-5 ml-5 mr-5">
<div class="column is-12">
<app-title></app-title>
</div>
</div>
<div class="columns mt-5 ml-5 mr-5">
<div class="column is-12">
<app-title></app-title>
</div>
</div>
title.component.html
<div class="background">
<div class="item">
<span class="title titleMain">Unity Projects</span>
<div [style]="polygonDivStyle">
<div class="titleDiv" id="unityTitle" [style]="unityClipPath">
<svg id="triangle" width="320" height="320">
<polygon points="155, 30 280, 280 30, 280" stroke-width="30" stroke="#FF6EFF" fill="none" />
</svg>
</div>
</div>
</div>
</div>
title.component.ts
import { Component, OnInit, HostListener} from '@angular/core';
@Component({
selector: 'app-title',
templateUrl: './title.component.html',
styleUrls: ['./title.component.css']
})
export class TitleComponent implements OnInit {
contactClipPath!: string;
contactTitle!: HTMLDivElement | null;
unityClipPath!: string;
unityTitle!: HTMLDivElement | null;
polygonDivStyle!: string;
constructor() { }
ngOnInit(): void {
this.unityClipPath = `-webkit-clip-path: polygon(0% 0%);`;
this.unityTitle = document.getElementById('unityTitle') as HTMLDivElement| null
this.RadialReveal(this.unityTitle, this.unityClipPath);
this.polygonDivStyle = "";
}
@HostListener('window:scroll', ['$event'])
onScroll(event:Event){
this.RadialReveal(this.unityTitle, this.unityClipPath);
}
RadialReveal(clip:HTMLDivElement | null, clipPath:string) {
let top = clip?.getBoundingClientRect().top;
let scrollPercent = 0;
if(top && visualViewport)
scrollPercent= ((top / visualViewport.height) * 300 -100);
if (clip != null && scrollPercent > 1 && scrollPercent < 100) {
this.polygonDivStyle = '';
let scrollOpposite = 100 - scrollPercent;
if(scrollOpposite >= 0 && scrollOpposite < 33)
{
clipPath = `-webkit-clip-path: polygon(0% `+[scrollPercent-67]+`% ,50% 33%, 0% 33%, 0% 66%, 100% 66%, 100% `+[scrollOpposite+66]+`%, 50% 66%, 0% 66%);`;
}
else if(scrollOpposite >= 33 && scrollOpposite < 66)
{
clipPath = `-webkit-clip-path: polygon(0% 0%, `+[(scrollOpposite-34)*3]+`% 0% ,50% 33%, 0% 33%, 0% 100%, `+[(scrollPercent-34)*3]+`% 100%, 50% 66%, 100% 66%, 100% 100%, 0% 100%);`;
}
else if(scrollOpposite >= 66 && scrollOpposite <= 100)
{
clipPath = `-webkit-clip-path: polygon(0% 0%, 100% 0% , 100% `+[33-scrollPercent]+`% ,50% 33%, 0% 33%, 0% `+[scrollPercent+66]+`%,50% 66%, 100% 66%, 100% 100%, 0% 100%);`;
}
}
else if(scrollPercent > 100)
{
clipPath = `-webkit-clip-path: polygon(0% 0%);`;
}
else if(scrollPercent < 1)
{
clipPath = `-webkit-clip-path: polygon(0% 0%, 100% 0% , 100% 33% ,50% 33%, 0% 33%, 0% 66%,50% 66%, 100% 66%, 100% 100%, 0% 100%);`;
this.polygonDivStyle = 'filter: drop-shadow(10px 10px 200px #ff00ff) drop-shadow(-10px -10px 50px #ff00ff);'
}
this.unityClipPath = clipPath;
}
}
Solution
Instead of using getElementById within the title component try using @ViewChild
@Component({
selector: 'app-title',
templateUrl: './title.component.html',
styleUrls: ['./title.component.css']
})
export class TitleComponent implements AfterViewInit {
@ViewChild('unityTitle') unityTitle!: ElementRef;
// your code goes here
ngAfterViewInit(): void {
// you can access the properties where you would normally do in elementRef
this.unityTitle.nativeElement.style.color = '#FFFFFF';
this.unityTitle.nativeElement.style.backgroundColor = '#5789D8';
}
}
In your html. (Note the usage of html reference #unityTitle)
<div class="background">
<div class="item">
<span class="title titleMain">Unity Projects</span>
<div [style]="polygonDivStyle">
<div #unityTitle class="titleDiv" id="unityTitle" [style]="unityClipPath">
<svg id="triangle" width="320" height="320">
<polygon points="155, 30 280, 280 30, 280" stroke-width="30" stroke="#FF6EFF" fill="none" />
</svg>
</div>
</div>
</div>
</div>
Answered By - Kelum Bandara
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.