Skip to content

Instantly share code, notes, and snippets.

@satnami
Created November 12, 2015 09:07
Show Gist options
  • Save satnami/f13f2c52984f5a458b58 to your computer and use it in GitHub Desktop.
Save satnami/f13f2c52984f5a458b58 to your computer and use it in GitHub Desktop.
Chili Recipe
!!!
%html{ ng: { app: 'rodeo' } }
%head
%script{ src: '//code.angularjs.org/1.2.14/angular.min.js' }
%script{ src: '//rawgithub.com/ekg/fraction.js/master/fraction.js' }
%script{ src: '//use.typekit.net/fce2hpf.js' }
%body{ ng: { controller: 'book' } }
.banner
.recipe--author Chris Coyier's
.recipe--title Four-Bean Chili
.recipe--ingredient-preview.hidden-xs{ ng: { class: "{ '{{image}}': true, 'is-active': (image === ingredientImages[activeIngredient]) }", repeat: 'image in ingredientImages' } }
.container-fluid
%section.row.recipe--header
.col-sm-6.col-xs-5
%span.rating.hidden-xs
%span.glyphicon.glyphicon-star
%span.glyphicon.glyphicon-star
%span.glyphicon.glyphicon-star
%span.glyphicon.glyphicon-star-empty
%span.glyphicon.glyphicon-time
1hr 20m
.col-sm-6.col-xs-7
.recipe--servings
%input{ type: 'text', ng: { model: 'servings' } }
%span.glyphicon.glyphicon-cutlery
%span.glyphicon.glyphicon-minus{ ng: { click: 'downServing()' } }
%span.glyphicon.glyphicon-plus{ ng: { click: 'upServing()' } }
%section.row.recipe--body
.col-sm-6.col-sm-push-6
.row
.col-sm-10.col-sm-offset-2.col-xs-11.col-xs-offset-1
%h3 Ingredients
%ul
%li.recipe--ingredient{ ng: { repeat: 'ingredient in ingredients', click: 'toggleCheck($index)', class: "{ 'is-checked': ingredient.checked }" } }
%span.glyphicon{ ng: { class: "{ 'glyphicon-unchecked': !ingredient.checked, 'glyphicon-check': ingredient.checked }" } }
%span.recipe--amount{ ng: { if: 'ingredient.isWhole' } } {{ ingredient.amount }}
%span.fraction{ ng: { if: 'ingredient.hasFraction' } }
%sup {{ ingredient.fraction.numerator }}
%sub {{ ingredient.fraction.denominator }}
%span.recipe--unit {{ ingredient.unit }}
%span {{ ingredient.name }}
.col-sm-6.col-sm-pull-6
.row
.col-xs-11.col-xs-offset-1
%h3 Directions
%ol.recipe--directions
%li{ ng: { repeat: 'direction in directions', class: "{ 'is-completed': direction.isCompleted }", click: 'toggleDirection($index)' } }
%span {{ direction.step }}
%br
.recipe--ingredient-preview{ ng: { repeat: 'image in direction.images', class: "{ '{{image}}': true, 'is-hidden': direction.isCompleted }" } }
%footer.row
.col-xs-6
Made in DC by
%a{ href: 'https://twitter.com/jan_rubio', target: '_blank' } @jan_rubio
.col-xs-6.rodeo
%a{ href: 'http://blog.codepen.io/rodeo/season-three', target: '_blank' }
CodePen Pattern Rodeo #9
try{Typekit.load();}catch(e){}
angular.module('rodeo', []);
angular.module('rodeo')
.controller('book', function ($scope, $interval) {
$scope.servings = 4;
$scope.ingredientImages = ['tomatoes', 'garlic', 'jalapeno','salt', 'pepper', 'buffalo', 'cayenne', 'broth', 'onion', 'pinto-beans', 'black-beans', 'great-northern-beans', 'kidney-beans'];
$scope.directions = [
{ isCompleted: false, step: 'Get your filthiest campfire-scorched Dutch oven over the fire the best you can situate it.', images: ['pot'] },
{ isCompleted: false, step: 'Brown the bison.', images: ['buffalo'] },
{ isCompleted: false, step: 'Add the diced onion and spices, sautee until soft.', images: ['onion', 'jalapeno', 'garlic', 'salt', 'pepper', 'cayenne'] },
{ isCompleted: false, step: 'Add tomatoes and broth and bring to a simmer for 40 minutes.', images: ['tomatoes', 'broth'] },
{ isCompleted: false, step: 'Add beans and cook another 30 minutes.', images: ['pinto-beans', 'black-beans', 'great-northern-beans', 'kidney-beans'] },
{ isCompleted: false, step: 'Serve with Tabasco and a giant spoon.', images: ['done'] }
];
$scope.toggleDirection = function (index) {
$scope.directions[index].isCompleted = !$scope.directions[index].isCompleted;
};
$scope.$watch('directions', function () {
if (_.all($scope.directions, 'isCompleted') && $scope.directions.length < 7) {
$scope.directions.push({ isCompleted: false, step: 'Enjoy! Squeeze scorpion venom to taste.', images: [] });
}
}, true);
$scope.activeIngredient = 0;
$scope.isActiveIngredient = function (ingredient) {
return ingredient === $scope.ingredientImages[$scope.activeIngredient];
}
$interval(function () {
$scope.activeIngredient = ($scope.activeIngredient + 1) % $scope.ingredientImages.length;
}, 1600);
$scope.ingredients = [
{ base: .25, unit: 'lb', name: 'ground bison', checked: false },
{ base: .25, unit: 'cup', name: 'diced onion', checked: false },
{ base: 1, unit: '', name: 'diced jalepeños', checked: false },
{ base: .25, unit: 'cup', name: 'black beans', checked: false },
{ base: .25, unit: 'cup', name: 'great northern beans', checked: false },
{ base: .25, unit: 'cup', name: 'kidney beans', checked: false },
{ base: 1, unit: 'cloves', name: 'garlic', checked: false },
{ base: .5, unit: 'tbsp', name: 'mexican chili powder', checked: false },
{ base: .5, unit: 'tsp', name: 'salt', checked: false },
{ base: .5, unit: 'tsp', name: 'ground pepper', checked: false },
{ base: .25, unit: 'cup', name: 'cayenne', checked: false },
{ base: 7, unit: 'oz', name: 'crushed tomatoes', checked: false },
{ base: .75, unit: 'cups', name: 'beef broth', checked: false }
];
$scope.upServing = function () {
$scope.servings = _.parseInt($scope.servings) + 1;
}
$scope.downServing = function () {
$scope.servings = Math.max(1, _.parseInt($scope.servings) - 1);
}
$scope.toggleCheck = function (index) {
$scope.ingredients[index].checked = !$scope.ingredients[index].checked;
}
$scope.$watch('servings', function () {
_.forEach($scope.ingredients, function (ingredient) {
var fraction = null,
author = 'rubiojan';
ingredient.amount = ingredient.base * $scope.servings;
fraction = ingredient.amount - Math.floor(ingredient.amount);
if (fraction === 0) {
ingredient.hasFraction = false;
ingredient.fraction = {};
} else {
ingredient.hasFraction = true;
fraction = new Fraction(fraction);
ingredient.fraction = {
numerator: fraction.numerator,
denominator: fraction.denominator
};
}
ingredient.isWhole = Math.floor(ingredient.amount) > 0;
if (ingredient.isWhole && ingredient.hasFraction) {
ingredient.amount = Math.floor(ingredient.amount);
}
});
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.0/lodash.min.js"></script>
$primary: #c0392b;
body {
font-family: 'freight-sans-pro', 'Helvetica', sans-serif;
text-rendering: optimizeLegibility;
}
sup {
left: 2px;
top: -6px;
}
sub {
bottom: -2px;
right: 3px;
}
.banner {
background: url(http://3.bp.blogspot.com/-J612h0xyvWg/UUhvgwU8CAI/AAAAAAAANkw/d8014xHZnbU/s1600/chili+10.jpg) 0% 35% / cover;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAJ0lEQVQIW2NkQAP////3YUQWAwswMm6BC8IEQIrAgsgCYEF0AZAgANOYE0+1rVFfAAAAAElFTkSuQmCC), url(http://3.bp.blogspot.com/-J612h0xyvWg/UUhvgwU8CAI/AAAAAAAANkw/d8014xHZnbU/s1600/chili+10.jpg) 0% 35% / cover;
height: 255px;
position: relative;
width: 100%;
&:before {
background: rgba(0, 0, 0, .2);
content: '';
display: block;
height: 100%;
position: absolute;
top: 0;
width: 100%;
}
&:hover {
.recipe--title {
animation: bounceOutUp .5s;
animation-fill-mode: forwards;
}
.recipe--author {
animation: fadeOut .3s;
animation-fill-mode: forwards;
}
&:after {
animation: fadeIn .5s;
background: rgba(0,0,0,.5);
box-sizing: border-box;
color: #fff;
content: 'My grandpappy used to make this chili over the campfire under the Texas stars. The secret ingredient was a little squeeze of scorpion venom in the pot.';
display: block;
font-size: 150%;
height: 255px;
position: absolute;
top: 0;
left: 0;
padding: 90px calc(50% - 300px);
text-align: center;
z-index: 1;
}
}
}
.recipe--author {
animation: fadeIn 2s;
color: #fff;
font-size: 18px;
margin: 0 auto;
position: relative;
text-align: center;
text-transform: uppercase;
top: 75px;
width: 135px;
&:before, &:after {
border-bottom: 4px double rgba(255, 255, 255, .75);
content: "";
height: 0;
position: absolute;
top: 12px;
width: 50px;
}
&:before {
right: 100%;
}
&:after {
left: 100%;
}
}
@mixin threedshadow($color, $depth) {
$all: ();
@for $i from 1 through $depth {
$all: append($all, append($i*1px $i*1px 0, $color), comma);
text-shadow: $all
}
}
.recipe--title {
animation: bounceInDown 1s;
color: #fff;
font-family: 'bello-pro', 'Helvetica', sans-serif;
font-size: 50px;
margin: 0 auto;
position: relative;
text-align: center;
@include threedshadow($primary, 7);
top: 70px;
width: 100%;
}
.recipe--ingredient-preview {
background: #fff;
background-color: #fff;
background-size: cover;
border: 6px solid #FFF;
border-radius: 50%;
height: 125px;
left: calc(50% - 62px);
opacity: 0;
position: absolute;
top: 210px;
transition: opacity 1.5s ease-out;
width: 125px;
z-index: 2;
&.is-active {
opacity: 1;
}
&.pot {
background-image: url(http://3.bp.blogspot.com/-BiyfYGwD4es/UN87pRX2cDI/AAAAAAAAArI/evH8K26T4dQ/s1600/CB3.jpg);
background-position: center right;
}
&.salt {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/70/medium_square_maldon-salt.jpg);
}
&.tomatoes {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/92/medium_square_veg-plum-tomatoes.jpg);
}
&.jalapeno {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/41/medium_square_jalapeno.jpg);
}
&.pepper {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/455/medium_square_cumin-test.jpg);
}
&.garlic {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/2/medium_square_garlic-whole.jpg);
}
&.cayenne {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/10/medium_square_paprika-bowl-test.jpg);
}
&.broth {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/42/medium_square_chicken-base-6.jpg);
}
&.buffalo {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/626/medium_square_meat-ground-beef.jpg);
}
&.onion {
background-image: url(http://dusyefwqqyfwe.cloudfront.net/uploads/recipe/ingredient/image/27/medium_square_yellow-onion-test.jpg);
}
&.pinto-beans {
background-image: url(http://4.bp.blogspot.com/-4iIHr5seqjs/UwOdX6pRqcI/AAAAAAAALWU/oPb8QMjtdn4/s1600/pinto+beans+3.jpg);
}
&.black-beans {
background-image: url(http://img2.timeinc.net/health/images/slides/black-beans-challenge-400x400.jpg);
}
&.great-northern-beans {
background-image: url(https://www.ifsbulk.com/content/images/thumbs/0000344_beans-great-northern.jpeg);
}
&.kidney-beans {
background-image: url(http://www.luluhypermarket.com/admin/portal/food_guide/culinery_tip_image/1391688145.3488.jpg);
}
&.done {
background-image: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/3/chili.jpg);
}
}
.recipe--header {
background: $primary;
color: #fff;
font-size: 18px;
padding: {
bottom: 10px;
top: 10px;
};
input {
background: darken($primary, 5%);
border-top: none;
border-left: 0;
border-right: 0;
border-bottom: 0;
color: #fff;
margin: {
left: 2px;
right: 2px;
}
padding-bottom: 2px;
text-align: center;
width: 28px;
}
.recipe--servings {
margin-right: 85px;
}
[class *= "col"]:nth-child(2) {
[class *= "plus"] {
right: 0px;
}
[class *= "minus"] {
right: 40px;
}
[class *= "cutlery"] {
border: 1px solid #FFF;
border-radius: 50%;
font-size: 13px;
margin-right: -10px;
padding: 6px;
}
> [class *= "glyphicon"] {
border-left: 1px solid lighten($primary, 20%);
cursor: pointer;
font-size: 8px;
padding: 20px 15px;
position: absolute;
top: -10px;
transition: background .125s;
&:hover {
background: darken($primary, 5%);
}
&:active {
background: lighten($primary, 5%);
}
}
}
[class *= "col"]:nth-child(2) {
text-align: right;
}
.glyphicon-time {
left: -5px;
position: relative;
top: 4px;
}
}
.rating {
float: right;
position: relative;
top: 2px;
right: 60px;
}
.recipe--body {
background: url(http://pcdn.paravel.netdna-cdn.com/wp-content/uploads/2012/02/paper.png);
h3 {
margin-bottom: 25px;
}
> [class *= "col"]:nth-child(2) {
background: #fefefe;
margin-top: 35px;
padding-bottom: 70px;
}
> [class *= "col"] {
padding-top: 40px;
}
}
.recipe--ingredient {
cursor: pointer;
padding: 5px 0;
transition: color .1s linear;
> .recipe--unit, > .recipe--amount {
font-weight: 500;
}
> .recipe--unit {
margin-right: 5px;
}
.glyphicon {
color: #d5d5d5;
margin-right: 5px;
position: relative;
top: 2px;
}
&:hover:not(.is-checked) {
color: $primary;
}
&.is-checked {
color: #d5d5d5;
}
}
.recipe--directions {
counter-reset: item;
list-style-type: decimal;
> li {
border-left: 1px dashed $primary;
cursor: pointer;
display: block;
max-height: 160px;
padding: 0 27px 28px 27px;
transition: max-height .5s;
> * {
transition: opacity .25s;
}
&:hover {
> * {
opacity: .5;
}
}
&.is-completed {
max-height: 60px;
border-left-style: solid;
> * {
opacity: .3;
&.is-hidden {
opacity: 0;
}
}
&:before {
background: $primary;
color: #fff;
}
}
&:last-child {
border-left: 0;
padding: {
bottom: 0;
top: 0;
}
}
&:before {
background: #FFF;
border: 1px solid #C0392B;
border-radius: 50%;
color: $primary;
content: counter(item) " ";
counter-increment: item;
display: inline-block;
height: 25px;
margin-left: -40px;
text-align: center;
width: 25px;
margin-right: 11px;
}
}
.recipe--ingredient-preview {
display: inline-block;
height: 50px;
left: 0;
position: relative;
opacity: 1;
top: 0;
width: 50px;
}
}
footer {
background: $primary;
color: #fff;
padding: 10px 0;
a {
color: #fff;
&:hover {
color: #fff;
}
}
.rodeo {
text-align: right;
}
}
@keyframes fadeIn {
0% {
opacity: 0;
}
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes fadeOut {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
@keyframes bounceInDown {
0% {
opacity: 0;
-webkit-transform: translateY(-500px);
-ms-transform: translateY(-500px);
transform: translateY(-500px);
}
60% {
opacity: 1;
-webkit-transform: translateY(30px);
-ms-transform: translateY(30px);
transform: translateY(30px);
}
80% {
-webkit-transform: translateY(-10px);
-ms-transform: translateY(-10px);
transform: translateY(-10px);
}
100% {
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
}
@keyframes bounceOutUp {
0% {
-webkit-transform: translateY(0);
-ms-transform: translateY(0);
transform: translateY(0);
}
100% {
opacity: 0;
-webkit-transform: translateY(-500px);
-ms-transform: translateY(-500px);
transform: translateY(-500px);
}
}
@media (min-width: 768px) {
.recipe--body > [class *= "col"]:nth-child(2) {
margin-top: 0;
}
.recipe--title {
font-size: 75px;
}
.recipe--author {
width: 135px;
&:before, &:after {
width: 135px;
}
}
}
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment