Created
July 14, 2016 22:16
-
-
Save seandogg/ef1f15a388a6ce50042b19537e173041 to your computer and use it in GitHub Desktop.
Frontend Scratch Paper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{# Frontend Experiments #} | |
<div class="row"> | |
<div class="col-xs-12 text-center"> | |
<canvas id="drawing"></canvas> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-xs-12 text-center hearted"> | |
<p>Do You Like This?</p> | |
<input id="toggle-heart" type="checkbox" /> | |
<label for="toggle-heart">❤</label> | |
</div> | |
</div> | |
</div> | |
<style> | |
/* This makes the CSS Twitter Heart // Easier to make with Sass // This is the compiled CSS output */ | |
[id='toggle-heart'] { | |
position: absolute; | |
left: -100vw; | |
} | |
[id='toggle-heart']:checked + label { | |
color: #e2264d; | |
-webkit-filter: none; | |
filter: none; | |
will-change: font-size; | |
-webkit-animation: heart 1s cubic-bezier(0.17, 0.89, 0.32, 1.49); | |
animation: heart 1s cubic-bezier(0.17, 0.89, 0.32, 1.49); | |
} | |
[id='toggle-heart']:checked + label:before, [id='toggle-heart']:checked + label:after { | |
-webkit-animation: inherit; | |
animation: inherit; | |
-webkit-animation-timing-function: ease-out; | |
animation-timing-function: ease-out; | |
} | |
[id='toggle-heart']:checked + label:before { | |
will-change: transform, border-width, border-color; | |
-webkit-animation-name: bubble; | |
animation-name: bubble; | |
} | |
[id='toggle-heart']:checked + label:after { | |
will-change: opacity, box-shadow; | |
-webkit-animation-name: sparkles; | |
animation-name: sparkles; | |
} | |
[id='toggle-heart']:focus + label { | |
text-shadow: 0 0 3px white, 0 1px 1px white, 0 -1px 1px white, 1px 0 1px white, -1px 0 1px white; | |
} | |
[for='toggle-heart'] { | |
-webkit-align-self: center; | |
-ms-flex-item-align: center; | |
align-self: center; | |
position: relative; | |
color: #888; | |
font-size: 2em; | |
-webkit-filter: grayscale(1); | |
filter: grayscale(1); | |
-webkit-user-select: none; | |
-moz-user-select: none; | |
-ms-user-select: none; | |
user-select: none; | |
cursor: pointer; | |
} | |
[for='toggle-heart']:before, [for='toggle-heart']:after { | |
position: absolute; | |
z-index: -1; | |
top: 50%; | |
left: 50%; | |
border-radius: 50%; | |
content: ''; | |
} | |
[for='toggle-heart']:before { | |
box-sizing: border-box; | |
margin: -2.25rem; | |
border: solid 2.25rem #e2264d; | |
width: 4.5rem; | |
height: 4.5rem; | |
-webkit-transform: scale(0); | |
transform: scale(0); | |
} | |
[for='toggle-heart']:after { | |
margin: -0.1875rem; | |
width: 0.375rem; | |
height: 0.375rem; | |
box-shadow: 0.32476rem -3rem 0 -0.1875rem #ff8080, -0.32476rem -2.625rem 0 -0.1875rem #ffed80, 2.54798rem -1.61656rem 0 -0.1875rem #ffed80, 1.84982rem -1.89057rem 0 -0.1875rem #a4ff80, 2.85252rem 0.98418rem 0 -0.1875rem #a4ff80, 2.63145rem 0.2675rem 0 -0.1875rem #80ffc8, 1.00905rem 2.84381rem 0 -0.1875rem #80ffc8, 1.43154rem 2.22414rem 0 -0.1875rem #80c8ff, -1.59425rem 2.562rem 0 -0.1875rem #80c8ff, -0.84635rem 2.50595rem 0 -0.1875rem #a480ff, -2.99705rem 0.35095rem 0 -0.1875rem #a480ff, -2.48692rem 0.90073rem 0 -0.1875rem #ff80ed, -2.14301rem -2.12438rem 0 -0.1875rem #ff80ed, -2.25479rem -1.38275rem 0 -0.1875rem #ff8080; | |
} | |
@-webkit-keyframes heart { | |
0%, 17.5% { | |
font-size: 0; | |
} | |
} | |
@keyframes heart { | |
0%, 17.5% { | |
font-size: 0; | |
} | |
} | |
@-webkit-keyframes bubble { | |
15% { | |
-webkit-transform: scale(1); | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 2.25rem; | |
} | |
30%, 100% { | |
-webkit-transform: scale(1); | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 0; | |
} | |
} | |
@keyframes bubble { | |
15% { | |
-webkit-transform: scale(1); | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 2.25rem; | |
} | |
30%, 100% { | |
-webkit-transform: scale(1); | |
transform: scale(1); | |
border-color: #cc8ef5; | |
border-width: 0; | |
} | |
} | |
@-webkit-keyframes sparkles { | |
0%, 20% { | |
opacity: 0; | |
} | |
25% { | |
opacity: 1; | |
box-shadow: 0.32476rem -2.4375rem 0 0rem #ff8080, -0.32476rem -2.0625rem 0 0rem #ffed80, 2.1082rem -1.26585rem 0 0rem #ffed80, 1.41004rem -1.53985rem 0 0rem #a4ff80, 2.30412rem 0.85901rem 0 0rem #a4ff80, 2.08305rem 0.14233rem 0 0rem #80ffc8, 0.76499rem 2.33702rem 0 0rem #80ffc8, 1.18748rem 1.71734rem 0 0rem #80c8ff, -1.35019rem 2.0552rem 0 0rem #80c8ff, -0.60229rem 1.99916rem 0 0rem #a480ff, -2.44865rem 0.22578rem 0 0rem #a480ff, -1.93852rem 0.77557rem 0 0rem #ff80ed, -1.70323rem -1.77366rem 0 0rem #ff80ed, -1.81501rem -1.03204rem 0 0rem #ff8080; | |
} | |
} | |
@keyframes sparkles { | |
0%, 20% { | |
opacity: 0; | |
} | |
25% { | |
opacity: 1; | |
box-shadow: 0.32476rem -2.4375rem 0 0rem #ff8080, -0.32476rem -2.0625rem 0 0rem #ffed80, 2.1082rem -1.26585rem 0 0rem #ffed80, 1.41004rem -1.53985rem 0 0rem #a4ff80, 2.30412rem 0.85901rem 0 0rem #a4ff80, 2.08305rem 0.14233rem 0 0rem #80ffc8, 0.76499rem 2.33702rem 0 0rem #80ffc8, 1.18748rem 1.71734rem 0 0rem #80c8ff, -1.35019rem 2.0552rem 0 0rem #80c8ff, -0.60229rem 1.99916rem 0 0rem #a480ff, -2.44865rem 0.22578rem 0 0rem #a480ff, -1.93852rem 0.77557rem 0 0rem #ff80ed, -1.70323rem -1.77366rem 0 0rem #ff80ed, -1.81501rem -1.03204rem 0 0rem #ff8080; | |
} | |
} | |
</style> | |
{% block javascripts %} | |
{{ parent() }} | |
<script type="text/javascript"> | |
/*** The Spiral Animation thing ***/ | |
jQuery(document).ready(function($){ | |
(function() { | |
var width = 600, | |
height = 600; | |
/*** Config - you can play around with these to see what you get! ***/ | |
var | |
// Dot radius in pixels | |
dotRadius = 3, | |
// How many dots in a full circle. Prime numbers seem to add to the effect. | |
dotCount = 19, | |
// Minimum/maximum boundaries of dot placement, measured from the centre. | |
minRadius = dotRadius * 0.4, | |
maxRadius = height * 0.4, | |
// How much further from / closer to the centre to move each successive dot. | |
radiusShift = 0.2, | |
// A multiplier to move dots further around the circle when they're further from the centre. | |
// Changing this produces the most dramatic differences in the result. | |
angleShift = 0.03; | |
/*** End config ***/ | |
// Derived values | |
var maxRadians = Math.PI * 2, | |
cx = width / 2, | |
cy = height / 2, | |
angleStep = maxRadians / dotCount, | |
hueStep = 360 / (dotCount + 1); | |
// State | |
var curAngle = 0, | |
curHue = 0, | |
curRadius = minRadius, | |
radiusDirection = 1; | |
var canvas = document.getElementById('drawing'); | |
canvas.width = width; | |
canvas.height = height; | |
var ctx = canvas.getContext('2d'); | |
ctx.translate(cx, cy); | |
ctx.strokeStyle = '#fff'; | |
function drawDot() { | |
var x = Math.sin(curAngle) * curRadius; | |
var y = Math.cos(curAngle) * curRadius; | |
ctx.save(); | |
ctx.beginPath(); | |
ctx.arc(x, y, dotRadius, 0, maxRadians); | |
ctx.fillStyle = 'hsl(' + curHue + ', 50%, 50%)'; | |
ctx.fill(); | |
ctx.stroke(); | |
ctx.restore(); | |
} | |
var stop = false; | |
function nextStep() { | |
drawDot(); | |
if (radiusDirection === 1 && curRadius >= maxRadius) radiusDirection = -1; | |
if (radiusDirection === -1 && curRadius <= minRadius) radiusDirection = 1; | |
curRadius += radiusShift * radiusDirection; | |
curHue = (curHue + hueStep) % 360; | |
var angleExtra = (curRadius / maxRadius) * angleStep * angleShift; | |
curAngle = (curAngle + angleStep + angleExtra) % maxRadians; | |
if (!stop) { | |
requestAnimationFrame(nextStep); | |
} | |
} | |
nextStep(); | |
})(); | |
}); | |
</script> | |
{% endblock %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment