Creating a natural flame flicker with random()!
A Pen by Joseph Fusco on CodePen.
<h1>SASS Candle Flicker</h1> | |
<input id="toggle" type="checkbox"> | |
<label for="toggle"></label> | |
<div class="candle"> | |
<div class="flicker"></div> | |
</div> |
Creating a natural flame flicker with random()!
A Pen by Joseph Fusco on CodePen.
// demonstration purposes only, please don't actually use these settings as this compiles to over 2000 lines :P | |
$color-flame--base: #FEE3AC; | |
$flame-height--base: 80px; | |
$tolerance: .3; | |
$flickers: ( | |
// opacity : frequency | |
0 : 100, | |
.23 : 30, | |
.45 : 90, | |
.32 : 40 | |
// Frequency is how many times the flame could possibly hit that opacity level for every 100 frames (increments of 10). Since the hitting is random, there is a great chance that keyframe percentages will be repeated. | |
// Keep in mind this compiles to over 2000 lines at its current settings. Try to keep your frequency below 50 for production. | |
); | |
body{ | |
background-color: #000; | |
text-align: center; | |
} | |
h1{ | |
font-family: sans-serif; | |
color: #222; | |
font-size: 3em; | |
margin: 20px 0px; | |
text-shadow: 0 -1px 2px #333; | |
} | |
.candle{ | |
width: 300px; | |
height: 300px; | |
margin: 0px auto; | |
background: url('http://i.imgur.com/4I5IR6Q.jpg') no-repeat; | |
background-size: contain; | |
position: relative; | |
} | |
.flicker{ | |
position: absolute; | |
width: 10px; | |
height: $flame-height--base; | |
border-radius: 50%; | |
bottom: 60%; | |
left: 48%; | |
background-color: $color-flame--base; | |
box-shadow: 0 0 0px 0px $color-flame--base; | |
-webkit-animation: 10s flicker infinite; | |
animation: 10s flicker infinite; | |
} | |
@keyframes flicker{ | |
$angle: 0; | |
@each $level, $frequency in $flickers{ | |
@for $i from 1 through 100{ | |
@if $i % (floor(100 / $frequency)) == 0{ | |
$r: random(100); | |
#{($r)}%{ | |
$amount: floor($i / 10); | |
$color-flame: darken($color-flame--base, $amount); | |
opacity: $level; | |
$f-blur: $i * .33; | |
$f-spread: $f-blur * .5; | |
box-shadow: 0 0 #{$f-blur}px #{$f-spread}px $color-flame; | |
@if $i % 2 == 0{ | |
$angle: $amount / 2; | |
} | |
@else{ | |
$angle: 0 - $amount / 2; | |
} | |
@if $level <= $tolerance { | |
height: 0; | |
} | |
@else if $level <= ($tolerance - $flame-height--base * .1){ | |
height: ( ($flame-height--base - $flame-height--base * .1) - 2 * $amount); | |
} | |
@else{ | |
height: ( $flame-height--base - 2 * $amount); | |
} | |
-webkit-transform: rotate(#{$angle}deg); | |
transform: rotate(#{$angle}deg); | |
} | |
} | |
} | |
} | |
} | |
// controls | |
label{ | |
position: fixed; | |
top: 300px; | |
z-index: 100; | |
left: 0; | |
right: 0; | |
margin: 0 auto; | |
width: 150px; | |
text-align: center; | |
font-family: sans-serif; | |
color: #FFF; | |
padding: 10px; | |
background-color: #E74C3C; | |
cursor: pointer; | |
border-radius: 4px; | |
&:after{ | |
content: 'remove candle'; | |
} | |
&:hover{ | |
background-color: lighten(#E74C3C,8%); | |
} | |
} | |
input{ | |
display: none; | |
&:checked{ | |
+ label{ | |
&:after{ | |
content: 'show candle'; | |
} | |
} | |
~ .candle{ | |
background: none; | |
} | |
} | |
} |