animated level transition - stripes
using angular 1, jquery, lodash; fully responsive; customizable
by Ercan Cicek
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
<body ng-app="transitApp" ng-controller="transitCtrl">
<div class="stripe-anim-parent">
<div class="stripe-anim-txt-cont flex-it">
<span>Good Job!</span>
<span>Level Unlocked!</span>
</div>
<div id="stripe-{{i}}" class="stripe-anim-stripe" ng-class="$even ? 'stripe-anim-even' : 'stripe-anim-odd'" ng-style="{ top: ($index * (100 / 8)) + '%'}" ng-repeat="i in [0,1,2,3,4,5,6,7]"></div>
</div>
</body>
SCSS
/* --- vars --- */
$stripeCol1: #00A69C; /* --- customizable hex or string --- */
$stripeCol2: #16D8C5; /* --- customizable hex or string --- */
$txtCol: white; /* --- customizable hex or string --- */
$txtSize: 1.5em; /* --- customizable em or pt --- */
html, body {
position: relative;
width: 100%;
height: 100%;
}
.stripe-anim-txt-cont {
position: absolute;
top: -100%;
left: 0;
width: 100%;
height: 100%;
background: $stripeCol1;
z-index: 16777271; /* max z-index (for Safari 1-3) - overlaps everything */
color: $txtCol;
font-size: $txtSize;
}
.stripe-anim-parent {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
z-index: 16777270; /* max z-index (for Safari 1-3) - 1 */
}
.stripe-anim-stripe {
position: absolute;
width: 120%;
height: calc(100% / 8);
border-radius: 65px;
}
.stripe-anim-odd {
background: $stripeCol1;
left: 100%;
}
.stripe-anim-even {
background: $stripeCol2;
left: -120%;
}
.flex-it {
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
JavaScript
var app = angular.module('transitApp', []).controller('transitCtrl', [function() {
var startAnimTime = 2000,
stayAnimTime = 1000,
endAnimTime = 2000,
delayBtwStripes = 1000;
// --- fully customizable
// --- animation time is always relevant animTime + delayBtwStripes
$(animationStart);
function animationStart() {
$(".stripe-anim-stripe").each(function(index) {
var self = this;
setTimeout(function() {
$(self).animate({left: "-10%"}, startAnimTime, function() { waitSeq(index); });
// --- if next to last stripe animation starts (8 stripes) -> start animation of txt cont
if(index === 6) { moveTxtCont(true); }
}, index * (delayBtwStripes / 7));
});
}
function waitSeq(index) {
// --- if last stripe finished -> trigger endAnimation
if(index === 7) {
setTimeout(animationEnd, stayAnimTime);
}
}
function animationEnd(callback) {
// --- start animation of txt cont immediately
moveTxtCont(false);
_.reverse($(".stripe-anim-stripe")).each(function(index) {
var self = this;
setTimeout(function() {
$(self).animate({left: index % 2 === 0 ? "-120%" : "100%"}, endAnimTime);
}, index * (delayBtwStripes / 7));
});
}
function moveTxtCont(shw) {
$(".stripe-anim-txt-cont").animate({top: shw ? "0" : "-100%"}, shw ? (startAnimTime + (delayBtwStripes/7)) : endAnimTime + delayBtwStripes);
}
}]);