Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. If you link to another Pen, it will include the CSS from that Pen. If the preprocessor matches, it will attempt to combine them before processing.

+ add another resource

JavaScript

Babel is required to process package imports. If you need a different preprocessor remove all packages first.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <div class="container">
  <div class="post-item" id="post-one">
    <div class="featured-image" style="background-image: url('http://i.ytimg.com/vi/_XePuRyD6_o/maxresdefault.jpg');"></div>
    <div class="post-overlay"></div>
    <div class="post-heading">
       <h3 class="post-title">
         <a class="post-link transition-link">This is a Post Title</a>
      </h3>
       <p class="post-date">06/19/2015</p>
    </div>
    <div class="post-content">
      <div class="post-body">
          <p>I’m currently working on a project in which I require a Slides.com presentation to control a meteor app that pushes content to subscribers whenever slides change. This required the creator of the slide deck to sync their deck to the content they created in my app. Simple enough?

But Slides.com doesn’t have a public API, so there is no direct way to accomplish this. I decided to create a Chrome extension that allows the author of the slide deck to authenticate their credentials with my Meteor application and sync their slide deck to the app. Check out my publicGitHub repo for the full extension code.</p>
      </div>
    </div>
  </div>
   <div class="post-item">
     <div class="featured-image" style="background-image: url('http://cdn2.vox-cdn.com/uploads/chorus_image/image/33941339/haltcatchfire.0_standard_800.0.jpg');"></div>
    <div class="post-overlay"></div>
    <div class="post-heading">
       <h3 class="post-title">
         <a class="post-link transition-link">You should click on this post title. You wont believe what happens next.</a>
      </h3>
       <p class="post-date">06/19/2015</p>
    </div>
    <div class="post-content">
      <div class="post-body">
          <p>I’m currently working on a project in which I require a Slides.com presentation to control a meteor app that pushes content to subscribers whenever slides change. This required the creator of the slide deck to sync their deck to the content they created in my app. Simple enough?

But Slides.com doesn’t have a public API, so there is no direct way to accomplish this. I decided to create a Chrome extension that allows the author of the slide deck to authenticate their credentials with my Meteor application and sync their slide deck to the app. Check out my publicGitHub repo for the full extension code.</p>
      </div>
    </div>
  </div>
   <div class="post-item">
     <div class="featured-image" style="background-image: url('https://i.vimeocdn.com/video/477337239_1280x720.jpg');"></div>
    <div class="post-overlay"></div>
    <div class="post-heading">
       <h3 class="post-title">
         <a class="post-link transition-link">This is a Post Title</a>
      </h3>
       <p class="post-date">06/19/2015</p>
    </div>
    <div class="post-content">
      <div class="post-body">
          <p>I’m currently working on a project in which I require a Slides.com presentation to control a meteor app that pushes content to subscribers whenever slides change. This required the creator of the slide deck to sync their deck to the content they created in my app. Simple enough?

But Slides.com doesn’t have a public API, so there is no direct way to accomplish this. I decided to create a Chrome extension that allows the author of the slide deck to authenticate their credentials with my Meteor application and sync their slide deck to the app. Check out my publicGitHub repo for the full extension code.</p>
      </div>
    </div>
  </div>
  
  
</div>
              
            
!

CSS

              
                @import url(https://fonts.googleapis.com/css?family=Lora:400,700,400italic);
@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700);

$serif: 'Lora', Helvetica, serif;
$sansSerif: 'Source Sans Pro', Helvetica, sans-serif;
$dark: #27073A;

h1,h2,h3{
  font-family: $serif;
}

h1{
  font-size: 4rem;
}

h3{
  font-size: 2.5rem;
}

body{
  font-family: $sansSerif;
}

.post-item{
  width: 100%;
	position: relative;
  padding: 2rem;
	backface-visibility: hidden;
	margin-bottom: .5rem;
  z-index: 1;
  opacity: 0;

	&:hover:not(.active){
    
		.post-link{
			color: $dark;
		}

		.post-date{
			background-color: $dark;
			color: white;
		}
	}

	&.active{
    z-index: 100;
		.post-content{
			opacity: 1;
      transform: translateY(0px);
      max-height: 2000px;
      transition: all 600ms ease-out 600ms; 
		}
    
    .post-title{
      color: white;
    }
	}
}

.featured-image{
  position: absolute;
  top: 0;
  left: 0%;
  height: 100%;
  width: 100%;
  background-size: cover;
  background-position: center center;
  z-index: -1;
  backface-visibility: hidden;
}

.post-heading{
  width: 100%;
  padding: 2rem 0rem;
  transition: opacity 600ms ease-out;
}

