如何在滚动上获得“膨胀”效果?

时间:2016-04-24 22:44:00

标签: javascript jquery html css

我正在尝试使用jQuery实现此效果:

enter image description here

我需要:

  • 确定.project是否在视口中。
  • 如果不是,我需要将其从0.3缩放到1,并在对象进入视口25%时将不透明度从0更改为1(从顶部开始的75%)。

这就是我所拥有的,但是当我滚动时,卡片似乎一下子反过来。

$(window).scroll(function() {
  var scrollTop = $(window).scrollTop(),
      scaleVal = (1/scrollTop),
      screenBottom = $(window).scrollTop() + $(window).height(),
      offset = $('.project').offset().top;
    if(scrollTop > (scrollTop/2)){
      $(".project").css('transform', "scale("+scaleVal+")");
      $(".project").css('opacity', scaleVal);
    }
});

// var screenBottom = $(window).height();
// $(window).scroll(function{
//  screenBottom = $(window).height() + $(window).scrollTop();
//  if ( screenBottom == cardStartsHeight ) {
//    // magic on the card
//  }
// });
@charset "UTF-8";
@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,800|Gentium+Book+Basic);
.project--image, .project--description {
  float: left;
}

body {
  background: #eee;
  font-family: "Open Sans", arial, sans-serif;
}

img {
  width: 100%;
  height: auto;
}

#wrapper {
  margin: 0 auto;
  max-width: 1024px;
  padding: 0 30px;
}
#wrapper::after {
  clear: both;
  content: "";
  display: table;
}

.side-bar {
  width: 20%;
  position: fixed;
  top: 30px;
}
.side-bar .logo {
  border-bottom: dashed 1px #ccc;
  padding-bottom: 20px;
}
.side-bar .logo .avatar {
  height: 90px;
  width: 90px;
  background-color: #ccc;
  background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/243277/avatar.jpg");
  background-size: cover;
  border-radius: 50%;
  margin-bottom: 10px;
}
.side-bar .logo .name {
  font-size: 12px;
  display: block;
  text-transform: uppercase;
}
.side-bar .logo .title {
  font-size: 16px;
}
.side-bar nav a {
  color: #4A90E2;
  margin-top: 20px;
  text-decoration: none;
  display: block;
  font-size: 12px;
}
.side-bar nav a i {
  margin-right: 6px;
  opacity: 0.5;
  -webkit-transition: all 0.15s ease-out 0s;
  transition: all 0.15s ease-out 0s;
}
.side-bar nav a:hover i {
  opacity: 1;
}

main {
  width: 75%;
  box-sizing: border-box;
  margin-left: 25%;
}

.project {
  margin-top: 30px;
  box-shadow: 0 8px 20px rgba(50, 50, 50, 0.3);
  background: white;
  padding: 70px;
  border-radius: 9px;
}
.project::after {
  clear: both;
  content: "";
  display: table;
}
.project--image {
  display: inline-block;
  width: 25%;
}
.project--description {
  width: 75%;
  box-sizing: border-box;
  padding-left: 20px;
}
.project--description .title {
  font-size: 30px;
  margin-bottom: 10px;
}
.project--description .about {
  font-family: "Gentium Book Basic", serif;
  font-size: 20px;
  line-height: 26px;
  margin-bottom: 20px;
}
.project--description .cta {
  color: #4A90E2;
  text-align: right;
  text-decoration: none;
}
.project--description .cta:after {
  -webkit-transition: all 0.15s ease-out 0s;
  transition: all 0.15s ease-out 0s;
  content: "→";
  margin-left: 5px;
}
.project--description .cta:hover:after {
  margin-left: 10px;
}

