Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
337 lines (323 sloc) 11.3 KB
<!DOCTYPE html>
<html lang="en">
<meta charset="utf-8" />
<title>Bertie Botts’ Every Flavour Badge</title>
@font-face {
font-family: 'FontAwesome';
src: url('fontawesome-webfont.woff?') format('woff');
font-weight: normal;
font-style: normal;
stroke: none;
fill: #E24D2B;
filter: url(#dropshadow);
stroke-linejoin: round;
fill: white;
fill: url(#stripey);
fill: none;
stroke: #EEBDA6;
stroke-width: 5;
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 20,20;
stroke: none;
fill: white;
filter: url(#innershadow);
font-family: FontAwesome;
font-weight: normal;
font-size: 96px;
filter: url(#dropshadow);
fill: url(#stripey);
text-anchor: middle;
<body id="home">
<h1>Every Badge</h1>
<svg id="svg" width="100%" height="100%" viewBox="-300 -300 600 600">
<filter id="dropshadow" height="130%">
<feGaussianBlur in="SourceAlpha" stdDeviation="3"/> <!-- stdDeviation is how much to blur -->
<feOffset dx="2" dy="2" result="offsetblur"/> <!-- how much to offset -->
<feMergeNode/> <!-- this contains the offset blurred image -->
<feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
<filter id="innershadow" height="130%">
<feOffset dx="5" dy="5" /><!-- Shadow Offset -->
<feGaussianBlur stdDeviation="3" result="offset-blur" /> <!-- Shadow Blur -->
<feComposite operator="out" in="SourceGraphic" in2="offset-blur" result="inverse" /> <!--Invert the drop shadow to create an inner shadow -->
<feFlood flood-color="black" flood-opacity="0.75" result="color" /> <!-- Color & opacity -->
<feComposite operator="in" in="color" in2="inverse" result="shadow" /> <!-- Clip color inside shadow -->
<feComposite operator="over" in="shadow" in2="SourceGraphic" /> <!-- Put shadow over original object -->
<linearGradient id="stripey" x1="0" y1="5" x2="5" y2="0" gradientUnits="userSpaceOnUse" spreadMethod="repeat">
<stop offset="0%" style="stop-color: #EE6629" />
<stop offset="50%" style="stop-color: #EE6629" />
<stop offset="51%" style="stop-color: #F1743E" />
<stop offset="100%" style="stop-color: #F1743E" />
<g id="svg" transform="translate(300,300)"></g>
var SVG_NS = '';
var svg = document.getElementById('svg');
function range(num){
var r = [];
for (var i = 0; i < num; i++){
return r;
function getPointAtDistance( p1, p2, dis ){
//get vector
var x3 = p2[0] - p1[0];
var y3 = p2[1] - p1[1];
//normalize vector
var length = Math.sqrt( x3 * x3 + y3 * y3 );
x3 /= length;
y3 /= length;
//scale vector
x3 *= dis;
y3 *= dis;
//add vector back onto initial point and return
return [p1[0] + x3, p1[1] + y3];
function dot(pt){
var c = document.createElementNS(SVG_NS, 'circle');
c.setAttribute('cx', pt[0]);
c.setAttribute('cy', pt[1]);
c.setAttribute('r', 10);
return c;
function roundedPolygon(sides, radius, cornerRadius, klass){
var angle = (Math.PI * 2) / sides;
var corners = range(sides).map(function(idx){
return [Math.cos(idx * angle + Math.PI / 6) * radius, Math.sin(idx * angle + Math.PI / 6) * radius];
// calculate midpoints
var pt = getPointAtDistance(corners[0], corners[sides - 1], cornerRadius);
var m = ['M' + pt[0] + ',' + pt[1]];
corners.forEach(function(corner, idx){
var next = corners[(idx + 1) % sides];
var p1 = getPointAtDistance(corner, next, cornerRadius);
var p2 = getPointAtDistance(next, corner, cornerRadius);
m.push('Q' + corner[0] + ',' + corner[1] + ' ' + p1[0] + ',' + p1[1]);
m.push('L' + p2[0] + ',' + p2[1]);
var poly = document.createElementNS(SVG_NS, 'path');
poly.setAttribute('class', klass);
poly.setAttribute('d', m.join(' '));
return poly;
svg.appendChild(roundedPolygon(6, 270, 20, 'edge'));
svg.appendChild(roundedPolygon(6, 250, 20, 'inner-ring'));
svg.appendChild(roundedPolygon(6, 240, 20, 'textured'));
svg.appendChild(roundedPolygon(6, 220, 20, 'stitches'));
var circle = document.createElementNS(SVG_NS, 'circle');
circle.setAttribute('cx', 0);
circle.setAttribute('cy', 0);
circle.setAttribute('r', 80);
circle.setAttribute('class', 'hole');
var text = document.createElementNS(SVG_NS, 'text');
text.setAttribute('x', 0);
text.setAttribute('y', 30);
text.setAttribute('class', 'icon');
var icons = {
glass: '\uf000',
music: '\uf001',
search: '\uf002',
envelope: '\uf003',
heart: '\uf004',
star: '\uf005',
starEmpty: '\uf006',
user: '\uf007',
film: '\uf008',
thLarge: '\uf009',
th: '\uf00a',
thList: '\uf00b',
ok: '\uf00c',
remove: '\uf00d',
zoomIn: '\uf00e',
zoomOut: '\uf010',
off: '\uf011',
signal: '\uf012',
cog: '\uf013',
trash: '\uf014',
home: '\uf015',
file: '\uf016',
time: '\uf017',
road: '\uf018',
downloadAlt: '\uf019',
download: '\uf01a',
upload: '\uf01b',
inbox: '\uf01c',
playCircle: '\uf01d',
repeat: '\uf01e',
refresh: '\uf021',
listAlt: '\uf022',
lock: '\uf023',
flag: '\uf024',
headphones: '\uf025',
volumeOff: '\uf026',
volumeDown: '\uf027',
volumeUp: '\uf028',
qrcode: '\uf029',
barcode: '\uf02a',
tag: '\uf02b',
tags: '\uf02c',
book: '\uf02d',
bookmark: '\uf02e',
print: '\uf02f',
camera: '\uf030',
font: '\uf031',
facetimeVideo: '\uf03d',
picture: '\uf03e',
pencil: '\uf040',
mapMarker: '\uf041',
okSign: '\uf058',
questionSign: '\uf059',
infoSign: '\uf05a',
screenshot: '\uf05b',
removeCircle: '\uf05c',
okCircle: '\uf05d',
banCircle: '\uf0fe',
shareAlt: '\uf064',
exclamationSign: '\uf06a',
gift: '\uf06b',
leaf: '\uf06c',
fire: '\uf06d',
eyeOpen: '\uf06e',
eyeClosed: '\uf070',
warningSign: '\uf071',
plane: '\uf072',
calendar: '\uf073',
random: '\uf074',
comment: '\uf075',
magnet: '\uf076',
retweet: '\uf079',
shoppingCart: '\uf07a',
folderClose: '\uf07b',
folderOpen: '\uf07c',
barChart: '\uf080',
twitterSign: '\uf081',
facebookSign: '\uf082',
cameraRetro: '\uf083',
key: '\uf084',
cogs: '\uf085',
comments: '\uf086',
thumbsUp: '\uf087',
thumbsDown: '\uf088',
starHalf: '\uf089',
heartEmpty: '\uf08a',
signout: '\uf08b',
pushpin: '\uf08d',
externalLink: '\uf08e',
signin: '\uf090',
trophy: '\uf091',
githubSign: '\uf092',
uploadAlt: '\uf093',
lemon: '\uf094',
phone: '\uf095',
checkEmpty: '\uf096',
bookmarkEmpty: '\uf097',
phoneSign: '\uf098',
twitter: '\uf099',
facebook: '\uf09a',
github: '\uf09b',
unlock: '\uf09c',
creditCard: '\uf09d',
rss: '\uf09e',
hdd: '\uf0a0',
bullhorn: '\uf0a1',
bell: '\uf0a2',
certificate: '\uf0a3',
handRight: '\uf0a4',
handLeft: '\uf0a5',
handUp: '\uf0a6',
handDown: '\uf0a7',
globe: '\uf0ac',
wrench: '\uf0ad',
tasks: '\uf0ae',
filter: '\uf0b0',
briefcase: '\uf0b1',
fullscreen: '\uf0b2',
group: '\uf0c0',
link: '\uf0c1',
cloud: '\uf0c2',
beaker: '\uf0c3',
paperClip: '\uf0c6',
signBlank: '\uf0c8',
magic: '\uf0d0',
truck: '\uf0d1',
pinterest: '\uf0d2',
pinterestSign: '\uf0d3',
googlePlusSign: '\uf0d4',
googlePlus: '\uf0d5',
money: '\uf0d6',
envelopeAlt: '\uf0e0',
undo: '\uf0e2',
legal: '\uf0e3',
dashboard: '\uf0e4',
commentAlt: '\uf0e5',
commentsAlt: '\uf0e6',
bolt: '\uf0e7',
sitemap: '\uf0e8',
umbrella: '\uf0e9',
lightbulb: '\uf0eb',
cloudDownload: '\uf0ed',
cloudUpdload: '\uf0ee',
userMd: '\uf0f0',
stethoscope: '\uf0f1',
suitcase: '\uf0f2',
bellAlt: '\uf0f3',
coffee: '\uf0f4',
food: '\uf0f5',
fileAlt: '\uf0f6',
building: '\uf0f7',
hospital: '\uf0f8',
ambulance: '\uf0f9',
medkit: '\uf0fa',
fighterJet: '\uf0fb',
beer: '\uf0fc',
hSign: '\uf0fd',
desktop: '\uf108',
laptop: '\uf109',
tablet: '\uf10a',
mobilePhone: '\uf10b',
spinner: '\uf110',
reply: '\uf112',
githubAlt: '\uf113'
function updateIcon(){
var names = Object.keys(icons);
var idx = Math.floor(Math.random() * names.length);
var name = names[idx];
var icon = icons[name];
document.querySelector('.icon').textContent = icon;
setTimeout(updateIcon, 1000);