.post-overlay{
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
  z-index: -1;
  backface-visibility: hidden;

	svg{
		position: absolute;
		top: 0;
		left: 0;
		height: 100%;
		width: 100%;
		pointer-events: none;
	}

	path{
		stroke-opacity: .5;
    stroke-width: 2;
	}
}

.post-content{
  position: absolute;
  left: 0;
  top: 100;
  height: 100%;
  width: 100%;
  max-width: 600px;
  background-color: white;
  padding: 2rem;
  opacity: 0;
  max-height: 0;
  overflow: hidden;
  transition: opacity 300ms ease-out;
  transform: translateY(50px);
  pointer-events: none;
  
  .post-title{
    margin-bottom: 1.5rem;
  }
}

.post-title{
  max-width: 700px;
  transition: all 1000ms ease-out 200ms;
  cursor: pointer;
}

.post-body p{
  line-height: 1.6rem;
}

.post-link{
  color: white;
  line-height: 3rem;
  transition: all 1000ms ease-out 200ms;
}

.post-date{
  padding: .5rem;
  background-color: white;
  color: $dark;
  float: left;
}
              
            
!

JS

              
                var defaultEasing = Power4.easeOut;

function animateTriangles(post, direction){
  var triangles = $(post).find('path');
	var postItemWidth = $(post).find('.post-link').outerWidth();
  _.each(triangles, function(triangle, index){
    var offsetLeft = triangle.getBoundingClientRect().left - 100;
    var props = {};
    
    if (direction === 'reset'){
      var props = {
        opacity: 1,
        fill: "#fff",
        stroke: "#fff",
        ease: defaultEasing,
        delay:  ((triangles.length) - (index)) / 1000
      }
      TweenMax.to(triangle, .5, props);
    } else if (direction === 'in' && offsetLeft < postItemWidth){   
      var props = {
        fill: "#fff",
        stroke: "#fff",
        ease: defaultEasing,
        delay: ((triangles.length) - (index)) / 1000
      }
      TweenMax.to(triangle, 1, props);
      
    } else if (direction === 'out' && offsetLeft < postItemWidth ){
       var props = {
        fill: "#27073A",
        stroke: "#27073A",
        ease: defaultEasing,
        delay: ((triangles.length) - (index)) / 1000
      }
      TweenMax.to(triangle, .3, props);
      
    } else if (direction === 'inAndOut'){
       var propsIn = {
         fill: "#27073A",
         stroke: "#27073A",
         ease: defaultEasing,
         delay: ((triangles.length) - (index)) / 1000
       }
       
       var propsOut = {
         fill: "#fff",
         stroke: '#fff',
         opacity: 0,
         ease: defaultEasing,
         delay: ((triangles.length) - (index)) / 900
       }
       
       TweenMax.to(triangle, .6, propsIn);
       TweenMax.to(triangle, 1, propsOut);
    }
  })                 
}

function animatePostsOut(posts){
  var activePost = $('.post-item.active');
  var offset = activePost.offset().top
  console.log(offset);
  
  _.each(posts, function(post){
    if (!$(post).hasClass('active')){
      TweenMax.to(post, .3, {opacity: 0, ease: defaultEasing})
    } else {
       TweenMax.to(post, .6, {top: -offset, ease: defaultEasing, delay: .5})
    }
  })
}

function animatePostsIn(posts){
  _.each(posts, function(post){
    if (!$(post).hasClass('active')){
      TweenMax.to(post, .3, {opacity: 1, top: 0, ease: defaultEasing});
    }
  })
}

$(function(){

  var posts = $('.post-item');
  
  _.each(posts, function(post, index){

    TweenMax.to(post, .1, {opacity: 1});

    var height = $(post).outerHeight();
    var width = $(post).outerWidth();
    var postOverlay = $(post).find('.post-overlay');

    var pattern = Trianglify({
      width: width, 
      height: height,
      x_colors: ['#fff', '#fff'],
      cell_size: 40
    });

    postOverlay.append(pattern.svg());

    var triangles = postOverlay.find('path');
    var postItemWidth = $(post).find('.post-link').outerWidth();
    animateTriangles(post, 'out');
  })

  $('.post-item').on('mouseenter', function(e){
    var post = this;
    if (!$(post).hasClass('active')){
      animateTriangles(post, 'in');
    }
  });

  $('.post-item').on('mouseleave', function(e){
    var post = this;
    if (!$(post).hasClass('active')){
      animateTriangles(post, 'out');   
    }
  });

  $('.post-item').on('click', function(e){
    e.preventDefault();
    var post = this;
    $(post).toggleClass('active');
    if ($(post).hasClass('active')){ 
      animatePostsOut(posts); 
      animateTriangles(post, 'inAndOut');
    } else {
       animatePostsIn(posts); 
       animateTriangles(post, 'reset');
    }
  })
});
              
            
!
999px

Console