Skip to content

Instantly share code, notes, and snippets.

@happyguohua
Created February 12, 2015 09:15
Show Gist options
  • Select an option

  • Save happyguohua/1ec223e89d1b33fde97d to your computer and use it in GitHub Desktop.

Select an option

Save happyguohua/1ec223e89d1b33fde97d to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Loading...</title>
<style>
html,
body {
padding: 0;
margin: 0;
}
ul,
li {
margin: 0;
padding: 0;
list-style: none;
}
li {
position: relative;
height: 50px;
float: left;
width: 25%;
}
canvas {
position: absolute;
left: 0;
}
p {
padding: 15px;
}
.container {
min-width: 768px;
width: 80%;
margin:0 auto;
position: relative;
color: #ecedef;
}
.step {
height: 38px;
width: 38px;
background-color: #fff;
position: absolute;
left: 50%;
top: 4px;
margin-left: -21px;
border-radius: 50%;
border: 2px solid #ecedef;
text-align: center;
font-size: 120%;
line-height: 34px;
}
.checked {
width: 10px;
height: 8px;
background-image: url("icon-checked.png");
position: absolute;
top: 50%;
left: 50%;
margin-top: -4px;
margin-left: -5px;
z-index: 9999;
-moz-transform: rotateX(90deg) ;
-ms-transform: rotateX(90deg) ;
-webkit-transform: rotateX(90deg);
transform: rotateX(90deg);
transform-style: preserve-3d;
transition: all .3s linear;
}
.checked.active {
-moz-transform: rotateX(0deg) ;
-ms-transform: rotateX(0deg) ;
-webkit-transform: rotateX(0deg);
transform: rotateX(0deg);
}
.progress-line {
position: absolute;
top: 25px;
height: 2px;
width: 100%;
box-sizing: border-box;
background: -webkit-linear-gradient(left, rgba(236,237,239,0) 0%,rgba(236,237,239,1) 5%,rgba(236,237,239,1) 95%,rgba(236,237,239,0) 100%); /* Chrome10+,Safari5.1+ */
background: -moz-linear-gradient(left, rgba(236,237,239,0) 0%,rgba(236,237,239,1) 5%,rgba(236,237,239,1) 95%,rgba(236,237,239,0) 100%); /* Chrome10+,Safari5.1+ */
background: -ms-linear-gradient(left, rgba(236,237,239,0) 0%,rgba(236,237,239,1) 5%,rgba(236,237,239,1) 95%,rgba(236,237,239,0) 100%); /* Chrome10+,Safari5.1+ */
background: linear-gradient(left, rgba(236,237,239,0) 0%,rgba(236,237,239,1) 5%,rgba(236,237,239,1) 95%,rgba(236,237,239,0) 100%); /* Chrome10+,Safari5.1+ */
}
.loading-message {
color: #555;
text-align: center;
}
.loading-message p {
-moz-transform: translateX(-10px);
-ms-transform: translateX(-10px);
-webkit-transform: translateX(-10px);
transform: translateX(-10px);
opacity: 0;
}
.loading-message p.show {
-moz-transform: translateX(0) ;
-ms-transform: translateX(0) ;
-webkit-transform: translateX(0);
transform: translateX(0);
transition: all .2s linear;
opacity: 1;
}
.loading-bar {
height: 50px;
}
</style>
</head>
<body>
<div class="container">
<div class="loading-bar">
<span class="progress-line"></span>
<span class="progress-line progress-line-highlight"></span>
<ul>
<li>
<div class="step">
1
<span class="checked"></span>
</div>
</li>
<li>
<div class="step">
2
<span class="checked"></span>
</div>
</li>
<li>
<div class="step">
3
<span class="checked"></span>
</div>
</li>
<li>
<div class="step">
4
<span class="checked"></span>
</div>
</li>
</ul>
<canvas id="myCanvas" height="50px" width="900px"></canvas>
</div>
<div class="loading-message">
<p class="hide" style="display: none">Confirming your class entering request</p>
<p class="hide" style="display: none">Your class entering request is confirmed</p>
<p class="hide" style="display: none">Assigning teacher to your class, it my take a few minutes. Please be patient...</p>
<p class="hide" style="display: none">Your teacher has been assigned</p>
<p class="hide" style="display: none">Preparing virtual classroom</p>
<p class="hide" style="display: none">Virtual classroom ready</p>
<p class="hide" style="display: none">Redirecting you to your class</p>
</div>
<p style="text-align: center">
<button type="button" id="btn-start-animation">Start Animation</button>
<button type="button" id="btn-stop-animation">Stop Animation</button>
</p>
</div>
<script>
// requestAnimationFrame Shim
(function() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame || function fallbackRAF(callback) {
window.setTimeout(callback, 16.7);
};
})();
var progressLine = document.querySelector('.progress-line-highlight');
var currentProgress = 0;
var shadowSteps = 0;
var colorValue = 'rgba(53,57,63,';
var containerWidthStyle = window.getComputedStyle(progressLine).getPropertyValue('width');
var containerWidth = Number(containerWidthStyle.substring(0, containerWidthStyle.length - 2));
var stepWidth = Math.floor(containerWidth / 4);
var steps = [];
var lineSteps;
for (var index = 0, length = 4; index < length; index++) {
if (index == 0) {
steps.push(stepWidth / 2);
} else {
steps.push(steps[index - 1] + stepWidth);
};
}
lineSteps = steps.map(function(value) {
return value - 20;
});
lineSteps.push(containerWidth);
lineSteps.slice().forEach(function(value, index, cloneLineSteps) {
if (index === 0) {
value = value / 2;
} else {
value = cloneLineSteps[index - 1] + (value - cloneLineSteps[index - 1]) / 2;
}
lineSteps.splice(index * 2, 0, value);
})
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var y = 25;
var radius = 20;
var stepPerc = Math.PI / 100;
var quart = Math.PI;
var curPerc = 0;
canvas.width = containerWidth;
context.lineWidth = 2;
context.fillStyle = "#35393f";
context.strokeStyle = '#35393f';
function generateCirle(start, endPercentage) {
var x = start;
return new Promise(function(resolve) {
function animate(current) {
context.clearRect(x - radius - 1, 0, radius * 2 + 10, radius * 2 + 10);
context.beginPath();
context.arc(x, y, radius, quart - curPerc, quart + curPerc, false)
context.stroke();
curPerc += stepPerc * 5;
if (curPerc <= Math.PI * endPercentage) {
requestAnimationFrame(function () {
animate(curPerc);
});
} else {
resolve();
}
}
animate();
});
}
function drawShadow(start) {
return new Promise(function(resolve) {
function drawCircle() {
context.beginPath();
context.arc(start, y, radius * (shadowSteps / 100), 0, Math.PI*2, false);
context.fill();
if ((shadowSteps += 10) <= 100) {
requestAnimationFrame(function() {
drawCircle();
});
} else {
resolve();
}
}
drawCircle();
})
}
var messageList = [].slice.call(document.querySelectorAll('.loading-message p'));
function animateMessage(index) {
if (index % 6 == 0) {
index = index / 6;
} else {
return;
}
messageList.forEach(function(message, indexMessage) {
message.style.cssText = 'display: none';
if (index === indexMessage) {
message.style.cssText = 'display: block';
window.setTimeout(function() {
message.className = 'hide show'
}, 5);
} else {
message.className = 'hide';
}
});
}
function generateProgress(endPosition) {
var prefixVendor = [
'-webkit-linear-gradient',
'-moz-linear-gradient',
'-ms-linear-gradient',
'linear-gradient'
],
start = '(left, ',
firstStep = '0) 0',
lastStep = '0) 100',
endPercentage = endPosition / containerWidth * 100;
return new Promise(function(resolve) {
function animateProgress() {
var pathArray = [],
breakPoint,
applyStyle = '',
suffixStyle;
currentProgress += 0.5;
if (currentProgress > 100) {
currentProgress = 100;
}
if (currentProgress <= 5 && currentProgress > 0) {
breakPoint = (currentProgress / 5);
pathArray.push(breakPoint + ') ' + currentProgress);
pathArray.push('0) ' + currentProgress);
} else if (currentProgress > 5 && currentProgress < 95) {
pathArray.push('1) 5');
pathArray.push('1) ' + currentProgress);
pathArray.push('0) ' + currentProgress);
} else if (currentProgress >= 95 && currentProgress <= 100) {
breakPoint = (1 - (currentProgress - 95) / 5);
pathArray.push('1) 5');
pathArray.push('1) 95');
pathArray.push(breakPoint + ') ' + currentProgress)
}
pathArray.unshift(firstStep);
pathArray.push(lastStep);
suffixStyle = colorValue + pathArray.join('%,' + colorValue) + '%)';
prefixVendor.forEach(function(prefix) {
applyStyle += ';background:' + prefix + start + suffixStyle;
});
progressLine.style.cssText = applyStyle;
if (currentProgress < endPercentage) {
requestAnimationFrame(animateProgress);
} else {
resolve();
}
}
animateProgress();
})
}
var animateQuenue = [];
function generateQueneList(index) {
animateQuenue.push(function() {
curPerc = 0;
shadowSteps = 0;
return generateProgress(lineSteps[index * 2]);
},
function() {
return generateProgress(lineSteps[index * 2 + 1]);
},
function() {
return generateCirle(steps[index], .5);
},
function() {
return generateCirle(steps[index], 1);
},
function() {
return drawShadow(steps[index]);
},
function() {
return new Promise(function(resolve){
document.querySelectorAll('.checked')[index].className =
document.querySelectorAll('.checked')[index].className + ' active';
resolve();
})
});
}
steps.forEach(function(value, index){
generateQueneList(index);
});
animateQuenue.push(function() {
return generateProgress(lineSteps[lineSteps.length - 1]);
});
var runnerQuene = (function() {
var isStopped = false;
var steps = 0;
function stop() {
isStopped = true;
}
function resume() {
isStopped = false;
start();
}
function start() {
animateQuenue.slice(steps).reduce(function(first, second, index) {
return first.then(function() {
if (index != 0) {
if (++steps % 6 == 0) {
stop();
}
}
if (isStopped) {
throw new Error('error');
}
animateMessage(steps);
return second();
});
}, Promise.resolve()).catch(function(){});
}
return {
stop: stop,
resume: resume,
start: start
}
})();
document.querySelector('#btn-stop-animation').addEventListener('click', function() {
runnerQuene.stop();
}, false);
document.querySelector('#btn-start-animation').addEventListener('click', function() {
runnerQuene.resume();
}, false);
/*
function generateQuene(index) {
curPerc = 0;
shadowSteps = 0;
return generateProgress(lineSteps[index * 2])
.then(function(){
return new Promise(function(resolve) {
window.setTimeout(resolve, 500)
})
})
.then(function(){
return generateProgress(lineSteps[index * 2 + 1]);
})
.then(function(){
return generateCirle(steps[index], .5);
})
.then(function(){
return generateCirle(steps[index], 1)
})
.then(function(){
return drawShadow(steps[index]);
})
.then(function(){
document.querySelectorAll('.checked')[index].className =
document.querySelectorAll('.checked')[index].className + ' active';
});
}
steps.reduce(function(first, second, index) {
return first.then(function() {
return generateQuene(index);
});
}, Promise.resolve())
.then(function() {
return generateProgress(lineSteps[lineSteps.length - 1]);
});
*/
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment