2
\$\begingroup\$

I wanted to learn how to create awesome parallax scrolling effects so I decided to look up how to do it, after some searching I put together this test. It works fine to some extent but it feels a bit messy, especially if you would expand it with more effects and elements.

You can see it in action here (had to replace the images with colors to make it work)

Basically what I need feedback on is this:

  • How can I rewrite the jQuery to allow easy adding of new elements and effects?
  • How can I make the scrolling smoother, i.e not having the elements jump on mouse scrolling but instead go up in an animation like fashion?
  • Are there better way of controlling the scroll speed instead of data-speed?
  • Are there ways to improve my CSS3 animations (never worked with them before)
  • Anything else worth pointing out to make it better?

This is the markup:

<section id="header" class="section" data-type="background" data-speed="5">
    <article id="header-article" class="article"></article>
</section>
<section id="main" class="section box-shadow" data-type="background" data-speed="5">
    <article id="main-article" class="article"></article>
</section>
<section id="footer" class="section box-shadow" data-type="background" data-speed="5">
    <article id="footer-article" class="article">Footer content</article>
</section>

jQuery:

$(document).ready(function() {

    var $window = $(window);
    var $title = $('#header-article');
    var $content = $('#main-article');
    var $footer = $('#footer-article');

    $('section[data-type="background"]').each(function() {

        var $bgobj = $(this);

        $(window).scroll(function() {
            var yPos = -($window.scrollTop() / $bgobj.data('speed'));
            var coords = '50% ' + yPos + 'px';

            $bgobj.css({backgroundPosition: coords});

            if (yPos < (-28)) {
                $title.css({top: 15, position: 'fixed'});
                $title.html('I am fixed positioned');
            } 
            else {
                $title.css({top: 150, position: 'absolute'});
                $title.html('I am absolute positioned');
            }

            if (yPos < (-115)) {
                $content.stop().removeClass('reverse-spin').addClass('spin');
                $content.html("I'm spinniiiiiing!");
            }
            else {

                $content.stop().addClass('reverse-spin').removeClass('spin');
                $content.html('Spin me!');
            }

            if (yPos < (-300)) {
                $footer.stop().animate({left: 0}, 'slow');
            }
            else {
                $footer.css({color: 'black'});
                $footer.stop().animate({left: '-75%'}, 'slow');
            }
            console.log(yPos);
        });
    });
});

CSS:

body, html{
    margin: 0;
    padding: 0;
}

.section {
    min-height: 1000px;
    height: 1000px;
    margin: 0 auto;
    width: 100%;
    max-width: 1920px;
    position: relative;
}

.article {
    position: absolute;
    width: 100%;
    color: white;
    font-size: 3em;
}

.box-shadow {
    -webkit-box-shadow: 0 0 50px rgba(0,0,0,0.8);
    box-shadow: 0 0 50px rgba(0,0,0,0.8);
}

#header {
    background: url('pic1.jpg') 50% 0 repeat fixed;
}

#header-article {
    height: 458px;
    top: 150px;
    text-align: center;
}

#main {
    background: url('pic2.jpg') 50% 0 no-repeat;
}

#main-article {
    height: 50px;
    top: 150px;
    -webkit-transform-origin: 50% 50%;
    -moz-transform-origin: 50% 50%;
    -o-transform-origin: 50% 50%;
    transform-origin: 50% 50%;
    text-align: center;
}

#footer{
    background: url('pic3.jpg') 50% 0 no-repeat;
}

#footer-article {
    top: 200px;
    left: -100%;
    text-align: center;
}

@-webkit-keyframes spin {
    0% {
        -webkit-transform: rotate(0deg) translate(0%, 0%);
    }
    50%{
        -webkit-transform: rotate(180deg) translate(0%, 0%);
        color: black;
    }
    100%{
        -webkit-transform: rotate(0deg) translate(0%, 0%);
        color: black;
    }
}

@-webkit-keyframes spin {
    0% {
        -webkit-transform: rotate(0deg) translate(0%, 0%);
    }
    50%{
        color: black;
    }
    100%{
        -webkit-transform: rotate(360deg) translate(0%, 0%);
        color: black;
    }
}

@-webkit-keyframes reverse-spin {
    0% {
        -webkit-transform: rotate(0deg) translate(0%, 0%);
    }
    50%{
        color: white;
    }
    100%{
        -webkit-transform: rotate(-360deg) translate(0%, 0%);
    }
}

.spin {
    -webkit-animation-name: spin;
    -webkit-animation-duration: 1s;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
}

.reverse-spin {
    -webkit-animation-name: reverse-spin;
    -webkit-animation-duration: 1s;
    -webkit-animation-iteration-count: 1;
    -webkit-animation-fill-mode: forwards;
}
\$\endgroup\$
  • \$\begingroup\$ Have you checked out velocity.js? \$\endgroup\$ – darcher Jan 16 '15 at 14:24
  • \$\begingroup\$ @darcher I have not, I'm not a huge fan of plugins. Trying to do stuff from scratch by myself in order to gain an understanding and learn. \$\endgroup\$ – Chrillewoodz Jan 16 '15 at 15:26
  • \$\begingroup\$ velocity.js basically replaces the .animate() method using its own, more performant, animation stack. If you're looking for smoother transitions vanilla javascript or velocity.js performs infinitely better than jquery, and depending on your support levels you could pass all the animation off to the css layer instead of using the .animate() method. \$\endgroup\$ – darcher Jan 16 '15 at 15:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.