footer {
  margin-top: 30px;
  padding-top: 30px;
  border-top: dashed 1px #ccc;
  font-size: 12px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.1/jquery.min.js"></script>

<div id="wrapper">
  <aside class="side-bar">
    <h1 class="logo">
      <div class="avatar"></div><span class="name">Aaron Benjamin</span><span class="title">Digital UX Designer</span>
    </h1>
    <nav><a href="#" target="_blank"><i class="fa fa-dribbble"></i> Dribbble</a><a href="#" target="_blank"><i class="fa fa-twitter"></i> Twitter</a><a href="#" target="_blank"><i class="fa fa-medium"></i> Medium</a><a href="#" target="_blank"><i class="fa fa-codepen"></i> Code Pen</a></nav>
  </aside>
  <main>
    <article class="project">
      <div class="project--image"><img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt=""/></div>
      <div class="project--description">
        <h2 class="title">Hello World</h2>
        <p class="about"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#" class="cta">Read more</a>
      </div>
    </article>
    <article class="project">
      <div class="project--image"><img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt=""/></div>
      <div class="project--description">
        <h2 class="title">Hello World</h2>
        <p class="about"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#" class="cta">Read more</a>
      </div>
    </article>
    <article class="project">
      <div class="project--image"><img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt=""/></div>
      <div class="project--description">
        <h2 class="title">Hello World</h2>
        <p class="about"> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#" class="cta">Read more</a>
      </div>
    </article>
    <footer>
      <p>Hello</p>
    </footer>
  </main>
</div>

1 个答案:

答案 0 :(得分:1)

修改

我认为我的内容与你原来的帖子更加一致。

已知错误

  1. 特别是在代码段编辑器上,您会得到一些奇怪的缩放,因为第一个元素在技术上与屏幕底部重叠。当我在Codepen上使用此代码时,我没有遇到任何问题,因为第一个元素没有重叠,但我可以想象它会成为一个问题。也许有代码跳过第一个孩子?

  2. 我偶尔(滚动速度非常快)获得增长/缩小的行为。也许使用Math.minMath.max可以提供帮助。

  3. 代码的作用

    1. 查看底部位置与窗口高度的比较,如果从底部的值中删除窗口高度,这会给出我们有多少重叠。
    2. 然后获取此值并根据窗口的高度将其转换为分数。
    3. 设置项目的初始比例。我希望有一种比.each()更快的方式,但我找不到它。
    4. 检查滚动条。见第3点第二句。
    5. 快乐的编码!

      function fractional_overlay(el) {
        var rect = el.getBoundingClientRect();
        //Bounding Client Rectangle;
        var win_height = $(window).height();
        return (rect.bottom - win_height) / win_height;
      
      }
      
      $(document).ready(function() {
        //Initial Set for items off screen. I could not find a faster way
        $('.project').each(function(i, el) {
      
          var sf = fractional_overlay(el);
          // sf = Scale Factor;
      
          if (sf > 0 && sf < 1) {
            $(el).css({
              'transform': 'scale(' + sf + ',' + sf + ')'
            });
          }
      
        });
      
        //On every scroll, check to see that the items are either above the viewport or inside it.
        $(document).scroll(function(e) {
      
          $('.project').each(function(i, el) {
            var sf = fractional_overlay(el);
            if (sf > 0 && sf < 1) {
              sf = 1 - sf;
              $(el).css({
                'transform': 'scale(' + sf + ',' + sf + ')'
              });
            }
          });
      
        });
      });
      @charset "UTF-8";
      @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,800|Gentium+Book+Basic);
       .project--image,
      .project--description {
        float: left;
      }
      body {
        background: #eee;
        font-family: "Open Sans", arial, sans-serif;
      }
      img {
        width: 100%;
        height: auto;
      }
      #wrapper {
        margin: 0 auto;
        max-width: 1024px;
        padding: 0 30px;
      }
      #wrapper::after {
        clear: both;
        content: "";
        display: table;
      }
      .side-bar {
        width: 20%;
        position: fixed;
        top: 30px;
      }
      .side-bar .logo {
        border-bottom: dashed 1px #ccc;
        padding-bottom: 20px;
      }
      .side-bar .logo .avatar {
        height: 90px;
        width: 90px;
        background-color: #ccc;
        background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/243277/avatar.jpg");
        background-size: cover;
        border-radius: 50%;
        margin-bottom: 10px;
      }
      .side-bar .logo .name {
        font-size: 12px;
        display: block;
        text-transform: uppercase;
      }
      .side-bar .logo .title {
        font-size: 16px;
      }
      .side-bar nav a {
        color: #4A90E2;
        margin-top: 20px;
        text-decoration: none;
        display: block;
        font-size: 12px;
      }
      .side-bar nav a i {
        margin-right: 6px;
        opacity: 0.5;
        -webkit-transition: all 0.15s ease-out 0s;
        transition: all 0.15s ease-out 0s;
      }
      .side-bar nav a:hover i {
        opacity: 1;
      }
      main {
        width: 75%;
        box-sizing: border-box;
        margin-left: 25%;
      }
      .project {
        transition: all linear 0.3s;
        margin-top: 30px;
        box-shadow: 0 8px 20px rgba(50, 50, 50, 0.3);
        background: white;
        padding: 70px;
        border-radius: 9px;
      }
      .project::after {
        clear: both;
        content: "";
        display: table;
      }
      .project--image {
        display: inline-block;
        width: 25%;
      }
      .project--description {
        width: 75%;
        box-sizing: border-box;
        padding-left: 20px;
      }
      .project--description .title {
        font-size: 30px;
        margin-bottom: 10px;
      }
      .project--description .about {
        font-family: "Gentium Book Basic", serif;
        font-size: 20px;
        line-height: 26px;
        margin-bottom: 20px;
      }
      .project--description .cta {
        color: #4A90E2;
        text-align: right;
        text-decoration: none;
      }
      .project--description .cta:after {
        -webkit-transition: all 0.15s ease-out 0s;
        transition: all 0.15s ease-out 0s;
        content: "→";
        margin-left: 5px;
      }
      .project--description .cta:hover:after {
        margin-left: 10px;
      }
      footer {
        margin-top: 30px;
        padding-top: 30px;
        border-top: dashed 1px #ccc;
        font-size: 12px;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="wrapper">
        <aside class="side-bar">
          <h1 class="logo">
            <div class="avatar"></div><span class="name">Aaron Benjamin</span><span class="title">Digital UX Designer</span>
          </h1>
          <nav><a href="#" target="_blank"><i class="fa fa-dribbble"></i> Dribbble</a><a href="#" target="_blank"><i class="fa fa-twitter"></i> Twitter</a><a href="#" target="_blank"><i class="fa fa-medium"></i> Medium</a><a href="#" target="_blank"><i class="fa fa-codepen"></i> Code Pen</a>
          </nav>
        </aside>
        <main>
          <article class="project" id="first">
            <div class="project--image">
              <img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt="" />
            </div>
            <div class="project--description">
              <h2 class="title">Hello World</h2>
              <p class="about">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#"
              class="cta">Read more</a>
            </div>
          </article>
          <article class="project" id="second">
            <div class="project--image">
              <img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt="" />
            </div>
            <div class="project--description">
              <h2 class="title">Hello World</h2>
              <p class="about">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#"
              class="cta">Read more</a>
            </div>
          </article>
          <article class="project" id="third">
            <div class="project--image">
              <img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt="" />
            </div>
            <div class="project--description">
              <h2 class="title">Hello World</h2>
              <p class="about">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#"
              class="cta">Read more</a>
            </div>
          </article>
          <footer>
            <p>Hello</p>
          </footer>
        </main>
      </div>

      这是一个快速回答:

      我看到的问题是,在滚动条中,您正在编辑页面上每个.project元素的样式。我使用$(document)卷轴的原因是因为当我使用$('.project')卷轴尝试它时没有发生任何事情。希望这为您提供了一个很好的起点,您可以使用它来获得您想要的精确效果。

      我做了什么:

      1. 我找到了一种方法来判断元素是否在视口内。我从另一个Stack Overflow question找到了这个,我修改了一下作为默认代码(我留在那里以防你可能需要它)导致在向上方向上离开视口的元素也缩小了。根据你的演示,我认为你不想要那个。
      2. 我不确定您使用该窗口的原因,老实说我只是使用了document对象而不是window,因为它首先浮现在脑海中。窗口可能是更好的方式,老实说我不知道​​。
      3. 在CSS中添加了.scale类和transition声明。
      4. 注意 我在<article>标记中添加了ID,以便在编辑in_viewport_or_higher函数时帮助我进行调试。
      5. Javascript代码的描述(主要针对后来发现此答案的任何人)

        1. 如果忽略这两个函数声明,从$(document).ready()调用开始,我会遍历所有.project元素,如果它们低于底部边缘,则添加缩放类。
        2. 将滚动事件侦听器添加到文档中。
        3. 每个滚动我们必须循环遍历.projects集合中的元素,并重新评估它们是否被显示。根据我们的发现切换比例等级。
        4. 你能做什么

          您可以计算出仍然隐藏在底部边缘下的每个元素的比例,并使用它来通过.css()调用transform样式声明手动设置比例变换量,这样它就不是“全有或全无”的方法。

          function in_viewport_or_higher(el) {
            var rect = el.getBoundingClientRect();
          
            return (
              rect.left >= 0 &&
              rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
              rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
            );
          }
          
          function in_viewport(el) {
          
            //special bonus for those using jQuery
            if (typeof jQuery === "function" && el instanceof jQuery) {
              el = el[0];
            }
          
            var rect = el.getBoundingClientRect();
          
            return (
              rect.top >= 0 &&
              rect.left >= 0 &&
              rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
              rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
            );
          }
          $(document).ready(function() {
            //Initial Set for items off screen. I could not find a faster way
            $('.project').each(function(i, el) {
              $(this).toggleClass('scale', !in_viewport_or_higher(el));
            });
          
            //On every scroll, check to see that the items are either above the viewport or inside it.
            $(document).scroll(function(e) {
          
              $('.project').each(function(i, el) {
                $(this).toggleClass('scale', !in_viewport_or_higher(el));
              });
          
            });
          });
          @charset "UTF-8";
          @import url(https://fonts.googleapis.com/css?family=Open+Sans:400,800|Gentium+Book+Basic);
           .project--image,
          .project--description {
            float: left;
          }
          body {
            background: #eee;
            font-family: "Open Sans", arial, sans-serif;
          }
          img {
            width: 100%;
            height: auto;
          }
          #wrapper {
            margin: 0 auto;
            max-width: 1024px;
            padding: 0 30px;
          }
          #wrapper::after {
            clear: both;
            content: "";
            display: table;
          }
          .side-bar {
            width: 20%;
            position: fixed;
            top: 30px;
          }
          .side-bar .logo {
            border-bottom: dashed 1px #ccc;
            padding-bottom: 20px;
          }
          .side-bar .logo .avatar {
            height: 90px;
            width: 90px;
            background-color: #ccc;
            background-image: url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/243277/avatar.jpg");
            background-size: cover;
            border-radius: 50%;
            margin-bottom: 10px;
          }
          .side-bar .logo .name {
            font-size: 12px;
            display: block;
            text-transform: uppercase;
          }
          .side-bar .logo .title {
            font-size: 16px;
          }
          .side-bar nav a {
            color: #4A90E2;
            margin-top: 20px;
            text-decoration: none;
            display: block;
            font-size: 12px;
          }
          .side-bar nav a i {
            margin-right: 6px;
            opacity: 0.5;
            -webkit-transition: all 0.15s ease-out 0s;
            transition: all 0.15s ease-out 0s;
          }
          .side-bar nav a:hover i {
            opacity: 1;
          }
          main {
            width: 75%;
            box-sizing: border-box;
            margin-left: 25%;
          }
          .project {
            transition: all linear 0.7s;
            margin-top: 30px;
            box-shadow: 0 8px 20px rgba(50, 50, 50, 0.3);
            background: white;
            padding: 70px;
            border-radius: 9px;
          }
          .project.scale {
            opacity: 0.2;
            transform: scale(0.2, 0.2);
          }
          .project::after {
            clear: both;
            content: "";
            display: table;
          }
          .project--image {
            display: inline-block;
            width: 25%;
          }
          .project--description {
            width: 75%;
            box-sizing: border-box;
            padding-left: 20px;
          }
          .project--description .title {
            font-size: 30px;
            margin-bottom: 10px;
          }
          .project--description .about {
            font-family: "Gentium Book Basic", serif;
            font-size: 20px;
            line-height: 26px;
            margin-bottom: 20px;
          }
          .project--description .cta {
            color: #4A90E2;
            text-align: right;
            text-decoration: none;
          }
          .project--description .cta:after {
            -webkit-transition: all 0.15s ease-out 0s;
            transition: all 0.15s ease-out 0s;
            content: "→";
            margin-left: 5px;
          }
          .project--description .cta:hover:after {
            margin-left: 10px;
          }
          footer {
            margin-top: 30px;
            padding-top: 30px;
            border-top: dashed 1px #ccc;
            font-size: 12px;
          }
          <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
          <div id="wrapper">
            <aside class="side-bar">
              <h1 class="logo">
                <div class="avatar"></div><span class="name">Aaron Benjamin</span><span class="title">Digital UX Designer</span>
              </h1>
              <nav><a href="#" target="_blank"><i class="fa fa-dribbble"></i> Dribbble</a><a href="#" target="_blank"><i class="fa fa-twitter"></i> Twitter</a><a href="#" target="_blank"><i class="fa fa-medium"></i> Medium</a><a href="#" target="_blank"><i class="fa fa-codepen"></i> Code Pen</a>
              </nav>
            </aside>
            <main>
              <article class="project" id="first">
                <div class="project--image">
                  <img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt="" />
                </div>
                <div class="project--description">
                  <h2 class="title">Hello World</h2>
                  <p class="about">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#"
                  class="cta">Read more</a>
                </div>
              </article>
              <article class="project" id="second">
                <div class="project--image">
                  <img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt="" />
                </div>
                <div class="project--description">
                  <h2 class="title">Hello World</h2>
                  <p class="about">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#"
                  class="cta">Read more</a>
                </div>
              </article>
              <article class="project" id="third">
                <div class="project--image">
                  <img src="http://simonpan.com/wp-content/themes/sp_portfolio/assets/prime-music-tile-hero.jpg" alt="" />
                </div>
                <div class="project--description">
                  <h2 class="title">Hello World</h2>
                  <p class="about">Lorem ipsum dolor sit amet, consectetur adipisicing elit. Minima architecto numquam eius dicta mollitia quo consequuntur ducimus eveniet eos modi voluptate quidem saepe aliquid distinctio esse temporibus delectus, repellat facere?</p><a href="#"
                  class="cta">Read more</a>
                </div>
              </article>
              <footer>
                <p>Hello</p>
              </footer>
            </main>
          </div>