6

I am trying to fix Section 2 once it comes to the viewport and on every scroll the next paragraph on the left highlights to the other one and the phone screen on the right slides to next one.

So on every scroll i want to highlight the next text and change the sceen inside the phone like you see on many app landing pages.

Here's a demo

enter image description here

undefinedtoken
  • 921
  • 1
  • 8
  • 26
  • Yes, but what would you like to change in the Codepen you provided?? I mean: what are you asking for? to show those text inside the "screen"? – Luca De Nardi Dec 01 '16 at 14:52
  • @LucaDeNardi when the 2nd section's offset top is 0 the section gets fixed and on every scroll the highlighted text switches to next one and the screen inside phone changes. So after 4 slides the section unhooks and starts scrolling normally – undefinedtoken Dec 01 '16 at 15:23
  • What you're describing sounds like something that can be accomplished with this plugin: http://scrollmagic.io/ – mhatch Dec 01 '16 at 20:56
  • @mhatch I tried this plugin for pinning the section but didn't get any onScroll event to change the slide as per each scroll. – undefinedtoken Dec 02 '16 at 07:53

3 Answers3

2

Edit:

I have updated the code and here is a new JSFiddle.

Old Answer: (similar to fullpage.js)

Since your HTML includes sections, you set each section height to 100vh and you tagged your post with parallax tag I assumed the following:

  • You need each section to scroll and fill the entire screen.
  • The scrollbar seems to be useless in this setting.
  • Each mousewheel scroll need to bring an entire section to the screen.
  • Once the section with mobile phone div is in view you need the scrolling to occur to the children element and not the sections.

So based on that I changed your code to the following:

var lastScrollPos = 0;
var scrollFired = false;

var textConainersElement = jQuery('.text-container p');
var mainElem = jQuery("[data-main='true']");
var firstElem = jQuery("section:first-child");
var lastElem = jQuery("section:last-child");
var wrapper = jQuery(".wrapper");

jQuery(document).on('DOMMouseScroll mousewheel', function(e) {

  // if the scroll has occrued already then dont fire it again until transition ended
  if (scrollFired == true) {
    jQuery(window).scrollTop(lastScrollPos);
    return false;
  }

  var inviewElem = jQuery("[data-inview='true']");
  var nextElem = inviewElem.next();
  var prevElem = inviewElem.prev();
  var currentTop = parseInt(firstElem.attr('data-top'));



  if (e.originalEvent.detail > 0 || e.originalEvent.wheelDelta < 0) {
    // Scrolling down 
    // if viewed element is last element do nothing
    if (inviewElem.index() >= lastElem.index())
      return false;

    // if main section is inview then scroll through its elements
    if (inviewElem.index() == mainElem.index()) {
      // if the active child is not the last element then process
      var active = jQuery('.text-container .active');
      if (active.index() != textConainersElement.length - 1) {
        jQuery('.text-container .active').removeClass('active').next().addClass('active');

        // Dont scroll further
        return false;
      }
    }

    var top = currentTop + 100;
    firstElem.css("margin-top", "-" + top + "vh").attr("data-top", top);
    nextElem.attr("data-inview", 'true');
    inviewElem.attr("data-inview", 'false');

  } else {
    // Scrolling up 
    // if viewed element is first element do nothing
    if (inviewElem.index() <= firstElem.index())
      return false;

    // if main section is inview then scroll through its elements
    if (inviewElem.index() == mainElem.index()) {
      // if the active child is not the last element then process
      var active = jQuery('.text-container .active');
      if (active.index() != 0) {
        jQuery('.text-container .active').removeClass('active').prev().addClass('active');

        // Dont scroll further
        return false;
      }
    }

    var top = currentTop - 100;
    firstElem.css("margin-top", "-" + top + "vh").attr("data-top", top);
    prevElem.attr("data-inview", 'true');
    inviewElem.attr("data-inview", 'false');
  }

  // Set values to use for next scrolling event
  lastScrollPos = jQuery(window).scrollTop();
  scrollFired = true;

  // reset scrollFired var after transition ended
  firstElem.one('transitionend', function() {
    scrollFired = false;
  });

  //prevent page fom scrolling
  return false;
});
body {
  margin: 0;
}

.wrapper {
  display: block;
  width: 100%;
  height: 100vh;
  overflow: hidden;
}

section {
  display: block;
  width: 100%;
  height: 100vh;
  border-bottom: 2px dashed black;
  position: relative;
  transition: all 0.5s;
  background-color: #c4c4c4;
}

section[data-inview="true"] {
  background-color: #929292;
}

.phone-container {
  align-items: center;
  background: #dedede none repeat scroll 0 0;
  border-left: 5px solid black;
  display: flex;
  float: right;
  height: 100vh;
  justify-content: center;
  width: 500px;
}

