Skip to content

Instantly share code, notes, and snippets.

@ja-k-e
Last active November 12, 2015 04:10
Show Gist options
  • Select an option

  • Save ja-k-e/419be9b00f919db4d1d9 to your computer and use it in GitHub Desktop.

Select an option

Save ja-k-e/419be9b00f919db4d1d9 to your computer and use it in GitHub Desktop.
CodePen Stat Battles

CodePen Stat Battles

In an effort to promote the antithesis of this amazing community, I give you CodePen Stat Battles!

Enter two names and watch that ish go!

Comment changes to the weight of each metric. Right now a view is valued at 1/100 of a heart, 1/50 of a comment and 1/20 of a pen.

A Pen by Jake Albaugh on CodePen.

License.

<section ng-app=CodepenData>
<div ng-controller=CodepenDataController>
<h1>
Stat
<img src="http://blog.codepen.io/wp-content/uploads/2012/06/Button-Fill-White-Large.png" />
Battles
</h1>
<div class=form ng-if=edit>
<div class=input-wrap>
<input placeholder="Hero 1" ng-model=users[0].nickname type=text />
<button class=small ng-click="randomUser(0)">rand</button>
</div>
<h1 class=label>vs</h1>
<div class=input-wrap>
<input placeholder="Hero 2" ng-model=users[1].nickname type=text />
<button ng-click="randomUser(1)">rand</button>
</div>
<p><small>usernames are case sensitive!</small></p>
<button class="fight button"
ng-disabled="!users[0].nickname || !users[1].nickname"
ng-click=loadCodepenData()>Fight!</button>
<!--<h1 class=label>or</h1>
<button class=button ng-click=random()>Random Heroes!</button>-->
</div>
<div class=results ng-if="!edit">
<div ng-repeat="user in users" ng-class="{winning: user.winning}" class=user>
<h2><a href="http://codepen.io/{{user.nickname}}" target="blank">@{{user.nickname}}</a></h2>
<div class="bars">
<div bar="user.pens.length"
comp="top.pens"
label="Pens"></div>
<div bar="user.stats.hearts"
comp="top.hearts"
label="Hearts"></div>
<div bar="user.stats.views"
comp="top.views"
label="Views"></div>
<div bar="user.stats.comments"
comp="top.comments"
label="Comments"></div>
</div>
<span class=points>{{user.points|number:0}} BP</span>
</div>
</div>
<div ng-cloak ng-if=complete>
<h2 ng-repeat="user in users" ng-if="user.winning">
<a href="http://codepen.io/{{user.nickname}}" target="blank">@{{user.nickname}}</a> wins with <strong>{{user.points|number:0}}</strong> Battle Points!
</h2>
<button class='button reset' ng-click="reset()">Reset</button>
</div>
</div>
</section>
var app = angular.module('CodepenData', []);
app.service('CodepenDataService', [
'$q',
function($q) {
return {
getPens: function(who,which,page) {
var request = 'http://codepen-awesomepi.timpietrusky.com/'+who+'/'+which+'/'+page;
var deferred_data = $q.defer();
$.ajax({
dataType: 'jsonp', jsonp: 'jsonp',
url: request,
success: function (res) {
if(res.content && res.content.pens.length) {
deferred_data.resolve(res.content.pens);
} else {
deferred_data.reject(res);
}
},
error: function (err) { deferred_data.reject(err); }
});
return deferred_data.promise;
}
}
}
]);
app.directive('bar', [
function() {
return {
scope: {
val: "=bar",
comp: "=",
label: "@"
},
template: '<div class="bar">'+
'<div class="bar-track">'+
'<span class="bar-val"'+
'ng-class="{winning: val == comp}"'+
'ng-style="{\'top\': 100 - val/comp * 100 + \'%\'}">'+
'{{val|number}}</span>'+
'</div>'+
'<span>{{label}}</span>' +
'</div>',
link: function(scope, $el, attrs) {
scope.top = scope.val/scope.comp * 100 + "%";
}
}
}
]);
app.controller('CodepenDataController', [
'$scope', '$http', '$timeout', 'CodepenDataService',
function($scope, $http, $timeout, CodepenDataService) {
$scope.edit = true;
$scope.complete = false;
var empty_user = function() {
return {
nickname: '',
loaded: false,
pens: [],
points: 0,
winning: false,
stats: { hearts: 0, views: 0, comments: 0 }
};
};
var users_base = [
empty_user(),
empty_user()
];
var top_base = {
pens: 0,
hearts: 0,
views: 0,
comments: 0
};
$scope.users = users_base;
$scope.top = top_base;
$scope.reset = function() {
$scope.users = [
empty_user(),
empty_user()
];
$scope.top = top_base;
$scope.complete = false;
$scope.edit = true;
}
function updateTops() {
var u1 = $scope.users[0],
u2 = $scope.users[1],
top = {
pens: Math.max(u1.pens.length, u2.pens.length),
hearts: Math.max(u1.stats.hearts, u2.stats.hearts),
views: Math.max(u1.stats.views, u2.stats.views),
comments: Math.max(u1.stats.comments, u2.stats.comments)
}
$scope.top = top;
// who is winning?
if(u1.points > u2.points) {
u1.winning = true;
u2.winning = false;
} else {
u1.winning = false;
u2.winning = true;
}
}
function updatePen(user, pen) {
user.stats.hearts += pen.hearts;
user.stats.views += pen.views;
user.stats.comments += pen.comments;
user.pens.push(pen);
}
function checkComplete() {
if($scope.users[0].loaded && $scope.users[1].loaded) {
$scope.complete = true;
} else {
$scope.complete = false;
}
}
function getPoints(user) {
var points = 0;
points += user.stats.views;
points += user.pens.length * 20;
points += user.stats.hearts * 100;
points += user.stats.comments * 50;
user.points = points / 10000;
}
function getUserPens(user, page) {
var getPens = CodepenDataService.getPens(user.nickname, 'public', page);
getPens.then(function(pens) {
$.each(pens, function() {
updatePen(user,this);
});
getPoints(user);
updateTops();
$timeout(function() {
getUserPens(user, page + 1);
}, 500);
}, function(err) {
if(!user.loaded) user.loaded = true;
checkComplete();
console.warn(err);
});
}
$scope.loadCodepenData = function() {
$scope.edit = false;
$.each($scope.users, function() {
var user = this;
var getting = true;
getUserPens(user,1);
});
};
$scope.random = function() {
randomUsers();
$scope.loadCodepenData();
}
$scope.randomUser = function(which) {
$scope.users[which].nickname = randomUser();
}
function randomUser() {
var users = usersList();
return users[Math.round(Math.random() * (users.length - 1))]
}
function randomUsers() {
$scope.users[0].nickname = randomUser();
$scope.users[1].nickname = randomUser();
}
// top 300 users. thanks @natewiley!
function usersList() {
return [
"thebabydino","tmrDevelops","pixelass","WhiteWolfWizard","natewiley","oknoblich","bennettfeely","jackrugile","hugo","LukyVj","towc","yoksel","dudleystorey","lukerichardville","Hornebom","netsi1964","nakome","berdejitendra","kenjiSpecial","katydecorah","rlemon","abergin","chrisgannon","ge1doot","lbebber","loktar00","Sonick","FWeinb","juanbrujo","andreasstorm","zadvorsky","tholman","Mombasa","fixcl","judag","MyXoToD","EduardoLopes","Zeaklous","HugoGiraudel","suez","grayghostvisuals","satchmorun","rileyjshaw","dope","gbnikolov","jakealbaugh","hakimel","elrumordelaluz","Mamboleoo","rachsmith","chrisota","kevinjannis","Kseso","TimPietrusky","ImagineProgramming","enxaneta","SitePoint","joshnh","KyleDavidE","brbcoding","TimLamber","raurir","rafaelcastrocouto","joe-watkins","alexsafayan","leemark","samarkandiy","motorlatitude","desandro","the_ruther4d","antoniskamamis","sdras","DonKarlssonSan","carpenumidium","ettrics","pmk","jakob-e","lonekorean","pouretrebelle","jshawl","wontem","tystrong","ScottMarshall","akwright","laviperchik","sol0mka","Pesca","mariusbalaj","spookyscary","chriscoyier","scottkellum","donovanh","GreenSock","code_dependant","zerospree","grgrdvrt","markmurray","Thibaut","unmeshpro","davatron5000","jorgeatgu","trhino","Dreamdealer","maggiben","m412c0","soulwire","32bitkid","waddington","rickyeckhardt","yukulele","egrucza","Francext","winkerVSbecks","nicolazj","schoenwaldnils","pcameron","indyplanets","EightArmsHQ","dervondenbergen","fbrz","seanseansean","mikehobizal","joshbader","zachernuk","nicoptere","noahblon","daneden","cx20","codeandcam","roborich","gastonfig","simeydotme","vineethtr","gpyne","Ruddy","wenbin5243","shubhra","hynden","acarva1","martinwolf","SaschaSigl","kaliedarik","stefanjudis","Xanmia","noeldelgado","Michiel","simurai","timohausmann","GabbeV","boltaway","pixelthing","airnan","MichaelArestad","ykob","Metty","DeptofJeffAyer","atelierbram","everblind","jjmartucci","creme","soulrider911","designcouch","ZevanRosser","dehash","geoffyuen","davilious","msurguy","hans","dissimulate","edankwan","satcy","chinchang","trajektorijus","mladen___","johnie","kman","tjoen","chrisnager","AmeliaBR","yusufbkr","jonitrythall","rachelwong","beesandtrees","jpod","cchambers","auginator","frytyler","jessenwells","robertmesserle","Oka","naoyashiga","mariosmaselli","XDBoy018","larrygeams","BrianDGLS","moklick","andytran","CrocoDillon","zessx","msval","pankajparashar","jonigiuro","MarcMalignan","jeroens","ludviglindblom","sakri","keithclark","ajerez","mallendeo","alexdevero","jurbank","brownerd","jcoulterdesign","potatoDie","shakdaniel","marian-cojoc-ro","rachelnabors","uriuriuriu","virgilpana","zachacole","bronsrobin","daless14","Elbone","ZCKVNS","vsync","pirrera","matt-west","long-lazuli","awesomephant","frxnz","Lewitje","amcharts","yy","SaraSoueidan","Aldlevine","jxnblk","icebob","PageOnline","ElmahdiMahmoud","terrymun","icutpeople","prowebix","carmination","bali_balo","fusco","jaflo","boylett","adamjld","brandonbrule","chris-creditdesign","nickmoreton","mknadler","igcorreia","scrimothy","rss","run-time","jlong","macreart","achudars","ssh","cjgammon","ControlledChaos","monstersaurous","christian-fei","captainbrosset","Funsella","kevingimbel","onediv","s","rlacorne","Yakudoo","drew_mc","shshaw","michaellee","ThisIsJohnBrown","chrislaarman","jotavejv","BeatAlex","tdevine33","ionic","pwsm50","shadeed","georgehastings","ademilter","keithwyland","khadkamhn","rikschennink","bphillips201","zitrusfrisch","jhamon","andersschmidt","Rplus","chrishutchinson","Zaku","jsbrown","kowlor","paintbycode","ashmind","souporserious","Guilh"
]
}
}
]);
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.14/angular.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
@import url(http://fonts.googleapis.com/css?family=Quicksand:400);
$c-pos: #60AE24;
$c-neg: #C44928;
$c-primary: #FFBB00;
.user {
display: block;
width: 50%;
box-sizing: border-box;
padding: 1rem;
&:first-of-type { float: left; }
&:last-of-type { float: right; }
}
.points {
display: block;
text-align: center;
background: $c-neg;
box-sizing: border-box;
border-radius: 0.125rem;
padding: 0.5rem;
margin: 0 0.125rem;
font-weight: 400;
font-size: 1.25rem;
.winning & {
background: $c-pos;
}
}
.bars {
&:after {
content: ""; clear: both; display: table;
}
.bar {
display: block;
width: 25%;
float: left;
font-size: 0.875rem;
box-sizing: border-box;
padding: 0.125rem;
text-align: center;
> span {
display: block;
line-height: 1;
margin: 0.5rem 0;
}
}
.bar-track {
position: relative;
overflow: hidden;
height: 200px;
}
.bar-val {
position: absolute;
bottom: 0; top: 100%;
left: 0; right: 0;
transition: top 250ms ease-in-out, background 500ms ease-in-out;
background: $c-neg;
box-sizing: border-box;
border-radius: 0.125rem;
padding: 0.25rem;
&.winning {
background: $c-pos;
}
}
}
[ng-controller] {
max-width: 1000px;
min-width: 600px;
margin: 2rem auto;
}
[ng-cloak] {
display: none;
}
.label {
margin: 0.5em 0;
font-size: 2rem;
}
.input-wrap {
position: relative;
width: 50%;
min-width: 280px;
margin: 0 auto;
input {
width: 100%;
display: block;
}
button {
display: block;
position: absolute;
padding: 0.5rem;
font-size: 1rem;
top: 50%; right: 1rem;
transform: translateY(-50%) scale(1);
&:hover {
transform: translateY(-50%) scale(1.05);
}
}
}
input, button {
outline: none;
appearance: none;
border: none;
box-sizing: border-box;
padding: 1rem 1rem;
border-radius: 0.125rem;
font-family: Quicksand;
font-weight: 400;
font-size: 1.5rem;
text-align: center;
}
.button {
display: block;
}
input {
background: rgba(white,0.2);
&:focus {
background: rgba(white,0.4);
}
}
button {
text-transform: uppercase;
border: 1px solid rgba(white,0.2);
background: black;
}
.button {
margin: 0 auto;
width: 50%;
min-width: 240px;
&.fight {
background-color: $c-primary;
animation: glow 2s ease-in-out infinite;
&:hover {
animation: none;
}
&:disabled {
opacity: 0.5;
animation: none;
}
}
&:hover:not(:disabled) {
transform: scale(1.05);
}
}
@keyframes glow {
0%, 100% { box-shadow: 0px 0px 0px 0px $c-primary; }
50% { box-shadow: 0px 0px 20px 0px $c-primary; }
}
p {
text-align: center;
small {
color: rgba(white,0.8);
font-style: italic;
}
}
h1, h2 {
font-family: Quicksand;
text-transform: uppercase;
font-weight: 400;
line-height: 1;
text-align: center;
color: #FFF;
}
h1 {
position: relative;
font-size: 40px;
img {
vertical-align: middle;
width: 100px; height: auto;
z-index: -1;
}
}
h2 {
margin-top: 0px;
}
a {
text-decoration: none;
color: white;
&:hover {
color: $c-primary;
}
}
body {
font-family: Quicksand;
background: #111;
background: linear-gradient(
bottom right,
#111, #222
);
color: white;
}
html, body {
min-height: 100vh;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment