3

I'm trying to achieve this effect using jQuery:

enter image description here

I need to:

  • Determine if .project is in the viewport.
  • If it's not, I need it to scale from 0.3 to 1 and change the opacity from 0 to 1 by the time the object is 25% into the viewport (75% from the top).

This is what I have, but the cards seem to be going in reverse all at once as i scroll.

$(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>
Aaron Benjamin
  • 1,041
  • 3
  • 14
  • 25
  • Just giving a quick glance at your code, you're editing the CSS on every `.project` element every scroll. You need to work on the individual items instead. – Jhecht Apr 24 '16 at 22:53
  • I've got a very rough thing working right now over at [This Code Pen](http://codepen.io/jhechtf/pen/aNaoJo?editors=0010), just trying to get the last little bit to work. – Jhecht Apr 24 '16 at 23:18

1 Answers1

1

Edit

I think i got something a little more in-line with your original post.

Known Bugs

  1. Especially on the snippet editor, you get some weird scaling because the first element technically overlaps the bottom of the screen. I didn't have a problem when I used this code on Codepen because the first element didn't overlap, but I could envision that it becomes a problem. Perhaps have code that skips the first child?

  2. I occasionally (scrolling really fast) get a growing/shrinking behavior. Maybe using Math.min or Math.max could help.

What the Code Does

  1. Looks at the bottom position vs the window's height, if removes the windows height from the bottom's value, which gives us how much overlap there is.
  2. It then takes this value and turns it into a fraction based on the height of the window.
  3. Sets the initial scale of items. I wish there was a faster way than .each() but I couldn't find it.
  4. checks the scroll. See second sentence of point #3.

Happy Coding!

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>

Here's a quick answer:

The issue I saw was that on your scroll you were editing the styles of every .project element on the page. The reason I use the $(document) scroll is because when I tried it with the $('.project') scroll nothing happened. Hopefully this gives you a good starting point that you can use to get the exact effect you want.

List of what I did:

  1. I found a way to get whether or not an element was inside the viewport. I found this from another Stack Overflow question which I modified a bit as the default code (which I left in there just in case you might need it) was causing elements that left the viewport in the up direction to shrink as well. Based on your demo, I figured you didn't want that.
  2. Wasn't sure why you were using the window, and honestly I just used the document object instead of the window because it's what came to mind first. Window may be a better way to go, I honestly don't know.
  3. added a .scale class and a transition declaration in your CSS.
  4. Note I added id's to the <article> tags to help my debug while editing the in_viewport_or_higher function.

Description of Javascript Code (mostly for anyone who finds this answer later)

  1. If you ignore the two function declarations, starting in the $(document).ready() call, I go through all of the .project elements and add the scale class if they're below the bottom edge.
  2. Add scroll event listener onto the document.
  3. Every scroll we have to loop through the elements in the .projects collection and reevaluate whether or not they're being shown. Toggle the scale class depending on our findings.

What you could do

You could figure out the ratio of each element still hidden under the bottom edge and use that to manually set the scale transform amount via the .css() call to the transform style declaration so that it's not an "all or nothing" approach.

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>
Community
  • 1
  • 1
Jhecht
  • 4,040
  • 1
  • 26
  • 39