Skip to content
Snippets Groups Projects
Commit b0162df3 authored by Wferr's avatar Wferr
Browse files

Merge pull request #3 from vivaxy/gh-pages

Merge pull request from vivaxy, Make posts have URLS and add feed.xml
parents 479f19ec da520578
No related branches found
No related tags found
No related merge requests found
Showing
with 629 additions and 600 deletions
......@@ -43,4 +43,7 @@ Temporary Items
.apdisk
#Jekyll
_site
\ No newline at end of file
_site
# webstorm
.idea
.card{position:relative;float:left;width:29%;height:0;margin:2%;padding-bottom:20%;}
.card__container{position:fixed;top:0;left:0;overflow-x:hidden;overflow-y:auto;width:100%;height:100%;-webkit-overflow-scrolling:touch;}
.card__container--closed{position:absolute;overflow:hidden;}
.card__image{position:absolute;top:0;left:0;display:block;width:100%;height:100%;}
.card__container--closed .card__image{position:relative;cursor:pointer;}
.card__container--fix-image .card__image{position:fixed;}
.card__content{position:relative;width:100%;max-width:800px;height:auto;margin:400px auto 60px;padding:30px 40px 22px;background:#fff;}
.card__container--closed .card__content{margin-top:0;padding:0 16px;pointer-events:none;background:transparent;}
.card__caption{font-size:2em;max-width:800px;margin:0 auto;padding:35px 30px 0px;}
.card__container--closed .card__caption{font-size:1em;max-width:auto;padding:10px 10px 25px;-webkit-transform:translateY(-100%);-ms-transform:translateY(-100%);transform:translateY(-100%);}
.card__title{font-size:1.5em;line-height:1;margin:5px 0 0 0;color:#3b393d;}
.card__container--closed .card__title{color:#fff;}
.card__subtitle{font-size:.95em;line-height:1;margin:5px 0 0;color:#777778;}
.card__container--closed .card__subtitle{color:#f5f5f5;}
.card__copy{font-size:1.25em;max-width:900px;margin:0 auto;padding:25px 30px 100px;color:#3b393d;}
.card__copy p:first-of-type{font-size:1.5em;padding:0 0 1em 0;}
.card__btn-close{font-size:18px;position:absolute;top:0;right:0;padding:36px;cursor:pointer;}
.card__container--closed .card__btn-close{display:none;}
.meta{font-size:.85em;display:-webkit-flex;display:flex;padding:0 0 35px 0;-webkit-align-items:center;align-items:center;}
.meta__avatar{border-radius:50%;height:50px;width:50px;}
.meta__author{font-weight:bold;padding:0 15px;}
.meta__date{margin:0 0 0 auto;}
@media only screen and (max-width:980px){.card{width:46%;padding-bottom:32.2%;}
.card__content{margin-bottom:0;padding-right:20px;padding-left:20px;}
}
@media only screen and (max-width:580px){.card{width:96%;padding-bottom:67.2%;}
}
@media only screen and (max-width:400px){.card__caption{font-size:1.25em;padding:35px 0px 0px;}
.meta{padding:0 0 25px 0;}
.card__copy{font-size:90%;padding:25px 0px 100px;}
}
*,
*:after,
*:before{-webkit-box-sizing:border-box;box-sizing:border-box;}
.clearfix:before,
.clearfix:after{content:'';display:table;}
.clearfix:after{clear:both;}
body{font-family:Avenir, 'Helvetica Neue', 'Lato', 'Segoe UI', Helvetica, Arial, sans-serif;line-height:1.5;color:#3b393d;background:#f0f0f0;background-size:cover;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overflow:hidden;overflow-y:scroll;}
body.body--hidden{overflow:hidden;}
body.body--hidden .header{opacity:0;}
.header{-webkit-transition:opacity 300ms ease-in-out;transition:opacity 300ms ease-in-out;}
a{text-decoration:none;color:#de6551;outline:none;}
a:hover,
a:focus{color:#3b393d;}
.body{background:#acaad1;}
.body a{color:#4f4c4c;}
.body .header h1 span{color:#4f4c4c;}
.hidden{position:absolute;overflow:hidden;width:0;height:0;pointer-events:none;}
.header{padding:2em 1em;text-align:center;}
.header h1{font-size:3em;font-weight:400;line-height:1.2;margin:.5em 0 0;}
.header h1 span{font-size:.45em;display:block;padding:.5em 0 1em;color:#999;}
.links{margin:2em 0 0;}
.links a{display:inline-block;margin:0 .5em;}
.wrapper{overflow:auto;width:95%;max-width:1366px;margin:0 auto;}
@media screen and (max-width:50em){.header{padding:3em 10% 4em;}
}
@media screen and (max-width:40em){.header h1{font-size:2.4em;line-height:1.2;}
}
.pattern{position:fixed;z-index:-1;top:0;left:0;width:100%;height:100%;background:no-repeat center center/cover;}
.pattern--hidden{visibility:hidden;opacity:0;}
.pattern--hidden .polygon{transition-duration:0ms;}
.pattern svg{width:100%;height:100%;}
.polygon{transition:-webkit-transform 300ms ease-in-out, opacity 300ms ease-in-out;transition:transform 300ms ease-in-out, opacity 300ms ease-in-out;-webkit-transform:scale(1);transform:scale(1);-webkit-transform-origin:center bottom;transform-origin:center bottom;}
.polygon--hidden{opacity:0;-webkit-transform:scale(0);transform:scale(0);}
.ff .polygon{-webkit-transform:scale(1)!important;transform:scale(1)!important;}
\ No newline at end of file
feed.xml 0 → 100644
---
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ site.title | xml_escape }}</title>
<description>{{ site.description | xml_escape }}</description>
<link>{{ site.url }}{{ site.baseurl }}/</link>
<atom:link href="{{ "/feed.xml" | prepend: site.baseurl | prepend: site.url }}" rel="self"
type="application/rss+xml"/>
<pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
<lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
<generator>Jekyll v{{ jekyll.version }}</generator>
{% for post in site.posts limit:10 %}
<item>
<title>{{ post.title | xml_escape }}</title>
<description>{{ post.content | xml_escape }}</description>
<pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
<link>{{ site.baseurl | prepend: site.url }}#{{ post.url }}</link>
<guid isPermaLink="true">{{ site.baseurl | prepend: site.url }}#{{ post.url }}</guid>
{% for tag in post.tags %}
<category>{{ tag | xml_escape }}</category>
{% endfor %}
{% for cat in post.categories %}
<category>{{ cat | xml_escape }}</category>
{% endfor %}
</item>
{% endfor %}
</channel>
</rss>
This diff is collapsed.
......@@ -3,83 +3,87 @@ layout: compress
---
<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ site.title }}</title>
<meta name="description" content="{{ site.description }}" />
<meta name="keywords" content="{{ site.keywords }}" />
<meta name="author" content="{{ site.author }}" />
<link rel="shortcut icon" href="img/favicon.ico">
<link rel="stylesheet" type="text/css" href="css/normalize.css" />
<link rel="stylesheet" type="text/css" href="fonts/font-awesome-4.3.0/css/font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="css/modern-blog.min.css" />
<!--[if IE]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script>
<head>
<meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ site.title }}</title>
<meta name="description" content="{{ site.description }}"/>
<meta name="keywords" content="{{ site.keywords }}"/>
<meta name="author" content="{{ site.author }}"/>
<link rel="shortcut icon" href="img/favicon.ico">
<link rel="stylesheet" type="text/css" href="css/normalize.css"/>
<link rel="stylesheet" type="text/css" href="fonts/font-awesome/css/font-awesome.css"/>
<link rel="stylesheet" type="text/css" href="css/modern-blog.css"/>
<!--[if IE]>
<script type="text/javascript" src="js/vendors/html5.min.js"></script>
<![endif]-->
<script>
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) {
var root = document.getElementsByTagName('html')[0];
root.setAttribute('class', 'ff');
};
</script>
</head>
<body class="body">
<div class="container">
<header class="header">
<h1>Modern Blog<span>A Clean, Fresh Minimal Look.</span></h1>
<nav class="links">
<a href="#"><i class="fa fa-twitter-square fa-3x"></i></a>
<a href="#"><i class="fa fa-instagram fa-3x"></i></a>
<a href="#"><i class="fa fa-facebook-square fa-3x"></i></a>
<a href="#"><i class="fa fa-tumblr-square fa-3x"></i></a>
</nav>
</header>
<div class="content">
<!-- trianglify pattern container -->
<div class="pattern pattern--hidden"></div>
<!-- cards -->
<div class="wrapper">
{% for post in site.posts %}
<div class="card">
<div class="card__container card__container--closed">
<svg class="card__image" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1200" preserveAspectRatio="xMidYMid slice">
<defs>
<clipPath id="{{ post.subtitle | slugify }}">
var root = document.getElementsByTagName('html')[0];
root.setAttribute('class', 'ff');
}
</script>
</head>
<body class="body">
<div class="container">
<header class="header">
<h1>Modern Blog<span>A Clean, Fresh Minimal Look.</span></h1>
<nav class="links">
<a href="#"><i class="fa fa-twitter-square fa-3x"></i></a>
<a href="#"><i class="fa fa-instagram fa-3x"></i></a>
<a href="#"><i class="fa fa-facebook-square fa-3x"></i></a>
<a href="#"><i class="fa fa-tumblr-square fa-3x"></i></a>
</nav>
</header>
<div class="content">
<!-- trianglify pattern container -->
<div class="pattern pattern--hidden"></div>
<!-- cards -->
<div class="wrapper">
{% for post in site.posts %}
<div class="card" data-id="{{ post.id }}">
<div class="card__container card__container--closed">
<svg class="card__image" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 1920 1200"
preserveAspectRatio="xMidYMid slice">
<defs>
<clipPath id="{{ post.id }}-clip-path">
<polygon class="clip" points="0,1200 0,0 1920,0 1920,1200"></polygon>
</clipPath>
</defs>
<image clip-path="url(#{{ post.subtitle | slugify }})" width="1920" height="1200" xlink:href="{{ post.image }}"></image>
</svg>
<div class="card__content">
<i class="card__btn-close fa fa-times"></i>
<div class="card__caption">
<h2 class="card__title">{{ post.title }}</h2>
<p class="card__subtitle">{{ post.subtitle }}</p>
</div>
<div class="card__copy">
<div class="meta">
<img class="meta__avatar" src="{{ post.avatar }}" />
<span class="meta__author">{{ post.author }}</span>
<span class="meta__date">{{ post.date | date: "%b %-d, %Y" }}</span>
</div>
{{ post.content }}
</div>
</clipPath>
</defs>
<image clip-path="url(#{{ post.id }}-clip-path)" width="1920" height="1200"
xlink:href="{{ post.image }}"></image>
</svg>
<div class="card__content">
<i class="card__btn-close fa fa-times"></i>
<div class="card__caption">
<h2 class="card__title">{{ post.title }}</h2>
<p class="card__subtitle">{{ post.subtitle }}</p>
</div>
<div class="card__copy">
<div class="meta">
<img class="meta__avatar" src="{{ post.avatar }}"/>
<span class="meta__author">{{ post.author }}</span>
<span class="meta__date">{{ post.date | date: "%Y-%m-%d" }}</span>
</div>
{{ post.content }}
</div>
</div>
{% endfor %}
<!-- /cards -->
</div>
</div>
{% endfor %}
<!-- /cards -->
</div>
<!-- /container -->
<!-- JS -->
<script src="js/vendors/trianglify.min.js"></script>
<script src="js/vendors/TweenMax.min.js"></script>
<script src="js/vendors/ScrollToPlugin.min.js"></script>
<script src="js/vendors/cash.min.js"></script>
<script src="js/card-modern-blog.min.js"></script>
<script src="js/modern-blog.min.js"></script>
</body>
</html>
\ No newline at end of file
</div>
<!-- /container -->
</div>
<!-- JS -->
<script src="js/vendors/trianglify.min.js"></script>
<script src="js/vendors/TweenMax.min.js"></script>
<script src="js/vendors/ScrollToPlugin.min.js"></script>
<script src="js/vendors/cash.min.js"></script>
<script src="js/card-modern-blog.js"></script>
<script src="js/modern-blog.js"></script>
</body>
</html>
......@@ -3,275 +3,275 @@
/**
* Card.
*/
var Card = (function(window, undefined) {
/**
* Enum of CSS selectors.
*/
var SELECTORS = {
container: '.card__container',
content: '.card__content',
clip: '.clip'
};
/**
* Enum of CSS classes.
*/
var CLASSES = {
containerClosed: 'card__container--closed',
bodyHidden: 'body--hidden'
};
/**
* Card.
*/
function Card(id, el) {
this.id = id;
this._el = el;
// Get elements.
this._container = $(this._el).find(SELECTORS.container)[0];
this._clip = $(this._el).find(SELECTORS.clip)[0];
this._content = $(this._el).find(SELECTORS.content)[0];
this.isOpen = false;
this._TL = null;
};
/**
* Open card.
* @param {Function} callback The callback `onCardMove`.
*/
Card.prototype.openCard = function(callback) {
this._TL = new TimelineLite;
var slideContentDown = this._slideContentDown();
var clipImageIn = this._clipImageIn();
var floatContainer = this._floatContainer(callback);
var clipImageOut = this._clipImageOut();
var slideContentUp = this._slideContentUp();
// Compose sequence and use duration to overlap tweens.
this._TL.add(slideContentDown);
this._TL.add(clipImageIn, 0);
this._TL.add(floatContainer, '-=' + clipImageIn.duration() * 0.6);
// this._TL.add(clipImageOut, '-=' + floatContainer.duration() * 0.3);
this._TL.add(slideContentUp/*, '-=' + clipImageOut.duration() * 0.6*/);
this.isOpen = true;
return this._TL;
};
/**
* Slide content down.
* @private
*/
Card.prototype._slideContentDown = function() {
var tween = TweenLite.to(this._content, 0.8, {
y: window.innerHeight,
ease: Expo.easeInOut
});
return tween;
};
/**
* Clip image in.
* @private
*/
Card.prototype._clipImageIn = function() {
// Polygon.
var TL = new TimelineLite;
var start = [
[0, 1200],
[0, 0],
[1920, 0],
[1920, 1200]
];
var end = [
[916, 430],
[1125, 643],
[960, 607],
[793, 570]
];
var points = [];
// Create a tween for each point.
start.forEach(function(point, i) {
var tween = TweenLite.to(point, 1.5, end[i]);
end[i].onUpdate = function() {
points.push(point.join());
// Every 4 point update clip-path.
if (points.length === end.length) {
$(this._clip).attr('points', points.join(' '));
// Reset.
points = [];
var Card = (function (window) {
/**
* Enum of CSS selectors.
*/
var SELECTORS = {
container: '.card__container',
content: '.card__content',
clip: '.clip'
};
/**
* Enum of CSS classes.
*/
var CLASSES = {
containerClosed: 'card__container--closed',
bodyHidden: 'body--hidden'
};
/**
* Card.
*/
var Card = function (id, el) {
this.id = id;
this._el = el;
// Get elements.
this._container = $(this._el).find(SELECTORS.container)[0];
this._clip = $(this._el).find(SELECTORS.clip)[0];
this._content = $(this._el).find(SELECTORS.content)[0];
this.isOpen = false;
this._TL = null;
};
/**
* Open card.
* @param {Function} callback The callback `onCardMove`.
*/
Card.prototype.openCard = function (callback) {
this._TL = new TimelineLite;
var slideContentDown = this._slideContentDown();
var clipImageIn = this._clipImageIn();
var floatContainer = this._floatContainer(callback);
var clipImageOut = this._clipImageOut();
var slideContentUp = this._slideContentUp();
// Compose sequence and use duration to overlap tweens.
this._TL.add(slideContentDown);
this._TL.add(clipImageIn, 0);
this._TL.add(floatContainer, '-=' + clipImageIn.duration() * 0.6);
// this._TL.add(clipImageOut, '-=' + floatContainer.duration() * 0.3);
this._TL.add(slideContentUp/*, '-=' + clipImageOut.duration() * 0.6*/);
this.isOpen = true;
return this._TL;
};
/**
* Slide content down.
* @private
*/
Card.prototype._slideContentDown = function () {
var tween = TweenLite.to(this._content, 0.8, {
y: window.innerHeight,
ease: Expo.easeInOut
});
return tween;
};
/**
* Clip image in.
* @private
*/
Card.prototype._clipImageIn = function () {
// Polygon.
var TL = new TimelineLite;
var start = [
[0, 1200],
[0, 0],
[1920, 0],
[1920, 1200]
];
var end = [
[916, 430],
[1125, 643],
[960, 607],
[793, 570]
];
var points = [];
// Create a tween for each point.
start.forEach(function (point, i) {
var tween = TweenLite.to(point, 1.5, end[i]);
end[i].onUpdate = function () {
points.push(point.join());
// Every 4 point update clip-path.
if (points.length === end.length) {
$(this._clip).attr('points', points.join(' '));
// Reset.
points = [];
}
}.bind(this);
tween.vars.ease = Expo.easeInOut;
// Add at position 0.
TL.add(tween, 0);
}, this);
return TL;
};
/**
* Float card to final position.
* @param {Function} callback The callback `onCardMove`.
* @private
*/
Card.prototype._floatContainer = function (callback) {
$(document.body).addClass(CLASSES.bodyHidden);
var TL = new TimelineLite;
var rect = this._container.getBoundingClientRect();
var windowW = window.innerWidth;
var track = {
width: 0,
x: rect.left + (rect.width / 2),
y: rect.top + (rect.height / 2)
};
}.bind(this);
TL.set(this._container, {
width: rect.width,
height: rect.height,
x: rect.left,
y: rect.top,
position: 'fixed',
overflow: 'hidden'
});
TL.to([this._container, track], 2, {
width: windowW,
height: '100%',
x: windowW / 2,
y: 0,
xPercent: -50,
ease: Expo.easeInOut,
clearProps: 'all',
className: '-=' + CLASSES.containerClosed,
onUpdate: callback.bind(this, track),
// Fix IE: if the image is set to fixed when CLASSES.containerClosed
// is removed IE doesn't follow the tween, fix by setting
// the image position to fixed when tween is completed.
onComplete: function () {
$(this._container).addClass('card__container--fix-image');
}.bind(this)
});
return TL;
};
/**
* Clip image out.
* @private
*/
Card.prototype._clipImageOut = function () {
tween.vars.ease = Expo.easeInOut;
var tween = this._clipImageIn();
// Add at position 0.
TL.add(tween, 0);
tween.reverse();
}, this);
return tween;
};
return TL;
};
/**
* Slide content up.
* @private
*/
Card.prototype._slideContentUp = function () {
/**
* Float card to final position.
* @param {Function} callback The callback `onCardMove`.
* @private
*/
Card.prototype._floatContainer = function(callback) {
var tween = TweenLite.to(this._content, 1, {
y: 0,
clearProps: 'all',
ease: Expo.easeInOut
});
$(document.body).addClass(CLASSES.bodyHidden);
return tween;
};
/**
* Close card.
*/
Card.prototype.closeCard = function () {
TweenLite.to(this._container, 0.4, {
scrollTo: {
y: 0
},
onComplete: function () {
$(this._container).css('overflow', 'hidden');
}.bind(this),
ease: Power2.easeOut
});
this._TL.eventCallback('onReverseComplete', function () {
TweenLite.set([this._container, this._content], {
clearProps: 'all'
});
$(document.body).removeClass(CLASSES.bodyHidden);
this.isOpen = false;
}.bind(this));
return this._TL.reverse();
};
/**
* Hide card, called for all cards except the selected one.
*/
Card.prototype.hideCard = function () {
var tween = TweenLite.to(this._el, 0.4, {
scale: 0.8,
autoAlpha: 0,
transformOrigin: 'center bottom',
ease: Expo.easeInOut
});
return tween;
};
var TL = new TimelineLite;
/**
* Show card, called for all cards except the selected one.
*/
Card.prototype.showCard = function () {
var rect = this._container.getBoundingClientRect();
var windowW = window.innerWidth;
var tween = TweenLite.to(this._el, 0.5, {
scale: 1,
autoAlpha: 1,
clearProps: 'all',
ease: Expo.easeInOut
});
var track = {
width: 0,
x: rect.left + (rect.width / 2),
y: rect.top + (rect.height / 2),
return tween;
};
TL.set(this._container, {
width: rect.width,
height: rect.height,
x: rect.left,
y: rect.top,
position: 'fixed',
overflow: 'hidden'
});
TL.to([this._container, track], 2, {
width: windowW,
height: '100%',
x: windowW / 2,
y: 0,
xPercent: -50,
ease: Expo.easeInOut,
clearProps: 'all',
className: '-=' + CLASSES.containerClosed,
onUpdate: callback.bind(this, track),
// Fix IE: if the image is set to fixed when CLASSES.containerClosed
// is removed IE doesn't follow the tween, fix by setting
// the image position to fixed when tween is completed.
onComplete: function() {
$(this._container).addClass('card__container--fix-image');
}.bind(this)
});
return TL;
};
/**
* Clip image out.
* @private
*/
Card.prototype._clipImageOut = function() {
var tween = this._clipImageIn();
tween.reverse();
return tween;
};
/**
* Slide content up.
* @private
*/
Card.prototype._slideContentUp = function() {
var tween = TweenLite.to(this._content, 1, {
y: 0,
clearProps: 'all',
ease: Expo.easeInOut
});
return tween;
};
/**
* Close card.
*/
Card.prototype.closeCard = function() {
TweenLite.to(this._container, 0.4, {
scrollTo: {
y: 0
},
onComplete: function() {
$(this._container).css('overflow', 'hidden');
}.bind(this),
ease: Power2.easeOut
});
this._TL.eventCallback('onReverseComplete', function() {
TweenLite.set([this._container, this._content], {
clearProps: 'all'
});
$(document.body).removeClass(CLASSES.bodyHidden);
this.isOpen = false;
}.bind(this));
return this._TL.reverse();
};
/**
* Hide card, called for all cards except the selected one.
*/
Card.prototype.hideCard = function() {
var tween = TweenLite.to(this._el, 0.4, {
scale: 0.8,
autoAlpha: 0,
transformOrigin: 'center bottom',
ease: Expo.easeInOut
});
return tween;
};
/**
* Show card, called for all cards except the selected one.
*/
Card.prototype.showCard = function() {
var tween = TweenLite.to(this._el, 0.5, {
scale: 1,
autoAlpha: 1,
clearProps: 'all',
ease: Expo.easeInOut
});
return tween;
};
return Card;
return Card;
})(window);
'use strict';var Card=(function(window,undefined){var SELECTORS={container:'.card__container',content:'.card__content',clip:'.clip'};var CLASSES={containerClosed:'card__container--closed',bodyHidden:'body--hidden'};function Card(id,el){this.id=id;this._el=el;this._container=$(this._el).find(SELECTORS.container)[0];this._clip=$(this._el).find(SELECTORS.clip)[0];this._content=$(this._el).find(SELECTORS.content)[0];this.isOpen=false;this._TL=null;};Card.prototype.openCard=function(callback){this._TL=new TimelineLite;var slideContentDown=this._slideContentDown();var clipImageIn=this._clipImageIn();var floatContainer=this._floatContainer(callback);var clipImageOut=this._clipImageOut();var slideContentUp=this._slideContentUp();this._TL.add(slideContentDown);this._TL.add(clipImageIn,0);this._TL.add(floatContainer,'-='+clipImageIn.duration()*0.6);this._TL.add(slideContentUp);this.isOpen=true;return this._TL;};Card.prototype._slideContentDown=function(){var tween=TweenLite.to(this._content,0.8,{y:window.innerHeight,ease:Expo.easeInOut});return tween;};Card.prototype._clipImageIn=function(){var TL=new TimelineLite;var start=[[0,1200],[0,0],[1920,0],[1920,1200]];var end=[[916,430],[1125,643],[960,607],[793,570]];var points=[];start.forEach(function(point,i){var tween=TweenLite.to(point,1.5,end[i]);end[i].onUpdate=function(){points.push(point.join());if(points.length===end.length){$(this._clip).attr('points',points.join(' '));points=[];};}.bind(this);tween.vars.ease=Expo.easeInOut;TL.add(tween,0);},this);return TL;};Card.prototype._floatContainer=function(callback){$(document.body).addClass(CLASSES.bodyHidden);var TL=new TimelineLite;var rect=this._container.getBoundingClientRect();var windowW=window.innerWidth;var track={width:0,x:rect.left+(rect.width/2),y:rect.top+(rect.height/2),};TL.set(this._container,{width:rect.width,height:rect.height,x:rect.left,y:rect.top,position:'fixed',overflow:'hidden'});TL.to([this._container,track],2,{width:windowW,height:'100%',x:windowW/2,y:0,xPercent:-50,ease:Expo.easeInOut,clearProps:'all',className:'-='+CLASSES.containerClosed,onUpdate:callback.bind(this,track),onComplete:function(){$(this._container).addClass('card__container--fix-image');}.bind(this)});return TL;};Card.prototype._clipImageOut=function(){var tween=this._clipImageIn();tween.reverse();return tween;};Card.prototype._slideContentUp=function(){var tween=TweenLite.to(this._content,1,{y:0,clearProps:'all',ease:Expo.easeInOut});return tween;};Card.prototype.closeCard=function(){TweenLite.to(this._container,0.4,{scrollTo:{y:0},onComplete:function(){$(this._container).css('overflow','hidden');}.bind(this),ease:Power2.easeOut});this._TL.eventCallback('onReverseComplete',function(){TweenLite.set([this._container,this._content],{clearProps:'all'});$(document.body).removeClass(CLASSES.bodyHidden);this.isOpen=false;}.bind(this));return this._TL.reverse();};Card.prototype.hideCard=function(){var tween=TweenLite.to(this._el,0.4,{scale:0.8,autoAlpha:0,transformOrigin:'center bottom',ease:Expo.easeInOut});return tween;};Card.prototype.showCard=function(){var tween=TweenLite.to(this._el,0.5,{scale:1,autoAlpha:1,clearProps:'all',ease:Expo.easeInOut});return tween;};return Card;})(window);
\ No newline at end of file
......@@ -3,251 +3,305 @@
/**
* Demo.
*/
var demo = (function(window, undefined) {
/**
* Enum of CSS selectors.
*/
var SELECTORS = {
pattern: '.pattern',
card: '.card',
cardImage: '.card__image',
cardClose: '.card__btn-close',
};
/**
* Enum of CSS classes.
*/
var CLASSES = {
patternHidden: 'pattern--hidden',
polygon: 'polygon',
polygonHidden: 'polygon--hidden'
};
/**
* Map of svg paths and points.
*/
var polygonMap = {
paths: null,
points: null
};
/**
* Container of Card instances.
*/
var layout = {};
/**
* Initialise demo.
*/
function init() {
// For options see: https://github.com/qrohlf/Trianglify
var pattern = Trianglify({
width: window.innerWidth,
height: window.innerHeight,
cell_size: 90,
variance: 1,
stroke_width: 1,
x_colors: 'random',
y_colors: 'random'
}).svg(); // Render as SVG.
_mapPolygons(pattern);
_bindCards();
};
var demo = (function (window) {
/**
* Enum of CSS selectors.
*/
var SELECTORS = {
pattern: '.pattern',
card: '.card',
cardImage: '.card__image',
cardClose: '.card__btn-close'
};
/**
* Enum of CSS classes.
*/
var CLASSES = {
patternHidden: 'pattern--hidden',
polygon: 'polygon',
polygonHidden: 'polygon--hidden'
};
var ATTRIBUTES = {
index: 'data-index',
id: 'data-id'
};
/**
* Map of svg paths and points.
*/
var polygonMap = {
paths: null,
points: null
};
/**
* Container of Card instances.
*/
var layout = {};
/**
* Initialise demo.
*/
var init = function () {
// For options see: https://github.com/qrohlf/Trianglify
var pattern = Trianglify({
width: window.innerWidth,
height: window.innerHeight,
cell_size: 90,
variance: 1,
stroke_width: 1,
x_colors: 'random',
y_colors: 'random'
}).svg(); // Render as SVG.
_mapPolygons(pattern);
_bindCards();
_bindHashChange();
_triggerOpenCard('', _getHashFromURL(location.href));
};
/**
* Store path elements, map coordinates and sizes.
* @param {Element} pattern The SVG Element generated with Trianglify.
* @private
*/
function _mapPolygons(pattern) {
// Append SVG to pattern container.
$(SELECTORS.pattern).append(pattern);
// Convert nodelist to array,
// Used `.childNodes` because IE doesn't support `.children` on SVG.
polygonMap.paths = [].slice.call(pattern.childNodes);
/**
* Store path elements, map coordinates and sizes.
* @param {Element} pattern The SVG Element generated with Trianglify.
* @private
*/
var _mapPolygons = function (pattern) {
polygonMap.points = [];
// Append SVG to pattern container.
$(SELECTORS.pattern).append(pattern);
polygonMap.paths.forEach(function(polygon) {
// Convert nodelist to array,
// Used `.childNodes` because IE doesn't support `.children` on SVG.
polygonMap.paths = [].slice.call(pattern.childNodes);
// Hide polygons by adding CSS classes to each svg path (used attrs because of IE).
$(polygon).attr('class', CLASSES.polygon);
polygonMap.points = [];
var rect = polygon.getBoundingClientRect();
polygonMap.paths.forEach(function (polygon) {
var point = {
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2
};
// Hide polygons by adding CSS classes to each svg path (used attrs because of IE).
$(polygon).attr('class', CLASSES.polygon);
polygonMap.points.push(point);
});
var rect = polygon.getBoundingClientRect();
// All polygons are hidden now, display the pattern container.
$(SELECTORS.pattern).removeClass(CLASSES.patternHidden);
};
/**
* Bind Card elements.
* @private
*/
function _bindCards() {
var point = {
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2
};
var elements = $(SELECTORS.card);
polygonMap.points.push(point);
});
$.each(elements, function(card, i) {
var instance = new Card(i, card);
layout[i] = {
card: instance
};
var cardImage = $(card).find(SELECTORS.cardImage);
var cardClose = $(card).find(SELECTORS.cardClose);
// All polygons are hidden now, display the pattern container.
$(SELECTORS.pattern).removeClass(CLASSES.patternHidden);
};
/**
* Bind Card elements.
* @private
*/
var _bindCards = function () {
$(cardImage).on('click', _playSequence.bind(this, true, i));
$(cardClose).on('click', _playSequence.bind(this, false, i));
});
};
var elements = $(SELECTORS.card);
/**
* Create a sequence for the open or close animation and play.
* @param {boolean} isOpenClick Flag to detect when it's a click to open.
* @param {number} id The id of the clicked card.
* @param {Event} e The event object.
* @private
*
*/
function _playSequence(isOpenClick, id, e) {
$.each(elements, function (card, i) {
var card = layout[id].card;
var instance = new Card(i, card);
// Prevent when card already open and user click on image.
if (card.isOpen && isOpenClick) return;
layout[i] = {
card: instance
};
// Create timeline for the whole sequence.
var sequence = new TimelineLite({paused: true});
var $card = $(card);
$card.attr(ATTRIBUTES.index, i + '');
var tweenOtherCards = _showHideOtherCards(id);
var cardImage = $card.find(SELECTORS.cardImage);
var cardClose = $card.find(SELECTORS.cardClose);
if (!card.isOpen) {
// Open sequence.
$(cardImage).on('click', function () {
location.hash = $card.attr(ATTRIBUTES.id);
});
$(cardClose).on('click', function () {
location.hash = '';
});
});
};
_setPatternBgImg(e.target);
/**
* Create a sequence for the open or close animation and play.
* @param {boolean} isOpenClick Flag to detect when it's a click to open.
* @param {number} id The id of the clicked card.
* @private
*
*/
var _playSequence = function (isOpenClick, id) {
sequence.add(tweenOtherCards);
sequence.add(card.openCard(_onCardMove), 0);
var card = layout[id].card;
} else {
// Close sequence.
// Prevent when card already open and user click on image.
if (card.isOpen && isOpenClick) {
return;
}
var closeCard = card.closeCard();
var position = closeCard.duration() * 0.8; // 80% of close card tween.
// Create timeline for the whole sequence.
var sequence = new TimelineLite({paused: true});
sequence.add(closeCard);
sequence.add(tweenOtherCards, position);
}
var tweenOtherCards = _showHideOtherCards(id);
sequence.play();
};
if (!card.isOpen) {
// Open sequence.
/**
* Show/Hide all other cards.
* @param {number} id The id of the clcked card to be avoided.
* @private
*/
function _showHideOtherCards(id) {
_setPatternBgImg($(this).find(SELECTORS.cardImage).find('image'));
var TL = new TimelineLite;
sequence.add(tweenOtherCards);
sequence.add(card.openCard(_onCardMove), 0);
var selectedCard = layout[id].card;
} else {
// Close sequence.
for (var i in layout) {
var closeCard = card.closeCard();
var position = closeCard.duration() * 0.8; // 80% of close card tween.
var card = layout[i].card;
sequence.add(closeCard);
sequence.add(tweenOtherCards, position);
}
// When called with `openCard`.
if (card.id !== id && !selectedCard.isOpen) {
TL.add(card.hideCard(), 0);
}
sequence.play();
};
// When called with `closeCard`.
if (card.id !== id && selectedCard.isOpen) {
TL.add(card.showCard(), 0);
}
}
/**
* Show/Hide all other cards.
* @param {number} id The id of the clcked card to be avoided.
* @private
*/
var _showHideOtherCards = function (id) {
return TL;
};
var TL = new TimelineLite;
/**
* Add card image to pattern background.
* @param {Element} image The clicked SVG Image Element.
* @private
*/
function _setPatternBgImg(image) {
var selectedCard = layout[id].card;
var imagePath = $(image).attr('xlink:href');
for (var i in layout) {
$(SELECTORS.pattern).css('background-image', 'url(' + imagePath + ')');
};
if (layout.hasOwnProperty(i)) {
var card = layout[i].card;
/**
* Callback to be executed on Tween update, whatever a polygon
* falls into a circular area defined by the card width the path's
* CSS class will change accordingly.
* @param {Object} track The card sizes and position during the floating.
* @private
*/
function _onCardMove(track) {
// When called with `openCard`.
if (card.id !== id && !selectedCard.isOpen) {
TL.add(card.hideCard(), 0);
}
var radius = track.width / 2;
// When called with `closeCard`.
if (card.id !== id && selectedCard.isOpen) {
TL.add(card.showCard(), 0);
}
}
}
var center = {
x: track.x,
y: track.y
return TL;
};
polygonMap.points.forEach(function(point, i) {
/**
* Add card image to pattern background.
* @param {Element} image The clicked SVG Image Element.
* @private
*/
var _setPatternBgImg = function (image) {
if (_detectPointInCircle(point, radius, center)) {
$(polygonMap.paths[i]).attr('class', CLASSES.polygon + ' ' + CLASSES.polygonHidden);
} else {
$(polygonMap.paths[i]).attr('class', CLASSES.polygon);
}
});
}
var imagePath = $(image).attr('xlink:href');
/**
* Detect if a point is inside a circle area.
* @private
*/
function _detectPointInCircle(point, radius, center) {
$(SELECTORS.pattern).css('background-image', 'url(' + imagePath + ')');
};
/**
* Callback to be executed on Tween update, whatever a polygon
* falls into a circular area defined by the card width the path's
* CSS class will change accordingly.
* @param {Object} track The card sizes and position during the floating.
* @private
*/
var _onCardMove = function (track) {
var radius = track.width / 2;
var center = {
x: track.x,
y: track.y
};
polygonMap.points.forEach(function (point, i) {
if (_detectPointInCircle(point, radius, center)) {
$(polygonMap.paths[i]).attr('class', CLASSES.polygon + ' ' + CLASSES.polygonHidden);
} else {
$(polygonMap.paths[i]).attr('class', CLASSES.polygon);
}
});
};
var xp = point.x;
var yp = point.y;
/**
* Detect if a point is inside a circle area.
* @private
*/
var _detectPointInCircle = function (point, radius, center) {
var xc = center.x;
var yc = center.y;
var xp = point.x;
var yp = point.y;
var d = radius * radius;
var xc = center.x;
var yc = center.y;
var isInside = Math.pow(xp - xc, 2) + Math.pow(yp - yc, 2) <= d;
var d = radius * radius;
return isInside;
};
return Math.pow(xp - xc, 2) + Math.pow(yp - yc, 2) <= d;
};
// Expose methods.
return {
init: init
};
/**
* initialize page view according to hash
* @private
*/
var _triggerOpenCard = function (fromId, toId) {
var getIndex = function (card) {
var index = $(card).attr(ATTRIBUTES.index);
return parseInt(index, 10);
};
if (fromId) {
var fromBlogCard = $('[' + ATTRIBUTES.id + '="' + fromId + '"]')[0];
if (fromBlogCard) {
_playSequence.call(fromBlogCard, false, getIndex(fromBlogCard));
}
}
if (toId) {
var toBlogCard = $('[' + ATTRIBUTES.id + '="' + toId + '"]')[0];
if (toBlogCard) {
_playSequence.call(toBlogCard, true, getIndex(toBlogCard));
}
}
};
var _getHashFromURL = function (url) {
var a = document.createElement('a');
a.href = url;
return a.hash.slice(1);
};
var _bindHashChange = function () {
window.addEventListener('hashchange', function (e) {
var newHash = _getHashFromURL(e.newURL);
var oldHash = _getHashFromURL(e.oldURL);
_triggerOpenCard(oldHash, newHash);
});
};
// Expose methods.
return {
init: init
};
})(window);
......
'use strict';var demo=(function(window,undefined){var SELECTORS={pattern:'.pattern',card:'.card',cardImage:'.card__image',cardClose:'.card__btn-close',};var CLASSES={patternHidden:'pattern--hidden',polygon:'polygon',polygonHidden:'polygon--hidden'};var polygonMap={paths:null,points:null};var layout={};function init(){var pattern=Trianglify({width:window.innerWidth,height:window.innerHeight,cell_size:90,variance:1,stroke_width:1,x_colors:'random',y_colors:'random'}).svg();_mapPolygons(pattern);_bindCards();};function _mapPolygons(pattern){$(SELECTORS.pattern).append(pattern);polygonMap.paths=[].slice.call(pattern.childNodes);polygonMap.points=[];polygonMap.paths.forEach(function(polygon){$(polygon).attr('class',CLASSES.polygon);var rect=polygon.getBoundingClientRect();var point={x:rect.left+rect.width/2,y:rect.top+rect.height/2};polygonMap.points.push(point);});$(SELECTORS.pattern).removeClass(CLASSES.patternHidden);};function _bindCards(){var elements=$(SELECTORS.card);$.each(elements,function(card,i){var instance=new Card(i,card);layout[i]={card:instance};var cardImage=$(card).find(SELECTORS.cardImage);var cardClose=$(card).find(SELECTORS.cardClose);$(cardImage).on('click',_playSequence.bind(this,true,i));$(cardClose).on('click',_playSequence.bind(this,false,i));});};function _playSequence(isOpenClick,id,e){var card=layout[id].card;if(card.isOpen&&isOpenClick)return;var sequence=new TimelineLite({paused:true});var tweenOtherCards=_showHideOtherCards(id);if(!card.isOpen){_setPatternBgImg(e.target);sequence.add(tweenOtherCards);sequence.add(card.openCard(_onCardMove),0);}else{var closeCard=card.closeCard();var position=closeCard.duration()*0.8;sequence.add(closeCard);sequence.add(tweenOtherCards,position);}sequence.play();};function _showHideOtherCards(id){var TL=new TimelineLite;var selectedCard=layout[id].card;for(var i in layout){var card=layout[i].card;if(card.id!==id&&!selectedCard.isOpen){TL.add(card.hideCard(),0);}if(card.id!==id&&selectedCard.isOpen){TL.add(card.showCard(),0);}}return TL;};function _setPatternBgImg(image){var imagePath=$(image).attr('xlink:href');$(SELECTORS.pattern).css('background-image','url('+imagePath+')');};function _onCardMove(track){var radius=track.width/2;var center={x:track.x,y:track.y};polygonMap.points.forEach(function(point,i){if(_detectPointInCircle(point,radius,center)){$(polygonMap.paths[i]).attr('class',CLASSES.polygon+' '+CLASSES.polygonHidden);}else{$(polygonMap.paths[i]).attr('class',CLASSES.polygon);}});}function _detectPointInCircle(point,radius,center){var xp=point.x;var yp=point.y;var xc=center.x;var yc=center.y;var d=radius*radius;var isInside=Math.pow(xp-xc,2)+Math.pow(yp-yc,2)<=d;return isInside;};return{init:init};})(window);window.onload=demo.init;
\ No newline at end of file
/*
HTML5 Shiv v3.7.0 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/
(function(l,f){function m(){var a=e.elements;return"string"==typeof a?a.split(" "):a}function i(a){var b=n[a[o]];b||(b={},h++,a[o]=h,n[h]=b);return b}function p(a,b,c){b||(b=f);if(g)return b.createElement(a);c||(c=i(b));b=c.cache[a]?c.cache[a].cloneNode():r.test(a)?(c.cache[a]=c.createElem(a)).cloneNode():c.createElem(a);return b.canHaveChildren&&!s.test(a)?c.frag.appendChild(b):b}function t(a,b){if(!b.cache)b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag();
a.createElement=function(c){return!e.shivMethods?b.createElem(c):p(c,a,b)};a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+m().join().replace(/[\w\-]+/g,function(a){b.createElem(a);b.frag.createElement(a);return'c("'+a+'")'})+");return n}")(e,b.frag)}function q(a){a||(a=f);var b=i(a);if(e.shivCSS&&!j&&!b.hasCSS){var c,d=a;c=d.createElement("p");d=d.getElementsByTagName("head")[0]||d.documentElement;c.innerHTML="x<style>article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}</style>";
c=d.insertBefore(c.lastChild,d.firstChild);b.hasCSS=!!c}g||t(a,b);return a}var k=l.html5||{},s=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,r=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,j,o="_html5shiv",h=0,n={},g;(function(){try{var a=f.createElement("a");a.innerHTML="<xyz></xyz>";j="hidden"in a;var b;if(!(b=1==a.childNodes.length)){f.createElement("a");var c=f.createDocumentFragment();b="undefined"==typeof c.cloneNode||
"undefined"==typeof c.createDocumentFragment||"undefined"==typeof c.createElement}g=b}catch(d){g=j=!0}})();var e={elements:k.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:"3.7.0",shivCSS:!1!==k.shivCSS,supportsUnknownElements:g,shivMethods:!1!==k.shivMethods,type:"default",shivDocument:q,createElement:p,createDocumentFragment:function(a,b){a||(a=f);
if(g)return a.createDocumentFragment();for(var b=b||i(a),c=b.frag.cloneNode(),d=0,e=m(),h=e.length;d<h;d++)c.createElement(e[d]);return c}};l.html5=e;q(f)})(this,document);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment