Shuffle 2.0!
@ -1,2 +1,5 @@
|
||||
|
||||
.DS_Store
|
||||
_site
|
||||
.sass_cache/*
|
||||
*.scssc
|
@ -0,0 +1,18 @@
|
||||
# [Shuffle](http://vestride.github.io/Shuffle)
|
||||
Categorize, sort, and filter a responsive grid of items
|
||||
|
||||
## Docs and Demos
|
||||
[All found here](http://vestride.github.io/Shuffle)
|
||||
|
||||
## Shuffle 2.0
|
||||
This is a large improvement to shuffle. Most notably, the ability for [masonry](http://masonry.desandro.com) layouts. Other additions include adding/removing items, enabling/disabling, multiple instances on a page, and more!
|
||||
|
||||
## Running locally
|
||||
This project uses [Jekyll](http://jekyllrb.com/), so head over to [their quickstart guide](http://jekyllrb.com/docs/quickstart/) to get set up.
|
||||
|
||||
## Improvements still to make
|
||||
* FAQ page
|
||||
* Use Deferred objects for callbacks
|
||||
* Horizontal layout
|
||||
|
||||
Inspired by [Isotope](http://isotope.metafizzy.co/) and [Packery](http://packery.metafizzy.co/).
|
@ -0,0 +1,144 @@
|
||||
source: .
|
||||
destination: ./_site
|
||||
plugins: ./_plugins
|
||||
layouts: ./_layouts
|
||||
include: ['.htaccess']
|
||||
exclude: ['./_scss/*.*']
|
||||
|
||||
permalink: /:title
|
||||
|
||||
_url: http://glen.local:4000
|
||||
__url: http://localhost:4000
|
||||
___url: http://vestride.github.io/Shuffle/
|
||||
|
||||
defaultTitle: 'Shuffle.js'
|
||||
defaultDescription: 'Categorize, sort, and filter a responsive grid of items'
|
||||
defaultImage: '/img/hero.png'
|
||||
|
||||
demos:
|
||||
- url: 'demos/2013-05-01-basic'
|
||||
slug: basic
|
||||
label: Basic masonry layout
|
||||
screenshot: basic.webp
|
||||
- url: 'demos/2013-06-19-adding-removing'
|
||||
slug: adding-removing
|
||||
label: Adding and removing items
|
||||
screenshot: removing.webp
|
||||
- url: 'demos/2013-05-02-adaptive'
|
||||
slug: adaptive
|
||||
label: Adaptive bootstrap grid with compound filters
|
||||
screenshot: adaptive.webp
|
||||
- url: 'demos/2013-05-03-images'
|
||||
slug: images
|
||||
label: Using images
|
||||
screenshot: images.webp
|
||||
|
||||
shapes:
|
||||
- shape: circle
|
||||
color: blue
|
||||
- shape: diamond
|
||||
color: red
|
||||
- shape: triangle
|
||||
color: green
|
||||
- shape: triangle
|
||||
color: orange
|
||||
- shape: square
|
||||
color: red
|
||||
- shape: diamond
|
||||
color: green
|
||||
- shape: circle
|
||||
color: red
|
||||
- shape: square
|
||||
color: green
|
||||
- shape: circle
|
||||
color: orange
|
||||
- shape: diamond
|
||||
color: blue
|
||||
- shape: square
|
||||
color: orange
|
||||
- shape: square
|
||||
color: blue
|
||||
|
||||
items:
|
||||
- groups: [ photography ]
|
||||
date: 2010-09-14
|
||||
title: Baseball
|
||||
img: baseball.png
|
||||
original: baseball.jpg
|
||||
cols: 3
|
||||
- groups: [ wallpaper, 3d ]
|
||||
date: 2011-08-14
|
||||
title: Tennis
|
||||
img: tennis-ball.png
|
||||
original: tennis-ball.jpg
|
||||
description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
cols: 6
|
||||
- groups: [ wallpaper, 3d ]
|
||||
date: 2009-05-27
|
||||
title: iMac
|
||||
img: imac.png
|
||||
original: imac.jpg
|
||||
cols: 3
|
||||
- groups: [ graphics ]
|
||||
date: 2012-05-14
|
||||
title: Master Chief
|
||||
img: master-chief.png
|
||||
original: Master_Chief_Portrait_by_Eightfold_Studios.jpg
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
|
||||
extras: [ h2 ]
|
||||
cols: 3
|
||||
- groups: [ wallpaper, 3d ]
|
||||
date: 2009-09-14
|
||||
title: Eightfold
|
||||
img: es-blue.png
|
||||
original: es-blue.jpg
|
||||
cols: 3
|
||||
- groups: [ photography ]
|
||||
date: 2012-03-14
|
||||
title: Pumpkin
|
||||
img: pumpkin.png
|
||||
original: pumpkin.jpg
|
||||
description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
cols: 6
|
||||
- groups: [ wallpaper, 3d ]
|
||||
date: 2013-05-19
|
||||
title: Vestride
|
||||
img: vestride-red.png
|
||||
original: vestride-red.jpg
|
||||
extras: [ h2 ]
|
||||
cols: 6
|
||||
- groups: [ graphics ]
|
||||
date: 2013-02-01
|
||||
title: Newegg
|
||||
img: newegg.png
|
||||
original: newegg.jpg
|
||||
description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'
|
||||
extras: [ h2 ]
|
||||
cols: 3
|
||||
- groups: [ wallpaper ]
|
||||
date: 2000-01-01
|
||||
title: Arc
|
||||
img: eightfoldarc.png
|
||||
original: eightfoldarc.jpg
|
||||
cols: 3
|
||||
- groups: [ photography ]
|
||||
date: 2012-07-04
|
||||
title: Ground
|
||||
img: ground.png
|
||||
original: ground!.jpg
|
||||
cols: 3
|
||||
- groups: [ wallpaper ]
|
||||
date: 2011-08-12
|
||||
title: Grass
|
||||
img: grassy-hills.png
|
||||
original: grassy-hills.tif
|
||||
description: 'Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
|
||||
cols: 6
|
||||
- groups: [ wallpaper, 3d ]
|
||||
date: 2013-05-19
|
||||
title: Vestride
|
||||
img: vestride-classy.png
|
||||
original: vestride-classy.jpg
|
||||
cols: 3
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
<h2>Advanced Filtering</h2>
|
||||
|
||||
<p>By passing a function to shuffle, you can customize the filtering to your hearts content. Shuffle will iterate over each item and give your function the element wrapped in jQuery and the shuffle instance. Return <code>true</code> to keep the element or <code>false</code> to hide it.</p>
|
||||
|
||||
<h3>Example</h3>
|
||||
<pre rel="JavaScript"><code class="language-javascript">// Filters elements with a data-title attribute with less than 10 characters
|
||||
$('#grid').shuffle('shuffle', function($el, shuffle) {
|
||||
return $el.data('title').length < 10;
|
||||
});</code></pre>
|
||||
|
||||
<h3>Searching</h3>
|
||||
<pre rel="JavaScript"><code class="language-javascript">// Advanced filtering
|
||||
$('.js-shuffle-search').on('keyup change', function() {
|
||||
var val = this.value.toLowerCase();
|
||||
$grid.shuffle('shuffle', function($el, shuffle) {
|
||||
|
||||
// Only search elements in the current group
|
||||
if (shuffle.group !== 'all' && $.inArray(shuffle.group, $el.data('groups')) === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var text = $.trim( $el.find('.picture-item__title').text() ).toLowerCase();
|
||||
return text.indexOf(val) !== -1;
|
||||
});
|
||||
});</code></pre>
|
||||
|
||||
<p>For another example of advanced filters, check out the <a href="{% post_url demos/2013-05-02-adaptive %}">compounded filters demo</a>.</p>
|
@ -0,0 +1,9 @@
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
<li>11.3.12 - Replaced layout system with <a href="http://masonry.desandro.com/">masonry</a>. Items can now be different sizes! Added addtional examples.</li>
|
||||
<li>10.24.12 - Better handling of grid item dimensions. Added a minimal markup page.</li>
|
||||
<li>9.20.12 - Added <code>destroy</code> method</li>
|
||||
<li>9.18.12 - Added sorting ability and made plugin responsive. Updated to Modernizr 2.6.2</li>
|
||||
<li>7.21.12 - Rewrote plugin in more object oriented structure. Added custom events. Updated to Modernizr 2.6.1</li>
|
||||
<li>7.3.12 - Removed dependency on the css file and now apply the css with javascript</li>
|
||||
</ul>
|
@ -0,0 +1,5 @@
|
||||
<footer class="site-footer light-text-dark-box">
|
||||
<div class="container-fluid">
|
||||
<p class="site-footer__credit">Photos and drawings by <a href="http://eightfoldstudios.com" target="_blank">Eightfold Studios</a>.</p>
|
||||
</div>
|
||||
</footer>
|
@ -0,0 +1,23 @@
|
||||
<h2>Events</h2>
|
||||
<p>A list of events shuffle triggers:</p>
|
||||
<ul>
|
||||
<li><code class="language-javascript">'loading.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'done.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'shrink.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'shrunk.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'filter.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'filtered.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'layout.shuffle'</code></li>
|
||||
<li><code class="language-javascript">'removed.shuffle'</code></li>
|
||||
</ul>
|
||||
|
||||
<h3>Get notified when shuffle is done with setup</h3>
|
||||
<pre rel="JavaScript"><code class="language-javascript">$grid.on('done.shuffle', function() {
|
||||
console.log('Finished initializing shuffle!');
|
||||
});</code></pre>
|
||||
|
||||
|
||||
<h3>Do something when an item is removed</h3>
|
||||
<pre rel="JavaScript"><code class="language-javascript">$grid.on('removed.shuffle', function( evt, $collection, shuffle ) {
|
||||
console.log( this, evt, $collection, shuffle );
|
||||
});</code></pre>
|
@ -0,0 +1,10 @@
|
||||
<h2>Features</h2>
|
||||
|
||||
<ul>
|
||||
<li>Uses CSS Transitions!</li>
|
||||
<li>Responsive (try resizing the window!)</li>
|
||||
<li>Filter items by groups</li>
|
||||
<li>Items can have multiple groups and be different sizes</li>
|
||||
<li>Sort items</li>
|
||||
<li>Advanced filtering method (like searching)</li>
|
||||
</ul>
|
@ -0,0 +1,2 @@
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js modern" lang="en"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>{{ page.title }}</title>
|
||||
{% capture description %}{% if page.description %}{{ page.description }}{% else %}{{ site.defaultDescription }}{% endif %}{% endcapture %}
|
||||
{% capture image %}{% if page.image %}{{ page.image }}{% else %}{{ site.defaultImage }}{% endif %}{% endcapture %}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta property="og:title" content="{{ page.title }}" />
|
||||
<meta property="og:description" content="{{ description }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="{{ site.url }}{{ page.url }}" />
|
||||
<meta property="og:image" content="{{ site.url }}{{ image }}" />
|
||||
<meta property="og:site_name" content="" />
|
||||
<meta property="fb:admins" content="771347349" />
|
||||
<meta name="author" content="https://plus.google.com/u/0/100210640453700033824" />
|
||||
<meta name="twitter:card" content="summary">
|
||||
<meta name="twitter:creator" content="@Vestride">
|
||||
<meta name="twitter:title" content="{{ page.title }}">
|
||||
<meta name="twitter:description" content="{{ description }}">
|
||||
<meta name="twitter:image" content="{{ site.url }}{{ image }}">
|
||||
|
||||
<link href="https://plus.google.com/u/0/100210640453700033824" rel="author" />
|
||||
|
||||
|
||||
<link id="favicon" rel="icon" type="image/png" href="favicon.png" >
|
||||
|
||||
<!-- Prefetch DNS for external assets -->
|
||||
<link rel="dns-prefetch" href="//fonts.googleapis.com">
|
||||
<link rel="dns-prefetch" href="//themes.googleusercontent.com">
|
||||
<link rel="dns-prefetch" href="//www.google-analytics.com">
|
||||
<link rel="dns-prefetch" href="//ajax.googleapis.com">
|
||||
|
||||
{% if page.prism %}<link rel="stylesheet" href="{{ site.url }}/css/prism.css" />{% endif %}
|
||||
<link rel="stylesheet" href="{{ site.url }}/css/style.css" />
|
||||
<link rel="stylesheet" href="{{ site.url }}/css/shuffle-styles.css" />
|
||||
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Ubuntu:300,400,700">
|
||||
{% if page.extraCSS %}
|
||||
{% for href in page.extraCSS %}
|
||||
<link rel="stylesheet" href="{{ href }}" />
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="{{ site.url }}/js/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body class="{{ page.bodyClass }}">
|
@ -0,0 +1,43 @@
|
||||
|
||||
<nav class="site-nav collapsed" id="nav" role="primary">
|
||||
|
||||
<div class="js-tray site-nav__tray light-text-dark-box">
|
||||
<div class="container-fluid site-nav__tray-inner">
|
||||
|
||||
<h3 class="site-nav__title">Shuffle.js</h3>
|
||||
<div class="row-fluid">
|
||||
<div class="span3">
|
||||
<a class="btn btn--primary" href="/">Home</a>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<a class="btn btn--primary" href="https://github.com/Vestride/Shuffle">GitHub Repo</a>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<a class="btn btn--primary" href="https://twitter.com/Vestride">By @Vestride</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3 class="site-nav__title">Demos</h3>
|
||||
<div class="row-fluid m-row js-demos site-nav__demos">
|
||||
{% for post in site.demos %}
|
||||
<div class="span3 m-span3 figure-wrap js-demo">
|
||||
<a href="/{{ post.slug }}">
|
||||
<figure>
|
||||
<div class="keep-ratio four-three">
|
||||
<img src="{{ site.url }}/img/demos/{{ post.slug }}.webp" alt="{{ post.label }}" />
|
||||
</div>
|
||||
<figcaption>{{ post.label }}</figcaption>
|
||||
</figure>
|
||||
</a>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="site-nav__band">
|
||||
<div class="container-fluid">
|
||||
<button class="js-nav-toggle pull-right" data-close-label="Close Nav">Open Nav</button>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
@ -0,0 +1,22 @@
|
||||
<h2>Options</h2>
|
||||
|
||||
<p>Settings you can change (these are the defaults)</p>
|
||||
<pre rel="JavaScript"><code class="language-javascript">// Overrideable options
|
||||
Shuffle.options = {
|
||||
group: 'all', // Filter group
|
||||
speed: 250, // Transition/animation speed (milliseconds)
|
||||
easing: 'ease-out', // css easing function to use
|
||||
itemSelector: '', // e.g. '.picture-item'
|
||||
sizer: null, // sizer element. Can be anything columnWidth is
|
||||
gutterWidth: 0, // a static number or function that tells the plugin how wide the gutters between columns are (in pixels)
|
||||
columnWidth: 0, // a static number or function that returns a number which tells the plugin how wide the columns are (in pixels)
|
||||
delimeter: null, // if your group is not json, and is comma delimeted, you could set delimeter to ','
|
||||
buffer: 0, // useful for percentage based heights when they might not always be exactly the same (in pixels)
|
||||
initialSort: null, // Shuffle can be initialized with a sort object. It is the same object given to the sort method
|
||||
throttle: $.throttle || null, // By default, shuffle will try to throttle the resize event. This option will change the method it uses
|
||||
throttleTime: 300, // How often shuffle can be called on resize (in milliseconds)
|
||||
sequentialFadeDelay: 150, // Delay between each item that fades in when adding items
|
||||
supported: Modernizr.csstransforms && Modernizr.csstransitions // supports transitions and transforms
|
||||
};</code></pre>
|
||||
|
||||
<p>No options <em>need</em> to be specified, but <code>itemSelector</code> should be used. Other common options to change are <code>speed</code>, <code>easing</code>, <code>gutterWidth</code>, and <code>columnWidth</code> (or <code>sizer</code>).</p>
|
@ -0,0 +1,16 @@
|
||||
{% comment %} Ghetto conversion to JSON {% endcomment %}
|
||||
{% capture groups %}["{{ item.groups | join: '","' }}"]{% endcapture %}
|
||||
{% if item.extras | size: > 0 %}
|
||||
{% capture extras %} picture-item--{{ item.extras | join: " picture-item--" }}{% endcapture %}
|
||||
{% else %}
|
||||
{% assign extras = "" %}
|
||||
{% endif %}
|
||||
{% if item.cols %}{% assign cols = item.cols %}{% else %}{% assign cols = 3 %}{% endif %}
|
||||
<figure class="span{{ cols }} m-span3 picture-item{{ extras }}" data-groups='{{ groups }}' data-date-created="{{ item.date }}" data-title="{{ item.title }}">
|
||||
<img src="{{ site.url }}/img/{{ item.img }}" alt="" height="145" width="230" />
|
||||
<div class="picture-item__details clearfix">
|
||||
<figcaption class="picture-item__title pull-left"><a href="{{ site.url }}/img/originals/{{ item.original }}" target="_blank">{{ item.title }}</a></figcaption>
|
||||
<p class="picture-item__tags pull-right">{{ item.groups | join: ', ' }}</p>
|
||||
</div>
|
||||
{% if item.description %}<p class="picture-item__description">{{ item.description }}</p>{% endif %}
|
||||
</figure>
|
@ -0,0 +1,23 @@
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
|
||||
<![endif]-->
|
||||
<!--[if gte IE 9]><!-->
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
|
||||
<!--<![endif]-->
|
||||
|
||||
<!-- Shuffle! -->
|
||||
<script src="{{ site.url }}/jquery.shuffle.js"></script>
|
||||
|
||||
{% if page.prism %}
|
||||
<!-- Syntax highlighting via Prism -->
|
||||
<script src="{{ site.url }}/js/prism.js"></script>
|
||||
{% endif %}
|
||||
|
||||
<!-- Make the nav work -->
|
||||
<script src="{{ site.url }}/js/page.js"></script>
|
||||
|
||||
{% if page.extraJS && page.extraJS.length %}
|
||||
{% for src in page.extraJS %}
|
||||
<script src="{{ site.url }}/js/{{ src }}"></script>
|
||||
{% endfor %}
|
||||
{% endif %}
|
@ -0,0 +1,40 @@
|
||||
<h2>Sorting</h2>
|
||||
|
||||
<p>You can order the elements based off a function you supply. In the demo above, each item has a <code>data-date-created</code> and <code>data-title</code> attribute. When the select option menu changes, a sort object is passed to shuffle.</p>
|
||||
|
||||
|
||||
<pre rel="HTML"><code class="language-markup"><select class="sort-options">
|
||||
<option value="">Default</option>
|
||||
<option value="title">Title</option>
|
||||
<option value="date-created">Date Created</option>
|
||||
</select></code></pre>
|
||||
|
||||
<pre rel="HTML"><code class="language-markup"><figure class="picture-item" data-groups='["photography"]' data-date-created="2010-09-14" data-title="Baseball">…</figure></code></pre>
|
||||
|
||||
<pre rel="JavaScript"><code class="language-javascript">// Sorting options
|
||||
$('.sort-options').on('change', function() {
|
||||
var sort = this.value,
|
||||
opts = {};
|
||||
|
||||
// We're given the element wrapped in jQuery
|
||||
if ( sort === 'date-created' ) {
|
||||
opts = {
|
||||
reverse: true,
|
||||
by: function($el) {
|
||||
return $el.data('date-created');
|
||||
}
|
||||
};
|
||||
} else if ( sort === 'title' ) {
|
||||
opts = {
|
||||
by: function($el) {
|
||||
return $el.data('title').toLowerCase();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle('sort', opts);
|
||||
});</code></pre>
|
||||
|
||||
<p>The <code class="language-javascript">opts</code> parameter can contain two properties. <code class="language-javascript">reverse</code>, a boolean which will reverse the array. <code class="language-javascript">by</code> is a function that is passed the element wrapped in jQuery. In the case above, we’re returning the value of the data-date-created or data-title attributes.</p>
|
||||
<p>Calling sort with an empty object will reset the elements to DOM order.</p>
|
@ -0,0 +1,60 @@
|
||||
<h2>Usage</h2>
|
||||
|
||||
<h3>The HTML Structure</h3>
|
||||
<p>The only real important thing here is the <code class="language-markup token attr-name">data-groups</code> attribute. It has to be a <a href="http://jsonlint.com/">valid JSON</a> array of strings. Optionally, it can be a string delimeted by a value you provide. See <code>delimeter</code> in the <a href="#options">options</a>.</p>
|
||||
|
||||
<p>In this example, shuffle is using the fluid grid from the <a href="http://twitter.github.io/bootstrap/">Twitter Bootstrap</a>. It's also making use of the <a href="http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/"><abbr title="Block-Element-Modifier">BEM</abbr></a>.</p>
|
||||
|
||||
<pre rel="HTML"><code class="language-markup"><div id="grid" class="row-fluid">
|
||||
<figure class="span3 picture-item" data-groups='["photography"]'>
|
||||
<img src="/img/baseball.png" height="145" width="230" />
|
||||
<div class="picture-item__details">
|
||||
<figcaption class="picture-item__title">Baseball</figcaption>
|
||||
<p class="picture-item__tags">photography</p>
|
||||
</div>
|
||||
</figure>
|
||||
<figure class="span6 picture-item" data-groups='["wallpaper","3d"]'>
|
||||
<img src="/img/tennis-ball.png" height="145" width="230" />
|
||||
<div class="picture-item__details">
|
||||
<figcaption class="picture-item__title">Tennis</figcaption>
|
||||
<p class="picture-item__tags">wallpaper, 3d</p>
|
||||
</div>
|
||||
<p class="picture-item__description">Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
</figure>
|
||||
<figure class="span3 picture-item" data-groups='["wallpaper","3d"]'>
|
||||
<img src="/img/imac.png" height="145" width="230" />
|
||||
<div class="picture-item__details">
|
||||
<figcaption class="picture-item__title">iMac</figcaption>
|
||||
<p class="picture-item__tags">wallpaper, 3d</p>
|
||||
</div>
|
||||
</figure>
|
||||
<figure class="span3 picture-item picture-item--h2" data-groups='["graphics"]'>
|
||||
<img src="/img/master-chief.png" height="145" width="230" />
|
||||
<div class="picture-item__details">
|
||||
<figcaption class="picture-item__title">Master Chief</figcaption>
|
||||
<p class="picture-item__tags">graphics</p>
|
||||
</div>
|
||||
<p class="picture-item__description">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p>
|
||||
</figure>
|
||||
</div></code></pre>
|
||||
|
||||
<h3 id="columns">How column widths work</h3>
|
||||
<p>The <code>columnWidth</code> option is used to calculate the column width. You have several options:</p>
|
||||
<ol>
|
||||
<li>Use a <strong>sizer</strong> element. This is the easest way to specify column and gutter widths. You can use an element or an element wrapped in jQuery. The column and gutter widths will be measured using this element. The <code>sizer</code> option is an alias for <code>columnWidth</code>. See <a href="{% post_url demos/2013-05-01-basic %}">a demo</a> using a sizer element or <a href="{{ site.url }}/js/demos/homepage.js">look at the js file</a> for the sizer demo.</li>
|
||||
<li>Use a <strong>function</strong>. When a function is used, its first parameter will be the width of the shuffle element. You need to return the column width for shuffle to use (in pixels).</li>
|
||||
<li>A <strong>number</strong>. This will explicitly set the column width to your number (in pixels).</li>
|
||||
<li>By default, shuffle will use jQuery's <code class="language-javascript">outerWidth(true)</code> to calculate the column width of the first item and use that value.</li>
|
||||
</ol>
|
||||
|
||||
<h3>A basic setup example</h3>
|
||||
<p>Sets up the button clicks and runs shuffle</p>
|
||||
<pre rel="JavaScript"><code class="language-javascript">$(document).ready(function() {
|
||||
var $grid = $('#grid'),
|
||||
$sizer = $grid.find('.shuffle__sizer');
|
||||
|
||||
$grid.shuffle({
|
||||
itemSelector: '.picture-item',
|
||||
sizer: $sizer
|
||||
});
|
||||
});</code></pre>
|
@ -0,0 +1,18 @@
|
||||
{% include head.html %}
|
||||
{% include nav.html %}
|
||||
{% if page.includeHeader %}
|
||||
<header class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<div class="span7">
|
||||
<h1>Shuffle</h1>
|
||||
<p>{{ site.defaultDescription }}</p>
|
||||
<p>By <a href="https://twitter.com/Vestride" target="_blank">@Vestride</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
{% endif %}
|
||||
<main role="main" id="main" class="language-markup">
|
||||
{{ content }}
|
||||
</main>
|
||||
{% include scripts.html %}
|
||||
{% include foot.html %}
|
@ -0,0 +1,39 @@
|
||||
---
|
||||
layout: default
|
||||
title: Basic Shuffle Demo
|
||||
description: A basic demo using shuffle with a masonry layout. This example also uses a sizer element
|
||||
image: /demos/basic.jpg
|
||||
bodyClass: basic
|
||||
extraJS: [ "demos/homepage.js" ]
|
||||
---
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<h2>Masonry with a sizer</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div id="grid" class="row-fluid m-row shuffle--container shuffle--fluid">
|
||||
{% for item in site.items %}
|
||||
{% assign item = item %}
|
||||
{% include picture-item.html %}
|
||||
{% endfor %}
|
||||
<div class="span3 m-span3 shuffle__sizer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid">
|
||||
<h2>Another Section</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include credit-jake.html %}
|
@ -0,0 +1,75 @@
|
||||
---
|
||||
layout: default
|
||||
title: Shuffle Adaptive Demo
|
||||
description: A responsive demo using the adaptive Twitter Bootstrap grid with compound filtering
|
||||
image: /demos/adaptive.jpg
|
||||
extraJS: [ "demos/gallery.js" ]
|
||||
extraCSS: [ "/css/gallery.css" ]
|
||||
---
|
||||
|
||||
<section class="container">
|
||||
<div class="row">
|
||||
<h2 class="span12">Adaptive Layout with Compound Filters</h2>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="gallery container">
|
||||
|
||||
<div class="filter-options row">
|
||||
|
||||
<div class="span6">
|
||||
<div class="filter-group filter--colors js-colors">
|
||||
<h5 class="filter__label">Colors</h5>
|
||||
<button class="btn btn--go" data-filter-value="green"><span class="visuallyhidden">Green</span></button>
|
||||
<button class="btn btn--primary" data-filter-value="blue"><span class="visuallyhidden">Blue</span></button>
|
||||
<button class="btn btn--danger" data-filter-value="red"><span class="visuallyhidden">Red</span></button>
|
||||
<button class="btn btn--warning" data-filter-value="orange"><span class="visuallyhidden">Orange</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="span6">
|
||||
<div class="filter-group filter--shapes js-shapes">
|
||||
<h5 class="filter-group__label">Shapes</h5>
|
||||
<span class="ib">
|
||||
<input type="checkbox" value="circle" id="cb-circle"> <label for="cb-circle">Circle</label>
|
||||
</span>
|
||||
<span class="ib">
|
||||
<input type="checkbox" value="diamond" id="cb-diamond"> <label for="cb-diamond">Diamond</label>
|
||||
</span>
|
||||
<span class="ib">
|
||||
<input type="checkbox" value="square" id="cb-square"> <label for="cb-square">Square</label>
|
||||
</span>
|
||||
<span class="ib">
|
||||
<input type="checkbox" value="triangle" id="cb-triangle"> <label for="cb-triangle">Triangle</label>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="shape-up js-shuffle">
|
||||
{% for shape in site.shapes %}
|
||||
<div class="span3 shape shape--{{ shape.shape }} shape--{{ shape.color }}" data-shape="{{ shape.shape }}" data-color="{{ shape.color }}">
|
||||
<div class="keep-ratio">
|
||||
<div class="shape__inner">
|
||||
<div class="shape__space">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<h2>Another section</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
</div>
|
||||
</section>
|
@ -0,0 +1,81 @@
|
||||
---
|
||||
layout: default
|
||||
title: Using images with imagesloaded.js
|
||||
description: A Shuffle.js demo using Desandro's imagesLoaded plugin. This comes in very handy when using shuffle with images affect the layout of shuffle items
|
||||
image: /demos/images.jpg
|
||||
extraJS: [ "imagesloaded.pkgd.js", "demos/images.js"]
|
||||
prism: true
|
||||
---
|
||||
|
||||
<div class="container-fluid">
|
||||
<h2>Images!</h2>
|
||||
<p>You can encounter problems when shuffle item dimensions depend on images. <a href="{% post_url demos/2013-06-29-image-problems %}">Like this demo</a>. There are three good solutions to this.</p>
|
||||
<ol>
|
||||
<li>Set an explicit height on <code>.shuffle-item</code>s like the <a href="{% post_url demos/2013-05-01-basic %}">basic demo</a>.</li>
|
||||
<li>Similar to number 1, make the height of the image container a percentage of the width. This can be seen in the nav images above with the <code>div.keep-ratio</code>.</li>
|
||||
<li>Get notified when images load (this page). In this case, I'm using <a href="http://desandro.github.io/imagesloaded/">Desandro's images loaded plugin</a>. Please note that imagesloaded does not support IE7.</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.shuffle-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.shuffle--images {
|
||||
position: relative;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.shuffle--images.images-loaded {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.shuffle--images .img-item {
|
||||
margin-top: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.shuffle--images .img-item img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.loader {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-top: -16px;
|
||||
margin-left: -16px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="container-fluid shuffle-wrap">
|
||||
<img id="loader" class="loader" alt="Loading..." src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAzMDAgMzAwIgogICAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4xIj4KICA8cGF0aCBkPSJNIDE1MCwwCiAgICAgICAgICAgYSAxNTAsMTUwIDAgMCwxIDEwNi4wNjYsMjU2LjA2NgogICAgICAgICAgIGwgLTM1LjM1NSwtMzUuMzU1CiAgICAgICAgICAgYSAtMTAwLC0xMDAgMCAwLDAgLTcwLjcxMSwtMTcwLjcxMSB6IgogICAgICAgIGZpbGw9IiMzZDdmZTYiPgogICAgPGFuaW1hdGVUcmFuc2Zvcm0gYXR0cmlidXRlTmFtZT0idHJhbnNmb3JtIiBhdHRyaWJ1dGVUeXBlPSJYTUwiCiAgICAgICAgICAgdHlwZT0icm90YXRlIiBmcm9tPSIwIDE1MCAxNTAiIHRvPSIzNjAgMTUwIDE1MCIKICAgICAgICAgICBiZWdpbj0iMHMiIGR1cj0iMXMiIGZpbGw9ImZyZWV6ZSIgcmVwZWF0Q291bnQ9ImluZGVmaW5pdGUiIC8+CiAgPC9wYXRoPgo8L3N2Zz4K" />
|
||||
<div class="shuffle--images row-fluid">
|
||||
{% for item in site.items %}
|
||||
<figure class="js-item img-item span3 m-span3">
|
||||
<img src="{{ site.url }}/img/{{ item.img }}" alt="{{item.title}}"/>
|
||||
<figcaption>{{ item.groups }}</figcaption>
|
||||
</figure>
|
||||
{% endfor %}
|
||||
<div class="span3 m-span3" id="js-sizer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<section>
|
||||
<div class="container-fluid">
|
||||
<h2>Another section</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{% include credit-jake.html %}
|
@ -0,0 +1,87 @@
|
||||
---
|
||||
layout: default
|
||||
title: Shuffle Adding and Removing Elements Demo
|
||||
description: This demo of shuffle shows how to add and removing items.
|
||||
image: /demos/adding-removing.jpg
|
||||
extraJS: [ "demos/adding-removing.js" ]
|
||||
---
|
||||
<style>
|
||||
|
||||
/* Styles for shuffle */
|
||||
.container {
|
||||
counter-reset: boxes;
|
||||
}
|
||||
|
||||
.box {
|
||||
position: relative;
|
||||
width: 18%;
|
||||
margin-left: 2.5%;
|
||||
height: 100px;
|
||||
margin-top: 20px;
|
||||
float: left;
|
||||
background: #E74C3C;
|
||||
counter-increment: boxes;
|
||||
}
|
||||
|
||||
.box::before {
|
||||
content: 'DOM order: ' counter(boxes);
|
||||
position: absolute;
|
||||
color: white;
|
||||
top: .5em;
|
||||
left: .5em;
|
||||
}
|
||||
|
||||
.box.shuffle-item,
|
||||
.box:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.w2 {
|
||||
width: 38.5%;
|
||||
}
|
||||
|
||||
.w3 {
|
||||
width: 59%;
|
||||
}
|
||||
|
||||
.h2 {
|
||||
height: 220px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<section class="container">
|
||||
<div class="row">
|
||||
<h2 class="span12">Adding and Removing Items</h2>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="container">
|
||||
<button id="randomize">Randomize</button>
|
||||
<button id="add">Add 5 Boxes</button>
|
||||
<button id="remove">Remove Some Boxes</button>
|
||||
</section>
|
||||
|
||||
<section class="container">
|
||||
<div id="my-shuffle" class="items">
|
||||
<div class="box"></div>
|
||||
<div class="box h2 w2"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box"></div>
|
||||
<div class="box w2"></div>
|
||||
<div class="box"></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="container">
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<h2>Another Section</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
@ -0,0 +1,52 @@
|
||||
---
|
||||
layout: default
|
||||
title: Mobile Grid Layout Test
|
||||
description: Testing out the mobile grid for this site
|
||||
---
|
||||
|
||||
<div class="container-fluid">
|
||||
<h2>Mobile Grid Demo</h2>
|
||||
</div>
|
||||
|
||||
<style scoped>
|
||||
|
||||
article {
|
||||
height: 30px;
|
||||
background-color: gray;
|
||||
color: white;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row-fluid m-row">
|
||||
<article class="span7 m-span3">
|
||||
span7 | m-span3
|
||||
</article>
|
||||
<article class="span4 m-span1">
|
||||
span4 | m-span1
|
||||
</article>
|
||||
<article class="span1 m-span2">
|
||||
span1 | m-span2
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row-fluid m-row">
|
||||
<article class="span6 m-span6"></article>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class="row-fluid m-row">
|
||||
<article class="span5 m-span3"></article>
|
||||
<article class="span7 m-span3"></article>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<article style="width:100%;text-align:center;">
|
||||
100%
|
||||
</article>
|
||||
</div>
|
@ -0,0 +1,56 @@
|
||||
---
|
||||
layout: default
|
||||
title: Image based items
|
||||
description: A demo of how NOT to use images with shuffle
|
||||
extraJS: [ "demos/images-broken.js"]
|
||||
---
|
||||
|
||||
<div class="container-fluid">
|
||||
<h2>This probably looks broken.</h2>
|
||||
<p>Demo in which shuffle item dimensions are based on images without a fix. <a href="{% post_url demos/2013-05-03-images %}">See here</a> for a solution.</p>
|
||||
<p>Resize the window and it'll fix itself.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.shuffle--images {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.shuffle--images .img-item {
|
||||
margin-top: 10px;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.shuffle--images .img-item img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="shuffle--images row-fluid">
|
||||
{% for item in site.items %}
|
||||
<figure class="js-item img-item span3 m-span3">
|
||||
<img src="{{ site.url }}/img/{{ item.img }}" alt="{{item.title}}"/>
|
||||
<figcaption>{{ item.groups }}</figcaption>
|
||||
</figure>
|
||||
{% endfor %}
|
||||
<div class="span3 m-span3" id="js-sizer"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<div class="container">
|
||||
<h2>Another section</h2>
|
||||
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{% include credit-jake.html %}
|
@ -0,0 +1,173 @@
|
||||
|
||||
|
||||
.btn-group {
|
||||
@include clearfix();
|
||||
|
||||
.btn {
|
||||
float: left;
|
||||
border-radius: 0;
|
||||
|
||||
&:first-child {
|
||||
border-radius: 6px 0 0 6px;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-radius: 0 6px 6px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn,
|
||||
button {
|
||||
display: inline-block;
|
||||
padding: .75em .375em;
|
||||
-webkit-appearance: none;
|
||||
text-align: center;
|
||||
color: white;
|
||||
border-radius: .0625em;
|
||||
border: 0;
|
||||
background-color: $wetAsphalt;
|
||||
transition: .2s ease-out;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($wetAsphalt, 12);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
background-color: $midnightBlue;
|
||||
box-shadow: inset 0 1px 2px rgba(0,0,0,.3);
|
||||
}
|
||||
|
||||
&:active {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--warning {
|
||||
background-color: $carrot;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($carrot, 8);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
background-color: $pumpkin;
|
||||
// background-color: $carrot;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--primary {
|
||||
background-color: $river;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($river, 8);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
// background-color: $belizeHole;
|
||||
background-color: $river;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--danger {
|
||||
background-color: $alizarin;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($alizarin, 8);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
// background-color: $pomegranate;
|
||||
background-color: $alizarin;
|
||||
}
|
||||
}
|
||||
|
||||
.btn--go {
|
||||
background-color: $emerald;
|
||||
|
||||
&:hover {
|
||||
background-color: lighten($emerald, 8);
|
||||
}
|
||||
|
||||
&.active,
|
||||
&:active {
|
||||
// background-color: $nephritis;
|
||||
background-color: $emerald;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.filter-group .btn {
|
||||
position: relative;
|
||||
|
||||
$size: 20px;
|
||||
// Circle and check
|
||||
&.active:before,
|
||||
&.active:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: $size;
|
||||
height: $size;
|
||||
margin-left: -$size / 2;
|
||||
margin-top: -$size / 2;
|
||||
opacity: 0;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
// Circle
|
||||
&:before {
|
||||
background-color: $gray10;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
// Check
|
||||
&:after {
|
||||
background-size: 60%;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-image: url(../img/check.svg);
|
||||
}
|
||||
|
||||
&.active:before,
|
||||
&.active:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media ( max-width: 47.9375em ) {
|
||||
|
||||
.btn,
|
||||
button {
|
||||
font-size: .875em;
|
||||
}
|
||||
}
|
||||
|
||||
@media ( max-width: 30em ) {
|
||||
|
||||
.btn,
|
||||
button {
|
||||
font-size: .75em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,90 @@
|
||||
.ib {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
|
||||
.keep-ratio {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
padding-bottom: 100%;
|
||||
|
||||
&.four-three {
|
||||
padding-bottom: 75%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Hide from both screenreaders and browsers: h5bp.com/u
|
||||
.hidden {
|
||||
display: none !important;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
// Hide only visually, but have it available for screenreaders: h5bp.com/v
|
||||
.visuallyhidden {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 1px;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
/*
|
||||
* Clearfix: contain floats
|
||||
*
|
||||
* For modern browsers
|
||||
* 1. The space content is one way to avoid an Opera bug when the
|
||||
* `contenteditable` attribute is included anywhere else in the document.
|
||||
* Otherwise it causes space to appear at the top and bottom of elements
|
||||
* that receive the `clearfix` class.
|
||||
* 2. The use of `table` rather than `block` is only necessary if using
|
||||
* `:before` to contain the top-margins of child elements.
|
||||
*/
|
||||
|
||||
.clearfix:before,
|
||||
.clearfix:after {
|
||||
content: " "; /* 1 */
|
||||
display: table; /* 2 */
|
||||
}
|
||||
|
||||
.clearfix:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
/*
|
||||
* For IE 6/7 only
|
||||
* Include this rule to trigger hasLayout and contain floats.
|
||||
*/
|
||||
|
||||
.clearfix {
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.pull-left {
|
||||
float: left;
|
||||
}
|
||||
.pull-right {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.hide-text {
|
||||
font: 0/0 a;
|
||||
color: transparent;
|
||||
text-shadow: none;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
}
|
||||
.input-block-level {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-height: 30px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
@ -0,0 +1,174 @@
|
||||
@import "variables";
|
||||
|
||||
* {
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
pre {
|
||||
max-height: 30em;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
/* lets have some constraints shall we */
|
||||
.container-fluid {
|
||||
width: 93%;
|
||||
max-width: 1200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.row.row--full {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
ul ul {
|
||||
padding-left: 1.25em;
|
||||
margin: 0;
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
|
||||
.site-nav {
|
||||
|
||||
.site-nav__title {
|
||||
color: $clouds;
|
||||
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.site-nav__tray {
|
||||
transition: .2s;
|
||||
overflow: hidden;
|
||||
height: 300px;
|
||||
background-color: $wetAsphalt;
|
||||
}
|
||||
|
||||
.site-nav__tray-inner {
|
||||
padding: 30px 0;
|
||||
}
|
||||
|
||||
&.collapsed .site-nav__tray {
|
||||
height: 0;
|
||||
|
||||
// IE7 wtf
|
||||
.lt-ie8 & {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.figure-wrap,
|
||||
.figure-wrap img {
|
||||
// Promote to its own layer. makes filters look ok on retina with images
|
||||
-webkit-transform: translateZ(0);
|
||||
-webkit-transition: .1s ease;
|
||||
transition: .1s ease;
|
||||
}
|
||||
|
||||
.site-nav__demos:hover .figure-wrap {
|
||||
-webkit-transform: scale3d( 1, 1, 1 );
|
||||
transform: scale3d( 1, 1, 1 );
|
||||
|
||||
img {
|
||||
|
||||
-webkit-filter: grayscale(1);
|
||||
filter: grayscale(1);
|
||||
}
|
||||
}
|
||||
|
||||
.site-nav__demos:hover .figure-wrap.hovered {
|
||||
-webkit-transform: scale3d( 1.05, 1.05, 1 );
|
||||
transform: scale3d( 1.05, 1.05, 1 );
|
||||
|
||||
img {
|
||||
-webkit-filter: none;
|
||||
filter: none;
|
||||
}
|
||||
}
|
||||
|
||||
.figure-wrap:nth-child(4n + 1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.figure-wrap > a {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.figure-wrap figcaption {
|
||||
margin-top: .5em;
|
||||
}
|
||||
|
||||
|
||||
.site-nav__band {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
background: $wetAsphalt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.site-footer {
|
||||
margin-top: 2em;
|
||||
padding: 1em 0;
|
||||
background-color: $wetAsphalt;
|
||||
}
|
||||
|
||||
.site-footer__credit {
|
||||
margin: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
nav > a {
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
|
||||
// Filters
|
||||
.filter__label {
|
||||
margin: 0 0 3px;
|
||||
}
|
||||
|
||||
.filter__search {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
|
||||
.sort-options {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@media ( max-width: 47.9375em ) {
|
||||
|
||||
.figure-wrap:nth-child(odd) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.figure-wrap:nth-child(n + 3) {
|
||||
margin-top: 1em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
|
||||
$columns: 6;
|
||||
$gutterWidth: 2; // 2% gutter width
|
||||
$columnWidth: (100 - ( $gutterWidth * ( $columns - 1 ))) / $columns;
|
||||
|
||||
@media ( max-width: 47.9375em ) {
|
||||
.m-row {
|
||||
|
||||
[class*="m-span"] {
|
||||
float: left;
|
||||
margin-left: $gutterWidth + 0%;
|
||||
|
||||
&:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@for $i from 1 through 6 {
|
||||
.m-span#{$i} {
|
||||
width: ($i * $columnWidth) + (($i - 1) * $gutterWidth) + 0%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,396 @@
|
||||
/*! normalize.css v2.1.2 | MIT License | git.io/normalize */
|
||||
|
||||
/* ==========================================================================
|
||||
HTML5 display definitions
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Correct `block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct `inline-block` display not defined in IE 8/9.
|
||||
*/
|
||||
|
||||
audio,
|
||||
canvas,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent modern browsers from displaying `audio` without controls.
|
||||
* Remove excess height in iOS 5 devices.
|
||||
*/
|
||||
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Base
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* 1. Set default font family to sans-serif.
|
||||
* 2. Prevent iOS text size adjust after orientation change, without disabling
|
||||
* user zoom.
|
||||
*/
|
||||
|
||||
html {
|
||||
font-family: sans-serif; /* 1 */
|
||||
-ms-text-size-adjust: 100%; /* 2 */
|
||||
-webkit-text-size-adjust: 100%; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove default margin.
|
||||
*/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Links
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address `outline` inconsistency between Chrome and other browsers.
|
||||
*/
|
||||
|
||||
a:focus {
|
||||
outline: thin dotted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve readability when focused and also mouse hovered in all browsers.
|
||||
*/
|
||||
|
||||
a:active,
|
||||
a:hover {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Typography
|
||||
========================================================================== */
|
||||
|
||||
// /**
|
||||
// * Address variable `h1` font-size and margin within `section` and `article`
|
||||
// * contexts in Firefox 4+, Safari 5, and Chrome.
|
||||
// */
|
||||
|
||||
// h1 {
|
||||
// font-size: 2em;
|
||||
// margin: 0.67em 0;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
b,
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address differences between Firefox and other browsers.
|
||||
*/
|
||||
|
||||
hr {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address styling not present in IE 8/9.
|
||||
*/
|
||||
|
||||
mark {
|
||||
background: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct font family set oddly in Safari 5 and Chrome.
|
||||
*/
|
||||
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, serif;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
/**
|
||||
* Improve readability of pre-formatted text in all browsers.
|
||||
*/
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set consistent quote types.
|
||||
*/
|
||||
|
||||
q {
|
||||
quotes: "\201C" "\201D" "\2018" "\2019";
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent and variable font size in all browsers.
|
||||
*/
|
||||
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
|
||||
*/
|
||||
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Embedded content
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove border when inside `a` element in IE 8/9.
|
||||
*/
|
||||
|
||||
img {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Correct overflow displayed oddly in IE 9.
|
||||
*/
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Figures
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Address margin not present in IE 8/9 and Safari 5.
|
||||
*/
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Forms
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Define consistent border, margin, and padding.
|
||||
*/
|
||||
|
||||
fieldset {
|
||||
border: 1px solid #c0c0c0;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct `color` not being inherited in IE 8/9.
|
||||
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
|
||||
*/
|
||||
|
||||
legend {
|
||||
border: 0; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Correct font family not being inherited in all browsers.
|
||||
* 2. Correct font size not being inherited in all browsers.
|
||||
* 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.
|
||||
*/
|
||||
|
||||
button,
|
||||
input,
|
||||
select,
|
||||
textarea {
|
||||
font-family: inherit; /* 1 */
|
||||
font-size: 100%; /* 2 */
|
||||
margin: 0; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
|
||||
* the UA stylesheet.
|
||||
*/
|
||||
|
||||
button,
|
||||
input {
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Address inconsistent `text-transform` inheritance for `button` and `select`.
|
||||
* All other form control elements do not inherit `text-transform` values.
|
||||
* Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.
|
||||
* Correct `select` style inheritance in Firefox 4+ and Opera.
|
||||
*/
|
||||
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
|
||||
* and `video` controls.
|
||||
* 2. Correct inability to style clickable `input` types in iOS.
|
||||
* 3. Improve usability and consistency of cursor style between image-type
|
||||
* `input` and others.
|
||||
*/
|
||||
|
||||
button,
|
||||
html input[type="button"], /* 1 */
|
||||
input[type="reset"],
|
||||
input[type="submit"] {
|
||||
-webkit-appearance: button; /* 2 */
|
||||
cursor: pointer; /* 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-set default cursor for disabled elements.
|
||||
*/
|
||||
|
||||
button[disabled],
|
||||
html input[disabled] {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Address box sizing set to `content-box` in IE 8/9.
|
||||
* 2. Remove excess padding in IE 8/9.
|
||||
*/
|
||||
|
||||
input[type="checkbox"],
|
||||
input[type="radio"] {
|
||||
box-sizing: border-box; /* 1 */
|
||||
padding: 0; /* 2 */
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.
|
||||
* 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome
|
||||
* (include `-moz` to future-proof).
|
||||
*/
|
||||
|
||||
input[type="search"] {
|
||||
-webkit-appearance: textfield; /* 1 */
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box; /* 2 */
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and search cancel button in Safari 5 and Chrome
|
||||
* on OS X.
|
||||
*/
|
||||
|
||||
input[type="search"]::-webkit-search-cancel-button,
|
||||
input[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove inner padding and border in Firefox 4+.
|
||||
*/
|
||||
|
||||
button::-moz-focus-inner,
|
||||
input::-moz-focus-inner {
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Remove default vertical scrollbar in IE 8/9.
|
||||
* 2. Improve readability and alignment in all browsers.
|
||||
*/
|
||||
|
||||
textarea {
|
||||
overflow: auto; /* 1 */
|
||||
vertical-align: top; /* 2 */
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
Tables
|
||||
========================================================================== */
|
||||
|
||||
/**
|
||||
* Remove most spacing between table cells.
|
||||
*/
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
body {
|
||||
font-family: 'Ubuntu', Verdana, sans-serif;
|
||||
color: $gray30;
|
||||
}
|
||||
|
||||
// Links
|
||||
a {
|
||||
text-decoration: none;
|
||||
|
||||
&,
|
||||
&:visited {
|
||||
color: $river;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
&:active {
|
||||
color: $emerald;
|
||||
}
|
||||
}
|
||||
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
color: $wetAsphalt;
|
||||
}
|
||||
|
||||
|
||||
// Headers
|
||||
h1 {
|
||||
margin: 20px 0;
|
||||
font-weight: 300;
|
||||
font-size: 4em;
|
||||
line-height: 1;
|
||||
color: $emerald;
|
||||
}
|
||||
|
||||
h2 {
|
||||
position: relative;
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 18px;
|
||||
|
||||
// Bottom border BEHIND the descenders!
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 4px;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
background-color: $emerald;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: .6667em 0 0.5em;
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
|
||||
@media ( max-width: 47.9375em ) {
|
||||
h1 {
|
||||
font-size: 8vw;
|
||||
margin: 3vw 0;
|
||||
}
|
||||
h2 {
|
||||
font-size: 6vw;
|
||||
margin: 2vw 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
.unstyled {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
||||
.light-text-dark-box {
|
||||
|
||||
p {
|
||||
color: $clouds;
|
||||
}
|
||||
|
||||
a {
|
||||
color: $clouds;
|
||||
|
||||
&:hover {
|
||||
color: white;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
// Colors from Flat UI
|
||||
|
||||
$turqoise: #1ABC9C;
|
||||
$greenSea: #16A085;
|
||||
|
||||
$emerald: #2ECC71;
|
||||
$nephritis: #27AE60;
|
||||
|
||||
$river: #3498DB;
|
||||
$belizeHole: #2980B9;
|
||||
|
||||
$amethyst: #9B59B6;
|
||||
$wisteria: #8E44AD;
|
||||
|
||||
$wetAsphalt: #34495E;
|
||||
$midnightBlue: #2C3E50;
|
||||
|
||||
$sunflower: #F1C40F;
|
||||
$orange: #F39C12;
|
||||
|
||||
$carrot: #E67E22;
|
||||
$pumpkin: #D35400;
|
||||
|
||||
$alizarin: #E74C3C;
|
||||
$pomegranate: #C0392B;
|
||||
|
||||
$clouds: #ECF0F1;
|
||||
$silver: #BDC3C7;
|
||||
|
||||
$concrete: #95A5A6;
|
||||
$asbestos: #7F8C8D;
|
||||
|
||||
|
||||
//
|
||||
|
||||
$black: #000;
|
||||
$gray10: $midnightBlue;
|
||||
$gray30: #5D6D77;
|
||||
$gray20: $wetAsphalt;
|
||||
$gray40: $concrete;
|
||||
$gray50: $asbestos;
|
||||
$white: #FFF;
|
||||
|
||||
|
||||
@mixin clearfix() {
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
content: " ";
|
||||
display: table;
|
||||
}
|
||||
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
& {
|
||||
*zoom: 1;
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
@import "variables";
|
||||
@import "compass";
|
||||
|
||||
.filter-options {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.filter-group {
|
||||
|
||||
.filter-group__label {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
label {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.shape-up {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shape {
|
||||
position: relative;
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
|
||||
.shape__inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.shape__space {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.shape--blue .shape__space {
|
||||
background-color: $river;
|
||||
border-bottom-color: $river;
|
||||
}
|
||||
|
||||
.shape--red .shape__space {
|
||||
background-color: $alizarin;
|
||||
border-bottom-color: $alizarin;
|
||||
}
|
||||
|
||||
.shape--orange .shape__space {
|
||||
background-color: $orange;
|
||||
border-bottom-color: $orange;
|
||||
}
|
||||
|
||||
.shape--green .shape__space {
|
||||
background-color: $emerald;
|
||||
border-bottom-color: $emerald;
|
||||
}
|
||||
|
||||
.shape--circle .shape__space {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.shape--square .shape__space {
|
||||
// Nothing to see here
|
||||
}
|
||||
|
||||
// 166 / sqrt(166^2 + 166^2) = scale
|
||||
.shape--diamond .shape__space {
|
||||
-webkit-transform: rotate(45deg) scale(0.707106781);
|
||||
transform: rotate(45deg) scale(0.707106781);
|
||||
}
|
||||
|
||||
|
||||
$triangleSize: 220px;
|
||||
$halfSize: $triangleSize / 2;
|
||||
$fullSideWidth: round(sqrt(3) * $halfSize);
|
||||
$leftOver: $triangleSize - $fullSideWidth;
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: $leftOver / 2;
|
||||
height: 0;
|
||||
width: 0;
|
||||
border-width: 0 $halfSize $fullSideWidth $halfSize;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
|
||||
// IE8 filter alpha wasn't working with the positioning stuff
|
||||
.lt-ie9 .shape {
|
||||
.keep-ratio {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
overflow: visible;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.shape__inner {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
|
||||
$triangleSize: 270px;
|
||||
$halfSize: $triangleSize / 2;
|
||||
$fullSideWidth: round(sqrt(3) * $halfSize);
|
||||
$leftOver: $triangleSize - $fullSideWidth;
|
||||
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: $leftOver / 2;
|
||||
border-width: 0 $halfSize $fullSideWidth $halfSize;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 979px) {
|
||||
|
||||
$triangleSize: 166px;
|
||||
$halfSize: $triangleSize / 2;
|
||||
$fullSideWidth: round(sqrt(3) * $halfSize);
|
||||
$leftOver: $triangleSize - $fullSideWidth;
|
||||
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: $leftOver / 2;
|
||||
border-width: 0 $halfSize $fullSideWidth $halfSize;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
|
||||
$triangleSize: 200px;
|
||||
$halfSize: $triangleSize / 2;
|
||||
$fullSideWidth: round(sqrt(3) * $halfSize);
|
||||
$leftOver: $triangleSize - $fullSideWidth;
|
||||
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: $leftOver / 2;
|
||||
border-width: 0 $halfSize $fullSideWidth $halfSize;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
|
||||
$triangleSize: 100px;
|
||||
$halfSize: $triangleSize / 2;
|
||||
$fullSideWidth: round(sqrt(3) * $halfSize);
|
||||
$leftOver: $triangleSize - $fullSideWidth;
|
||||
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: $leftOver / 2;
|
||||
border-width: 0 $halfSize $fullSideWidth $halfSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
body::before {
|
||||
content: 'Default - 940px';
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
background-color: hsla(110, 50%, 60%, .6);
|
||||
-webkit-transition: background .2s ease;
|
||||
-o-transition: background .2s ease;
|
||||
transition: background .2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
body::before {
|
||||
content: 'Large Desktop - 1200px+';
|
||||
background-color: hsla(10, 50%, 60%, .6);
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) and (max-width: 979px) {
|
||||
body::before {
|
||||
content: 'Portrait tablet to landscape and desktop - > 768px && < 979px';
|
||||
background-color: hsla(50, 50%, 60%, .6);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
body::before {
|
||||
content: 'Phones to Tablets - < 767px';
|
||||
background-color: hsla(210, 50%, 60%, .6);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
body::before {
|
||||
content: 'Phones - < 480px';
|
||||
background-color: hsla(300, 50%, 60%, .6);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,119 @@
|
||||
@import "variables";
|
||||
/*=============================================*\
|
||||
Some styles to show off masonry layout
|
||||
\*=============================================*/
|
||||
|
||||
$pictureGutter: 24px;
|
||||
$itemHeight: 220px;
|
||||
.picture-item {
|
||||
height: 220px;
|
||||
margin-top: $pictureGutter;
|
||||
overflow: hidden;
|
||||
background: $clouds;
|
||||
|
||||
&.shuffle-item {
|
||||
margin-left: 0; /* shuffle items shouldn't have a left margin*/
|
||||
}
|
||||
|
||||
&.picture-item--h2 {
|
||||
height: ($itemHeight * 2) + $pictureGutter; /* 2x the height + 1 gutter */
|
||||
}
|
||||
|
||||
// Ehh, i should really use something other than span6 to target this...
|
||||
&.span6:not(.picture-item--h2) {
|
||||
|
||||
.picture-item__details {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #333;
|
||||
background-color: rgba(black, .6);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.picture-item__description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.picture-item__details,
|
||||
.picture-item__description {
|
||||
padding: 1em;
|
||||
}
|
||||
.picture-item__description {
|
||||
margin: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
.picture-item__tags {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.picture-item__title {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Shuffle needs either relative or absolute positioning on the container
|
||||
It will set it for you, but it'll cause another style recalculation and layout.
|
||||
AKA worse performance - so just set it here
|
||||
*/
|
||||
.shuffle--container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shuffle--fluid .shuffle__sizer {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@media ( max-width: 47.9375em ) {
|
||||
|
||||
.picture-item {
|
||||
height: auto;
|
||||
margin-top: 20px;
|
||||
|
||||
&.picture-item--h2 {
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.picture-item__details,
|
||||
.picture-item__description {
|
||||
font-size: .875em;
|
||||
padding: .625em;
|
||||
}
|
||||
|
||||
.picture-item__description {
|
||||
padding-right: .875em;
|
||||
padding-bottom: 1.25em;
|
||||
}
|
||||
}
|
||||
|
||||
.filter > .row-fluid,
|
||||
.filter > .row-fluid > div {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.m-nofloat {
|
||||
float: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,11 @@
|
||||
@import "variables";
|
||||
@import "normalize";
|
||||
// @import "csswizardry-grids";
|
||||
@import "type";
|
||||
@import "bootstrap";
|
||||
@import "mobile-grid";
|
||||
@import "main";
|
||||
@import "buttons";
|
||||
@import "helpers";
|
||||
|
||||
|
@ -0,0 +1,25 @@
|
||||
# Require any additional compass plugins here.
|
||||
|
||||
# Set this to the root of your project when deployed:
|
||||
http_path = "/"
|
||||
css_dir = "css"
|
||||
sass_dir = "_scss"
|
||||
images_dir = "img"
|
||||
javascripts_dir = "js"
|
||||
|
||||
# You can select your preferred output style here (can be overridden via the command line):
|
||||
# output_style = :expanded or :nested or :compact or :compressed
|
||||
output_style = :expanded
|
||||
|
||||
# To enable relative paths to assets via compass helper functions. Uncomment:
|
||||
# relative_assets = true
|
||||
|
||||
# To disable debugging comments that display the original location of your selectors. Uncomment:
|
||||
line_comments = false
|
||||
|
||||
|
||||
# If you prefer the indented syntax, you might want to regenerate this
|
||||
# project again passing --syntax sass, or you can uncomment this:
|
||||
# preferred_syntax = :sass
|
||||
# and then run:
|
||||
# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass
|
@ -0,0 +1,155 @@
|
||||
.filter-options {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.filter-group .filter-group__label {
|
||||
margin: 0 0 5px;
|
||||
}
|
||||
.filter-group button {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
}
|
||||
.filter-group label {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.shape-up {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shape {
|
||||
position: relative;
|
||||
margin-left: 0;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.shape .shape__inner {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
.shape .shape__space {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
border-color: transparent;
|
||||
}
|
||||
|
||||
.shape--blue .shape__space {
|
||||
background-color: #3498db;
|
||||
border-bottom-color: #3498db;
|
||||
}
|
||||
|
||||
.shape--red .shape__space {
|
||||
background-color: #e74c3c;
|
||||
border-bottom-color: #e74c3c;
|
||||
}
|
||||
|
||||
.shape--orange .shape__space {
|
||||
background-color: #f39c12;
|
||||
border-bottom-color: #f39c12;
|
||||
}
|
||||
|
||||
.shape--green .shape__space {
|
||||
background-color: #2ecc71;
|
||||
border-bottom-color: #2ecc71;
|
||||
}
|
||||
|
||||
.shape--circle .shape__space {
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.shape--diamond .shape__space {
|
||||
-webkit-transform: rotate(45deg) scale(0.70711);
|
||||
transform: rotate(45deg) scale(0.70711);
|
||||
}
|
||||
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: 14.5px;
|
||||
height: 0;
|
||||
width: 0;
|
||||
border-width: 0 110px 191px 110px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.lt-ie9 .shape .keep-ratio {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
overflow: visible;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.lt-ie9 .shape .shape__inner {
|
||||
position: static;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: 18px;
|
||||
border-width: 0 135px 234px 135px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 979px) {
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: 11px;
|
||||
border-width: 0 83px 144px 83px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: 13.5px;
|
||||
border-width: 0 100px 173px 100px;
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
.shape--triangle .shape__space {
|
||||
padding-top: 6.5px;
|
||||
border-width: 0 50px 87px 50px;
|
||||
}
|
||||
}
|
||||
body::before {
|
||||
content: 'Default - 940px';
|
||||
position: fixed;
|
||||
z-index: 5;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 25px;
|
||||
background-color: rgba(119, 204, 102, 0.6);
|
||||
-webkit-transition: background .2s ease;
|
||||
-o-transition: background .2s ease;
|
||||
transition: background .2s ease;
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
body::before {
|
||||
content: 'Large Desktop - 1200px+';
|
||||
background-color: rgba(204, 119, 102, 0.6);
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) and (max-width: 979px) {
|
||||
body::before {
|
||||
content: 'Portrait tablet to landscape and desktop - > 768px && < 979px';
|
||||
background-color: rgba(204, 187, 102, 0.6);
|
||||
}
|
||||
}
|
||||
@media (max-width: 767px) {
|
||||
body::before {
|
||||
content: 'Phones to Tablets - < 767px';
|
||||
background-color: rgba(102, 153, 204, 0.6);
|
||||
}
|
||||
}
|
||||
@media (max-width: 480px) {
|
||||
body::before {
|
||||
content: 'Phones - < 480px';
|
||||
background-color: rgba(204, 102, 204, 0.6);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
/*=============================================*\
|
||||
Some styles to show off masonry layout
|
||||
\*=============================================*/
|
||||
.picture-item {
|
||||
height: 220px;
|
||||
margin-top: 24px;
|
||||
overflow: hidden;
|
||||
background: #ecf0f1;
|
||||
}
|
||||
.picture-item.shuffle-item {
|
||||
margin-left: 0;
|
||||
/* shuffle items shouldn't have a left margin*/
|
||||
}
|
||||
.picture-item.picture-item--h2 {
|
||||
height: 464px;
|
||||
/* 2x the height + 1 gutter */
|
||||
}
|
||||
.picture-item.span6:not(.picture-item--h2) .picture-item__details {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #333;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: white;
|
||||
}
|
||||
.picture-item.span6:not(.picture-item--h2) .picture-item__description {
|
||||
display: none;
|
||||
}
|
||||
.picture-item img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
.picture-item .picture-item__details,
|
||||
.picture-item .picture-item__description {
|
||||
padding: 1em;
|
||||
}
|
||||
.picture-item .picture-item__description {
|
||||
margin: 0;
|
||||
padding-top: 0;
|
||||
padding-right: 2em;
|
||||
}
|
||||
.picture-item .picture-item__tags {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Shuffle needs either relative or absolute positioning on the container
|
||||
It will set it for you, but it'll cause another style recalculation and layout.
|
||||
AKA worse performance - so just set it here
|
||||
*/
|
||||
.shuffle--container {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.shuffle--fluid .shuffle__sizer {
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media (max-width: 47.9375em) {
|
||||
.picture-item {
|
||||
height: auto;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.picture-item.picture-item--h2 {
|
||||
height: auto;
|
||||
}
|
||||
.picture-item .picture-item__details,
|
||||
.picture-item .picture-item__description {
|
||||
font-size: .875em;
|
||||
padding: .625em;
|
||||
}
|
||||
.picture-item .picture-item__description {
|
||||
padding-right: .875em;
|
||||
padding-bottom: 1.25em;
|
||||
}
|
||||
|
||||
.filter > .row-fluid,
|
||||
.filter > .row-fluid > div {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.m-nofloat {
|
||||
float: none;
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 199 B |
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="20px" height="20px" viewBox="38.953 38.347 20 20" enable-background="new 38.953 38.347 20 20" xml:space="preserve">
|
||||
<path fill="#FFFFFF" d="M46.137,55.759l-6.184-6.224l3.003-3.022l3.269,3.287l8.812-8.865l2.916,2.935L46.137,55.759z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 519 B |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 9.9 KiB |
After Width: | Height: | Size: 31 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 215 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 201 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 1.3 KiB |
@ -1,505 +1,174 @@
|
||||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Shuffle</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta property="og:title" content="jQuery Shuffle Plugin" />
|
||||
<meta property="og:description" content="Shuffle, categorize, sort, and filter a grid of items" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:url" content="http://vestride.github.com/Shuffle/" />
|
||||
<meta property="og:image" content="http://vestride.github.com/Shuffle/img/hero.png" />
|
||||
<meta property="og:site_name" content="jQuery Shuffle Plugin" />
|
||||
<meta property="fb:admins" content="771347349" />
|
||||
<meta name="author" content="https://plus.google.com/u/0/100210640453700033824" />
|
||||
|
||||
<link href="https://plus.google.com/u/0/100210640453700033824" rel="author" />
|
||||
|
||||
<link rel="stylesheet" href="css/prism.css" />
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Poly:400,400italic' rel='stylesheet' type='text/css' />
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="js/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<div class="container container-main">
|
||||
<header>
|
||||
<h1>Shuffle</h1>
|
||||
<p>Categorize, sort, and filter a responsive grid of items</p>
|
||||
</header>
|
||||
|
||||
<section class="downloads">
|
||||
<h2>Downloads</h2>
|
||||
<a href="js/jquery.shuffle.js">jquery.shuffle.js</a>
|
||||
<a href="js/jquery.shuffle.min.js">jquery.shuffle.min.js</a>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2>Example</h2>
|
||||
|
||||
<div class="filter clearfix">
|
||||
<p class="lfloat label">Filter:</p>
|
||||
<ul class="filter-options control-group lfloat">
|
||||
<li data-group="all" class="active">Most Recent</li>
|
||||
<li data-group="wallpaper">Wallpapers</li>
|
||||
<li data-group="graphics">Graphic Design</li>
|
||||
<li data-group="photography">Photography</li>
|
||||
<li data-group="3d">3D Renders</li>
|
||||
</ul>
|
||||
|
||||
<p class="lfloat label">Sort:</p>
|
||||
<ul class="sort-options control-group lfloat">
|
||||
<li data-sort class="active">Default</li>
|
||||
<li data-sort="title">Title</li>
|
||||
<li data-sort="date-created">Date Created</li>
|
||||
</ul>
|
||||
|
||||
<input class="search label" type="search" placeholder="Search..." />
|
||||
</div>
|
||||
|
||||
<div id="grid" class="clearfix">
|
||||
<div class="item" data-groups='["photography"]' data-date-created="2010-09-14" data-title="Baseball">
|
||||
<img src="img/baseball.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Baseball</span>
|
||||
<a href="img/originals/baseball.jpg">Photography</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["wallpaper", "3d"]' data-date-created="2011-08-14" data-title="Tennis">
|
||||
<img src="img/tennis-ball.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Tennis</span>
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["3d", "wallpaper"]' data-date-created="2009-05-27" data-title="iMac">
|
||||
<img src="img/imac.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">iMac</span>
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["graphics"]' data-date-created="2012-05-14" data-title="Master Chief">
|
||||
<img src="img/master-chief.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Master Chief</span>
|
||||
<a href="#">Graphic Design</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["3d", "wallpaper"]' data-date-created="2012-09-14" data-title="Eightfold">
|
||||
<img src="img/es-blue.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Eightfold</span>
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["photography"]' data-date-created="2012-03-14" data-title="Pumpkin">
|
||||
<img src="img/pumpkin.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Pumpkin</span>
|
||||
<a href="#">Photography</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["3d", "wallpaper"]' data-date-created="2012-09-14" data-title="Vestride">
|
||||
<img src="img/vestride-red.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Vestride</span>
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["graphics"]' data-date-created="2012-01-12" data-title="Newegg">
|
||||
<img src="img/newegg.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Newegg</span>
|
||||
<a href="#">Motion Graphics</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["wallpaper"]' data-date-created="2012-01-14" data-title="Arc">
|
||||
<img src="img/eightfoldarc.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Arc</span>
|
||||
<a href="#">Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["photography"]' data-date-created="2011-01-14" data-title="Ground">
|
||||
<img src="img/ground.png" alt="" height="145" width="230"/>
|
||||
<div class="item-details">
|
||||
<span class="title">Ground</span>
|
||||
<a href="img/originals/baseball.jpg">Photography</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["wallpaper"]' data-date-created="2011-12-14" data-title="Grass">
|
||||
<img src="img/grassy-hills.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Grass</span>
|
||||
<a href="#">Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["3d", "wallpaper"]' data-date-created="2012-04-14" data-title="Vestride">
|
||||
<img src="img/vestride-classy.png" alt="" height="145" width="230" />
|
||||
<div class="item-details">
|
||||
<span class="title">Vestride</span>
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Other Examples</h2>
|
||||
<ul>
|
||||
<li><a href="minimal.html">The minimal markup</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Features</h2>
|
||||
|
||||
<ul>
|
||||
<li>Uses CSS Transitions!</li>
|
||||
<li>Responsive (try resizing the window!)</li>
|
||||
<li>Filter items by groups</li>
|
||||
<li>Items can have multiple groups</li>
|
||||
<li>Sort items</li>
|
||||
<li>Advanced filtering method (like searching)</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Options</h2>
|
||||
|
||||
<div>
|
||||
<p>Settings you can change (these are the defaults)</p>
|
||||
<pre rel="JavaScript">
|
||||
<code class="language-javascript">
|
||||
var options = {
|
||||
group : 'all' // Which category to show
|
||||
speed : 800, // Speed of the transition (in milliseconds). 800 = .8 seconds
|
||||
easing : 'ease-out' // css easing function to use
|
||||
};
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>The easing function is one of <code>'default'</code>, <code>'linear'</code>, <code>'ease-in'</code>, <code>'ease-out'</code>, <code>'ease-in-out'</code>, or <code>'cubic-bezier'</code>.</p>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<h2>Usage</h2>
|
||||
|
||||
<div>
|
||||
<p>The html structure. The only real important thing here is the <code class="language-markup token attr-name">data-groups</code> attribute. It has to be a <a href="http://jsonlint.com/">valid JSON</a> array of strings.</p>
|
||||
<pre rel="HTML">
|
||||
<code class="language-markup">
|
||||
<div id="grid">
|
||||
<div class="item" data-groups='["photography"]' data-date-created="2010-09-14" data-title="Baseball">
|
||||
<img src="img/baseball.png" />
|
||||
<div class="item-details">
|
||||
<a href="#">Photography</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["wallpaper", "3d"]' data-date-created="2011-08-14" data-title="Tennis">
|
||||
<img src="img/tennis-ball.png" />
|
||||
<div class="item-details">
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["3d", "wallpaper"]' data-date-created="2009-05-27" data-title="iMac">
|
||||
<img src="img/imac.png" />
|
||||
<div class="item-details">
|
||||
<a href="#">3D Render, Wallpaper</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" data-groups='["graphics"]' data-date-created="2012-05-14" data-title="Master Chief">
|
||||
<img src="img/master-chief.png" />
|
||||
<div class="item-details">
|
||||
<a href="#">Graphic Design</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>Shuffle takes the width, margin-top, and marigin-right from the <code class="language-css token selector">.item</code>.</p>
|
||||
<pre rel="CSS">
|
||||
<code class="language-css">
|
||||
#grid .item {
|
||||
width: 230px;
|
||||
margin-top: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>Sets up the button clicks and runs shuffle</p>
|
||||
<pre rel="jQuery">
|
||||
<code class="language-javascript">
|
||||
$(document).ready(function(){
|
||||
|
||||
// Set up button clicks
|
||||
$('.filter-options li').on('click', function() {
|
||||
var $this = $(this),
|
||||
$grid = $('#grid');
|
||||
|
||||
// Hide current label, show current label in title
|
||||
$('.filter-options .active').removeClass('active');
|
||||
$this.addClass('active');
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle($this.data('group'));
|
||||
});
|
||||
|
||||
// instantiate the plugin
|
||||
$('#grid').shuffle({
|
||||
group : 'all',
|
||||
speed : 800,
|
||||
easing : 'ease-out'
|
||||
});
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>These events will be triggered at their respective times: <code>'shrink.shuffle'</code>, <code>'shrunk.shuffle'</code>, <code>'filter.shuffle'</code>, <code>'filtered.shuffle'</code>, and <code>'sorted.shuffle'</code>.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Sorting</h2>
|
||||
|
||||
<p>You can order the elements based off a function you supply. In the example above, each item has a <code>data-date-created</code> and <code>data-title</code> attribute. The filter buttons have a <code>data-sort</code> attribute with the value of the item’s attribute. Then, with some JavaScript, we can get the correct attribute and provide a function to sort by.</p>
|
||||
|
||||
<pre rel="HTML">
|
||||
<code class="language-markup">
|
||||
<li data-sort="title">Title</li>
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<pre rel="HTML">
|
||||
<code class="language-markup">
|
||||
<div class="item" data-title="Baseball">…</div>
|
||||
</code>
|
||||
</pre>
|
||||
<pre rel="JavaScript">
|
||||
<code class="language-javascript">
|
||||
// Sorting options
|
||||
$('.sort-options li').on('click', function() {
|
||||
var $this = $(this),
|
||||
$grid = $('#grid'),
|
||||
sort = $this.data('sort'),
|
||||
opts = {};
|
||||
|
||||
// Hide current label, show current label in title
|
||||
$('.sort-options .active').removeClass('active');
|
||||
$this.addClass('active');
|
||||
|
||||
// We're given the element wrapped in jQuery
|
||||
if (sort === 'date-created') {
|
||||
opts = {
|
||||
by: function($el) {
|
||||
return $el.data('date-created');
|
||||
}
|
||||
}
|
||||
} else if (sort === 'title') {
|
||||
opts = {
|
||||
by: function($el) {
|
||||
return $el.data('title').toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle('sort', opts);
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<p>The <code>opts</code> parameter can contain two properties. <code>reverse</code>, a boolean which will reverse the array. <code>by</code> is a function that is passed the element wrapped in jQuery. In the case above, we’re returning the value of the data-date-created or data-title attributes.</p>
|
||||
<p>Calling sort with an empty object will reset the elements to DOM order.</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Advanced Filtering</h2>
|
||||
|
||||
<p>By passing a function to shuffle, you can customize the filtering to your hearts content. Shuffle will iterate over each item in the container and give your function the element wrapped in jQuery and the shuffle instance. Return <code>true</code> to keep the element or <code>false</code> to hide it.</p>
|
||||
|
||||
<h3>Example</h3>
|
||||
<pre rel="JavaScript">
|
||||
<code class="language-javascript">
|
||||
// Filters elements with a data-title attribute with less than 10 characters
|
||||
$('#grid').shuffle(function($el, shuffle) {
|
||||
return $el.data('title').length < 10;
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
|
||||
<h3>Searching</h3>
|
||||
<pre rel="JavaScript">
|
||||
<code class="language-javascript">
|
||||
// Advanced filtering
|
||||
$('.filter .search').on('keyup change', function() {
|
||||
var val = this.value.toLowerCase();
|
||||
$('#grid').shuffle(function($el, shuffle) {
|
||||
|
||||
// Only search elements in the current group
|
||||
if (shuffle.group !== 'all' && $.inArray(shuffle.group, $el.data('groups')) === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the text inside our element and search for the value in the input
|
||||
var text = $.trim($el.text()).toLowerCase();
|
||||
return text.indexOf(val) != -1;
|
||||
});
|
||||
});
|
||||
</code>
|
||||
</pre>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Dependencies</h2>
|
||||
|
||||
<ul>
|
||||
<li><a target="_blank" href="http://jquery.com">jQuery</a></li>
|
||||
<li><a target="_blank" href="http://modernizr.com">Modernizr</a>
|
||||
<ul>
|
||||
<li>A custom Modernizr build has been included with the plugin.</li>
|
||||
<li>If you already have Modernizr on your site, you may delete it.</li>
|
||||
<li>If you don't know what Modernizr is, leave it!</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2>Supported Browsers</h2>
|
||||
|
||||
<ul>
|
||||
<li>Chrome</li>
|
||||
<li>Firefox</li>
|
||||
<li>IE 7+</li>
|
||||
<li>Opera</li>
|
||||
<li>Safari</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Browsers that don't support CSS transitions and transforms <strong>*cough*</strong> IE <= 9 <strong>*cough*</strong> will see a less cool, javascript based version of the effect.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>Links</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/Vestride/Shuffle">GitHub Repo</a></li>
|
||||
<li><a href="http://isotope.metafizzy.co/">Inspired by Isotope</a></li>
|
||||
<li><a href="http://glencheney.com">Me</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<h2>Changes</h2>
|
||||
<ul>
|
||||
<li>10.24.12 - Better handling of grid item dimensions. Added a minimal markup page.</li>
|
||||
<li>9.20.12 - Added <code>destroy</code> method</li>
|
||||
<li>9.18.12 - Added sorting ability and made plugin responsive. Updated to Modernizr 2.6.2</li>
|
||||
<li>7.21.12 - Rewrote plugin in more object oriented structure. Added custom events. Updated to Modernizr 2.6.1</li>
|
||||
<li>7.3.12 - Removed dependency on the css file and now apply the css with javascript</li>
|
||||
</ul>
|
||||
|
||||
</section>
|
||||
---
|
||||
layout: default
|
||||
title: Shuffle.js
|
||||
bodyClass: home
|
||||
extraJS: [ "demos/homepage.js" ]
|
||||
includeHeader: true
|
||||
prism: true
|
||||
---
|
||||
<section id="downloads">
|
||||
<div class="container-fluid">
|
||||
<h2>Downloads</h2>
|
||||
<div class="row-fluid">
|
||||
<nav class="span6" role="secondary">
|
||||
<a href="js/jquery.shuffle.js">jquery.shuffle.js</a>
|
||||
<a href="js/jquery.shuffle.min.js">jquery.shuffle.min.js</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="demo">
|
||||
<div class="container-fluid">
|
||||
<h2>Example</h2>
|
||||
</div>
|
||||
|
||||
<div class="container-fluid filter">
|
||||
|
||||
<div class="row-fluid">
|
||||
<input class="filter__search js-shuffle-search" type="search" placeholder="Search..." />
|
||||
</div>
|
||||
<div class="row-fluid">
|
||||
<div class="span9">
|
||||
<p class="filter__label">Filter:</p>
|
||||
<div class="filter-options btn-group">
|
||||
<button class="btn btn--warning" data-group="wallpaper">Wallpapers</button>
|
||||
<button class="btn btn--warning" data-group="graphics">Graphic Design</button>
|
||||
<button class="btn btn--warning" data-group="photography">Photos</button>
|
||||
<button class="btn btn--warning" data-group="3d">3D Renders</button>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
|
||||
<script src="js/jquery.shuffle.js"></script>
|
||||
<script src="js/prism.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
// Set up button clicks
|
||||
$('.filter-options li').on('click', function() {
|
||||
var $this = $(this),
|
||||
$grid = $('#grid');
|
||||
|
||||
// Hide current label, show current label in title
|
||||
$('.filter-options .active').removeClass('active');
|
||||
$this.addClass('active');
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle($this.data('group'));
|
||||
});
|
||||
|
||||
// Sorting options
|
||||
$('.sort-options li').on('click', function() {
|
||||
var $this = $(this),
|
||||
$grid = $('#grid'),
|
||||
sort = $this.data('sort'),
|
||||
opts = {};
|
||||
|
||||
// Hide current label, show current label in title
|
||||
$('.sort-options .active').removeClass('active');
|
||||
$this.addClass('active');
|
||||
|
||||
// We're given the element wrapped in jQuery
|
||||
if (sort === 'date-created') {
|
||||
opts = {
|
||||
by: function($el) {
|
||||
return $el.data('date-created');
|
||||
}
|
||||
}
|
||||
} else if (sort === 'title') {
|
||||
opts = {
|
||||
by: function($el) {
|
||||
return $el.data('title').toLowerCase();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle('sort', opts);
|
||||
});
|
||||
|
||||
// Advanced filtering
|
||||
$('.filter .search').on('keyup change', function() {
|
||||
var val = this.value.toLowerCase();
|
||||
$('#grid').shuffle(function($el, shuffle) {
|
||||
|
||||
// Only search elements in the current group
|
||||
if (shuffle.group !== 'all' && $.inArray(shuffle.group, $el.data('groups')) === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var text = $.trim($el.text()).toLowerCase();
|
||||
return text.indexOf(val) != -1;
|
||||
});
|
||||
});
|
||||
|
||||
// instantiate the plugin
|
||||
$('#grid').shuffle({
|
||||
group : 'all',
|
||||
speed : 800,
|
||||
easing : 'ease-out'
|
||||
});
|
||||
|
||||
// Destroy it! o_O
|
||||
// $('#grid').shuffle('destroy');
|
||||
|
||||
|
||||
// You can subscribe to custom events: shrink, shrunk, filter, filtered, and sorted
|
||||
$('#grid').on('shrink.shuffle shrunk.shuffle filter.shuffle filtered.shuffle sorted.shuffle', function(evt, shuffle) {
|
||||
// console.log(evt.type);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
<div class="span3">
|
||||
<div class="m-nofloat pull-right">
|
||||
<p class="filter__label">Sort:</p>
|
||||
<select class="sort-options">
|
||||
<option value>Default</option>
|
||||
<option value="title">Title</option>
|
||||
<option value="date-created">Date Created</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div id="grid" class="row-fluid m-row shuffle--container shuffle--fluid">
|
||||
{% for item in site.items %}
|
||||
{% assign item = item %}
|
||||
{% include picture-item.html %}
|
||||
{% endfor %}
|
||||
<div class="span3 m-span3 shuffle__sizer"></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="demos">
|
||||
<div class="container-fluid">
|
||||
<h2>Demos</h2>
|
||||
<a href="#nav">In the nav</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="features">
|
||||
<div class="container-fluid">
|
||||
{% include features.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="options">
|
||||
<div class="container-fluid">
|
||||
{% include options.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="usage">
|
||||
<div class="container-fluid">
|
||||
{% include usage.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="events">
|
||||
<div class="container-fluid">
|
||||
{% include events.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="sorting">
|
||||
<div class="container-fluid">
|
||||
{% include sorting.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="advanced-filters">
|
||||
<div class="container-fluid">
|
||||
{% include advanced-filters.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="extra-features">
|
||||
<div class="container-fluid">
|
||||
<h2>Extra Features</h2>
|
||||
|
||||
<p>Shuffle likely will not grow much farther than the current feature set. If you need something with drag and drop, filling in gaps, more layout modes, etc., I suggest looking into <a target="_blank" href="http://packery.metafizzy.co/">packery</a> or <a target="_blank" href="http://isotope.metafizzy.co/">isotope</a>.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="dependencies">
|
||||
<div class="container-fluid">
|
||||
<h2>Dependencies</h2>
|
||||
|
||||
<ul>
|
||||
<li><a target="_blank" href="http://jquery.com">jQuery 1.9+</a></li>
|
||||
<li><a target="_blank" href="http://modernizr.com">Modernizr</a>
|
||||
<ul>
|
||||
<li>A custom Modernizr build has been included with the plugin.</li>
|
||||
<li>If you already have Modernizr on your site, you may delete it.</li>
|
||||
<li>If you don't know what Modernizr is, leave it!</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="browsers">
|
||||
<div class="container-fluid">
|
||||
<h2>Supported Browsers</h2>
|
||||
|
||||
<ul>
|
||||
<li>Chrome</li>
|
||||
<li>Firefox</li>
|
||||
<li>IE 7+</li>
|
||||
<li>Opera</li>
|
||||
<li>Safari</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Browsers that don't support CSS transitions and transforms <strong>*cough*</strong> IE <= 9 <strong>*cough*</strong> will see a less cool, javascript based version of the effect.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="links">
|
||||
<div class="container-fluid">
|
||||
<h2>Links</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="https://github.com/Vestride/Shuffle">GitHub Repo</a></li>
|
||||
<li><a href="http://isotope.metafizzy.co/">Inspired by Isotope</a></li>
|
||||
<li><a href="http://glencheney.com">Me</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="changelog">
|
||||
<div class="container-fluid">
|
||||
{% include changelog.html %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
{% include credit-jake.html %}
|
||||
|
@ -0,0 +1,88 @@
|
||||
// IMPORTANT!
|
||||
// If you're already using Modernizr, delete it from this file. If you don't know what Modernizr is, leave it :)
|
||||
|
||||
/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
|
||||
* Build: http://modernizr.com/download/#-csstransforms-csstransforms3d-csstransitions-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
|
||||
*/
|
||||
;window.Modernizr=function(a,b,c){function z(a){j.cssText=a}function A(a,b){return z(m.join(a+";")+(b||""))}function B(a,b){return typeof a===b}function C(a,b){return!!~(""+a).indexOf(b)}function D(a,b){for(var d in a){var e=a[d];if(!C(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function E(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:B(f,"function")?f.bind(d||b):f}return!1}function F(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+o.join(d+" ")+d).split(" ");return B(b,"string")||B(b,"undefined")?D(e,b):(e=(a+" "+p.join(d+" ")+d).split(" "),E(e,b,c))}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n="Webkit Moz O ms",o=n.split(" "),p=n.toLowerCase().split(" "),q={},r={},s={},t=[],u=t.slice,v,w=function(a,c,d,e){var f,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),l.appendChild(j);return f=["­",'<style id="s',h,'">',a,"</style>"].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},x={}.hasOwnProperty,y;!B(x,"undefined")&&!B(x.call,"undefined")?y=function(a,b){return x.call(a,b)}:y=function(a,b){return b in a&&B(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=u.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(u.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(u.call(arguments)))};return e}),q.csstransforms=function(){return!!F("transform")},q.csstransforms3d=function(){var a=!!F("perspective");return a&&"webkitPerspective"in g.style&&w("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},q.csstransitions=function(){return F("transition")};for(var G in q)y(q,G)&&(v=G.toLowerCase(),e[v]=q[G](),t.push((e[v]?"":"no-")+v));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)y(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},z(""),i=k=null,e._version=d,e._prefixes=m,e._domPrefixes=p,e._cssomPrefixes=o,e.testProp=function(a){return D([a])},e.testAllProps=F,e.testStyles=w,e.prefixed=function(a,b,c){return b?F(a,b,c):F(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+t.join(" "):""),e}(this,this.document);
|
||||
|
||||
|
||||
// Shuffle Doesn't require this shuffle/debounce plugin, but it works better with it.
|
||||
|
||||
/*
|
||||
* jQuery throttle / debounce - v1.1 - 3/7/2010
|
||||
* http://benalman.com/projects/jquery-throttle-debounce-plugin/
|
||||
*
|
||||
* Copyright (c) 2010 "Cowboy" Ben Alman
|
||||
* Dual licensed under the MIT and GPL licenses.
|
||||
* http://benalman.com/about/license/
|
||||
*/
|
||||
(function(b,c){var $=b.jQuery||b.Cowboy||(b.Cowboy={}),a;$.throttle=a=function(e,f,j,i){var h,d=0;if(typeof f!=="boolean"){i=j;j=f;f=c}function g(){var o=this,m=+new Date()-d,n=arguments;function l(){d=+new Date();j.apply(o,n)}function k(){h=c}if(i&&!h){l()}h&&clearTimeout(h);if(i===c&&m>e){l()}else{if(f!==true){h=setTimeout(i?k:l,i===c?e-m:e)}}}if($.guid){g.guid=j.guid=j.guid||$.guid++}return g};$.debounce=function(d,e,f){return f===c?a(d,e,false):a(d,f,e!==false)}})(this);
|
||||
|
||||
/*!
|
||||
* jQuery Shuffle Plugin
|
||||
* Uses CSS Transforms to filter down a grid of items.
|
||||
* Dependencies: jQuery 1.9+, Modernizr 2.6.2. Optionally throttle/debounce by Ben Alman
|
||||
* Inspired by Isotope http://isotope.metafizzy.co/
|
||||
* Licensed under the MIT license.
|
||||
* @author Glen Cheney (http://glencheney.com)
|
||||
* @version 2.0
|
||||
* @date 07/05/13
|
||||
*/
|
||||
!function(t,e,i){"use strict"
|
||||
t.fn.sorted=function(e){var n=t.extend({},t.fn.sorted.defaults,e),s=this.get(),r=!1
|
||||
return s.length?n.randomize?t.fn.sorted.randomize(s):(n.by!==t.noop&&null!==n.by&&n.by!==i&&s.sort(function(e,s){if(r)return 0
|
||||
var o=n.by(t(e)),a=n.by(t(s))
|
||||
return o===i&&a===i?(r=!0,0):"sortFirst"===o||"sortLast"===a?-1:"sortLast"===o||"sortFirst"===a?1:a>o?-1:o>a?1:0}),r?this.get():(n.reverse&&s.reverse(),s)):[]},t.fn.sorted.defaults={reverse:!1,by:null,randomize:!1},t.fn.sorted.randomize=function(t){var e,i,n=t.length
|
||||
if(!n)return t
|
||||
for(;--n;)i=Math.floor(Math.random()*(n+1)),e=t[i],t[i]=t[n],t[n]=e
|
||||
return t}
|
||||
var n=0,s=function(e,i){var r=this
|
||||
t.extend(r,s.options,i,s.settings),r.$container=e,r.$window=t(window),r.unique="shuffle_"+n++,r._fire("loading"),r._init(),r._fire("done")}
|
||||
s.prototype={_init:function(){var e,i=this,n=t.proxy(i._onResize,i),s=i.throttle?i.throttle(i.throttleTime,n):n,r=i.initialSort?i.initialSort:null
|
||||
i._setVars(),i._resetCols(),i._addClasses(),i._initItems(),i.$window.on("resize.shuffle."+i.unique,s),e=i.$container.css(["paddingLeft","paddingRight","position","width"]),"static"===e.position&&i.$container.css("position","relative"),i.offset={left:parseInt(e.paddingLeft,10)||0,top:parseInt(e.paddingTop,10)||0},i._setColumns(parseInt(e.width,10)),i.shuffle(i.group,r),i.supported&&setTimeout(function(){i._setTransitions(),i.$container[0].style[i.transitionName]="height "+i.speed+"ms "+i.easing},0)},_addClasses:function(){var t=this
|
||||
return t.$container.addClass("shuffle"),t.$items.addClass("shuffle-item filtered"),t},_setVars:function(){var e=this
|
||||
return e.$items=e._getItems(),e.transitionName=e.prefixed("transition"),e.transitionDelayName=e.prefixed("transitionDelay"),e.transitionDuration=e.prefixed("transitionDuration"),e.transform=e.getPrefixed("transform"),e.transitionend={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"}[e.transitionName],e.isFluid=e.columnWidth&&"function"==typeof e.columnWidth,0===e.columnWidth&&null!==e.sizer&&(e.columnWidth=e.sizer),"string"==typeof e.columnWidth?e.$sizer=e.$container.find(e.columnWidth):e.columnWidth&&e.columnWidth.nodeType&&1===e.columnWidth.nodeType?e.$sizer=t(e.columnWidth):e.columnWidth&&e.columnWidth.jquery&&(e.$sizer=e.columnWidth),e.$sizer&&e.$sizer.length&&(e.useSizer=!0,e.sizer=e.$sizer[0]),e},_filter:function(e,n){var s=this,r=n!==i,o=r?n:s.$items,a=t()
|
||||
return e=e||s.lastFilter,s._fire("filter"),t.isFunction(e)?o.each(function(){var i=t(this),n=e.call(i[0],i,s)
|
||||
n&&(a=a.add(i))}):(s.group=e,"all"!==e?o.each(function(){var i=t(this),n=i.data("groups"),r=s.delimeter&&!t.isArray(n)?n.split(s.delimeter):n,o=t.inArray(e,r)>-1
|
||||
o&&(a=a.add(i))}):a=o),s._toggleFilterClasses(o,a),o=null,n=null,a},_toggleFilterClasses:function(e,i){var n="concealed",s="filtered"
|
||||
e.filter(i).each(function(){var e=t(this)
|
||||
e.hasClass(n)&&e.removeClass(n),e.hasClass(s)||e.addClass(s)}),e.not(i).each(function(){var e=t(this)
|
||||
e.hasClass(n)||e.addClass(n),e.hasClass(s)&&e.removeClass(s)})},_initItems:function(t){return t=t||this.$items,t.css(this.itemCss)},_updateItemCount:function(){return this.visibleItems=this.$items.filter(".filtered").length,this},_setTransition:function(t){var e=this
|
||||
return t.style[e.transitionName]=e.transform+" "+e.speed+"ms "+e.easing+", opacity "+e.speed+"ms "+e.easing,t},_setTransitions:function(t){var e=this
|
||||
return t=t||e.$items,t.each(function(){e._setTransition(this)}),e},_setSequentialDelay:function(e){var i=this
|
||||
i.supported&&t.each(e,function(e){this.style[i.transitionDelayName]="0ms,"+(e+1)*i.sequentialFadeDelay+"ms",t(this).one(i.transitionend,function(){this.style[i.transitionDelayName]="0ms"})})},_getItems:function(){return this.$container.children(this.itemSelector)},_getPreciseDimension:function(e,i){var n
|
||||
return n=window.getComputedStyle?window.getComputedStyle(e,null)[i]:t(e).css(i),parseFloat(n)},_setColumns:function(t){var e,i=this,n=t||i.$container.width(),s="function"==typeof i.gutterWidth?i.gutterWidth(n):i.useSizer?i._getPreciseDimension(i.sizer,"marginLeft"):i.gutterWidth
|
||||
i.colWidth=i.isFluid?i.columnWidth(n):i.useSizer?i._getPreciseDimension(i.sizer,"width"):i.columnWidth||i.$items.outerWidth(!0)||n,i.colWidth=i.colWidth||n,i.colWidth+=s,e=(n+s)/i.colWidth,Math.ceil(e)-e<.01&&(e=Math.ceil(e)),i.cols=Math.floor(e),i.cols=Math.max(i.cols,1),i.containerWidth=n},_setContainerSize:function(){var t=this,e=Math.max.apply(Math,t.colYs)
|
||||
t.$container.css("height",e+"px")},_fire:function(t,e){this.$container.trigger(t+".shuffle",e&&e.length?e:[this])},_layout:function(e,i,n,s){var r=this
|
||||
i=i||r.filterEnd,r.layoutTransitionEnded=!1,t.each(e,function(o){var a=t(e[o]),l=Math.ceil(a.outerWidth(!0)/r.colWidth)
|
||||
if(l=Math.min(l,r.cols),1===l)r._placeItem(a,r.colYs,i,n,s)
|
||||
else{var u,d,c=r.cols+1-l,f=[]
|
||||
for(d=0;c>d;d++)u=r.colYs.slice(d,d+l),f[d]=Math.max.apply(Math,u)
|
||||
r._placeItem(a,f,i,n,s)}}),r._processStyleQueue(),r._setContainerSize()},_resetCols:function(){var t=this.cols
|
||||
for(this.colYs=[];t--;)this.colYs.push(0)},_reLayout:function(t,e){var i=this
|
||||
t=t||i.filterEnd,i._resetCols(),i.keepSorted&&i.lastSort?i.sort(i.lastSort,!0,e):i._layout(i.$items.filter(".filtered").get(),i.filterEnd,e)},_placeItem:function(t,e,i,n,s){for(var r=this,o=Math.min.apply(Math,e),a=0,l=0,u=e.length;u>l;l++)if(e[l]>=o-r.buffer&&e[l]<=o+r.buffer){a=l
|
||||
break}var d=r.colWidth*a,c=o
|
||||
d=Math.round(d+r.offset.left),c=Math.round(c+r.offset.top),t.data({x:d,y:c})
|
||||
var f=o+t.outerHeight(!0),h=r.cols+1-u
|
||||
for(l=0;h>l;l++)r.colYs[a+l]=f
|
||||
var p={from:"layout",$this:t,x:d,y:c,scale:1}
|
||||
n?p.skipTransition=!0:(p.opacity=1,p.callback=i),s&&(p.opacity=0),r.styleQueue.push(p)},_shrink:function(e,i){var n=this,s=e||n.$items.filter(".concealed"),r={},o=i||n.shrinkEnd
|
||||
s.length&&(n._fire("shrink"),n.shrinkTransitionEnded=!1,s.each(function(){var e=t(this),i=e.data()
|
||||
r={from:"shrink",$this:e,x:i.x,y:i.y,scale:.001,opacity:0,callback:o},n.styleQueue.push(r)}))},_onResize:function(){var t,e=this
|
||||
e.enabled&&!e.destroyed&&(t=e.$container.width(),t!==e.containerWidth&&e.resized())},setPrefixedCss:function(t,e,i){t.css(this.prefixed(e),i)},getPrefixed:function(t){var e=this.prefixed(t)
|
||||
return e?e.replace(/([A-Z])/g,function(t,e){return"-"+e.toLowerCase()}).replace(/^ms-/,"-ms-"):e},transition:function(e){var n,s=this,r=function(){s.layoutTransitionEnded||"layout"!==e.from?s.shrinkTransitionEnded||"shrink"!==e.from||(e.callback.call(s),s.shrinkTransitionEnded=!0):(s._fire("layout"),e.callback.call(s),s.layoutTransitionEnded=!0)}
|
||||
if(e.callback=e.callback||t.noop,s.supported)e.scale===i&&(e.scale=1),n=s.threeD?"translate3d("+e.x+"px, "+e.y+"px, 0) scale3d("+e.scale+", "+e.scale+", 1)":"translate("+e.x+"px, "+e.y+"px) scale("+e.scale+", "+e.scale+")",e.x!==i&&s.setPrefixedCss(e.$this,"transform",n),e.opacity!==i&&e.$this.css("opacity",e.opacity),e.$this.one(s.transitionend,r)
|
||||
else{var o={left:e.x,top:e.y,opacity:e.opacity}
|
||||
e.$this.stop(!0).animate(o,s.speed,"swing",r)}},_processStyleQueue:function(){var e=this,i=e.styleQueue
|
||||
t.each(i,function(t,i){i.skipTransition?e._skipTransition(i.$this[0],function(){e.transition(i)}):e.transition(i)}),e.styleQueue.length=0},shrinkEnd:function(){this._fire("shrunk")},filterEnd:function(){this._fire("filtered")},sortEnd:function(){this._fire("sorted")},_skipTransition:function(e,i,n){var s,r=this,o=r.transitionDuration,a=e.style[o]
|
||||
e.style[o]="0ms",t.isFunction(i)?i():e.style[i]=n,s=e.offsetWidth,e.style[o]=a},_addItems:function(t,e,n){var s,r,o=this
|
||||
o.supported||(e=!1),t.addClass("shuffle-item"),o._initItems(t),o._setTransitions(t),o.$items=o._getItems(),t.css("opacity",0),s=o._filter(i,t),r=s.get(),o._updateItemCount(),e?(o._layout(r,null,!0,!0),n&&o._setSequentialDelay(s),o._revealAppended(s)):o._layout(r)},_revealAppended:function(e){var i=this
|
||||
setTimeout(function(){e.each(function(e,n){i.transition({from:"reveal",$this:t(n),opacity:1})})},i.revealAppendedDelay)},shuffle:function(t,e){var i=this
|
||||
i.enabled&&(t||(t="all"),i._filter(t),i.lastFilter=t,i._updateItemCount(),i._resetCols(),i._shrink(),e&&(i.lastSort=e),i._reLayout())},sort:function(t,e,i){var n=this,s=n.$items.filter(".filtered").sorted(t)
|
||||
e||n._resetCols(),n._layout(s,function(){e&&n.filterEnd(),n.sortEnd()},i),n.lastSort=t},resized:function(t){this.enabled&&(t||this._setColumns(),this._reLayout())},layout:function(){this.update(!0)},update:function(t){this.resized(t)},appended:function(t,e,i){e=e===!1?!1:!0,i=i===!1?!1:!0,this._addItems(t,e,i)},disable:function(){this.enabled=!1},enable:function(t){this.enabled=!0,t!==!1&&this.update()},remove:function(t){if(t.length&&t.jquery){var e=this
|
||||
return e._shrink(t,function(){var e=this
|
||||
t.remove(),setTimeout(function(){e.$items=e._getItems(),e.layout(),e._updateItemCount(),e._fire("removed",[t,e]),t=null},0)}),e._processStyleQueue(),e}},destroy:function(){var t=this
|
||||
t.$window.off("."+t.unique),t.$container.removeClass("shuffle").removeAttr("style").removeData("shuffle"),t.$items.removeAttr("style").removeClass("concealed filtered shuffle-item"),t.destroyed=!0}},s.options={group:"all",speed:250,easing:"ease-out",itemSelector:"",sizer:null,gutterWidth:0,columnWidth:0,delimeter:null,buffer:0,initialSort:null,throttle:t.throttle||null,throttleTime:300,sequentialFadeDelay:150,supported:e.csstransforms&&e.csstransitions},s.settings={$sizer:null,useSizer:!1,itemCss:{position:"absolute",top:0,left:0},offset:{top:0,left:0},revealAppendedDelay:300,keepSorted:!0,enabled:!0,destroyed:!1,styleQueue:[],prefixed:e.prefixed,threeD:e.csstransforms3d},t.fn.shuffle=function(e){var i=Array.prototype.slice.call(arguments,1)
|
||||
return this.each(function(){var n=t(this),r=n.data("shuffle")
|
||||
r||(r=new s(n,e),n.data("shuffle",r)),"string"==typeof e&&r[e]&&r[e].apply(r,i)})}}(jQuery,Modernizr)
|
@ -0,0 +1,150 @@
|
||||
window.Manipulator = (function($) {
|
||||
'use strict';
|
||||
|
||||
var hasConsole = window.console && typeof window.console.log === 'function';
|
||||
|
||||
var Manipulator = function( element ) {
|
||||
var self = this;
|
||||
|
||||
self.$el = $( element );
|
||||
self.init();
|
||||
};
|
||||
|
||||
Manipulator.prototype.init = function() {
|
||||
var self = this;
|
||||
|
||||
self.initShuffle();
|
||||
self.setupEvents();
|
||||
};
|
||||
|
||||
// Column width and gutter width options can be functions
|
||||
Manipulator.prototype.initShuffle = function() {
|
||||
this.$el.shuffle({
|
||||
itemSelector: '.box',
|
||||
speed: 250,
|
||||
easing: 'ease',
|
||||
columnWidth: function( containerWidth ) {
|
||||
// .box's have a width of 18%
|
||||
return 0.18 * containerWidth;
|
||||
},
|
||||
gutterWidth: function( containerWidth ) {
|
||||
// .box's have a margin-left of 2.5%
|
||||
return 0.025 * containerWidth;
|
||||
}
|
||||
});
|
||||
|
||||
// Shuffle is stored in the elements data with jQuery.
|
||||
// You can access the class instance here
|
||||
this.shuffle = this.$el.data('shuffle');
|
||||
};
|
||||
|
||||
Manipulator.prototype.setupEvents = function() {
|
||||
var self = this;
|
||||
|
||||
$('#add').on('click', $.proxy( self.onAddClick, self ));
|
||||
$('#randomize').on('click', $.proxy( self.onRandomize, self ));
|
||||
$('#remove').on('click', $.proxy( self.onRemoveClick, self ));
|
||||
|
||||
// Show off some shuffle events
|
||||
self.$el.on('removed.shuffle', function( evt, $collection, shuffle ) {
|
||||
|
||||
// Make sure logs work
|
||||
if ( !hasConsole ) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log( this, evt, $collection, shuffle );
|
||||
});
|
||||
};
|
||||
|
||||
Manipulator.prototype.onAddClick = function() {
|
||||
|
||||
// Creating random elements. You could use an
|
||||
// ajax request or clone elements instead
|
||||
var self = this,
|
||||
itemsToCreate = 5,
|
||||
frag = document.createDocumentFragment(),
|
||||
grid = self.$el[0],
|
||||
items = [],
|
||||
$items,
|
||||
classes = ['w2', 'h2', 'w3'],
|
||||
box, i, random, randomClass;
|
||||
|
||||
for (i = 0; i < itemsToCreate; i++) {
|
||||
random = Math.random();
|
||||
box = document.createElement('div');
|
||||
box.className = 'box';
|
||||
|
||||
// Randomly add a class
|
||||
if ( random > 0.8 ) {
|
||||
randomClass = Math.floor( Math.random() * 3 );
|
||||
box.className = box.className + ' ' + classes[ randomClass ];
|
||||
}
|
||||
items.push( box );
|
||||
frag.appendChild( box );
|
||||
}
|
||||
|
||||
grid.appendChild( frag );
|
||||
$items = $(items);
|
||||
|
||||
|
||||
// Tell shuffle items have been appended.
|
||||
// It expects a jQuery object as the parameter.
|
||||
self.shuffle.appended( $items );
|
||||
// or
|
||||
// self.$el.shuffle('appended', $items );
|
||||
};
|
||||
|
||||
Manipulator.prototype.getRandomInt = function(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
};
|
||||
|
||||
// Randomly choose some elements to remove
|
||||
Manipulator.prototype.onRemoveClick = function() {
|
||||
var self = this,
|
||||
total = self.shuffle.visibleItems,
|
||||
numberToRemove = Math.min( 3, total ),
|
||||
indexesToRemove = [],
|
||||
i = 0,
|
||||
$collection = $();
|
||||
|
||||
// None left
|
||||
if ( !total ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This has the possibility to choose the same index for more than
|
||||
// one in the array, meaning sometimes less than 3 will be removed
|
||||
for ( ; i < numberToRemove; i++ ) {
|
||||
indexesToRemove.push( self.getRandomInt( 0, total - 1 ) );
|
||||
}
|
||||
|
||||
// Make a jQuery collection out of the index selections
|
||||
$.each(indexesToRemove, function(i, index) {
|
||||
$collection = $collection.add( self.shuffle.$items.eq( index ) );
|
||||
});
|
||||
|
||||
// Tell shuffle to remove them
|
||||
self.shuffle.remove( $collection );
|
||||
// or
|
||||
// self.$el.shuffle('remove', $collection);
|
||||
};
|
||||
|
||||
Manipulator.prototype.onRandomize = function() {
|
||||
var self = this,
|
||||
sortObj = {
|
||||
randomize: true
|
||||
};
|
||||
|
||||
self.shuffle.sort( sortObj );
|
||||
// or
|
||||
// self.$el.shuffle('sort', sortObj);
|
||||
};
|
||||
|
||||
return Manipulator;
|
||||
|
||||
}(jQuery));
|
||||
|
||||
$(document).ready(function() {
|
||||
new window.Manipulator( document.getElementById('my-shuffle') );
|
||||
});
|
@ -0,0 +1,172 @@
|
||||
|
||||
var Exports = {
|
||||
Modules : {}
|
||||
};
|
||||
|
||||
Exports.Modules.Gallery = (function($, undefined) {
|
||||
var $grid,
|
||||
$shapes,
|
||||
$colors,
|
||||
shapes = [],
|
||||
colors = [],
|
||||
|
||||
// Using shuffle with specific column widths
|
||||
columnWidths = {
|
||||
1170: 70,
|
||||
940: 60,
|
||||
724: 42
|
||||
},
|
||||
gutterWidths = {
|
||||
1170: 30,
|
||||
940: 20,
|
||||
724: 20
|
||||
},
|
||||
|
||||
init = function() {
|
||||
setVars();
|
||||
initFilters();
|
||||
initShuffle();
|
||||
},
|
||||
|
||||
setVars = function() {
|
||||
$grid = $('.js-shuffle');
|
||||
$shapes = $('.js-shapes');
|
||||
$colors = $('.js-colors');
|
||||
},
|
||||
|
||||
initShuffle = function() {
|
||||
// instantiate the plugin
|
||||
$grid.shuffle({
|
||||
speed : 250,
|
||||
easing : 'cubic-bezier(0.165, 0.840, 0.440, 1.000)', // easeOutQuart
|
||||
columnWidth: function( containerWidth ) {
|
||||
var colW = columnWidths[ containerWidth ];
|
||||
|
||||
// Default to container width
|
||||
if ( colW === undefined ) {
|
||||
colW = containerWidth;
|
||||
}
|
||||
return colW;
|
||||
},
|
||||
gutterWidth: function( containerWidth ) {
|
||||
var gutter = gutterWidths[ containerWidth ];
|
||||
|
||||
// Default to zero
|
||||
if ( gutter === undefined ) {
|
||||
gutter = 0;
|
||||
}
|
||||
return gutter;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
initFilters = function() {
|
||||
// shapes
|
||||
$shapes.find('input').on('change', function() {
|
||||
var $checked = $shapes.find('input:checked'),
|
||||
groups = [];
|
||||
|
||||
// At least one checkbox is checked, clear the array and loop through the checked checkboxes
|
||||
// to build an array of strings
|
||||
if ($checked.length !== 0) {
|
||||
$checked.each(function() {
|
||||
groups.push(this.value);
|
||||
});
|
||||
}
|
||||
shapes = groups;
|
||||
|
||||
filter();
|
||||
});
|
||||
|
||||
// colors
|
||||
$colors.find('button').on('click', function() {
|
||||
var $this = $(this),
|
||||
$alreadyChecked,
|
||||
checked = [],
|
||||
active = 'active',
|
||||
isActive;
|
||||
|
||||
// Already checked buttons which are not this one
|
||||
$alreadyChecked = $this.siblings('.' + active);
|
||||
|
||||
$this.toggleClass( active );
|
||||
|
||||
// Remove active on already checked buttons to act like radio buttons
|
||||
if ( $alreadyChecked.length ) {
|
||||
$alreadyChecked.removeClass( active );
|
||||
}
|
||||
|
||||
isActive = $this.hasClass( active );
|
||||
|
||||
if ( isActive ) {
|
||||
checked.push( $this.data( 'filterValue' ) );
|
||||
}
|
||||
|
||||
colors = checked;
|
||||
|
||||
filter();
|
||||
});
|
||||
},
|
||||
|
||||
filter = function() {
|
||||
if ( hasActiveFilters() ) {
|
||||
$grid.shuffle('shuffle', function($el) {
|
||||
return itemPassesFilters( $el.data() );
|
||||
});
|
||||
} else {
|
||||
$grid.shuffle( 'shuffle', 'all' );
|
||||
}
|
||||
},
|
||||
|
||||
itemPassesFilters = function(data) {
|
||||
|
||||
// If a shapes filter is active
|
||||
if ( shapes.length > 0 && !valueInArray(data.shape, shapes) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If a colors filter is active
|
||||
if ( colors.length > 0 && !valueInArray(data.color, colors) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
hasActiveFilters = function() {
|
||||
return colors.length > 0 || shapes.length > 0;
|
||||
},
|
||||
|
||||
valueInArray = function(value, arr) {
|
||||
return $.inArray(value, arr) !== -1;
|
||||
};
|
||||
|
||||
// arrayContainsArray = function(arrToTest, requiredArr) {
|
||||
// var i = 0,
|
||||
// dictionary = {},
|
||||
// j;
|
||||
|
||||
// // Convert groups into object which we can test the keys
|
||||
// for (j = 0; j < arrToTest.length; j++) {
|
||||
// dictionary[ arrToTest[j] ] = true;
|
||||
// }
|
||||
|
||||
// // Loop through selected shapes, if that feature is not in this elements groups, return false
|
||||
// for (; i < requiredArr.length; i++) {
|
||||
// if ( dictionary[ requiredArr[i] ] === undefined ) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// };
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
}(jQuery));
|
||||
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
Exports.Modules.Gallery.init();
|
||||
});
|
@ -0,0 +1,141 @@
|
||||
var DEMO = (function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var $grid = $('#grid'),
|
||||
$filterOptions = $('.filter-options'),
|
||||
$sizer = $grid.find('.shuffle__sizer'),
|
||||
|
||||
init = function() {
|
||||
|
||||
// None of these need to be executed synchronously
|
||||
setTimeout(function() {
|
||||
listen();
|
||||
setupFilters();
|
||||
setupSorting();
|
||||
setupSearching();
|
||||
}, 100);
|
||||
|
||||
// instantiate the plugin
|
||||
$grid.shuffle({
|
||||
itemSelector: '.picture-item',
|
||||
sizer: $sizer
|
||||
});
|
||||
|
||||
// Destroy it! o_O
|
||||
// $grid.shuffle('destroy');
|
||||
|
||||
// You can subscribe to custom events:
|
||||
// shrink, shrunk, filter, filtered, sorted, load, done
|
||||
// $grid.on('shrink.shuffle shrunk.shuffle filter.shuffle filtered.shuffle sorted.shuffle layout.shuffle', function(evt, shuffle) {
|
||||
// if ( window.console ) {
|
||||
// console.log(evt.type, shuffle, this);
|
||||
// }
|
||||
// });
|
||||
},
|
||||
|
||||
// Set up button clicks
|
||||
setupFilters = function() {
|
||||
var $btns = $filterOptions.children();
|
||||
$btns.on('click', function() {
|
||||
var $this = $(this),
|
||||
isActive = $this.hasClass( 'active' ),
|
||||
group = isActive ? 'all' : $this.data('group');
|
||||
|
||||
// Hide current label, show current label in title
|
||||
if ( !isActive ) {
|
||||
$('.filter-options .active').removeClass('active');
|
||||
}
|
||||
|
||||
$this.toggleClass('active');
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle( 'shuffle', group );
|
||||
});
|
||||
|
||||
$btns = null;
|
||||
},
|
||||
|
||||
setupSorting = function() {
|
||||
// Sorting options
|
||||
$('.sort-options').on('change', function() {
|
||||
var sort = this.value,
|
||||
opts = {};
|
||||
|
||||
// We're given the element wrapped in jQuery
|
||||
if ( sort === 'date-created' ) {
|
||||
opts = {
|
||||
reverse: true,
|
||||
by: function($el) {
|
||||
return $el.data('date-created');
|
||||
}
|
||||
};
|
||||
} else if ( sort === 'title' ) {
|
||||
opts = {
|
||||
by: function($el) {
|
||||
return $el.data('title').toLowerCase();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle('sort', opts);
|
||||
});
|
||||
},
|
||||
|
||||
setupSearching = function() {
|
||||
// Advanced filtering
|
||||
$('.js-shuffle-search').on('keyup change', function() {
|
||||
var val = this.value.toLowerCase();
|
||||
$grid.shuffle('shuffle', function($el, shuffle) {
|
||||
|
||||
// Only search elements in the current group
|
||||
if (shuffle.group !== 'all' && $.inArray(shuffle.group, $el.data('groups')) === -1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var text = $.trim( $el.find('.picture-item__title').text() ).toLowerCase();
|
||||
return text.indexOf(val) !== -1;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
// Re layout shuffle when images load. This is only needed
|
||||
// below 768 pixels because the .picture-item height is auto and therefore
|
||||
// the height of the picture-item is dependent on the image
|
||||
// I recommend using imagesloaded to determine when an image is loaded
|
||||
// but that doesn't support IE7
|
||||
listen = function() {
|
||||
var debouncedLayout = $.throttle( 300, function() {
|
||||
$grid.shuffle('update');
|
||||
});
|
||||
|
||||
// Get all images inside shuffle
|
||||
$grid.find('img').each(function() {
|
||||
var proxyImage;
|
||||
|
||||
// Image already loaded
|
||||
if ( this.complete && this.naturalWidth !== undefined ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If none of the checks above matched, simulate loading on detached element.
|
||||
proxyImage = new Image();
|
||||
$( proxyImage ).on('load', function() {
|
||||
$(this).off('load');
|
||||
debouncedLayout();
|
||||
});
|
||||
|
||||
proxyImage.src = this.src;
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
}( jQuery ));
|
||||
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
DEMO.init();
|
||||
});
|
@ -0,0 +1,22 @@
|
||||
|
||||
var ImageDemo = (function( $ ) {
|
||||
|
||||
var $shuffle = $('.shuffle--images'),
|
||||
sizer = document.getElementById('js-sizer'),
|
||||
|
||||
init = function() {
|
||||
|
||||
$shuffle.shuffle({
|
||||
sizer: sizer,
|
||||
itemSelector: '.js-item'
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
}( jQuery ));
|
||||
|
||||
$(document).ready(function() {
|
||||
ImageDemo.init();
|
||||
});
|
@ -0,0 +1,54 @@
|
||||
|
||||
// For this demo, shuffle won't be initialized until
|
||||
// all the images have finished loading.
|
||||
|
||||
// Another approach would be to initialize shuffle on document
|
||||
// ready and as imagesLoaded reports back progress, call shuffle.layout()
|
||||
|
||||
// imagesLoade: https://github.com/desandro/imagesloaded
|
||||
|
||||
var ImageDemo = (function( $, imagesLoaded ) {
|
||||
|
||||
var $shuffle = $('.shuffle--images'),
|
||||
$imgs = $shuffle.find('img'),
|
||||
$loader = $('#loader'),
|
||||
sizer = document.getElementById('js-sizer'),
|
||||
imgLoad,
|
||||
|
||||
init = function() {
|
||||
|
||||
// Create a new imagesLoaded instance
|
||||
imgLoad = new imagesLoaded( $imgs.get() );
|
||||
|
||||
// Listen for when all images are done
|
||||
// will be executed even if some images fail
|
||||
imgLoad.on( 'always', onAllImagesFinished );
|
||||
},
|
||||
|
||||
onAllImagesFinished = function( instance ) {
|
||||
|
||||
if ( window.console && window.console.log ) {
|
||||
console.log( instance );
|
||||
}
|
||||
|
||||
// Hide loader
|
||||
$loader.addClass('hidden');
|
||||
|
||||
// Adds visibility: visible;
|
||||
$shuffle.addClass('images-loaded');
|
||||
|
||||
// Initialize shuffle
|
||||
$shuffle.shuffle({
|
||||
sizer: sizer,
|
||||
itemSelector: '.js-item'
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
}( jQuery, window.imagesLoaded ));
|
||||
|
||||
$(document).ready(function() {
|
||||
ImageDemo.init();
|
||||
});
|
@ -1,8 +1,8 @@
|
||||
/*
|
||||
HTML5 Shiv v3.6.2pre | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
|
||||
HTML5 Shiv v3.6.2 | @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,figcaption,figure,footer,header,hgroup,nav,section{display:block}mark{background:#FF0;color:#000}</style>";
|
||||
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,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}</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 figcaption figure footer header hgroup mark meter nav output progress section summary time video",version:"3.6.2pre",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();
|
||||
"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 figcaption figure footer header hgroup main mark meter nav output progress section summary time video",version:"3.6.2",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,0 +1,744 @@
|
||||
/*!
|
||||
* imagesLoaded PACKAGED v3.0.2
|
||||
* JavaScript is all like "You images are done yet or what?"
|
||||
*/
|
||||
|
||||
/*!
|
||||
* EventEmitter v4.1.0 - git.io/ee
|
||||
* Oliver Caldwell
|
||||
* MIT license
|
||||
* @preserve
|
||||
*/
|
||||
|
||||
(function (exports) {
|
||||
// Place the script in strict mode
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Class for managing events.
|
||||
* Can be extended to provide event functionality in other classes.
|
||||
*
|
||||
* @class Manages event registering and emitting.
|
||||
*/
|
||||
function EventEmitter() {}
|
||||
|
||||
// Shortcuts to improve speed and size
|
||||
|
||||
// Easy access to the prototype
|
||||
var proto = EventEmitter.prototype,
|
||||
nativeIndexOf = Array.prototype.indexOf ? true : false;
|
||||
|
||||
/**
|
||||
* Finds the index of the listener for the event in it's storage array.
|
||||
*
|
||||
* @param {Function} listener Method to look for.
|
||||
* @param {Function[]} listeners Array of listeners to search through.
|
||||
* @return {Number} Index of the specified listener, -1 if not found
|
||||
* @api private
|
||||
*/
|
||||
function indexOfListener(listener, listeners) {
|
||||
// Return the index via the native method if possible
|
||||
if (nativeIndexOf) {
|
||||
return listeners.indexOf(listener);
|
||||
}
|
||||
|
||||
// There is no native method
|
||||
// Use a manual loop to find the index
|
||||
var i = listeners.length;
|
||||
while (i--) {
|
||||
// If the listener matches, return it's index
|
||||
if (listeners[i] === listener) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Default to returning -1
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the events object and creates one if required.
|
||||
*
|
||||
* @return {Object} The events storage object.
|
||||
* @api private
|
||||
*/
|
||||
proto._getEvents = function () {
|
||||
return this._events || (this._events = {});
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the listener array for the specified event.
|
||||
* Will initialise the event object and listener arrays if required.
|
||||
* Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
|
||||
* Each property in the object response is an array of listener functions.
|
||||
*
|
||||
* @param {String|RegExp} evt Name of the event to return the listeners from.
|
||||
* @return {Function[]|Object} All listener functions for the event.
|
||||
*/
|
||||
proto.getListeners = function (evt) {
|
||||
// Create a shortcut to the storage object
|
||||
// Initialise it if it does not exists yet
|
||||
var events = this._getEvents(),
|
||||
response,
|
||||
key;
|
||||
|
||||
// Return a concatenated array of all matching events if
|
||||
// the selector is a regular expression.
|
||||
if (typeof evt === 'object') {
|
||||
response = {};
|
||||
for (key in events) {
|
||||
if (events.hasOwnProperty(key) && evt.test(key)) {
|
||||
response[key] = events[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
response = events[evt] || (events[evt] = []);
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
|
||||
*
|
||||
* @param {String|RegExp} evt Name of the event to return the listeners from.
|
||||
* @return {Object} All listener functions for an event in an object.
|
||||
*/
|
||||
proto.getListenersAsObject = function (evt) {
|
||||
var listeners = this.getListeners(evt),
|
||||
response;
|
||||
|
||||
if (listeners instanceof Array) {
|
||||
response = {};
|
||||
response[evt] = listeners;
|
||||
}
|
||||
|
||||
return response || listeners;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a listener function to the specified event.
|
||||
* The listener will not be added if it is a duplicate.
|
||||
* If the listener returns true then it will be removed after it is called.
|
||||
* If you pass a regular expression as the event name then the listener will be added to all events that match it.
|
||||
*
|
||||
* @param {String|RegExp} evt Name of the event to attach the listener to.
|
||||
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.addListener = function (evt, listener) {
|
||||
var listeners = this.getListenersAsObject(evt),
|
||||
key;
|
||||
|
||||
for (key in listeners) {
|
||||
if (listeners.hasOwnProperty(key) &&
|
||||
indexOfListener(listener, listeners[key]) === -1) {
|
||||
listeners[key].push(listener);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the instance of EventEmitter to allow chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias of addListener
|
||||
*/
|
||||
proto.on = proto.addListener;
|
||||
|
||||
/**
|
||||
* Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
|
||||
* You need to tell it what event names should be matched by a regex.
|
||||
*
|
||||
* @param {String} evt Name of the event to create.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.defineEvent = function (evt) {
|
||||
this.getListeners(evt);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Uses defineEvent to define multiple events.
|
||||
*
|
||||
* @param {String[]} evts An array of event names to define.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.defineEvents = function (evts)
|
||||
{
|
||||
for (var i = 0; i < evts.length; i += 1) {
|
||||
this.defineEvent(evts[i]);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes a listener function from the specified event.
|
||||
* When passed a regular expression as the event name, it will remove the listener from all events that match it.
|
||||
*
|
||||
* @param {String|RegExp} evt Name of the event to remove the listener from.
|
||||
* @param {Function} listener Method to remove from the event.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.removeListener = function (evt, listener) {
|
||||
var listeners = this.getListenersAsObject(evt),
|
||||
index,
|
||||
key;
|
||||
|
||||
for (key in listeners) {
|
||||
if (listeners.hasOwnProperty(key)) {
|
||||
index = indexOfListener(listener, listeners[key]);
|
||||
|
||||
if (index !== -1) {
|
||||
listeners[key].splice(index, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the instance of EventEmitter to allow chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias of removeListener
|
||||
*/
|
||||
proto.off = proto.removeListener;
|
||||
|
||||
/**
|
||||
* Adds listeners in bulk using the manipulateListeners method.
|
||||
* If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
|
||||
* You can also pass it a regular expression to add the array of listeners to all events that match it.
|
||||
* Yeah, this function does quite a bit. That's probably a bad thing.
|
||||
*
|
||||
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
|
||||
* @param {Function[]} [listeners] An optional array of listener functions to add.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.addListeners = function (evt, listeners) {
|
||||
// Pass through to manipulateListeners
|
||||
return this.manipulateListeners(false, evt, listeners);
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes listeners in bulk using the manipulateListeners method.
|
||||
* If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
|
||||
* You can also pass it an event name and an array of listeners to be removed.
|
||||
* You can also pass it a regular expression to remove the listeners from all events that match it.
|
||||
*
|
||||
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
|
||||
* @param {Function[]} [listeners] An optional array of listener functions to remove.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.removeListeners = function (evt, listeners) {
|
||||
// Pass through to manipulateListeners
|
||||
return this.manipulateListeners(true, evt, listeners);
|
||||
};
|
||||
|
||||
/**
|
||||
* Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
|
||||
* The first argument will determine if the listeners are removed (true) or added (false).
|
||||
* If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
|
||||
* You can also pass it an event name and an array of listeners to be added/removed.
|
||||
* You can also pass it a regular expression to manipulate the listeners of all events that match it.
|
||||
*
|
||||
* @param {Boolean} remove True if you want to remove listeners, false if you want to add.
|
||||
* @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
|
||||
* @param {Function[]} [listeners] An optional array of listener functions to add/remove.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.manipulateListeners = function (remove, evt, listeners) {
|
||||
// Initialise any required variables
|
||||
var i,
|
||||
value,
|
||||
single = remove ? this.removeListener : this.addListener,
|
||||
multiple = remove ? this.removeListeners : this.addListeners;
|
||||
|
||||
// If evt is an object then pass each of it's properties to this method
|
||||
if (typeof evt === 'object' && !(evt instanceof RegExp)) {
|
||||
for (i in evt) {
|
||||
if (evt.hasOwnProperty(i) && (value = evt[i])) {
|
||||
// Pass the single listener straight through to the singular method
|
||||
if (typeof value === 'function') {
|
||||
single.call(this, i, value);
|
||||
}
|
||||
else {
|
||||
// Otherwise pass back to the multiple function
|
||||
multiple.call(this, i, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// So evt must be a string
|
||||
// And listeners must be an array of listeners
|
||||
// Loop over it and pass each one to the multiple method
|
||||
i = listeners.length;
|
||||
while (i--) {
|
||||
single.call(this, evt, listeners[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the instance of EventEmitter to allow chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Removes all listeners from a specified event.
|
||||
* If you do not specify an event then all listeners will be removed.
|
||||
* That means every event will be emptied.
|
||||
* You can also pass a regex to remove all events that match it.
|
||||
*
|
||||
* @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.removeEvent = function (evt) {
|
||||
var type = typeof evt,
|
||||
events = this._getEvents(),
|
||||
key;
|
||||
|
||||
// Remove different things depending on the state of evt
|
||||
if (type === 'string') {
|
||||
// Remove all listeners for the specified event
|
||||
delete events[evt];
|
||||
}
|
||||
else if (type === 'object') {
|
||||
// Remove all events matching the regex.
|
||||
for (key in events) {
|
||||
if (events.hasOwnProperty(key) && evt.test(key)) {
|
||||
delete events[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Remove all listeners in all events
|
||||
delete this._events;
|
||||
}
|
||||
|
||||
// Return the instance of EventEmitter to allow chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Emits an event of your choice.
|
||||
* When emitted, every listener attached to that event will be executed.
|
||||
* If you pass the optional argument array then those arguments will be passed to every listener upon execution.
|
||||
* Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
|
||||
* So they will not arrive within the array on the other side, they will be separate.
|
||||
* You can also pass a regular expression to emit to all events that match it.
|
||||
*
|
||||
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
|
||||
* @param {Array} [args] Optional array of arguments to be passed to each listener.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.emitEvent = function (evt, args) {
|
||||
var listeners = this.getListenersAsObject(evt),
|
||||
i,
|
||||
key,
|
||||
response;
|
||||
|
||||
for (key in listeners) {
|
||||
if (listeners.hasOwnProperty(key)) {
|
||||
i = listeners[key].length;
|
||||
|
||||
while (i--) {
|
||||
// If the listener returns true then it shall be removed from the event
|
||||
// The function is executed either with a basic call or an apply if there is an args array
|
||||
response = args ? listeners[key][i].apply(null, args) : listeners[key][i]();
|
||||
if (response === true) {
|
||||
this.removeListener(evt, listeners[key][i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the instance of EventEmitter to allow chaining
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Alias of emitEvent
|
||||
*/
|
||||
proto.trigger = proto.emitEvent;
|
||||
|
||||
/**
|
||||
* Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
|
||||
* As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
|
||||
*
|
||||
* @param {String|RegExp} evt Name of the event to emit and execute listeners for.
|
||||
* @param {...*} Optional additional arguments to be passed to each listener.
|
||||
* @return {Object} Current instance of EventEmitter for chaining.
|
||||
*/
|
||||
proto.emit = function (evt) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
return this.emitEvent(evt, args);
|
||||
};
|
||||
|
||||
// Expose the class either via AMD or the global object
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(function () {
|
||||
return EventEmitter;
|
||||
});
|
||||
}
|
||||
else {
|
||||
exports.EventEmitter = EventEmitter;
|
||||
}
|
||||
}(this));
|
||||
/*!
|
||||
* eventie v1.0.3
|
||||
* event binding helper
|
||||
* eventie.bind( elem, 'click', myFn )
|
||||
* eventie.unbind( elem, 'click', myFn )
|
||||
*/
|
||||
|
||||
/*jshint browser: true, undef: true, unused: true */
|
||||
/*global define: false */
|
||||
|
||||
( function( window ) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var docElem = document.documentElement;
|
||||
|
||||
var bind = function() {};
|
||||
|
||||
if ( docElem.addEventListener ) {
|
||||
bind = function( obj, type, fn ) {
|
||||
obj.addEventListener( type, fn, false );
|
||||
};
|
||||
} else if ( docElem.attachEvent ) {
|
||||
bind = function( obj, type, fn ) {
|
||||
obj[ type + fn ] = fn.handleEvent ?
|
||||
function() {
|
||||
var event = window.event;
|
||||
// add event.target
|
||||
event.target = event.target || event.srcElement;
|
||||
fn.handleEvent.call( fn, event );
|
||||
} :
|
||||
function() {
|
||||
var event = window.event;
|
||||
// add event.target
|
||||
event.target = event.target || event.srcElement;
|
||||
fn.call( obj, event );
|
||||
};
|
||||
obj.attachEvent( "on" + type, obj[ type + fn ] );
|
||||
};
|
||||
}
|
||||
|
||||
var unbind = function() {};
|
||||
|
||||
if ( docElem.removeEventListener ) {
|
||||
unbind = function( obj, type, fn ) {
|
||||
obj.removeEventListener( type, fn, false );
|
||||
};
|
||||
} else if ( docElem.detachEvent ) {
|
||||
unbind = function( obj, type, fn ) {
|
||||
obj.detachEvent( "on" + type, obj[ type + fn ] );
|
||||
try {
|
||||
delete obj[ type + fn ];
|
||||
} catch ( err ) {
|
||||
// can't delete window object properties
|
||||
obj[ type + fn ] = undefined;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
var eventie = {
|
||||
bind: bind,
|
||||
unbind: unbind
|
||||
};
|
||||
|
||||
// transport
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( eventie );
|
||||
} else {
|
||||
// browser global
|
||||
window.eventie = eventie;
|
||||
}
|
||||
|
||||
})( this );
|
||||
|
||||
/*!
|
||||
* imagesLoaded v3.0.2
|
||||
* JavaScript is all like "You images are done yet or what?"
|
||||
*/
|
||||
|
||||
( function( window ) {
|
||||
|
||||
'use strict';
|
||||
|
||||
var $ = window.jQuery;
|
||||
var console = window.console;
|
||||
var hasConsole = typeof console !== 'undefined';
|
||||
|
||||
// -------------------------- helpers -------------------------- //
|
||||
|
||||
// extend objects
|
||||
function extend( a, b ) {
|
||||
for ( var prop in b ) {
|
||||
a[ prop ] = b[ prop ];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
var objToString = Object.prototype.toString;
|
||||
function isArray( obj ) {
|
||||
return objToString.call( obj ) === '[object Array]';
|
||||
}
|
||||
|
||||
// turn element or nodeList into an array
|
||||
function makeArray( obj ) {
|
||||
var ary = [];
|
||||
if ( isArray( obj ) ) {
|
||||
// use object if already an array
|
||||
ary = obj;
|
||||
} else if ( typeof obj.length === 'number' ) {
|
||||
// convert nodeList to array
|
||||
for ( var i=0, len = obj.length; i < len; i++ ) {
|
||||
ary.push( obj[i] );
|
||||
}
|
||||
} else {
|
||||
// array of single index
|
||||
ary.push( obj );
|
||||
}
|
||||
return ary;
|
||||
}
|
||||
|
||||
// -------------------------- -------------------------- //
|
||||
|
||||
function defineImagesLoaded( EventEmitter, eventie ) {
|
||||
|
||||
/**
|
||||
* @param {Array, Element, NodeList, String} elem
|
||||
* @param {Object or Function} options - if function, use as callback
|
||||
* @param {Function} onAlways - callback function
|
||||
*/
|
||||
function ImagesLoaded( elem, options, onAlways ) {
|
||||
// coerce ImagesLoaded() without new, to be new ImagesLoaded()
|
||||
if ( !( this instanceof ImagesLoaded ) ) {
|
||||
return new ImagesLoaded( elem, options );
|
||||
}
|
||||
// use elem as selector string
|
||||
if ( typeof elem === 'string' ) {
|
||||
elem = document.querySelectorAll( elem );
|
||||
}
|
||||
|
||||
this.elements = makeArray( elem );
|
||||
this.options = extend( {}, this.options );
|
||||
|
||||
if ( typeof options === 'function' ) {
|
||||
onAlways = options;
|
||||
} else {
|
||||
extend( this.options, options );
|
||||
}
|
||||
|
||||
if ( onAlways ) {
|
||||
this.on( 'always', onAlways );
|
||||
}
|
||||
|
||||
this.getImages();
|
||||
|
||||
if ( $ ) {
|
||||
// add jQuery Deferred object
|
||||
this.jqDeferred = new $.Deferred();
|
||||
}
|
||||
|
||||
// HACK check async to allow time to bind listeners
|
||||
var _this = this;
|
||||
setTimeout( function() {
|
||||
_this.check();
|
||||
});
|
||||
}
|
||||
|
||||
ImagesLoaded.prototype = new EventEmitter();
|
||||
|
||||
ImagesLoaded.prototype.options = {};
|
||||
|
||||
ImagesLoaded.prototype.getImages = function() {
|
||||
this.images = [];
|
||||
|
||||
// filter & find items if we have an item selector
|
||||
for ( var i=0, len = this.elements.length; i < len; i++ ) {
|
||||
var elem = this.elements[i];
|
||||
// filter siblings
|
||||
if ( elem.nodeName === 'IMG' ) {
|
||||
this.addImage( elem );
|
||||
}
|
||||
// find children
|
||||
var childElems = elem.querySelectorAll('img');
|
||||
// concat childElems to filterFound array
|
||||
for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
|
||||
var img = childElems[j];
|
||||
this.addImage( img );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Image} img
|
||||
*/
|
||||
ImagesLoaded.prototype.addImage = function( img ) {
|
||||
var loadingImage = new LoadingImage( img );
|
||||
this.images.push( loadingImage );
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.check = function() {
|
||||
var _this = this;
|
||||
var checkedCount = 0;
|
||||
var length = this.images.length;
|
||||
this.hasAnyBroken = false;
|
||||
// complete if no images
|
||||
if ( !length ) {
|
||||
this.complete();
|
||||
return;
|
||||
}
|
||||
|
||||
function onConfirm( image, message ) {
|
||||
if ( _this.options.debug && hasConsole ) {
|
||||
console.log( 'confirm', image, message );
|
||||
}
|
||||
|
||||
_this.progress( image );
|
||||
checkedCount++;
|
||||
if ( checkedCount === length ) {
|
||||
_this.complete();
|
||||
}
|
||||
return true; // bind once
|
||||
}
|
||||
|
||||
for ( var i=0; i < length; i++ ) {
|
||||
var loadingImage = this.images[i];
|
||||
loadingImage.on( 'confirm', onConfirm );
|
||||
loadingImage.check();
|
||||
}
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.progress = function( image ) {
|
||||
this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
|
||||
this.emit( 'progress', this, image );
|
||||
if ( this.jqDeferred ) {
|
||||
this.jqDeferred.notify( this, image );
|
||||
}
|
||||
};
|
||||
|
||||
ImagesLoaded.prototype.complete = function() {
|
||||
var eventName = this.hasAnyBroken ? 'fail' : 'done';
|
||||
this.isComplete = true;
|
||||
this.emit( eventName, this );
|
||||
this.emit( 'always', this );
|
||||
if ( this.jqDeferred ) {
|
||||
var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
|
||||
this.jqDeferred[ jqMethod ]( this );
|
||||
}
|
||||
};
|
||||
|
||||
// -------------------------- jquery -------------------------- //
|
||||
|
||||
if ( $ ) {
|
||||
$.fn.imagesLoaded = function( options, callback ) {
|
||||
var instance = new ImagesLoaded( this, options, callback );
|
||||
return instance.jqDeferred.promise( $(this) );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// -------------------------- -------------------------- //
|
||||
|
||||
var cache = {};
|
||||
|
||||
function LoadingImage( img ) {
|
||||
this.img = img;
|
||||
}
|
||||
|
||||
LoadingImage.prototype = new EventEmitter();
|
||||
|
||||
LoadingImage.prototype.check = function() {
|
||||
// first check cached any previous images that have same src
|
||||
var cached = cache[ this.img.src ];
|
||||
if ( cached ) {
|
||||
this.useCached( cached );
|
||||
return;
|
||||
}
|
||||
// add this to cache
|
||||
cache[ this.img.src ] = this;
|
||||
|
||||
// If complete is true and browser supports natural sizes,
|
||||
// try to check for image status manually.
|
||||
if ( this.img.complete && this.img.naturalWidth !== undefined ) {
|
||||
// report based on naturalWidth
|
||||
this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
|
||||
return;
|
||||
}
|
||||
|
||||
// If none of the checks above matched, simulate loading on detached element.
|
||||
var proxyImage = this.proxyImage = new Image();
|
||||
eventie.bind( proxyImage, 'load', this );
|
||||
eventie.bind( proxyImage, 'error', this );
|
||||
proxyImage.src = this.img.src;
|
||||
};
|
||||
|
||||
LoadingImage.prototype.useCached = function( cached ) {
|
||||
if ( cached.isConfirmed ) {
|
||||
this.confirm( cached.isLoaded, 'cached was confirmed' );
|
||||
} else {
|
||||
var _this = this;
|
||||
cached.on( 'confirm', function( image ) {
|
||||
_this.confirm( image.isLoaded, 'cache emitted confirmed' );
|
||||
return true; // bind once
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
LoadingImage.prototype.confirm = function( isLoaded, message ) {
|
||||
this.isConfirmed = true;
|
||||
this.isLoaded = isLoaded;
|
||||
this.emit( 'confirm', this, message );
|
||||
};
|
||||
|
||||
// trigger specified handler for event type
|
||||
LoadingImage.prototype.handleEvent = function( event ) {
|
||||
var method = 'on' + event.type;
|
||||
if ( this[ method ] ) {
|
||||
this[ method ]( event );
|
||||
}
|
||||
};
|
||||
|
||||
LoadingImage.prototype.onload = function() {
|
||||
this.confirm( true, 'onload' );
|
||||
this.unbindProxyEvents();
|
||||
};
|
||||
|
||||
LoadingImage.prototype.onerror = function() {
|
||||
this.confirm( false, 'onerror' );
|
||||
this.unbindProxyEvents();
|
||||
};
|
||||
|
||||
LoadingImage.prototype.unbindProxyEvents = function() {
|
||||
eventie.unbind( this.proxyImage, 'load', this );
|
||||
eventie.unbind( this.proxyImage, 'error', this );
|
||||
};
|
||||
|
||||
// ----- ----- //
|
||||
|
||||
return ImagesLoaded;
|
||||
}
|
||||
|
||||
// -------------------------- transport -------------------------- //
|
||||
|
||||
if ( typeof define === 'function' && define.amd ) {
|
||||
// AMD
|
||||
define( [
|
||||
'eventEmitter',
|
||||
'eventie'
|
||||
],
|
||||
defineImagesLoaded );
|
||||
} else {
|
||||
// browser global
|
||||
window.imagesLoaded = defineImagesLoaded(
|
||||
window.EventEmitter,
|
||||
window.eventie
|
||||
);
|
||||
}
|
||||
|
||||
})( window );
|
@ -1,489 +0,0 @@
|
||||
// IMPORTANT!
|
||||
// If you're already using Modernizr, delete it from this file. If you don't know what Modernizr is, leave it :)
|
||||
|
||||
/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
|
||||
* Build: http://modernizr.com/download/#-csstransforms-csstransforms3d-csstransitions-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
|
||||
*/
|
||||
;window.Modernizr=function(a,b,c){function y(a){i.cssText=a}function z(a,b){return y(l.join(a+";")+(b||""))}function A(a,b){return typeof a===b}function B(a,b){return!!~(""+a).indexOf(b)}function C(a,b){for(var d in a){var e=a[d];if(!B(e,"-")&&i[e]!==c)return b=="pfx"?e:!0}return!1}function D(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:A(f,"function")?f.bind(d||b):f}return!1}function E(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return A(b,"string")||A(b,"undefined")?C(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),D(e,b,c))}var d="2.6.2",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j,k={}.toString,l=" -webkit- -moz- -o- -ms- ".split(" "),m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},q={},r={},s=[],t=s.slice,u,v=function(a,c,d,e){var h,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:g+(d+1),l.appendChild(j);return h=["­",'<style id="s',g,'">',a,"</style>"].join(""),l.id=g,(m?l:n).innerHTML+=h,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=f.style.overflow,f.style.overflow="hidden",f.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),f.style.overflow=k),!!i},w={}.hasOwnProperty,x;!A(w,"undefined")&&!A(w.call,"undefined")?x=function(a,b){return w.call(a,b)}:x=function(a,b){return b in a&&A(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.csstransforms=function(){return!!E("transform")},p.csstransforms3d=function(){var a=!!E("perspective");return a&&"webkitPerspective"in f.style&&v("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},p.csstransitions=function(){return E("transition")};for(var F in p)x(p,F)&&(u=F.toLowerCase(),e[u]=p[F](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)x(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof enableClasses!="undefined"&&enableClasses&&(f.className+=" "+(b?"":"no-")+a),e[a]=b}return e},y(""),h=j=null,e._version=d,e._prefixes=l,e._domPrefixes=o,e._cssomPrefixes=n,e.testProp=function(a){return C([a])},e.testAllProps=E,e.testStyles=v,e.prefixed=function(a,b,c){return b?E(a,b,c):E(a,"pfx")},e}(this,this.document);
|
||||
|
||||
/**
|
||||
* jQuery Shuffle Plugin
|
||||
* Uses CSS Transforms to filter down a grid of items (degrades to jQuery's animate).
|
||||
* Inspired by Isotope http://isotope.metafizzy.co/
|
||||
* Use it for whatever you want!
|
||||
* @author Glen Cheney (http://glencheney.com)
|
||||
* @version 1.5.2
|
||||
* @date 10/24/12
|
||||
*/
|
||||
;(function($, Modernizr) {
|
||||
'use strict';
|
||||
|
||||
|
||||
$.fn.sorted = function(options) {
|
||||
var opts = $.extend({}, $.fn.sorted.defaults, options),
|
||||
arr = this.get();
|
||||
|
||||
// Sort the elements by the opts.by function.
|
||||
// If we don't have opts.by, default to DOM order
|
||||
if (opts.by !== $.noop && opts.by !== null && opts.by !== undefined) {
|
||||
arr.sort(function(a, b) {
|
||||
var valA = opts.by($(a));
|
||||
var valB = opts.by($(b));
|
||||
return (valA < valB) ? -1 : (valA > valB) ? 1 : 0;
|
||||
});
|
||||
}
|
||||
|
||||
if (opts.reverse) {
|
||||
arr.reverse();
|
||||
}
|
||||
return arr;
|
||||
|
||||
};
|
||||
|
||||
$.fn.sorted.defaults = {
|
||||
reverse: false,
|
||||
by: null
|
||||
};
|
||||
|
||||
var Shuffle = function($container, options) {
|
||||
var self = this;
|
||||
|
||||
$.extend(self, $.fn.shuffle.options, options, $.fn.shuffle.settings);
|
||||
|
||||
self.$container = $container;
|
||||
self.$items = self.$container.children();
|
||||
self.$item = self.$items.first();
|
||||
self.marginTop = parseInt(self.$item.css('marginTop'), 10);
|
||||
self.marginRight = parseInt(self.$item.css('marginRight'), 10);
|
||||
self.transitionName = self.prefixed('transition'),
|
||||
self.transform = self.getPrefixed('transform');
|
||||
|
||||
// Get transitionend event name
|
||||
var transEndEventNames = {
|
||||
'WebkitTransition' : 'webkitTransitionEnd',
|
||||
'MozTransition' : 'transitionend',
|
||||
'OTransition' : 'oTransitionEnd',
|
||||
'msTransition' : 'MSTransitionEnd',
|
||||
'transition' : 'transitionend'
|
||||
};
|
||||
self.transitionEndName = transEndEventNames[ self.transitionName ];
|
||||
|
||||
// CSS for each item
|
||||
self.itemCss = {
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
opacity: 1
|
||||
};
|
||||
|
||||
// Set up css for transitions
|
||||
self.$container.css('position', 'relative').get(0).style[self.transitionName] = 'height ' + self.speed + 'ms ' + self.easing;
|
||||
self.$items.each(function() {
|
||||
$(this).css(self.itemCss);
|
||||
|
||||
// Set CSS transition for transforms and opacity
|
||||
if (self.supported) {
|
||||
this.style[self.transitionName] = self.transform + ' ' + self.speed + 'ms ' + self.easing + ', opacity ' + self.speed + 'ms ' + self.easing;
|
||||
}
|
||||
|
||||
// Remove margins, we don't need them anymore
|
||||
this.style.marginTop = 0;
|
||||
this.style.marginRight = 0;
|
||||
});
|
||||
|
||||
// Get dimensions of the first item and items per row
|
||||
self.itemWidth = self.$item.outerWidth();
|
||||
self.itemHeight = self.$item.outerHeight();
|
||||
self.itemsPerRow = self.getItemsPerRow();
|
||||
|
||||
// http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer
|
||||
self.windowHeight = $(window).height();
|
||||
self.windowWidth = $(window).width();
|
||||
$(window).on('resize.shuffle', function () {
|
||||
var height = $(window).height(),
|
||||
width = $(window).width();
|
||||
|
||||
if (width !== self.windowWidth || height !== self.windowHeight) {
|
||||
self.resized();
|
||||
self.windowHeight = height;
|
||||
self.windowWidth = width;
|
||||
}
|
||||
});
|
||||
|
||||
// If our calculated values are 0 (maybe images haven't loaded), wait until window load
|
||||
if (self.itemWidth === 0 || self.itemHeight === 0) {
|
||||
$(window).on('load.shuffle', function() {
|
||||
self.itemWidth = self.$item.outerWidth();
|
||||
self.itemHeight = self.$item.outerHeight();
|
||||
self.itemsPerRow = self.getItemsPerRow();
|
||||
self.shuffle(self.group);
|
||||
})
|
||||
} else {
|
||||
self.shuffle(self.group);
|
||||
}
|
||||
};
|
||||
|
||||
Shuffle.prototype = {
|
||||
|
||||
constructor: Shuffle,
|
||||
|
||||
/**
|
||||
* The magic. This is what makes the plugin 'shuffle'
|
||||
*/
|
||||
shuffle : function(category) {
|
||||
var self = this;
|
||||
|
||||
if (!category) {
|
||||
category = 'all';
|
||||
}
|
||||
|
||||
// Default is to show all items
|
||||
self.$items.removeClass('concealed filtered');
|
||||
|
||||
// Loop through each item and use provided function to determine
|
||||
// whether to hide it or not.
|
||||
if ($.isFunction(category)) {
|
||||
self.$items.each(function() {
|
||||
var $item = $(this);
|
||||
$item.addClass(category($item, self) ? 'filtered' : 'concealed');
|
||||
});
|
||||
}
|
||||
|
||||
// Otherwise we've been passed a category to filter by
|
||||
else {
|
||||
self.group = category;
|
||||
if (category !== 'all') {
|
||||
self.$items.each(function() {
|
||||
var keys = $(this).data('groups');
|
||||
if ($.inArray(category, keys) === -1) {
|
||||
$(this).addClass('concealed');
|
||||
return;
|
||||
} else {
|
||||
$(this).addClass('filtered');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// category === all, add filtered class to everything
|
||||
else {
|
||||
self.$items.addClass('filtered');
|
||||
}
|
||||
}
|
||||
|
||||
// How many filtered elements?
|
||||
self.visibleItems = self.$items.filter('.filtered').length;
|
||||
|
||||
// Shrink each concealed item
|
||||
self.fire('shrink');
|
||||
self.shrink();
|
||||
|
||||
// Update transforms on .filtered elements so they will animate to their new positions
|
||||
self.fire('filter');
|
||||
self.filter();
|
||||
|
||||
// Adjust the height of the container
|
||||
self.resizeContainer();
|
||||
},
|
||||
|
||||
getItemsPerRow : function() {
|
||||
var self = this,
|
||||
totalWidth = self.$container.width(),
|
||||
num = Math.floor(totalWidth / self.itemWidth);
|
||||
|
||||
// Make sure the items will fit with margins too
|
||||
if (num * (self.itemWidth + self.marginRight) - self.marginRight > totalWidth) {
|
||||
num -= 1;
|
||||
}
|
||||
|
||||
return num;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adjust the height of the grid
|
||||
*/
|
||||
resizeContainer : function() {
|
||||
var self = this,
|
||||
gridHeight = (Math.ceil(self.visibleItems / self.itemsPerRow) * (self.itemHeight + self.marginTop)) - self.marginTop;
|
||||
self.$container.css('height', gridHeight + 'px');
|
||||
},
|
||||
|
||||
/**
|
||||
* Fire events with .shuffle namespace
|
||||
*/
|
||||
fire : function(name) {
|
||||
this.$container.trigger(name + '.shuffle', [this]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides the elements that don't match our filter
|
||||
*/
|
||||
shrink : function() {
|
||||
var self = this,
|
||||
$concealed = self.$items.filter('.concealed');
|
||||
|
||||
// Abort if no items
|
||||
if ($concealed.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.shrinkTransitionEnded = false;
|
||||
$concealed.each(function() {
|
||||
var $this = $(this),
|
||||
x = parseInt($this.attr('data-x'), 10),
|
||||
y = parseInt($this.attr('data-y'), 10);
|
||||
|
||||
if (!x) x = 0;
|
||||
if (!y) y = 0;
|
||||
|
||||
self.transition({
|
||||
from: 'shrink',
|
||||
$this: $this,
|
||||
x: x,
|
||||
y: y,
|
||||
left: (x + (self.itemWidth / 2)) + 'px',
|
||||
top: (y + (self.itemHeight / 2)) + 'px',
|
||||
scale : 0.001,
|
||||
opacity: 0,
|
||||
height: '0px',
|
||||
width: '0px',
|
||||
callback: self.shrinkEnd
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Loops through each item that should be shown
|
||||
* Calculates the x and y position and then transitions it
|
||||
* @param {array} items - array of items that will be shown/layed out in order in their array.
|
||||
* Because jQuery collection are always ordered in DOM order, we can't pass a jq collection
|
||||
* @param {function} complete callback function
|
||||
*/
|
||||
layout: function(items, fn) {
|
||||
var self = this,
|
||||
y = 0;
|
||||
|
||||
// Abort if no items
|
||||
if (items.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.layoutTransitionEnded = false;
|
||||
$.each(items, function(index) {
|
||||
var $this = $(items[index]),
|
||||
x = (index % self.itemsPerRow) * (self.itemWidth + self.marginRight),
|
||||
row = Math.floor(index / self.itemsPerRow);
|
||||
|
||||
if (index % self.itemsPerRow === 0) {
|
||||
y = row * (self.itemHeight + self.marginTop);
|
||||
}
|
||||
|
||||
// Save data for shrink
|
||||
$this.attr({'data-x' : x, 'data-y' : y});
|
||||
|
||||
self.transition({
|
||||
from: 'layout',
|
||||
$this: $this,
|
||||
x: x,
|
||||
y: y,
|
||||
left: x + 'px',
|
||||
top: y + 'px',
|
||||
scale : 1,
|
||||
opacity: 1,
|
||||
height: self.itemHeight + 'px',
|
||||
width: self.itemWidth + 'px',
|
||||
callback: fn
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Grabs the .filtered elements and passes them to layout
|
||||
*/
|
||||
filter : function() {
|
||||
var self = this;
|
||||
// If we've already sorted the elements, keep them sorted
|
||||
if (self.keepSorted && self.lastSort) {
|
||||
self.sort(self.lastSort, true);
|
||||
} else {
|
||||
var items = self.$items.filter('.filtered').get();
|
||||
self.layout(items, self.filterEnd);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the .filtered elements, sorts them, and passes them to layout
|
||||
*
|
||||
* @param {object} opts the options object for the sorted plugin
|
||||
* @param {bool} [fromFilter] was called from Shuffle.filter method.
|
||||
*/
|
||||
sort: function(opts, fromFilter) {
|
||||
var self = this,
|
||||
items = self.$items.filter('.filtered').sorted(opts);
|
||||
self.layout(items, function() {
|
||||
if (fromFilter) {
|
||||
self.filterEnd();
|
||||
}
|
||||
self.sortEnd();
|
||||
});
|
||||
self.lastSort = opts;
|
||||
},
|
||||
|
||||
/**
|
||||
* Uses Modernizr's prefixed() to get the correct vendor property name and sets it using jQuery .css()
|
||||
*
|
||||
* @param {jq} $el the jquery object to set the css on
|
||||
* @param {string} prop the property to set (e.g. 'transition')
|
||||
* @param {string} value the value of the prop
|
||||
*/
|
||||
setPrefixedCss : function($el, prop, value) {
|
||||
$el.css(this.prefixed(prop), value);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Returns things like -webkit-transition or -moz-box-sizing
|
||||
*
|
||||
* @param {string} property to be prefixed.
|
||||
* @return {string} the prefixed css property
|
||||
*/
|
||||
getPrefixed : function(prop) {
|
||||
var styleName = this.prefixed(prop);
|
||||
return styleName ? styleName.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-') : styleName;
|
||||
},
|
||||
|
||||
/**
|
||||
* Transitions an item in the grid
|
||||
*
|
||||
* @param {object} opts options
|
||||
* @param {jQuery} opts.$this jQuery object representing the current item
|
||||
* @param {int} opts.x translate's x
|
||||
* @param {int} opts.y translate's y
|
||||
* @param {String} opts.left left position (used when no transforms available)
|
||||
* @param {String} opts.top top position (used when no transforms available)
|
||||
* @param {float} opts.scale amount to scale the item
|
||||
* @param {float} opts.opacity opacity of the item
|
||||
* @param {String} opts.height the height of the item (used when no transforms available)
|
||||
* @param {String} opts.width the width of the item (used when no transforms available)
|
||||
* @param {function} opts.callback complete function for the animation
|
||||
*/
|
||||
transition: function(opts) {
|
||||
var self = this,
|
||||
transform,
|
||||
|
||||
// Only fire callback once per collection's transition
|
||||
complete = function() {
|
||||
if (!self.layoutTransitionEnded && opts.from === 'layout') {
|
||||
opts.callback.call(self);
|
||||
self.layoutTransitionEnded = true;
|
||||
} else if (!self.shrinkTransitionEnded && opts.from === 'shrink') {
|
||||
opts.callback.call(self);
|
||||
self.shrinkTransitionEnded = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Use CSS Transforms if we have them
|
||||
if (self.supported) {
|
||||
if (self.threeD) {
|
||||
transform = 'translate3d(' + opts.x + 'px, ' + opts.y + 'px, 0) scale3d(' + opts.scale + ', ' + opts.scale + ', 1)';
|
||||
} else {
|
||||
transform = 'translate(' + opts.x + 'px, ' + opts.y + 'px) scale(' + opts.scale + ', ' + opts.scale + ')';
|
||||
}
|
||||
|
||||
// Update css to trigger CSS Animation
|
||||
opts.$this.css('opacity' , opts.opacity);
|
||||
self.setPrefixedCss(opts.$this, 'transform', transform);
|
||||
opts.$this.one(self.transitionEndName, complete);
|
||||
} else {
|
||||
// Use jQuery to animate left/top
|
||||
opts.$this.stop().animate({
|
||||
left: opts.left,
|
||||
top: opts.top,
|
||||
opacity: opts.opacity,
|
||||
height: opts.height,
|
||||
width: opts.width
|
||||
}, self.speed, 'swing', complete);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* On window resize, recalculate the width, height, and items per row.
|
||||
*/
|
||||
resized: function() {
|
||||
var self = this;
|
||||
self.itemWidth = self.$items.filter('.filtered').outerWidth();
|
||||
self.itemHeight = self.$items.filter('.filtered').outerHeight();
|
||||
self.itemsPerRow = self.getItemsPerRow();
|
||||
self.filter();
|
||||
self.resizeContainer();
|
||||
},
|
||||
|
||||
shrinkEnd: function() {
|
||||
this.fire('shrunk');
|
||||
},
|
||||
|
||||
filterEnd: function() {
|
||||
this.fire('filtered');
|
||||
},
|
||||
|
||||
sortEnd: function() {
|
||||
this.fire('sorted');
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
var self = this;
|
||||
|
||||
self.$container.removeAttr('style').removeData('shuffle');
|
||||
$(window).off('.shuffle');
|
||||
self.$items.removeAttr('style data-y data-x').removeClass('concealed filtered');
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// Plugin definition
|
||||
$.fn.shuffle = function(opts, sortObj) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
shuffle = $this.data('shuffle');
|
||||
|
||||
// If we don't have a stored shuffle, make a new one and save it
|
||||
if (!shuffle) {
|
||||
shuffle = new Shuffle($this, opts);
|
||||
$this.data('shuffle', shuffle);
|
||||
}
|
||||
|
||||
// If passed a string, lets decide what to do with it. Or they've provided a function to filter by
|
||||
if ($.isFunction(opts)) {
|
||||
shuffle.shuffle(opts);
|
||||
|
||||
// Key should be an object with propreties reversed and by.
|
||||
} else if (typeof opts === 'string') {
|
||||
if (opts === 'sort') {
|
||||
shuffle.sort(sortObj);
|
||||
} else if (opts === 'destroy') {
|
||||
shuffle.destroy();
|
||||
} else {
|
||||
shuffle.shuffle(opts);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Overrideable options
|
||||
$.fn.shuffle.options = {
|
||||
group : 'all',
|
||||
speed : 800,
|
||||
easing : 'ease-out',
|
||||
keepSorted: true
|
||||
};
|
||||
|
||||
// Not overrideable
|
||||
$.fn.shuffle.settings = {
|
||||
supported: Modernizr.csstransforms && Modernizr.csstransitions,
|
||||
prefixed: Modernizr.prefixed,
|
||||
threeD: Modernizr.csstransforms3d
|
||||
};
|
||||
|
||||
})(jQuery, Modernizr);
|
@ -1,28 +0,0 @@
|
||||
// IMPORTANT!
|
||||
// If you're already using Modernizr, delete it from this file. If you don't know what Modernizr is, leave it :)
|
||||
|
||||
/* Modernizr 2.6.2 (Custom Build) | MIT & BSD
|
||||
* Build: http://modernizr.com/download/#-csstransforms-csstransforms3d-csstransitions-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes
|
||||
*/
|
||||
;window.Modernizr=function(a,b,c){function y(a){i.cssText=a}function z(a,b){return y(l.join(a+";")+(b||""))}function A(a,b){return typeof a===b}function B(a,b){return!!~(""+a).indexOf(b)}function C(a,b){for(var d in a){var e=a[d];if(!B(e,"-")&&i[e]!==c)return b=="pfx"?e:!0}return!1}function D(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:A(f,"function")?f.bind(d||b):f}return!1}function E(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return A(b,"string")||A(b,"undefined")?C(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),D(e,b,c))}var d="2.6.2",e={},f=b.documentElement,g="modernizr",h=b.createElement(g),i=h.style,j,k={}.toString,l=" -webkit- -moz- -o- -ms- ".split(" "),m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},q={},r={},s=[],t=s.slice,u,v=function(a,c,d,e){var h,i,j,k,l=b.createElement("div"),m=b.body,n=m||b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:g+(d+1),l.appendChild(j);return h=["­",'<style id="s',g,'">',a,"</style>"].join(""),l.id=g,(m?l:n).innerHTML+=h,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=f.style.overflow,f.style.overflow="hidden",f.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),f.style.overflow=k),!!i},w={}.hasOwnProperty,x;!A(w,"undefined")&&!A(w.call,"undefined")?x=function(a,b){return w.call(a,b)}:x=function(a,b){return b in a&&A(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e}),p.csstransforms=function(){return!!E("transform")},p.csstransforms3d=function(){var a=!!E("perspective");return a&&"webkitPerspective"in f.style&&v("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},p.csstransitions=function(){return E("transition")};for(var F in p)x(p,F)&&(u=F.toLowerCase(),e[u]=p[F](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)x(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof enableClasses!="undefined"&&enableClasses&&(f.className+=" "+(b?"":"no-")+a),e[a]=b}return e},y(""),h=j=null,e._version=d,e._prefixes=l,e._domPrefixes=o,e._cssomPrefixes=n,e.testProp=function(a){return C([a])},e.testAllProps=E,e.testStyles=v,e.prefixed=function(a,b,c){return b?E(a,b,c):E(a,"pfx")},e}(this,this.document);
|
||||
|
||||
/**
|
||||
* jQuery Shuffle Plugin
|
||||
* Uses CSS Transforms to filter down a grid of items (degrades to jQuery's animate).
|
||||
* Inspired by Isotope http://isotope.metafizzy.co/
|
||||
* Use it for whatever you want!
|
||||
* @author Glen Cheney (http://glencheney.com)
|
||||
* @version 1.5.2
|
||||
* @date 10/24/12
|
||||
*/
|
||||
;(function(d,g){d.fn.sorted=function(b){var c=d.extend({},d.fn.sorted.defaults,b),b=this.get();c.by!==d.noop&&(null!==c.by&&void 0!==c.by)&&b.sort(function(a,b){var f=c.by(d(a)),h=c.by(d(b));return f<h?-1:f>h?1:0});c.reverse&&b.reverse();return b};d.fn.sorted.defaults={reverse:!1,by:null};var i=function(b,c){var a=this;d.extend(a,d.fn.shuffle.options,c,d.fn.shuffle.settings);a.$container=b;a.$items=a.$container.children();a.$item=a.$items.first();a.marginTop=parseInt(a.$item.css("marginTop"),10);a.marginRight=
|
||||
parseInt(a.$item.css("marginRight"),10);a.transitionName=a.prefixed("transition");a.transform=a.getPrefixed("transform");a.transitionEndName={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd",msTransition:"MSTransitionEnd",transition:"transitionend"}[a.transitionName];a.itemCss={position:"absolute",top:0,left:0,opacity:1};a.$container.css("position","relative").get(0).style[a.transitionName]="height "+a.speed+"ms "+a.easing;a.$items.each(function(){d(this).css(a.itemCss);
|
||||
a.supported&&(this.style[a.transitionName]=a.transform+" "+a.speed+"ms "+a.easing+", opacity "+a.speed+"ms "+a.easing);this.style.marginTop=0;this.style.marginRight=0});a.itemWidth=a.$item.outerWidth();a.itemHeight=a.$item.outerHeight();a.itemsPerRow=a.getItemsPerRow();a.windowHeight=d(window).height();a.windowWidth=d(window).width();d(window).on("resize.shuffle",function(){var b=d(window).height(),c=d(window).width();if(c!==a.windowWidth||b!==a.windowHeight)a.resized(),a.windowHeight=b,a.windowWidth=
|
||||
c});if(0===a.itemWidth||0===a.itemHeight)d(window).on("load.shuffle",function(){a.itemWidth=a.$item.outerWidth();a.itemHeight=a.$item.outerHeight();a.itemsPerRow=a.getItemsPerRow();a.shuffle(a.group)});else a.shuffle(a.group)};i.prototype={constructor:i,shuffle:function(b){var c=this;b||(b="all");c.$items.removeClass("concealed filtered");d.isFunction(b)?c.$items.each(function(){var a=d(this);a.addClass(b(a,c)?"filtered":"concealed")}):(c.group=b,"all"!==b?c.$items.each(function(){var a=d(this).data("groups");
|
||||
-1===d.inArray(b,a)?d(this).addClass("concealed"):d(this).addClass("filtered")}):c.$items.addClass("filtered"));c.visibleItems=c.$items.filter(".filtered").length;c.fire("shrink");c.shrink();c.fire("filter");c.filter();c.resizeContainer()},getItemsPerRow:function(){var b=this.$container.width(),c=Math.floor(b/this.itemWidth);c*(this.itemWidth+this.marginRight)-this.marginRight>b&&(c-=1);return c},resizeContainer:function(){var b=Math.ceil(this.visibleItems/this.itemsPerRow)*(this.itemHeight+this.marginTop)-
|
||||
this.marginTop;this.$container.css("height",b+"px")},fire:function(b){this.$container.trigger(b+".shuffle",[this])},shrink:function(){var b=this,c=b.$items.filter(".concealed");0!==c.length&&(b.shrinkTransitionEnded=!1,c.each(function(){var a=d(this),c=parseInt(a.attr("data-x"),10),f=parseInt(a.attr("data-y"),10);c||(c=0);f||(f=0);b.transition({from:"shrink",$this:a,x:c,y:f,left:c+b.itemWidth/2+"px",top:f+b.itemHeight/2+"px",scale:0.001,opacity:0,height:"0px",width:"0px",callback:b.shrinkEnd})}))},
|
||||
layout:function(b,c){var a=this,e=0;0!==b.length&&(a.layoutTransitionEnded=!1,d.each(b,function(f){var h=d(b[f]),g=f%a.itemsPerRow*(a.itemWidth+a.marginRight),i=Math.floor(f/a.itemsPerRow);0===f%a.itemsPerRow&&(e=i*(a.itemHeight+a.marginTop));h.attr({"data-x":g,"data-y":e});a.transition({from:"layout",$this:h,x:g,y:e,left:g+"px",top:e+"px",scale:1,opacity:1,height:a.itemHeight+"px",width:a.itemWidth+"px",callback:c})}))},filter:function(){if(this.keepSorted&&this.lastSort)this.sort(this.lastSort,
|
||||
!0);else{var b=this.$items.filter(".filtered").get();this.layout(b,this.filterEnd)}},sort:function(b,c){var a=this,d=a.$items.filter(".filtered").sorted(b);a.layout(d,function(){c&&a.filterEnd();a.sortEnd()});a.lastSort=b},setPrefixedCss:function(b,c,a){b.css(this.prefixed(c),a)},getPrefixed:function(b){return(b=this.prefixed(b))?b.replace(/([A-Z])/g,function(b,a){return"-"+a.toLowerCase()}).replace(/^ms-/,"-ms-"):b},transition:function(b){var c=this,a,d=function(){!c.layoutTransitionEnded&&"layout"===
|
||||
b.from?(b.callback.call(c),c.layoutTransitionEnded=!0):!c.shrinkTransitionEnded&&"shrink"===b.from&&(b.callback.call(c),c.shrinkTransitionEnded=!0)};c.supported?(a=c.threeD?"translate3d("+b.x+"px, "+b.y+"px, 0) scale3d("+b.scale+", "+b.scale+", 1)":"translate("+b.x+"px, "+b.y+"px) scale("+b.scale+", "+b.scale+")",b.$this.css("opacity",b.opacity),c.setPrefixedCss(b.$this,"transform",a),b.$this.one(c.transitionEndName,d)):b.$this.stop().animate({left:b.left,top:b.top,opacity:b.opacity,height:b.height,
|
||||
width:b.width},c.speed,"swing",d)},resized:function(){this.itemWidth=this.$items.filter(".filtered").outerWidth();this.itemHeight=this.$items.filter(".filtered").outerHeight();this.itemsPerRow=this.getItemsPerRow();this.filter();this.resizeContainer()},shrinkEnd:function(){this.fire("shrunk")},filterEnd:function(){this.fire("filtered")},sortEnd:function(){this.fire("sorted")},destroy:function(){this.$container.removeAttr("style").removeData("shuffle");d(window).off(".shuffle");this.$items.removeAttr("style data-y data-x").removeClass("concealed filtered")}};
|
||||
d.fn.shuffle=function(b,c){return this.each(function(){var a=d(this),e=a.data("shuffle");e||(e=new i(a,b),a.data("shuffle",e));d.isFunction(b)?e.shuffle(b):"string"===typeof b&&("sort"===b?e.sort(c):"destroy"===b?e.destroy():e.shuffle(b))})};d.fn.shuffle.options={group:"all",speed:800,easing:"ease-out",keepSorted:!0};d.fn.shuffle.settings={supported:g.csstransforms&&g.csstransitions,prefixed:g.prefixed,threeD:g.csstransforms3d}})(jQuery,Modernizr);
|
@ -0,0 +1,414 @@
|
||||
/**
|
||||
* @author Glen Cheney
|
||||
* Debounce plugin is included in shuffle
|
||||
*/
|
||||
|
||||
var Modules = {};
|
||||
|
||||
Modules.Support = (function( $ ) {
|
||||
'use strict';
|
||||
|
||||
var self = {},
|
||||
|
||||
// some small (2x1 px) test images for each feature
|
||||
webpImages = {
|
||||
basic: 'data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==',
|
||||
lossless: 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA='
|
||||
};
|
||||
|
||||
self.webp = function( feature ) {
|
||||
var dfd = $.Deferred();
|
||||
|
||||
$('<img>')
|
||||
.on('load', function() {
|
||||
// the images should have these dimensions
|
||||
if ( this.width === 2 && this.height === 1 ) {
|
||||
dfd.resolve();
|
||||
} else {
|
||||
dfd.reject();
|
||||
}
|
||||
})
|
||||
|
||||
// Reject deferred on error
|
||||
.on('error', function() {
|
||||
dfd.reject();
|
||||
})
|
||||
|
||||
// Set the image src
|
||||
.attr('src', webpImages[ feature || 'basic' ]);
|
||||
|
||||
return dfd.promise();
|
||||
};
|
||||
|
||||
// Fill rAF
|
||||
var rAF = window.requestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.msRequestAnimationFrame;
|
||||
|
||||
window.requestAnimationFrame = rAF;
|
||||
|
||||
return self;
|
||||
}( jQuery ));
|
||||
|
||||
|
||||
Modules.Polyfill = (function( $, Support ) {
|
||||
'use strict';
|
||||
|
||||
var init = function() {
|
||||
|
||||
// If the deferred object in webp is rejected, call the webp polyfill function
|
||||
Support.webp().fail( webp );
|
||||
},
|
||||
|
||||
webp = function() {
|
||||
$('img[src$=".webp"]').each(function() {
|
||||
this.src = this.src.replace('.webp', '.jpg');
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
init: init
|
||||
};
|
||||
}( jQuery, Modules.Support ));
|
||||
|
||||
|
||||
Modules.Nav = (function( $ ) {
|
||||
'use strict';
|
||||
|
||||
function NavTray( element ) {
|
||||
this.$el = $( element );
|
||||
this.init();
|
||||
}
|
||||
|
||||
NavTray.prototype.init = function() {
|
||||
this
|
||||
.setVars()
|
||||
.listen();
|
||||
|
||||
// Google web font loading affects this.
|
||||
// I could use their loader, but don't really want their js too
|
||||
// I've changed the fallback font to Verdana, sans-serif to better
|
||||
// represent Ubuntu's wideness.
|
||||
// Also this isn't needed on load and could be done on window load
|
||||
setTimeout( $.proxy( this.saveHeight, this ), 100 );
|
||||
};
|
||||
|
||||
NavTray.prototype.setVars = function() {
|
||||
var self = this;
|
||||
|
||||
self.isOpen = false;
|
||||
self.$window = $( window );
|
||||
self.$trigger = self.$el.find('.js-nav-toggle');
|
||||
self.$tray = self.$el.find('.js-tray');
|
||||
|
||||
self.$trigger.data( 'openLabel', self.$trigger.text() );
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
NavTray.prototype.saveHeight = function() {
|
||||
var self = this,
|
||||
height = self.$tray.children().first().outerHeight();
|
||||
|
||||
self.collapseHeight = height;
|
||||
|
||||
return height;
|
||||
};
|
||||
|
||||
NavTray.prototype.listen = function() {
|
||||
var self = this;
|
||||
|
||||
self.$trigger.on( 'click', $.proxy( self.toggle, self ) );
|
||||
self.$window.on( 'resize', $.debounce( 250, $.proxy( self.onResize, self ) ) );
|
||||
|
||||
// This is a case for selectors level 4!
|
||||
self.$el.find('.js-demos').on('mouseenter', '.js-demo', function( evt ) {
|
||||
$( evt.currentTarget ).addClass('hovered');
|
||||
});
|
||||
|
||||
self.$el.find('.js-demos').on('mouseleave', '.js-demo', function( evt ) {
|
||||
$( evt.currentTarget ).removeClass('hovered');
|
||||
});
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
NavTray.prototype.onResize = function() {
|
||||
var self = this;
|
||||
|
||||
self.$tray.css( 'height', '' );
|
||||
self.saveHeight();
|
||||
|
||||
if ( self.isOpen ) {
|
||||
self.$tray.css( 'height', self.collapseHeight );
|
||||
}
|
||||
};
|
||||
|
||||
NavTray.prototype.toggle = function() {
|
||||
var self = this;
|
||||
|
||||
self.toggleBtnText();
|
||||
|
||||
if ( self.isOpen ) {
|
||||
self.close();
|
||||
} else {
|
||||
self.open();
|
||||
}
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
NavTray.prototype.open = function() {
|
||||
var self = this;
|
||||
|
||||
self.$el.removeClass('collapsed');
|
||||
self.$tray.css( 'height', self.collapseHeight );
|
||||
|
||||
self.isOpen = true;
|
||||
};
|
||||
|
||||
NavTray.prototype.close = function() {
|
||||
var self = this;
|
||||
|
||||
self.$el.addClass('collapsed');
|
||||
self.$tray.css( 'height', '' );
|
||||
|
||||
self.isOpen = false;
|
||||
};
|
||||
|
||||
|
||||
NavTray.prototype.toggleBtnText = function() {
|
||||
var self = this,
|
||||
key= self.isOpen ? 'openLabel' : 'closeLabel';
|
||||
|
||||
self.$trigger.text( self.$trigger.data( key ) );
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
return new NavTray( document.getElementById('nav') );
|
||||
}
|
||||
};
|
||||
|
||||
}( jQuery ));
|
||||
|
||||
|
||||
Modules.Favicon = (function( doc ) {
|
||||
'use strict';
|
||||
|
||||
var Favicon = function( src, numFrames, framesPerAnimation, animationDelay ) {
|
||||
var self = this;
|
||||
|
||||
// Variables based on params
|
||||
self.src = src;
|
||||
self.numFrames = numFrames;
|
||||
self.framesPerAnimation = framesPerAnimation;
|
||||
self.animationDelay = animationDelay;
|
||||
|
||||
// Elements
|
||||
self.canvas = doc.createElement('canvas');
|
||||
self.img = doc.createElement('img');
|
||||
self.html = doc.documentElement;
|
||||
|
||||
// Calculations
|
||||
self.size = window.devicePixelRatio > 1 ? 32 : 16;
|
||||
|
||||
// If it's not a data url, pick apart the filename and add @2x for retina
|
||||
if ( !self.src.match(/data:/) && window.devicePixelRatio > 1 ) {
|
||||
var dot = self.src.lastIndexOf('.');
|
||||
self.src = self.src.substring( 0, dot ) + '@2x' + self.src.substring( dot );
|
||||
}
|
||||
|
||||
self.currentFrame = 0;
|
||||
// Chrome chokes on this. It looks like it can handle 4 frames per second
|
||||
self.fps = 24;
|
||||
|
||||
self.init();
|
||||
};
|
||||
|
||||
Favicon.prototype.init = function() {
|
||||
var self = this;
|
||||
|
||||
// No #favicon element or browser doesn't support canvas or < IE9, stop
|
||||
if ( !doc.getElementById('favicon') || !self.canvas.getContext || self.html.className.indexOf('lt-ie9') > -1 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Save context
|
||||
self.ctx = self.canvas.getContext('2d');
|
||||
|
||||
// Set canvas dimensions based on device DPI
|
||||
self.canvas.height = self.canvas.width = self.size;
|
||||
|
||||
// Create a new sprite 32x32 size with 32x32 sprites
|
||||
self.sprite = new Sprite( self.ctx, self.img, self.size );
|
||||
|
||||
// Bind the image load handler
|
||||
self.img.onload = self.onSpriteLoaded.bind( self );
|
||||
|
||||
// Trigger image to load
|
||||
self.img.src = self.src;
|
||||
};
|
||||
|
||||
Favicon.prototype.getData = function() {
|
||||
return this.canvas.toDataURL('image/png');
|
||||
};
|
||||
|
||||
// Clone the current #favicon and replace it with a new element
|
||||
// which has the updated data URI href
|
||||
Favicon.prototype.setFavicon = function() {
|
||||
var self = this,
|
||||
data = self.getData(),
|
||||
originalFavicon = doc.getElementById('favicon'),
|
||||
clone = originalFavicon.cloneNode( true );
|
||||
|
||||
clone.setAttribute( 'href', data );
|
||||
originalFavicon.parentNode.replaceChild( clone, originalFavicon );
|
||||
};
|
||||
|
||||
// Request Animation Frame Loop
|
||||
Favicon.prototype.loop = function( timestamp ) {
|
||||
var self = this;
|
||||
|
||||
// If not enough time has elapse since the last call
|
||||
// immediately call the next rAF
|
||||
if ( timestamp - self.lastExecuted < self.timeToElapse ) {
|
||||
return requestAnimationFrame( self.loop.bind( self ) );
|
||||
}
|
||||
|
||||
// Increment current frame
|
||||
self.currentFrame += 1;
|
||||
if ( self.currentFrame === self.numFrames ) {
|
||||
self.currentFrame = 0;
|
||||
}
|
||||
|
||||
// Completed an animation state
|
||||
self.timeToElapse = self.currentFrame % self.framesPerAnimation === 0 ?
|
||||
self.animationDelay :
|
||||
1000 / self.fps;
|
||||
|
||||
// Draw current frame from sprite
|
||||
self.sprite.drawFrame( self.currentFrame );
|
||||
|
||||
// Swap <link>
|
||||
self.setFavicon();
|
||||
|
||||
// Set a timeout to draw again
|
||||
self.lastExecuted = timestamp;
|
||||
|
||||
// Continue loop
|
||||
return requestAnimationFrame( self.loop.bind( self ) );
|
||||
};
|
||||
|
||||
// Sprite loaded
|
||||
Favicon.prototype.onSpriteLoaded = function() {
|
||||
var self = this;
|
||||
|
||||
// Draw the first frame when the image loads
|
||||
self.sprite.drawFrame( self.currentFrame );
|
||||
|
||||
// Swap <link>
|
||||
self.setFavicon();
|
||||
|
||||
// Start loop
|
||||
requestAnimationFrame( self.loop.bind( self ) );
|
||||
};
|
||||
|
||||
|
||||
var Sprite = function( context, img, size ) {
|
||||
var self = this;
|
||||
self.ctx = context;
|
||||
self.img = img;
|
||||
self.width = size;
|
||||
self.height = size;
|
||||
self.frameWidth = size;
|
||||
self.frameHeight = size;
|
||||
};
|
||||
|
||||
// Assuming horizontal sprite
|
||||
Sprite.prototype.getFrame = function( frame ) {
|
||||
return {
|
||||
x: frame * this.frameWidth,
|
||||
y: 0
|
||||
};
|
||||
};
|
||||
|
||||
Sprite.prototype.clearCanvas = function() {
|
||||
this.ctx.clearRect( 0, 0, this.width, this.height );
|
||||
};
|
||||
|
||||
Sprite.prototype.drawFrame = function( frameNumber ) {
|
||||
var self = this;
|
||||
|
||||
var frame = self.getFrame( frameNumber );
|
||||
|
||||
// Clear out the last frame
|
||||
self.clearCanvas();
|
||||
|
||||
// Draw to the context. This method is really confusing...
|
||||
self.ctx.drawImage(
|
||||
self.img,
|
||||
frame.x,
|
||||
frame.y,
|
||||
self.width,
|
||||
self.height,
|
||||
0,
|
||||
0,
|
||||
self.width,
|
||||
self.height
|
||||
);
|
||||
};
|
||||
|
||||
return Favicon;
|
||||
}( document ));
|
||||
|
||||
|
||||
|
||||
// Analytics
|
||||
var _gaq = [ ['_setAccount', 'UA-39355642-1'], ['_trackPageview'] ];
|
||||
|
||||
(function(doc, script) {
|
||||
'use strict';
|
||||
|
||||
var js,
|
||||
fjs = doc.scripts[0],
|
||||
frag = doc.createDocumentFragment(),
|
||||
add = function(url, id) {
|
||||
if (doc.getElementById(id)) {return;}
|
||||
js = doc.createElement(script);
|
||||
js.src = url;
|
||||
if ( id ) { js.id = id; }
|
||||
frag.appendChild( js );
|
||||
};
|
||||
|
||||
// Twitter SDK
|
||||
// add('//platform.twitter.com/widgets.js', 'twitter-wjs');
|
||||
|
||||
// Load GA over http, we know it won't be over ssl
|
||||
add('//www.google-analytics.com/ga.js');
|
||||
|
||||
fjs.parentNode.insertBefore(frag, fjs);
|
||||
|
||||
}(document, 'script'));
|
||||
|
||||
|
||||
$(document).ready(function() {
|
||||
'use strict';
|
||||
|
||||
Modules.Nav.init();
|
||||
Modules.Polyfill.init();
|
||||
|
||||
var src = '/img/favicon-sprite.png';
|
||||
new Modules.Favicon( src, 21, 7, 3000 * 1 );
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,121 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]-->
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en"> <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Shuffle - Minimal</title>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<link rel="stylesheet" href="css/style.css" />
|
||||
<link href='http://fonts.googleapis.com/css?family=Poly:400,400italic' rel='stylesheet' type='text/css' />
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="js/html5shiv.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
<style>
|
||||
#grid > div {
|
||||
margin-right: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container container-main">
|
||||
|
||||
<section>
|
||||
<h2>Minimal</h2>
|
||||
|
||||
<div class="filter clearfix">
|
||||
<p class="lfloat label">Filter:</p>
|
||||
<ul class="filter-options control-group lfloat">
|
||||
<li data-group="all" class="active">Most Recent</li>
|
||||
<li data-group="wallpaper">Wallpapers</li>
|
||||
<li data-group="graphics">Graphic Design</li>
|
||||
<li data-group="photography">Photography</li>
|
||||
<li data-group="3d">3D Renders</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="grid" class="clearfix">
|
||||
<div data-groups='["photography"]'>
|
||||
<img src="img/baseball.png" alt="" />
|
||||
<div><a href="img/originals/baseball.jpg">Photography</a></div>
|
||||
</div>
|
||||
<div data-groups='["wallpaper", "3d"]'>
|
||||
<img src="img/tennis-ball.png" alt="" />
|
||||
<div><a href="#">3D Render, Wallpaper</a></div>
|
||||
</div>
|
||||
<div data-groups='["3d", "wallpaper"]'>
|
||||
<img src="img/imac.png" alt="" />
|
||||
<div><a href="#">3D Render, Wallpaper</a></div>
|
||||
</div>
|
||||
<div data-groups='["graphics"]'>
|
||||
<img src="img/master-chief.png" alt="" />
|
||||
<div><a href="#">Graphic Design</a></div>
|
||||
</div>
|
||||
<div data-groups='["3d", "wallpaper"]'>
|
||||
<img src="img/es-blue.png" alt="" />
|
||||
<div><a href="#">3D Render, Wallpaper</a></div>
|
||||
</div>
|
||||
<div data-groups='["photography"]'>
|
||||
<img src="img/pumpkin.png" alt="" />
|
||||
<div><a href="#">Photography</a></div>
|
||||
</div>
|
||||
<div data-groups='["3d", "wallpaper"]'>
|
||||
<img src="img/vestride-red.png" alt="" />
|
||||
<div><a href="#">3D Render, Wallpaper</a></div>
|
||||
</div>
|
||||
<div data-groups='["graphics"]'>
|
||||
<img src="img/newegg.png" alt="" />
|
||||
<div><a href="#">Motion Graphics</a></div>
|
||||
</div>
|
||||
<div data-groups='["wallpaper"]'>
|
||||
<img src="img/eightfoldarc.png" alt="" />
|
||||
<div><a href="#">Wallpaper</a></div>
|
||||
</div>
|
||||
<div data-groups='["photography"]'>
|
||||
<img src="img/ground.png" alt=""/>
|
||||
<div><a href="img/originals/baseball.jpg">Photography</a></div>
|
||||
</div>
|
||||
<div data-groups='["wallpaper"]'>
|
||||
<img src="img/grassy-hills.png" alt="" />
|
||||
<div><a href="#">Wallpaper</a></div>
|
||||
</div>
|
||||
<div data-groups='["3d", "wallpaper"]'>
|
||||
<img src="img/vestride-classy.png" alt="" />
|
||||
<div><a href="#">3D Render, Wallpaper</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
|
||||
<script src="js/jquery.shuffle.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
// Set up button clicks
|
||||
$('.filter-options li').on('click', function() {
|
||||
var $this = $(this),
|
||||
$grid = $('#grid');
|
||||
|
||||
// Hide current label, show current label in title
|
||||
$('.filter-options .active').removeClass('active');
|
||||
$this.addClass('active');
|
||||
|
||||
// Filter elements
|
||||
$grid.shuffle($this.data('group'));
|
||||
});
|
||||
|
||||
// instantiate the plugin
|
||||
$('#grid').shuffle();
|
||||
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|