.phone {
  width: 200px;
  height: 500px;
  background: #A6A6A6 none repeat scroll 0 0;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 5px;
}

section.long-scroll {
  height: auto;
}

p {
  margin-top: 80px;
}

p:first-child {
  margin-top: 0px;
}

.text-container {
  float: left;
  width: 200px;
}

.spacer {
  display: block;
  width: 100%;
}

p.active {
  color: #C1E7FF;
}

.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}

.clearfix {
  display: inline-block;
}


/* start commented backslash hack \*/

* html .clearfix {
  height: 1%;
}

.clearfix {
  display: block;
}


/* close commented backslash hack */

.stuck {
  position: fixed;
  top: 0;
}

.fixed {
  position: fixed;
  top: 0;
}

.sticky-wrapper {
  height: auto !important;
}

.text-container {
  padding-left: 40px;
  padding-top: 40px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='wrapper'>
  <section data-inview='true' data-top='0'>
    Scroll-down
  </section>
  <section class="long-scroll clearfix" id="pin" data-main='true'>
    <div class="text-container">
      <p class="active">Text - 1</p>
      <p>Text - 2</p>
      <p>Text - 3</p>
      <p>Text - 4</p>
    </div>

    <div class="phone-container">
      <div class="phone">Slide-1</div>
    </div>
  </section>
  <section id="unhook"></section>
</div>

I commented the code to make it clear to understand and also here is a jsfiddle with the same code: https://jsfiddle.net/8zgsdzy0/.

Kalimah
  • 11,217
  • 11
  • 43
  • 80
1

Check this out - here is a summary of what I do here:

  1. I'm absolutely positioning section2 (pin) with respect to a wrapper that I added to it.

  2. On a resize listener I set the pin's height the same as the phone container so that the heights match.

  3. On a scroll listener I calculate if section2 comes into play / slides out of view.

See the demo below:

var found = false, last = false;;
var lockedScrollTop = 0, step = 0, slide = 1;

var wrapper = $('#wrap');
var pin = $('#pin');
var box = $('#phone');

$(document).resize(function() {
  pin.outerHeight(box.innerHeight());
});

$(document).scroll(function() {
  var offsetTop = -wrapper.offset().top + $(window).scrollTop();
  
  // conditions on scroll from top down
  if(offsetTop >= 0 && offsetTop < wrapper.outerHeight() && !last) {
    slide = 2;
  } else if(offsetTop >= 0 && offsetTop >= wrapper.outerHeight()) {
    if(!last) {
      $(window).scrollTop(lockedScrollTop);
      last = true;
      slide = 3;
    } else {
      slide = 4;
    }
  } 
  
  // conditions of scroll from bottom up
  if(offsetTop >= 0 && offsetTop < wrapper.outerHeight() && slide === 4) {
    last = true;
    slide = 3;
  } else if(offsetTop < 0 && last) {
    last = false;
    $(window).scrollTop(lockedScrollTop + wrapper.outerHeight() - 1);
    slide = 2;
  } else if(offsetTop < 0 && !last) {
    slide = 1;
    // reset
    found = false;
    lockedScrollTop = 0;
    step = 0;
  }
  
  // console.log(slide);
  
  if (slide == 2) {
    if(offsetTop < 0)
      offsetTop = 0;
    pin.css({'top': offsetTop + 'px'});
    if (!found) {
      // calculate step
      lockedScrollTop = wrapper.offset().top;
      step = wrapper.outerHeight() / 4;
      found = true;
    }
    // set/unset active text
    var index = Math.floor(($(window).scrollTop() - lockedScrollTop) / step);
    $('#pin .text-container > p').removeClass('active');
    $('#pin .text-container > p').eq(index).addClass('active');
  } else {
    pin.css({'top': 0});
  }
});
section {
  display: block;
  width: 100%;
  height: 100vh;
  border-bottom: 1px solid red;
}
.phone-container {
  height: 100vh;
  width: 500px;
  background: red;
  display: flex;
  align-items: center;
  justify-content: center;
  float: right;
}
.phone {
  width: 200px;
  height: 500px;
  background: #000;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
section.long-scroll {
  height: auto;
}
p {
  margin-top: 80px;
}
p:first-child {
  margin-top: 0px;
}
.text-container {
  float: left;
  width: 200px;
}
.spacer {
  display: block;
  width: 100%;
}
p.active {
  color: pink;
}
.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}
.clearfix {
  display: inline-block;
}
/* start commented backslash hack \*/

* html .clearfix {
  height: 1%;
}
.clearfix {
  display: block;
}
/* close commented backslash hack */

.stuck {
  position: fixed;
  top: 0;
}
.fixed {
  position: fixed;
  top: 0;
}
.sticky-wrapper {
  height: auto !important;
}
.text-container {
  padding-left: 40px;
  padding-top: 40px;
}

/*NEW STYLES ADDED*/
#pin {
  position: absolute;
  right: 0;
  top: 0;
}
#pin.transition {
  transition: top ease 1s;
}
#wrap {
  position: relative;
  border: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<section>
  Scroll-down
