【问题标题】:Achieve fluid skew transform on scroll在滚动上实现流体倾斜变换
【发布时间】:2018-03-16 10:02:11
【问题描述】:

我一直在尝试重新创建在此网站 www.section32.com 上完成的滚动效果,其中元素与向上或向下滚动相对应而倾斜。

我试图做到这一点的方法是在一个滚动到一个限制时更新 transform:skew 值,然后当它们停止滚动以转换回来时。

但是,这里的效果非常流畅。看看他们的代码,他们正在使用变换矩阵,但不是所有可以在矩阵中完成的事情都可以用正常的变换值完成吗?

如何实现这种效果并使其像这里一样流畅?

这是我的代码:

window.onscroll=function(){
        if(!os) os=window.pageYOffset; //original scrollTop value
        if(window.pageYOffset-os>0 && ns>-3) ns-=0.125;
        else if(window.pageYOffset-os<=0 && ns<3) ns=Math.abs(ns+=1);
        clearTimeout(timer);
        for(var i=0; i<items.length; i++){
            items[i].style.transform="skew("+ns+"deg) translateY("+ns/2+"px) rotate("+ns/-7+"deg)";
        }
        timer=setTimeout(function(){
            //console.log('scrolling done!', window.pageYOffset);
            for(var i=0; i<items.length; i++){
                items[i].className+=" inPlace";
                items[i].addEventListener('transitionend', function(){
                    var n=this.className;
                    n=n.replace(/inPlace/g, "");
                    this.style.transform="skew(0)";
                    this.className=n;
                });
            }
            os=timer=null;
            ns=-1;
        }, 100);
    };

【问题讨论】:

  • 我们可以有一个完整的代码来看看发生了什么吗?

标签: javascript css matrix css-transitions transform


【解决方案1】:

像 @Temani Afif's answer 一样,您的元素可能缺少 transition 属性。

我可以补充的另一件事是(并非您的所有逻辑都在这里,因此您可能已经这样做了)您需要计算滚动的加速度。在您提供的页面中,如果您快速滚动,元素会倾斜更多,如果您滚动缓慢,您甚至不会注意到它们是倾斜的。所以滚动事件的触发频率必须在计算中。

【讨论】:

  • 你如何计算滚动的加速度?我没有这样做,但我将如何做到这一点是最终滚动值 - 原始滚动值,但只有在滚动完成后才会设置样式,因为只有这样我才知道最终滚动值。现在我在每次滚动更改时都在设计样式,然后在滚动完成后恢复。我已经在使用过渡,这就是我正在监听 transitionend 并在完成后将其修复回 skew(0) 的方式。
  • Here 是关于如何计算滚动速度的一个很好的答案,您可以使用类似的示例来说明您正在尝试做什么。我认为你应该检查一下。
  • 我正在努力隔离这个效果,我会在半小时内发布整个代码。
【解决方案2】:

所有元素都做同样的事情,..

而不是循环所有元素并更改变换。

改为更改实际的 CSS。

这是 1000 个 div 的示例。

const stylesheet = document.styleSheets[1];
let a = 0;

for (let l = 0; l < 1000; l ++) {
  const d = document.createElement('div');
  d.innerText = l;
  document.body.append(d);
}

setInterval(() => {
  stylesheet.cssRules[0].style.transform=
    `skew(${Math.sin(a)*20}deg)`;
  a = a + 1;
}, 1000);
<style id="s1" type="text/css">
div {
 transform: skew(10deg);
 width: 40px;
 height: 40px;
 margin: 5px;
 float: left;
 background-color: red;
 transition: 1s;
 color: white;
}
</style>

【讨论】:

  • 你检查问题中的链接了吗...动画取决于滚动效果,每个元素都会根据它的位置进行变换,所以他需要制作循环
  • @TemaniAfif 他知道如何做滚动部分,它是How can one achieve this effect and make it as fluid as done here?这是我正在回答的部分。
猜你喜欢
  • 2023-02-08
  • 2013-06-01
  • 2011-07-14
  • 1970-01-01
  • 2023-03-09
  • 2015-06-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多