如何获得视差工作的核心部分 - 这就是诀窍?

How to get the core part - that does the trick - of parallax work?

我尝试用视差进行实验,并从头开始了解这个魔法的核心部分。给你一个我喜欢用作灵感的例子,你可以在 "Photos" 部分看到它 at this link here

最新代码和相关信息在页面下方。要全面了解问题,请查看其余详细信息。

我已经知道的核心部分是 $windowscrollTop() 和元素的 offsetTop 对于在 DOM 元素上应用视差效果很重要,因为以及 factor 表示效果对滚动速度的响应灵敏度。最终结果应该是一些公式,它将以像素或百分比计算 translateYtranslate3d 坐标。

我在互联网上看到 CSS 属性 translateposition: absolute 中的 top 更快,我的偏好是也可以将 translate 与 TweenMax GSAP 结合使用。所以视差的移动会很流​​畅。但是,如果 css 属性 translate 就足够了,那也很好。我看到了一些使用 TweenMax 的示例,所以这就是我现在使用它的原因。

JS

我有基本的代码:

var win = $(window);
var el = $('#daily .entry').find('figure');

win.scroll(function() {
  var scrollTop = win.scrollTop();
  var parallaxFactor = 5;

  el.each(function() {
    var image = $(this).find('img');
    var offsetTop = $(this).offset().top;

    // This is the part where I am talking about. 
    // Here should be the magic happen...

  });
});

所以我在上面的代码中编写了代码,但它当然什么也没做。 See CodePen from above code here。它只会控制台日志 scrollTopoffsetTop。如前所述,我只知道 scrollTopoffsetTop 等核心部分来应用视差效果。然后应该创建一些区域来触发和发生视差效果,因此将只对视口内的元素进行计算以保持良好的性能。之后应该做一些数学运算,但不知道究竟是什么或如何实现这一点。只有在我有了最终数字之后,我才能在 Greensock 的 TweenMax 中使用它,例如:

TweenMax

TweenMax.to(image, 0.1, {
    yPercent: offsetPercent + '%',
    ease: Linear.easeNone
});

视差公式

如果我四处寻找公式,我会得出这样的结果(在互联网上找到):

var viewportOffset = scrollTop - offsetTop + win.height();
var offsetPercent = ((viewportOffset / win.height() * 100) - 100) / parallaxFactor;

if (viewportOffset >= 0 && viewportOffset <= win.height() * 2) {
    TweenMax.to(image, 0.1, {
        yPercent: offsetPercent + '%',
        ease: Linear.easeNone
    });
}

但老实说,我不知道这到底是做什么的,也不知道为什么 should/could 会这样。我想知道这一点,这样我就能理解产生视差的整个过程。 scrollTop()offsetTop$(window).height() 的功能对我来说很清楚,但是公式背后的技巧是什么,是我不明白的部分。

更新

更新 1

@Scott 已经通知灵感网站使用了一个名为 scrollmagic.io 的插件,但我很好奇如何在不使用插件的情况下自己创建视差。它是如何工作的以及如何实现它。强调公式,为什么我应该这样做或那样做以及究竟会计算什么,因为我不理解它并且真的很想知道这个,以便将来在应用视差效果时可以使用这些知识.

更新 2

我试图弄清楚以下代码片段究竟做了什么。我说的是这个:

var viewportOffset = scrollTop - offsetTop + win.height();

经过一些良好的调试会话后,我认为我找到了线索。所以 scrollTop 是您向下滚动页面并从视图中隐藏的像素数量。 offsetTop 是元素在 DOM 中的起始位置,$(window).height 是视口高度——在浏览器中可见的部分。

这就是我认为这个公式的作用:

将零点设置为元素开始的点。例如,当 scrollTop 等于 0 且元素从顶部开始 240px 时,则公式为:0 减去 240 为 -240。所以当前滚动位置低于零点。向下滚动 240px 后,公式将输出 0,因为 240 减去 240 当然是 0(零)。我说得对吗?

但是我还不明白的部分是为什么 + win.height。 如果我们回到上面的公式(在更新 2)并且 scrollTop 为零,那么 $(window).height 是从 240px 到视口底部的 space。向下滚动时,滚动时像素的数量会增加,这对我来说毫无意义。如果有人可以解释这样做的目的是什么,那就太好了。很好奇。第二部分计算视差的公式offsetPercent我还是没看懂。一般计算滚动上的视差强度。

更新 3 / 4

在@Edisoni 的建议下,我过去几天走了 by the videos of Travis Neilson 并且我对视差的基本功能变得更加明智。每个想要挖掘视差的人都必须学习。我已经使用关于视差的新知识来使我的上述脚本工作:

var root = this;
var win = $(window);
var offset = 0;