</section>
<section id="wrap">
  <section class="long-scroll clearfix" id="pin">
    <div class="text-container">
      <p class="active">Text - 1</p>
      <p>Text - 2</p>
      <p>Text - 3</p>
      <p>Text - 4</p>
    </div>
    <div class="phone-container" id="phone">
      <div class="phone">Slide-1</div>
    </div>
  </section>
</section>
<section id="unhook"></section>
kukkuz
  • 41,512
  • 6
  • 59
  • 95
1

Similar to this? http://codepen.io/jkochis/pen/ZBxgKd

JS

$(document).ready(function () {
    $(document).on("scroll", onScroll);

    //smoothscroll
    $('a[href^="#"]').on('click', function (e) {
        e.preventDefault();
        $(document).off("scroll");

        $('a').each(function () {
            $(this).removeClass('active');
        })
        $(this).addClass('active');

        var target = this.hash,
            menu = target;
        $target = $(target);
        $('html, body').stop().animate({
            'scrollTop': $target.offset().top+2
        }, 500, 'swing', function () {
            window.location.hash = target;
            $(document).on("scroll", onScroll);
        });
    });
});

function onScroll(event){
    var scrollPos = $(document).scrollTop();
    $('#menu-center a').each(function () {
        var currLink = $(this);
        var refElement = $(currLink.attr("href"));
        if (refElement.position().top <= scrollPos && refElement.position().top + refElement.height() > scrollPos) {
            $('#menu-center ul li a').removeClass("active");
            currLink.addClass("active");
        }
        else{
            currLink.removeClass("active");
        }
      console.log($('#menu-center ul li a.active').attr("href"), $('#menu-center a:eq(0)').attr("href"));
      if($('#menu-center ul li a.active').attr("href") !== $('#menu-center a:eq(0)').attr("href")) {
        $('body').addClass('fixed-product');
      } else {
        $('body').removeClass('fixed-product');
      }
    });
}

HTML

<div class="m1 menu">
    <div id="menu-center">
        <ul>
            <li><a class="active" href="#section1">Section 1</a>

            </li>
            <li><a href="#section2">Section 2</a>

            </li>
            <li><a href="#section3">Section 3</a>

            </li>
            <li><a href="#section4">Section 4</a>

            </li>
        </ul>
    </div>
</div>
<div id="section1"></div>
<div id="section2">
  <div class="product">PRODUCT</div>
</div>
<div id="section3"></div>
<div id="section4"></div>

CSS

body, html {
    margin: 0;
    padding: 0;
    height: 100%;
    width: 100%;
}
.menu {
    width: 200px;
    height: 400px;
    background-color: rgba(0, 0, 0, 1);
    position: fixed;
    background-color:rgba(4, 180, 49, 0.6);
    -webkit-transition: all 0.3s ease;
    -moz-transition: all 0.3s ease;
    -o-transition: all 0.3s ease;
    transition: all 0.3s ease;
}
.light-menu {
    width: 100%;
    height: 75px;
    background-color: rgba(255, 255, 255, 1);
    position: fixed;
    background-color:rgba(4, 180, 49, 0.6);
    -webkit-transition: all 0.3s ease;
    -moz-transition: all 0.3s ease;
    -o-transition: all 0.3s ease;
    transition: all 0.3s ease;
}
#menu-center {
    width: 980px;
    height: 75px;
    margin: 0 auto;
}
#menu-center ul {
    margin: 15px 0 0 0;
}
#menu-center ul li {
    list-style: none;
    margin: 0 30px 0 0;
    display: block;
}
.active {
    font-family:'Droid Sans', serif;
    font-size: 14px;
    color: #fff;
    text-decoration: none;
    line-height: 50px;
}
a {
    font-family:'Droid Sans', serif;
    font-size: 14px;
    color: black;
    text-decoration: none;
    line-height: 50px;
}
#section1 {
    background-color: grey;
    height: 100%;
    width: 100%;
    overflow: hidden;
}
#section2 {
    height: 100%;
    width: 100%;
}
#section3 {
    background-color: blue;
    height: 100%;
    width: 100%;
}
#section4 {
    background-color: red;
    height: 100%;
    width: 100%;
}
.product {
  background: yellow;
  float: right;
  padding: 100px
}
.fixed-product .product {
  position: fixed;
  top: 0;
  right: 0;
}

Disclaimer: I found this JSFiddle: https://jsfiddle.net/cse_tushar/Dxtyu/141/ and based my Codepen off of it.

Jesse Kochis
  • 766
  • 3
  • 10