与 Angular onscroll 事件一样的视差

Parallax like with Angular onscroll event

我试图用 Angular 和 OnScroll 事件创建一种视差,但是当滚动时出现的文本闪烁。你知道如何让onscroll的效果渲染更流畅吗?也许只有 CSS?

创建的脚本 https://stackblitz.com/edit/angular-b5cmf7?file=src%2Fapp%2Fapp.component.html

实现这个效果的主要函数就是这个

  @HostListener('window:scroll', ['$event'])
  isScrolledIntoView(){
    const offsetHeight = this.testDiv.nativeElement.children[0].offsetHeight; 
    const rect = this.testDiv.nativeElement.getBoundingClientRect();
    if( rect.bottom <= window.innerHeight){ // when the div is visible in viewport change the height (not more than the height of the content)
      let height = (window.innerHeight - rect.bottom);
      if(height<offsetHeight){
        this.height = height;
      }else{
        this.height = offsetHeight
      }
    }
  }

一看到您的闪电战,我就意识到了一个我 运行 多次遇到的问题。这与如何在 per-frame 基础上计算值有关。我不确定如何最好地用语言表达它,但它是这样的:

Don't base your calculations on values that will be modified by the result.

有点抽象,但具体到你的情况,问题出在rect.botthis.height之间的关系上。每次调用 onscroll 函数时,您都会修改部分的高度。但是修改高度也会修改rect.bot的值,在下一个滚动事件中,你会得到不同的结果,所以高度从不同的基数修改,导致你观察到的振荡。

为避免这种情况,您希望所有计算仅基于不受结果影响的值。在这种情况下,我建议使用 rect.top,它不关心该部分的高度是多少。

此外,我建议使用插值法,因为它可以让您更好地控制。这个想法是你想选择这些值:

  • 显示应该在 window 高度的多少百分比处开始(实际上,this.height = 0
  • 该部分应在 window 高度的多少百分比处完全显示(this.height = offsetHeight)
  • 我应该如何在这两个值之间进行插值? (最简单的是线性的)

所以我分叉了你的闪电战,我继续前进并从这里彻底窃取了 clampinvlerp 函数:

https://www.trysmudford.com/blog/linear-interpolation-functions/

您可以在 link.

中了解这些插值函数及其用途

你会看到我创建了两个名为“startPercentage”和“endPercentage”的变量——它们与 rect.top 的值相关,作为 window innerHeight 的百分比。您可以使用这些来获得不同的速度或视差质量,以获得您喜欢的效果。

这是叉子:

https://stackblitz.com/edit/angular-lcyc4q?file=src%2Fapp%2Fapp.component.ts

如果您愿意,可以研究其他插值函数,用 ease-in 和 ease-out 试验不同的效果。