JSFiddle - React, Tailwind, and code Playground
HTML
<p>Ut non enim eleifend felis pretium feugiat. Duis vel nibh at velit scelerisque suscipit. Donec sodales sagittis magna. Fusce egestas elit eget lorem. Cras risus ipsum, faucibus ut, ullamcorper id, varius ac, leo.</p>
<p>Proin pretium, leo ac pellentesque mollis, felis nunc ultrices eros, sed gravida augue augue mollis justo. Sed cursus turpis vitae tortor. Suspendisse non nisl sit amet velit hendrerit rutrum. Ut a nisl id ante tempus hendrerit. Vestibulum facilisis, purus nec pulvinar iaculis, ligula mi congue nunc, vitae euismod ligula urna in dolor.</p>
<p>Nullam sagittis. Sed a libero. Donec venenatis vulputate lorem. Donec elit libero, sodales nec, volutpat a, suscipit non, turpis. Praesent congue erat at massa.</p>
<div id="lightbulb-fx">
<div id="lightbulb-emitter">
<img src="http://i.imgur.com/kNvanMw.png" />
</div>
</div>
<p>Aliquam erat volutpat. Aliquam erat volutpat. Fusce ac felis sit amet ligula pharetra condimentum. Etiam rhoncus. Phasellus dolor.</p>
<p>Sed augue ipsum, egestas nec, vestibulum et, malesuada adipiscing, dui. Quisque id odio. Curabitur at lacus ac velit ornare lobortis. Aliquam lobortis. Sed a libero.</p>
CSS
body{
overflow-x: hidden;
}
#lightbulb-fx{
position: relative;
text-align: center;
overflow: visible;
padding: 20px;
z-index: 0;
}
#lightbulb-fx > div{
position: relative;
max-width: 100%;
display: inline-block;
}
#lightbulb-fx > div > img{
max-width: 100%;
display: block;
}
#lightbulb-emitter > .em{
position: absolute;
width: 5%;
padding-top: 200%;
transform-origin: bottom center;
-webkit-transform-origin: bottom center;
-moz-transform-origin: bottom center;
-ms-transform-origin: bottom center;
-o-transform-origin: bottom center;
}
#lightbulb-emitter > .em span{
display: block;
position: absolute;
bottom: 0;
width: 100%;
padding-bottom: 100%;
background-color: #9EE9F7;
border-radius: 50%;
animation-name: em-span;
animation-duration: 3s;
animation-iteration-count: infinite;
opacity: 0;
transform-origin: center center;
}
#lightbulb-emitter > .em span:nth-child(1){
animation-delay: 0ms;
}
#lightbulb-emitter > .em span:nth-child(2){
animation-delay: 100ms;
}
#lightbulb-emitter > .em span:nth-child(3){
animation-delay: 200ms;
}
#lightbulb-emitter > .em span:nth-child(4){
animation-delay: 300ms;
}
#lightbulb-emitter > .em span:nth-child(5){
animation-delay: 400ms;
}
#lightbulb-emitter > .em span:nth-child(6){
animation-delay: 500ms;
}
#lightbulb-emitter > .em span:nth-child(7){
animation-delay: 600ms;
}
#lightbulb-emitter > .em span:nth-child(8){
animation-delay: 700ms;
}
#lightbulb-emitter > .em span:nth-child(9){
animation-delay: 800ms;
}
#lightbulb-emitter > .em span:nth-child(10){
animation-delay: 900ms;
}
@keyframes em-span{
0%{
opacity: 0;
transform: scale(0);
bottom: 0;
animation-timing-function: linear;
}
5%{
opacity: 1;
transform: scale(0.5);
bottom: 10%;
animation-timing-function: ease-in;
}
15%{
...
JavaScript
var lfx = {
elem: document.getElementById('lightbulb-emitter'),
emGaps: 30,
emCenter: [47, -98],
emDistance: -30,
emRange: 270,
emStart: -135,
pointCount: 3,
init: function(){
var as = lfx.emRange / lfx.emGaps; // Angle step size
var ca = lfx.emStart; // Current angle
// Run CW build sweep
for(var i = 0; i <= lfx.emGaps; i++){
var a = Math.ceil(ca);
console.log(a);
var e = document.createElement('div');
var t = 'transform: rotate('+ a +'deg); translateY(' + lfx.emDistance + '%) translateX(-50%); ';
t += '-webkit-transform: rotate('+ a +'deg) translateY(' + lfx.emDistance + '%) translateX(-50%); ';
t += '-moz-transform: rotate('+ a +'deg) translateY(' + lfx.emDistance + '%) translateX(-50%); ';
t += '-o-transform: rotate('+ a +'deg) translateY(' + lfx.emDistance + '%) translateX(-50%); ';
t += '-ms-transform: rotate('+ a +'deg) translateY(' + lfx.emDistance + '%) translateX(-50%); ';
t += 'left: ' + lfx.emCenter[0] + '%; ';
t += 'top: ' + lfx.emCenter[1] + '%; ';
e.setAttribute('style', t);
e.setAttribute('class', 'em');
lfx.elem.appendChild(e);
ca += as;
}
var emitters = lfx.elem.querySelectorAll('div');
console.log(emitters.length);
for(var i = 0; i < emitters.length; i++){
for(var p = 0; p < lfx.pointCount; p++){
var point = document.createElement('span');
emitters[i].appendChild(point);
}
}
}
}
lfx.init();