var elements = $('#daily .entry figure');

if (win.width() >= 768) {
    win.scroll(function() {

        // Get current scroll position
        var scrollPos = win.scrollTop();
        console.log(scrollPos);

        elements.each(function(i) {
            var elem = $(this);
            var triggerElement = elem.offset().top;
            var elemHeight = elem.height();
            var animElem = elem.find('img');

            if (scrollPos > triggerElement - (elemHeight / 2) && scrollPos < triggerElement + elemHeight + (elemHeight / 2)) {
                // Do the magic
                TweenMax.to(animElem, 0.1, {
                    yPercent: -(scrollPos - elemHeight / 2) / 100, 
                    ease: Linear.easeNone
                });

            } else {
                return false;
            }

        });

    });

}

但是,该脚本仅适用于特定部分元素。问题是它只适用于前两个元素。我怀疑 "error" 位于 if 语句中的 AND && 符号之后,但无法解决错误。 http://codepen.io/anon/pen/XKwBAB

当在触发器上工作的元素设置动画时,它们会将一些像素跳到底部,不知道如何解决这个问题。 触发触发器后跳转到:1.135%。所以它不是从 0% 开始的。我已经检查过是否应该将 CSS 属性 translate 添加到 CSS 并将数字类型设置为 %,但这不适用于我。

-webkit-transform: translateY(0%);
-moz-transform: translateY(0%);
-o-transform: translateY(0%);
transform: translateY(0%);

我是否应该使用 TweenMax .fromTo() 函数而不是 .to() 函数以便我也可以设置起始位置,或者我的想法是错误的并且有不同的原因?

像这样:

TweenMax.fromTo(animElem, 0.1, {
    yPercent: triggerElement,
    z: 1
}, {
    yPercent: -(scrollPos - elemHeight / 2) / 100,
    ease: Linear.easeNone
});

除此之外,我试图在不使用 scrollMagic 插件的情况下重新创建我想用作灵感来源的网站的效果,但我真的不知道这是如何工作的,使用了两种不同的动画对象。

最后,如果有人认为代码可以更好地格式化,请不要犹豫,我想听听您的建议

我的实际问题是更新 2 和 3/4:

  1. 如何计算视差y坐标才能"the magic"完成?
  2. 我对更新 2 是否正确,零点将重置为每个元素的 offsetTop?
  3. 为什么我的代码只适用于前两个元素,如果将 translate 的内联样式添加到动画元素,为什么它们会向下跳转一些像素?有关所有信息,请参阅更新 3/4。

Parallax其实原理很简单。只需让视差元素滚动得比其他内容慢即可。也就是说,视差实现可以像将滚动距离除以一个因子一样简单:

var parallaxFactor = 3;
window.addEventListener("scroll", function(e){
    el.style.top = (document.body.scrollTop / parallaxFactor) + "px"; 
    // This is the magic. This positions the element's y-cord based off of the page scroll
}, false);

CODEPEN

这是一个极其简单的视差效果演示。其他更彻底的实现可能会以百分比形式处理值,或尝试使用 TweenMax 平滑动画。然而,这正是您正在寻找的魔法。

长命百岁。

更新:

此示例仅适用于屏幕顶部的元素。如果这是为了更一般的目的,您可能希望存储元素的默认 y 位置,然后存储类似于 defaultYCord + (document.body.scrollTop / parallaxFactor).

的内容

更新二:

一个非常好的视差可视化来自 Keith Clark,他制作了一个纯 css 视差滚动器:http://keithclark.co.uk/articles/pure-css-parallax-websites/demo3/。如果你点击左上角的调试,它会给你一个漂亮的魔法 3d 视图。

这不是如何在 JS 中构建视差的答案。但它显示了一些基础知识,如果您对代码投入过多,这些知识往往会被遗忘。

基础知识:

  1. 在 z 层中订购图形对象。 z 越高,越近 给屏幕前的观察者。
  2. 你的物体在 z 轴上的位置越高,它在出现的东西上移动的速度就越快,f.e。你的滚动
  3. 现在您将获得 3-D 效果,离您较近的物体随着距离较远的物体移动得更快。

你的问题

如何计算视差y坐标才能"the magic"完成?

y 位置取决于您的 z 索引。如果距离很远 a.k.a z-index 很低,delta-y 很小。如果它离你太近,则 delta-y 很大。 请考虑 z-index 不一定用作 Style-属性,它更像是它的样子。 我会向每个视差层添加一个像 data-z 这样的属性。

function parallaxingY(el){
   //el is a parallaxing element with attribute data-z
   return $(el).data('z')*window.scrollTop;
}

建议的 CSS- 解决方案很好,应该首选。 "magic" - "z-index" - 由 css 风格 "scale".

制作