下面是代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Light Loader - CodePen</title>
<style>
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
</style>
<style>
body {
background: #111;
}
canvas {
background: #111;
border: 1px solid #171717;
display: block;
left: 50%;
margin: -51px 0 0 -201px;
position: absolute;
top: 50%;
}
</style>
<script src="js/prefixfree.min.js"></script>
</head>
<body>
<script src="js/index.js"></script>
<div style="text-align:center;clear:both">
<script src="/gg_bd_ad_720x90.js" type="text/javascript"></script>
<script src="/follow.js" type="text/javascript"></script>
</div>
</body>
</html>
reset.css
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
style.css
body {
background: #111;
}
canvas {
background: #111;
border: 1px solid #171717;
display: block;
left: 50%;
margin: -51px 0 0 -201px;
position: absolute;
top: 50%;
}
index.js
/*========================================================*/
/* Light Loader
/*========================================================*/
var lightLoader = function(c, cw, ch){
var _this = this;
this.c = c;
this.ctx = c.getContext('2d');
this.cw = cw;
this.ch = ch;
this.loaded = 0;
this.loaderSpeed = .6;
this.loaderHeight = 10;
this.loaderWidth = 310;
this.loader = {
x: (this.cw/2) - (this.loaderWidth/2),
y: (this.ch/2) - (this.loaderHeight/2)
};
this.particles = [];
this.particleLift = 180;
this.hueStart = 0
this.hueEnd = 120;
this.hue = 0;
this.gravity = .15;
this.particleRate = 4;
/*========================================================*/
/* Initialize
/*========================================================*/
this.init = function(){
this.loop();
};
/*========================================================*/
/* Utility Functions
/*========================================================*/
this.rand = function(rMi, rMa){return ~~((Math.random()*(rMa-rMi+1))+rMi);};
this.hitTest = function(x1, y1, w1, h1, x2, y2, w2, h2){return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1);};
/*========================================================*/
/* Update Loader
/*========================================================*/
this.updateLoader = function(){
if(this.loaded < 100){
this.loaded += this.loaderSpeed;
} else {
this.loaded = 0;
}
};
/*========================================================*/
/* Render Loader
/*========================================================*/
this.renderLoader = function(){
this.ctx.fillStyle = '#000';
this.ctx.fillRect(this.loader.x, this.loader.y, this.loaderWidth, this.loaderHeight);
this.hue = this.hueStart + (this.loaded/100)*(this.hueEnd - this.hueStart);
var newWidth = (this.loaded/100)*this.loaderWidth;
this.ctx.fillStyle = 'hsla('+this.hue+', 100%, 40%, 1)';
this.ctx.fillRect(this.loader.x, this.loader.y, newWidth, this.loaderHeight);
this.ctx.fillStyle = '#222';
this.ctx.fillRect(this.loader.x, this.loader.y, newWidth, this.loaderHeight/2);
};
/*========================================================*/
/* Particles
/*========================================================*/
this.Particle = function(){
this.x = _this.loader.x + ((_this.loaded/100)*_this.loaderWidth) - _this.rand(0, 1);
this.y = _this.ch/2 + _this.rand(0,_this.loaderHeight)-_this.loaderHeight/2;
this.vx = (_this.rand(0,4)-2)/100;
this.vy = (_this.rand(0,_this.particleLift)-_this.particleLift*2)/100;
this.width = _this.rand(1,4)/2;
this.height = _this.rand(1,4)/2;
this.hue = _this.hue;
};
this.Particle.prototype.update = function(i){
this.vx += (_this.rand(0,6)-3)/100;
this.vy += _this.gravity;
this.x += this.vx;
this.y += this.vy;
if(this.y > _this.ch){
_this.particles.splice(i, 1);
}
};
this.Particle.prototype.render = function(){
_this.ctx.fillStyle = 'hsla('+this.hue+', 100%, '+_this.rand(50,70)+'%, '+_this.rand(20,100)/100+')';
_this.ctx.fillRect(this.x, this.y, this.width, this.height);
};
this.createParticles = function(){
var i = this.particleRate;
while(i--){
this.particles.push(new this.Particle());
};
};
this.updateParticles = function(){
var i = this.particles.length;
while(i--){
var p = this.particles[i];
p.update(i);
};
};
this.renderParticles = function(){
var i = this.particles.length;
while(i--){
var p = this.particles[i];
p.render();
};
};
/*========================================================*/
/* Clear Canvas
/*========================================================*/
this.clearCanvas = function(){
this.ctx.globalCompositeOperation = 'source-over';
this.ctx.clearRect(0,0,this.cw,this.ch);
this.ctx.globalCompositeOperation = 'lighter';
};
/*========================================================*/
/* Animation Loop
/*========================================================*/
this.loop = function(){
var loopIt = function(){
requestAnimationFrame(loopIt, _this.c);
_this.clearCanvas();
_this.createParticles();
_this.updateLoader();
_this.updateParticles();
_this.renderLoader();
_this.renderParticles();
};
loopIt();
};
};
/*========================================================*/
/* Check Canvas Support
/*========================================================*/
var isCanvasSupported = function(){
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
};
/*========================================================*/
/* Setup requestAnimationFrame
/*========================================================*/
var setupRAF = function(){
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x){
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
};
if(!window.requestAnimationFrame){
window.requestAnimationFrame = function(callback, element){
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
lastTime = currTime + timeToCall;
return id;
};
};
if (!window.cancelAnimationFrame){
window.cancelAnimationFrame = function(id){
clearTimeout(id);
};
};
};
/*========================================================*/
/* Define Canvas and Initialize
/*========================================================*/
if(isCanvasSupported){
var c = document.createElement('canvas');
c.width = 400;
c.height = 100;
var cw = c.width;
var ch = c.height;
document.body.appendChild(c);
var cl = new lightLoader(c, cw, ch);
setupRAF();
cl.init();
}
prefixfree.min.js
/**
* StyleFix 1.0.3 & PrefixFree 1.0.7
* @author Lea Verou
* MIT license
*/
(function(){
if(!window.addEventListener) {
return;
}
var self = window.StyleFix = {
link: function(link) {
try {
// Ignore stylesheets with data-noprefix attribute as well as alternate stylesheets
if(link.rel !== 'stylesheet' || link.hasAttribute('data-noprefix')) {
return;
}
}
catch(e) {
return;
}
var url = link.href || link.getAttribute('data-href'),
base = url.replace(/[^\/]+$/, ''),
base_scheme = (/^[a-z]{3,10}:/.exec(base) || [''])[0],
base_domain = (/^[a-z]{3,10}:\/\/[^\/]+/.exec(base) || [''])[0],
base_query = /^([^?]*)\??/.exec(url)[1],
parent = link.parentNode,
xhr = new XMLHttpRequest(),
process;
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
process();
}
};
process = function() {
var css = xhr.responseText;
if(css && link.parentNode && (!xhr.status || xhr.status < 400 || xhr.status > 600)) {
css = self.fix(css, true, link);
// Convert relative URLs to absolute, if needed
if(base) {
css = css.replace(/url\(\s*?((?:"|')?)(.+?)\1\s*?\)/gi, function($0, quote, url) {
if(/^([a-z]{3,10}:|#)/i.test(url)) { // Absolute & or hash-relative
return $0;
}
else if(/^\/\//.test(url)) { // Scheme-relative
// May contain sequences like /../ and /./ but those DO work
return 'url("' + base_scheme + url + '")';
}
else if(/^\//.test(url)) { // Domain-relative
return 'url("' + base_domain + url + '")';
}
else if(/^\?/.test(url)) { // Query-relative
return 'url("' + base_query + url + '")';
}
else {
// Path-relative
return 'url("' + base + url + '")';
}
});
// behavior URLs shoudn鈥檛 be converted (Issue #19)
// base should be escaped before added to RegExp (Issue #81)
var escaped_base = base.replace(/([\\\^\$*+[\]?{}.=!:(|)])/g,"\\$1");
css = css.replace(RegExp('\\b(behavior:\\s*?url\\(\'?"?)' + escaped_base, 'gi'), '$1');
}
var style = document.createElement('style');
style.textContent = css;
style.media = link.media;
style.disabled = link.disabled;
style.setAttribute('data-href', link.getAttribute('href'));
parent.insertBefore(style, link);
parent.removeChild(link);
style.media = link.media; // Duplicate is intentional. See issue #31
}
};
try {
xhr.open('GET', url);
xhr.send(null);
} catch (e) {
// Fallback to XDomainRequest if available
if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.onerror = xhr.onprogress = function() {};
xhr.onload = process;
xhr.open("GET", url);
xhr.send(null);
}
}
link.setAttribute('data-inprogress', '');
},
styleElement: function(style) {
if (style.hasAttribute('data-noprefix')) {
return;
}
var disabled = style.disabled;
style.textContent = self.fix(style.textContent, true, style);
style.disabled = disabled;
},
styleAttribute: function(element) {
var css = element.getAttribute('style');
css = self.fix(css, false, element);
element.setAttribute('style', css);
},
process: function() {
// Linked stylesheets
$('link[rel="stylesheet"]:not([data-inprogress])').forEach(StyleFix.link);
// Inline stylesheets
$('style').forEach(StyleFix.styleElement);
// Inline styles
$('[style]').forEach(StyleFix.styleAttribute);
},
register: function(fixer, index) {
(self.fixers = self.fixers || [])
.splice(index === undefined? self.fixers.length : index, 0, fixer);
},
fix: function(css, raw, element) {
for(var i=0; i<self.fixers.length; i++) {
css = self.fixers[i](css, raw, element) || css;
}
return css;
},
camelCase: function(str) {
return str.replace(/-([a-z])/g, function($0, $1) { return $1.toUpperCase(); }).replace('-','');
},
deCamelCase: function(str) {
return str.replace(/[A-Z]/g, function($0) { return '-' + $0.toLowerCase() });
}
};
/**************************************
* Process styles
**************************************/
(function(){
setTimeout(function(){
$('link[rel="stylesheet"]').forEach(StyleFix.link);
}, 10);
document.addEventListener('DOMContentLoaded', StyleFix.process, false);
})();
function $(expr, con) {
return [].slice.call((con || document).querySelectorAll(expr));
}
})();
/**
* PrefixFree
*/
(function(root){
if(!window.StyleFix || !window.getComputedStyle) {
return;
}
// Private helper
function fix(what, before, after, replacement, css) {
what = self[what];
if(what.length) {
var regex = RegExp(before + '(' + what.join('|') + ')' + after, 'gi');
css = css.replace(regex, replacement);
}
return css;
}
var self = window.PrefixFree = {
prefixCSS: function(css, raw, element) {
var prefix = self.prefix;
// Gradient angles hotfix
if(self.functions.indexOf('linear-gradient') > -1) {
// Gradients are supported with a prefix, convert angles to legacy
css = css.replace(/(\s|:|,)(repeating-)?linear-gradient\(\s*(-?\d*\.?\d*)deg/ig, function ($0, delim, repeating, deg) {
return delim + (repeating || '') + 'linear-gradient(' + (90-deg) + 'deg';
});
}
css = fix('functions', '(\\s|:|,)', '\\s*\\(', '$1' + prefix + '$2(', css);
css = fix('keywords', '(\\s|:)', '(\\s|;|\\}|$)', '$1' + prefix + '$2$3', css);
css = fix('properties', '(^|\\{|\\s|;)', '\\s*:', '$1' + prefix + '$2:', css);
// Prefix properties *inside* values (issue #8)
if (self.properties.length) {
var regex = RegExp('\\b(' + self.properties.join('|') + ')(?!:)', 'gi');
css = fix('valueProperties', '\\b', ':(.+?);', function($0) {
return $0.replace(regex, prefix + "$1")
}, css);
}
if(raw) {
css = fix('selectors', '', '\\b', self.prefixSelector, css);
css = fix('atrules', '@', '\\b', '@' + prefix + '$1', css);
}
// Fix double prefixing
css = css.replace(RegExp('-' + prefix, 'g'), '-');
// Prefix wildcard
css = css.replace(/-\*-(?=[a-z]+)/gi, self.prefix);
return css;
},
property: function(property) {
return (self.properties.indexOf(property)? self.prefix : '') + property;
},
value: function(value, property) {
value = fix('functions', '(^|\\s|,)', '\\s*\\(', '$1' + self.prefix + '$2(', value);
value = fix('keywords', '(^|\\s)', '(\\s|$)', '$1' + self.prefix + '$2$3', value);
// TODO properties inside values
return value;
},
// Warning: Prefixes no matter what, even if the selector is supported prefix-less
prefixSelector: function(selector) {
return selector.replace(/^:{1,2}/, function($0) { return $0 + self.prefix })
},
// Warning: Prefixes no matter what, even if the property is supported prefix-less
prefixProperty: function(property, camelCase) {
var prefixed = self.prefix + property;
return camelCase? StyleFix.camelCase(prefixed) : prefixed;
}
};
/**************************************
* Properties
**************************************/
(function() {
var prefixes = {},
properties = [],
shorthands = {},
style = getComputedStyle(document.documentElement, null),
dummy = document.createElement('div').style;
// Why are we doing this instead of iterating over properties in a .style object? Cause Webkit won't iterate over those.
var iterate = function(property) {
if(property.charAt(0) === '-') {
properties.push(property);
var parts = property.split('-'),
prefix = parts[1];
// Count prefix uses
prefixes[prefix] = ++prefixes[prefix] || 1;
// This helps determining shorthands
while(parts.length > 3) {
parts.pop();
var shorthand = parts.join('-');
if(supported(shorthand) && properties.indexOf(shorthand) === -1) {
properties.push(shorthand);
}
}
}
},
supported = function(property) {
return StyleFix.camelCase(property) in dummy;
}
// Some browsers have numerical indices for the properties, some don't
if(style.length > 0) {
for(var i=0; i<style.length; i++) {
iterate(style[i])
}
}
else {
for(var property in style) {
iterate(StyleFix.deCamelCase(property));
}
}
// Find most frequently used prefix
var highest = {uses:0};
for(var prefix in prefixes) {
var uses = prefixes[prefix];
if(highest.uses < uses) {
highest = {prefix: prefix, uses: uses};
}
}
self.prefix = '-' + highest.prefix + '-';
self.Prefix = StyleFix.camelCase(self.prefix);
self.properties = [];
// Get properties ONLY supported with a prefix
for(var i=0; i<properties.length; i++) {
var property = properties[i];
if(property.indexOf(self.prefix) === 0) { // we might have multiple prefixes, like Opera
var unprefixed = property.slice(self.prefix.length);
if(!supported(unprefixed)) {
self.properties.push(unprefixed);
}
}
}
// IE fix
if(self.Prefix == 'Ms'
&& !('transform' in dummy)
&& !('MsTransform' in dummy)
&& ('msTransform' in dummy)) {
self.properties.push('transform', 'transform-origin');
}
self.properties.sort();
})();
/**************************************
* Values
**************************************/
(function() {
// Values that might need prefixing
var functions = {
'linear-gradient': {
property: 'backgroundImage',
params: 'red, teal'
},
'calc': {
property: 'width',
params: '1px + 5%'
},
'element': {
property: 'backgroundImage',
params: '#foo'
},
'cross-fade': {
property: 'backgroundImage',
params: 'url(a.png), url(b.png), 50%'
}
};
functions['repeating-linear-gradient'] =
functions['repeating-radial-gradient'] =
functions['radial-gradient'] =
functions['linear-gradient'];
// Note: The properties assigned are just to *test* support.
// The keywords will be prefixed everywhere.
var keywords = {
'initial': 'color',
'zoom-in': 'cursor',
'zoom-out': 'cursor',
'box': 'display',
'flexbox': 'display',
'inline-flexbox': 'display',
'flex': 'display',
'inline-flex': 'display',
'grid': 'display',
'inline-grid': 'display',
'min-content': 'width'
};
self.functions = [];
self.keywords = [];
var style = document.createElement('div').style;
function supported(value, property) {
style[property] = '';
style[property] = value;
return !!style[property];
}
for (var func in functions) {
var test = functions[func],
property = test.property,
value = func + '(' + test.params + ')';
if (!supported(value, property)
&& supported(self.prefix + value, property)) {
// It's supported, but with a prefix
self.functions.push(func);
}
}
for (var keyword in keywords) {
var property = keywords[keyword];
if (!supported(keyword, property)
&& supported(self.prefix + keyword, property)) {
// It's supported, but with a prefix
self.keywords.push(keyword);
}
}
})();
/**************************************
* Selectors and @-rules
**************************************/
(function() {
var
selectors = {
':read-only': null,
':read-write': null,
':any-link': null,
'::selection': null
},
atrules = {
'keyframes': 'name',
'viewport': null,
'document': 'regexp(".")'
};
self.selectors = [];
self.atrules = [];
var style = root.appendChild(document.createElement('style'));
function supported(selector) {
style.textContent = selector + '{}'; // Safari 4 has issues with style.innerHTML
return !!style.sheet.cssRules.length;
}
for(var selector in selectors) {
var test = selector + (selectors[selector]? '(' + selectors[selector] + ')' : '');
if(!supported(test) && supported(self.prefixSelector(test))) {
self.selectors.push(selector);
}
}
for(var atrule in atrules) {
var test = atrule + ' ' + (atrules[atrule] || '');
if(!supported('@' + test) && supported('@' + self.prefix + test)) {
self.atrules.push(atrule);
}
}
root.removeChild(style);
})();
// Properties that accept properties as their value
self.valueProperties = [
'transition',
'transition-property'
]
// Add class for current prefix
root.className += ' ' + self.prefix;
StyleFix.register(self.prefixCSS);
})(document.documentElement);
下面是运行效果: