Created
February 12, 2015 09:15
-
-
Save happyguohua/1ec223e89d1b33fde97d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!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