Abheek Talukdar
Abheek Talukdar

Reputation: 97

Activate CSS 3d transforms when element scrolls into viewport

I am trying to activate this small CSS animation involving CSS 3d transforms, when each of the elements scroll into view. The laptops need to open and close when scrolled into position. Is there any way this can be done using only CSS? If not Jquery answers will also be helpful! The code is below.

/* Css Code */
    .macbook {
      width: 300px;
      margin: 50px auto;
      -webkit-perspective: 750;
      -webkit-perspective-origin: 50% bottom;
      -webkit-transform-style: preserve-3d;
      -moz-perspective: 750px;
      -moz-perspective-origin: 50% bottom;
      -moz-transform-style: preserve-3d;
      perspective: 750;
      perspective-origin: 50% bottom;
      transform-style: preserve-3d;
    }
    .macbook-lid {
      width: 80%;
      margin: 0 auto;
      -webkit-transform-origin: 50% bottom;
      -webkit-transform-style: preserve-3d;
      -moz-transform-origin: 50% bottom;
      -moz-transform-style: preserve-3d;
      transform-origin: 50% bottom;
      transform-style: preserve-3d;
      -webkit-transition: all 1s;
      -moz-transition: all 1s;
      transition: all 1s;
    }
    .macbook-lid:before {
      display: block;
      content: '';
      width: 92%;
      margin: 0 auto;
      padding: 2% 3% 0 3%;
      background-color: #D3D1D2;
      border-radius: 10px 10px 0 0;
      -webkit-transform-origin: 50% bottom;
      -webkit-transform: rotate3d(1, 0, 0, 90deg);
      -moz-transform-origin: 50% bottom;
      -moz-transform: rotate3d(1, 0, 0, 90deg);
      transform-origin: 50% bottom;
      transform: rotate3d(1, 0, 0, 90deg);
      -webkit-transition: all 1s;
      -moz-transition: all 1s;
      transition: all 1s;
    }
    .macbook-screen {
      position: relative;
      background-color: #353535;
      margin: 0 auto;
      padding: 3%;
      border-radius: 5px 5px 0 0;
      -webkit-transform-style: preserve-3d;
      -moz-transform-style: preserve-3d;
      transform-style: preserve-3d;
      -webkit-transition: all 1s;
      -moz-transition: all 1s;
      transition: all 1s;
    }
    .macbook-screen:before {
      display: block;
      content: '';
      position: absolute;
      top: 2%;
      left: 49%;
      width: 1%;
      padding-top: 1%;
      background-color: #000;
    }
    .macbook-content {
      position: relative;
      overflow: hidden;
      box-shadow: inset 0px 0px 6px #222;
    }
    
    .macbook-content1 {
      background-image: url("../img/cs.png");
    }
    .macbook-content2 {
      background-image: url("../img/xyz.png");
    }
    .macbook-content3 {
      background-image: url("../img/abc.png");
    }
    .macbook-content4 {
      background-image: url("../img/def.png");
    }
    .macbook-content5 {
      background-image: url("../img/ghi.png");
    }
    
    .macbook-content6 {
      background-image: url("../img/jkl.png");
    }
    
    
    .macbook-content:before {
      display: block;
      content: '';
      width: 1px;
      padding-top: 60%;
      float: left;
    }
    .macbook-content:after {
      display: block;
      content: '';
      clear: both;
    }
    
    .macbook:not(:hover) .macbook-lid {
      -webkit-transform: rotate3d(-1, 0, 0, 91deg);
      -moz-transform: rotate3d(-1, 0, 0, 91deg);
      transform: rotate3d(-1, 0, 0, 91deg);
    }
    .macbook:not(:hover) .macbook-lid:before {
      width: 94%;
    }
 <div class="row">
        <div class="col-md-3">
              <div class="macbook">
                <div class="macbook-lid">
                  <div class="macbook-screen">
                    <div class="macbook-content macbook-content1">
                  
                    </div>
                  </div>
                </div>
                <div class="macbook-base"></div>
              </div>
        </div>
        <div class="col-md-9">
          <div class="website-description text-content-yellow">
            <h1>EYE- Name</h1>
            <p>Description</p>
            </div>

        </div>
      </div>

Upvotes: 3

Views: 1071

Answers (2)

Abheek Talukdar
Abheek Talukdar

Reputation: 97

This seems to work. I've added separate classes for the 7 separate elements on display

$(window).scroll(function () {
    $('.macbook').each(function () {
        var imagePos = $(this).offset().top;
        var imageHeight = $(this).height();
        var topOfWindow = $(window).scrollTop();

        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-1");
        } else {
            $(this).addClass("macbook-1");
        }
        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-2");
        } else {
            $(this).addClass("macbook-2");
        }
        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-3");
        } else {
            $(this).addClass("macbook-3");
        }
        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-4");
        } else {
            $(this).addClass("macbook-4");
        }
        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-5");
        } else {
            $(this).addClass("macbook-5");
        }
        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-6");
        } else {
            $(this).addClass("macbook-6");
        }
        if (imagePos < topOfWindow + imageHeight && imagePos + imageHeight > topOfWindow) {
            $(this).removeClass("macbook-7");
        } else {
            $(this).addClass("macbook-7");
        }
    });
});

Upvotes: 0

Filipe Merker
Filipe Merker

Reputation: 2446

There is no way to do this via CSS only.

But you can acompilsh this easily via Waypoints library

var waypoint = new Waypoint({
  element: document.getElementById('yourElement'),
  handler: function(direction) {
    console.log('Scrolled to waypoint!');
  }
})

or with jQuery

var waypoints = $('.col-md-3').waypoint({
  handler: function(direction) {
    $('.col-md-3').addClass('inview');
  }
})

Edit

But, for the sake of education, here is a solution built from scratch, library agnostic, easy to use.

var getPoints = function($el, wt){
  return (wt > ($el.offset().top - ($(window).height()/2)) && wt < (($el.offset().top) + $el.height()));
}

var cm = function checkMilestones() {
  var wt = $(window).scrollTop();


  if(getPoints($('.col-md-3'), wt)){
    //check if your element is in view
    $('.col-md-3').addClass('inview');
  } else if (getPoints($('.col-md-9'), wt)){
    //if your another element is in view
    $('.col-md-9').addClass('inview');
  }
};

$(document).on('ready', cm);
$(window).on('scroll', cm);

Implementing

In your case, you should do this:

instead of :not(:hover), use a class

.macbook.closed .macbook-lid {
  -webkit-transform: rotate3d(-1, 0, 0, 91deg);
  -moz-transform: rotate3d(-1, 0, 0, 91deg);
  transform: rotate3d(-1, 0, 0, 91deg);
}

Put this class in your div

<div class="macbook closed">

And use your js like this:

var getPoints = function($el, wt){
  return (wt > ($el.offset().top - ($(window).height()/2)) && wt < (($el.offset().top) + $el.height()));
}

var cm = function checkMilestones() {
  var wt = $(window).scrollTop();


  if(getPoints($('.macbook'), wt)){
    //check if your element is in view
    $('.macbook').removeClass('closed');
  } else if (getPoints($('.anotherElement'), wt)){
    //if your another element is in view
    $('.anotherElement').removeClass('removeClass');
  }
};

$(document).on('ready', cm);
$(window).on('scroll', cm);

Upvotes: 4

Related Questions