I'm trying to achieve this effect using jQuery:
I need to:
.project
is in the viewport. 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 ai { 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>
I think i got something a little more in-line with your original post.
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?
I occasionally (scrolling really fast) get a growing/shrinking behavior. Maybe using Math.min
or Math.max
could help.
.each()
but I couldn't find it. 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 ai { 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:
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. .scale
class and a transition
declaration in your CSS. <article>
tags to help my debug while editing the in_viewport_or_higher
function. $(document).ready()
call, I go through all of the .project
elements and add the scale class if they're below the bottom edge. .projects
collection and reevaluate whether or not they're being shown. Toggle the scale class depending on our findings. 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 ai { 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>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.