Skip to content

Instantly share code, notes, and snippets.

@pbrocks
Created January 14, 2015 01:24
Show Gist options
  • Save pbrocks/adb801cec3f0e5ad7f70 to your computer and use it in GitHub Desktop.
Save pbrocks/adb801cec3f0e5ad7f70 to your computer and use it in GitHub Desktop.
Material Show/Hide Grid
header
h1.small Material Design
h2 Grid Animation
div(ng-app='app',
ng-controller='ctrl as c')
a.btn(ng-click='c.shown = !c.shown') {{c.shown ? 'Hide' : 'Show'}} Items
a.btn.sm.minus(ng-class="{ show: c.shown, disabled: c.items.length === 0 }" ng-click='c.sub()')
a.btn.sm.plus(ng-class="{ show: c.shown, disabled: c.items.length >= 30 }" ng-click='c.add()')
grid(ng-class="{ show: c.shown }")
item(ng-repeat='item in c.items') {{$index + 1}}
angular
.module('app', ['ngAnimate'])
.controller('ctrl', ctrl)
.controller('gridCtrl', gridCtrl)
.directive('grid', grid)
.directive('item', item);
function ctrl () {
this.items = generateArray(15);
this.shown = true;
this.add = function () { this.items.push({}); };
this.sub = function () { this.items.pop(); };
function generateArray (count) {
var arr = [];
while (count--) arr.push({});
return arr;
}
}
function gridCtrl () {
var queue = [];
this.scope = null;
this.element = null;
this.init = function (scope, element) {
this.scope = scope;
this.element = element;
//-- process queue
while (queue.length) queue.pop()();
};
this.ready = function (callback) {
if (this.scope) callback()
else queue.push(callback);
};
this.setDelay = function (item) {
var left = item.prop('offsetLeft') - this.element.prop('offsetLeft'),
top = item.prop('offsetTop') - this.element.prop('offsetTop'),
dist = Math.sqrt(left * left + top * top),
delay = dist * 0.75;
item.css('transition-delay', delay + 'ms');
};
}
function grid () {
return {
controller: 'gridCtrl',
link: link
};
function link (scope, element, attr, ctrl) {
ctrl.init(scope, element);
}
}
function item ($timeout, $window) {
return {
require: '^grid',
link: link
};
function link (scope, element, attr, ctrl) {
ctrl.ready(function () {
ctrl.setDelay(element);
angular.element($window).on('resize', handleResize);
function handleResize () {
$timeout(ctrl.setDelay.bind(ctrl, element), 0, false);
}
element.on('$destroy', function () {
element.off('resize', handleResize);
});
});
}
}
@import "compass/css3";
@import url(http://fonts.googleapis.com/css?family=Roboto:300);
@import "compass/utilities/general/clearfix";
$spacing : 3px;
$size : 104px;
$duration : 0.35s;
$ease-out : cubic-bezier(0.25, 0.8, 0.25, 1);
$ease-in : cubic-bezier(0.55, 0, 0.55, 0.2);
$colors : (
darkPrimary: #303F9F,
lightPrimary: #C5CAE9,
primary: #3F51B5,
accent: #8BC34A,
primaryText: #212121,
secondaryText: #727272,
divider: #B6B6B6,
text: #FFFFFF
);
body {
font: 300 16px/20px Roboto, Lato, sans-serif;
padding: 0;
margin: 0;
}
header {
background: map-get($colors, darkPrimary);
padding: $size * 0.5;
}
[ng-app] {
min-width: ($spacing + $size) * 3;
max-width: ($spacing + $size) * 7;
padding: $size * 0.5;
}
h1.small {
font-size: 16px;
line-height: 22px;
margin: 0;
text-transform: uppercase;
text-indent: 5px;
color: tint(map-get($colors, accent), 20%);
}
h2 {
font-size: 45px;
line-height: 48px;
margin: 0;
color: map-get($colors, text);
}
p {
margin: 2em 0;
}
.light {
font-weight: 100;
}
.btn {
width: ($spacing + $size) * 2 - $spacing;
background: map-get($colors, primary);
color: map-get($colors, text);
font-size: 14px;
letter-spacing: 0.03em;
display: block;
padding: 0;
text-align: center;
text-transform: uppercase;
border-radius: 3px;
margin: 0 $spacing $spacing 0;
cursor: pointer;
user-select: none;
box-sizing: border-box;
float: left;
height: $size * 0.5;
line-height: $size * 0.5;
&.disabled {
background: map-get($colors, lightPrimary);
pointer-events: none;
}
&:hover {
background: tint(map-get($colors, primary), 15%);
}
&.sm {
width: ($size - $spacing) * 0.5;
background: map-get($colors, text);
transition: $duration $ease-in;
transform: scale(0);
background: #eee;
&:hover {
background: shade(map-get($colors, text), 10%);
}
&.show-add:nth-child(3) {
transition-delay: 200ms;
}
&.show-remove:nth-child(2) {
transition-delay: 100ms;
}
&.show {
transition: $duration $ease-out;
transform: scale(1);
&:nth-child(3) {
transition-delay: 100ms;
}
}
&.minus, &.plus {
&:before {
position: absolute;
width: 14px;
height: 2px;
background: map-get($colors, primary);
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
content: '';
}
}
&.plus {
&:after {
position: absolute;
height: 14px;
width: 2px;
background: map-get($colors, primary);
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
content: '';
}
}
}
}
grid {
@include clearfix();
clear: left;
margin: $spacing 0;
display: block;
item {
background: map-get($colors, accent);
color: map-get($colors, text);
width: $size;
height: $size;
display: block;
float: left;
margin: 0 $spacing $spacing 0;
text-align: center;
line-height: $size;
font-size: 46px;
border-radius: 3px;
transition: $duration $ease-in;
transform: scale(0);
}
&.show {
item {
transition: $duration $ease-out;
transform: scale(1);
&.ng-enter {
transition-delay: 0 !important;
transform: scale(0);
&.ng-enter-active {
transform: scale(1);
}
}
&.ng-leave {
transition-delay: 0 !important;
transition: 0.25 $ease-in;
&.ng-leave-active {
transform: scale(0);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment