So I'm trying to do an animation that moves the divs and fades them based on the scroll distance. I've got the transform working,but the opacity change only appears to work on desktop. When viewing it from my mobile device (iOS safari, and iOS firefox) the opacity doesn't change, and I cannot figure out why. These animations also appear choppy when scrolling on mobile, but not on desktop.
@HostListener('window:scroll', ['$event'])
@HostListener('window:touchmove', ['$event'])
onScroll(): void {
if (this.isEffectActive) {
/* get position of the bottom of the component */
const introductionContainerBottomPos =
this.elementRef.nativeElement.offsetTop +
this.elementRef.nativeElement.offsetHeight;
const scrollPos = window.scrollY;
const distance =
introductionContainerBottomPos -
this.clamp(scrollPos, 0, introductionContainerBottomPos);
const val = this.lerp(0, 1, distance / introductionContainerBottomPos);
this.fadeValue = Math.round(val * 100) / 100;
window.requestAnimationFrame(() => {
this.container.nativeElement.style.opacity = this.fadeValue;
this.container.nativeElement.style.transform = `translateY(${this.getTranslation()}px)`;
this.container2.nativeElement.style.opacity = this.fadeValue;
this.container2.nativeElement.style.transform = `translateY(${this.getTranslation()}px)`;
});
}
}
Anyone know a better solution?
I've tried changing the filter: alpha but that didn't work. I tried inlining the opacity, but that doesn't work either.
EDIT: I've refactored it to add some of the suggestions in the comments:
@HostListener('window:scroll', ['$event'])
@HostListener('window:touchmove', ['$event'])
onScroll(): void {
/* get position of the bottom of the component */
const introductionContainerBottomPos =
this.container.nativeElement.offsetTop +
this.container.nativeElement.offsetHeight;
const scrollPos = window.scrollY;
const distance =
introductionContainerBottomPos -
this.clamp(scrollPos, 0, introductionContainerBottomPos);
const val = this.lerp(0, 1, distance / introductionContainerBottomPos);
this.fadeValue = Math.round(val * 100) / 100;
window.requestAnimationFrame(() => {
this.title.nativeElement.style.opacity =
this.fadeValue > 0 ? this.fadeValue : 0;
this.body.nativeElement.style.opacity =
this.fadeValue > 0 ? this.fadeValue : 0;
});
window.requestAnimationFrame(() => {
this.title.nativeElement.style.transform =
this.fadeValue > 0
? `translateY(${this.getTranslation()}px)`
: this.container.nativeElement.style.transform;
this.body.nativeElement.style.transform =
this.fadeValue > 0
? `translateY(${this.getTranslation()}px)`
: this.container.nativeElement.style.transform;
});
}
Looks like this.elementRef is Nan on mobile, so using a ViewChild fixes that, which fixed the fading value not being updated on mobile. I've fixed half my issues, but now I've noticed the touchmove event runs the animation much smoother than scroll does (I think it gets updated more frequently thus allowing a smoother looking animation. Is there a better even to use than scroll? Or maybe a life cycle hook that could help me?
will-changeproperty to the elements you're animating.2.Throttling: Implement a debounce function to throttle the scroll event handler. You can use a library like lodash or implement a simple debounce function yourself.
3:Optimize Opacity Changes: Use Angular's animation module to handle opacity changes. Define animations in your component's TypeScript file using Angular's animation DSL.
code
These approaches should help optimize your Angular code for better performance and compatibility across different devices and browsers. Adjust the values and settings as needed for your specific use case.