JSFiddle - React, Tailwind, and code Playground
by _sir
HTML
<script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script src="js/jquery.pause.min.js"></script>
<div class="row">
<div class="col-5 musicVisualizer">
<div class="bar bar1"></div>
<div class="bar bar2"></div>
<div class="bar bar3"></div>
<div class="bar bar4"></div>
<div class="bar bar5"></div>
<i class="fa fa-sort-desc fa-lg"></i>
</div>
</div>
CSS
.musicVisualizer {
margin-top: 28.5em;
width: 200px;
height: 200px; }
.bar {
background-color: #444;
width: 1rem;
position: fixed;
box-shadow: inset 0px -6px 0px 0px #5baac7; }
.bar1 {
height: 3rem;
background-repeat: no-repeat;
background-size: contain; }
.bar2 {
margin-left: 1.3rem;
height: 4rem;
background-repeat: no-repeat;
background-size: contain; }
.bar3 {
margin-left: 2.6rem;
height: 5rem;
background-repeat: no-repeat;
background-size: contain; }
.bar4 {
margin-left: 3.9rem;
height: 3rem;
background-repeat: no-repeat;
background-size: contain; }
.bar5 {
margin-left: 5.2rem;
height: 2rem;
background-repeat: no-repeat;
background-size: contain; }
JavaScript
var continueCycle = true;
$(document).ready(function(){
$('.musicVisualizer').one('click', function() {
$('.bar').stop();
continueCycle = false;
function barMorph() {
$('.bar').animate({height: '5px'}, 'easeInCubic', function() {
$('.fa-caret-right').hide();
});
$('.bar1').animate({'width': '5px'});
$('.bar2').animate({'marginTop': "+=20px", 'marginLeft': '-=21px', 'width': '5px'
}, 600);
$('.bar3').animate({'marginTop': "+=40px", 'marginLeft': '-=42px', 'width': '5px'}, 600);
$('.bar4').animate({'marginTop': "+=60px", 'marginLeft': '-=62px', 'width': '5px'}, 600);
$('.bar5').animate({'marginTop': "+=80px", 'marginLeft': '-=83px', 'width': '5px'}, 600);
}
barMorph();
});
});
// Call this to make a function used in the promise chain
function jqAnimatePromise($el, props, duration, easing) {
// We could just use bind, but the point is we need to make a function
// that will be called when the promise resolves;
return function() {
if (continueCycle === false) {
return false;
}
// This needs to return so we pass on the next promise.
return $el.animate(props, duration, easing).promise();
}
}
function bar1Animate() {
var $bar1 = $('.bar1');
// As our function returns a function, we have to kick it off
// Which is why there are an "extra" pair of parentheses
jqAnimatePromise($bar1, {height: '2rem'}, 180, 'linear')()
.then(jqAnimatePromise($bar1, {height: '5rem'}, 270, 'linear'))
.then(jqAnimatePromise($bar1, {height: '1rem'}, 360, 'linear'))
.then(jqAnimatePromise($bar1, {height: '3rem'}, 180, 'linear'))
.then(function() {
if (continueCycle) {
bar1Animate();
}
});
}
// I've split up the functions so that eash bar has its own process.
// Because we know there are certain repetitions, we can simplify
function...