HTML5加载动画

<!doctype html>
<meta charset="utf-8" />
<title>Sonic</title>

<style>

body {
background: #222;
color: #FFF;
text-align: center;
font-family: sans-serif;
font-size: .8em;
}

#container {
overflow: hidden;
padding: 20px;
522px;
margin: 0 auto;
}

#in {
overflow: hidden;
}

a { color: #FFF; }

div.l {
float: left;
margin: 20px 20px 0 0;
border: 2px solid #666;
background: #000;
height: 150px;
150px;
position: relative;
}
.sonic {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
canvas { display: block; }
</style>

<body>

<div id="container">

<h1>&lt;canvas&gt; loaders</h1>

<div id="in"></div>

<p>By <a href="http://padolsey.net">Padolsey</a> | <a href="https://github.com/padolsey/Sonic">Sonic on github</a></p>

</div>

<script>/*
* Sonic 0.2.1
* --
* https://github.com/padolsey/Sonic
* --
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details. */

(function(){

var emptyFn = function(){};

function Sonic(d) {

this.converter = d.converter;

this.data = d.path || d.data;
this.imageData = [];

this.multiplier = d.multiplier || 1;
this.padding = d.padding || 0;

this.fps = d.fps || 25;

this.stepsPerFrame = ~~d.stepsPerFrame || 1;
this.trailLength = d.trailLength || 1;
this.pointDistance = d.pointDistance || .05;

this.domClass = d.domClass || 'sonic';

this.backgroundColor = d.backgroundColor || 'rgba(0,0,0,0)';
this.fillColor = d.fillColor;
this.strokeColor = d.strokeColor;

this.stepMethod = typeof d.step == 'string' ?
stepMethods[d.step] :
d.step || stepMethods.square;

this._setup = d.setup || emptyFn;
this._teardown = d.teardown || emptyFn;
this._preStep = d.preStep || emptyFn;

this.pixelRatio = d.pixelRatio || null;

this.width = d.width;
this.height = d.height;

this.fullWidth = this.width + 2 * this.padding;
this.fullHeight = this.height + 2 * this.padding;

this.domClass = d.domClass || 'sonic';

this.setup();

}

var argTypes = Sonic.argTypes = {
DIM: 1,
DEGREE: 2,
RADIUS: 3,
OTHER: 0
};

var argSignatures = Sonic.argSignatures = {
arc: [1, 1, 3, 2, 2, 0],
bezier: [1, 1, 1, 1, 1, 1, 1, 1],
line: [1,1,1,1]
};

var pathMethods = Sonic.pathMethods = {
bezier: function(t, p0x, p0y, p1x, p1y, c0x, c0y, c1x, c1y) {

t = 1-t;

var i = 1-t,
x = t*t,
y = i*i,
a = x*t,
b = 3 * x * i,
c = 3 * t * y,
d = y * i;

return [
a * p0x + b * c0x + c * c1x + d * p1x,
a * p0y + b * c0y + c * c1y + d * p1y
]

},
arc: function(t, cx, cy, radius, start, end) {

var point = (end - start) * t + start;

var ret = [
(Math.cos(point) * radius) + cx,
(Math.sin(point) * radius) + cy
];

ret.angle = point;
ret.t = t;

return ret;

},
line: function(t, sx, sy, ex, ey) {
return [
(ex - sx) * t + sx,
(ey - sy) * t + sy
]
}
};

var stepMethods = Sonic.stepMethods = {

square: function(point, i, f, color, alpha) {
this._.fillRect(point.x - 3, point.y - 3, 6, 6);
},

fader: function(point, i, f, color, alpha) {

this._.beginPath();

if (this._last) {
this._.moveTo(this._last.x, this._last.y);
}

this._.lineTo(point.x, point.y);
this._.closePath();
this._.stroke();

this._last = point;

}

}

Sonic.prototype = {

calculatePixelRatio: function(){

var devicePixelRatio = window.devicePixelRatio || 1;
var backingStoreRatio = this._.webkitBackingStorePixelRatio
|| this._.mozBackingStorePixelRatio
|| this._.msBackingStorePixelRatio
|| this._.oBackingStorePixelRatio
|| this._.backingStorePixelRatio
|| 1;

return devicePixelRatio / backingStoreRatio;
},

setup: function() {

var args,
type,
method,
value,
data = this.data;

this.canvas = document.createElement('canvas');
this._ = this.canvas.getContext('2d');

if(this.pixelRatio == null){
this.pixelRatio = this.calculatePixelRatio();
}

this.canvas.className = this.domClass;

if(this.pixelRatio != 1){

this.canvas.style.height = this.fullHeight + 'px';
this.canvas.style.width = this.fullWidth + 'px';

this.fullHeight *= this.pixelRatio;
this.fullWidth *= this.pixelRatio;

this.canvas.height = this.fullHeight;
this.canvas.width = this.fullWidth;

this._.scale(this.pixelRatio, this.pixelRatio);

} else{

this.canvas.height = this.fullHeight;
this.canvas.width = this.fullWidth;

}

this.points = [];

for (var i = -1, l = data.length; ++i < l;) {

args = data[i].slice(1);
method = data[i][0];

if (method in argSignatures) for (var a = -1, al = args.length; ++a < al;) {

type = argSignatures[method][a];
value = args[a];

switch (type) {
case argTypes.RADIUS:
value *= this.multiplier;
break;
case argTypes.DIM:
value *= this.multiplier;
value += this.padding;
break;
case argTypes.DEGREE:
value *= Math.PI/180;
break;
};

args[a] = value;

}

args.unshift(0);

for (var r, pd = this.pointDistance, t = pd; t <= 1; t += pd) {

// Avoid crap like 0.15000000000000002
t = Math.round(t*1/pd) / (1/pd);

args[0] = t;

r = pathMethods[method].apply(null, args);

this.points.push({
x: r[0],
y: r[1],
progress: t
});

}

}

this.frame = 0;

if (this.converter && this.converter.setup) {
this.converter.setup(this);
}

},

prep: function(frame) {

if (frame in this.imageData) {
return;
}

this._.clearRect(0, 0, this.fullWidth, this.fullHeight);
this._.fillStyle = this.backgroundColor;
this._.fillRect(0, 0, this.fullWidth, this.fullHeight);

var points = this.points,
pointsLength = points.length,
pd = this.pointDistance,
point,
index,
frameD;

this._setup();

for (var i = -1, l = pointsLength*this.trailLength; ++i < l && !this.stopped;) {

index = frame + i;

point = points[index] || points[index - pointsLength];

if (!point) continue;

this.alpha = Math.round(1000*(i/(l-1)))/1000;

this._.globalAlpha = this.alpha;

if (this.fillColor) {
this._.fillStyle = this.fillColor;
}
if (this.strokeColor) {
this._.strokeStyle = this.strokeColor;
}

frameD = frame/(this.points.length-1);
indexD = i/(l-1);

this._preStep(point, indexD, frameD);
this.stepMethod(point, indexD, frameD);

}

this._teardown();

this.imageData[frame] = (
this._.getImageData(0, 0, this.fullWidth, this.fullWidth)
);

return true;

},

draw: function() {

if (!this.prep(this.frame)) {

this._.clearRect(0, 0, this.fullWidth, this.fullWidth);

this._.putImageData(
this.imageData[this.frame],
0, 0
);

}

if (this.converter && this.converter.step) {
this.converter.step(this);
}

if (!this.iterateFrame()) {
if (this.converter && this.converter.teardown) {
this.converter.teardown(this);
this.converter = null;
}
}

},

iterateFrame: function() {

this.frame += this.stepsPerFrame;

if (this.frame >= this.points.length) {
this.frame = 0;
return false;
}

return true;

},

play: function() {

this.stopped = false;

var hoc = this;

this.timer = setInterval(function(){
hoc.draw();
}, 1000 / this.fps);

},
stop: function() {

this.stopped = true;
this.timer && clearInterval(this.timer);

}
};

window.Sonic = Sonic;

}());
</script>
<script>

var loaders = [

{

100,
height: 50,
padding: 10,

stepsPerFrame: 2,
trailLength: 1,
pointDistance: .03,

strokeColor: '#FF7B24',

step: 'fader',

multiplier: 2,

setup: function() {
this._.lineWidth = 5;
},

path: [

['arc', 10, 10, 10, -270, -90],
['bezier', 10, 0, 40, 20, 20, 0, 30, 20],
['arc', 40, 10, 10, 90, -90],
['bezier', 40, 0, 10, 20, 30, 0, 20, 20]
]
},

{

30,
height: 30,

stepsPerFrame: 2,
trailLength: .3,
pointDistance: .1,
padding: 10,

fillColor: '#D4FF00',
strokeColor: '#FFF',

setup: function() {
this._.lineWidth = 20;
},

path: [
['line', 0, 0, 30, 0],
['line', 30, 0, 30, 30],
['line', 30, 30, 0, 30],
['line', 0, 30, 0, 0]
]
},

{

100,
height: 100,

stepsPerFrame: 1,
trailLength: 1,
pointDistance: .025,

strokeColor: '#05E2FF',

fps: 20,

setup: function() {
this._.lineWidth = 2;
},
step: function(point, index) {

var cx = this.padding + 50,
cy = this.padding + 50,
_ = this._,
angle = (Math.PI/180) * (point.progress * 360);

this._.globalAlpha = Math.max(.5, this.alpha);

_.beginPath();
_.moveTo(point.x, point.y);
_.lineTo(
(Math.cos(angle) * 35) + cx,
(Math.sin(angle) * 35) + cy
);
_.closePath();
_.stroke();

_.beginPath();
_.moveTo(
(Math.cos(-angle) * 32) + cx,
(Math.sin(-angle) * 32) + cy
);
_.lineTo(
(Math.cos(-angle) * 27) + cx,
(Math.sin(-angle) * 27) + cy
);
_.closePath();
_.stroke();

},
path: [
['arc', 50, 50, 40, 0, 360]
]
},

{

100,
height: 50,

stepsPerFrame: 1,
trailLength: 1,
pointDistance: .1,
fps: 15,
padding: 10,
//step: 'fader',

fillColor: '#FF2E82',

setup: function() {
this._.lineWidth = 20;
},

path: [
['line', 0, 20, 100, 20],
['line', 100, 20, 0, 20]
]
},

{

100,
height: 100,

stepsPerFrame: 7,
trailLength: .7,
pointDistance: .01,
fps: 30,
fillColor: 'white',

setup: function() {
this._.lineWidth = 10;
},

path: [
['line', 20, 70, 50, 20],
['line', 50, 20, 80, 70],
['line', 80, 70, 20, 70]
]
},

{

100,
height: 100,

stepsPerFrame: 4,
trailLength: 1,
pointDistance: .01,
fps: 25,

fillColor: '#FF7B24',

setup: function() {
this._.lineWidth = 10;
},

step: function(point, i, f) {

var progress = point.progress,
degAngle = 360 * progress,
angle = Math.PI/180 * degAngle,
angleB = Math.PI/180 * (degAngle - 180),
size = i*5;

this._.fillRect(
Math.cos(angle) * 25 + (50-size/2),
Math.sin(angle) * 15 + (50-size/2),
size,
size
);

this._.fillStyle = '#63D3FF';

this._.fillRect(
Math.cos(angleB) * 15 + (50-size/2),
Math.sin(angleB) * 25 + (50-size/2),
size,
size
);

if (point.progress == 1) {

this._.globalAlpha = f < .5 ? 1-f : f;

this._.fillStyle = '#EEE';

this._.beginPath();
this._.arc(50, 50, 5, 0, 360, 0);
this._.closePath();
this._.fill();

}


},

path: [
['line', 40, 10, 60, 90]
]
},

{

100,
height: 100,

stepsPerFrame: 3,
trailLength: 1,
pointDistance: .01,
fps: 30,
step: 'fader',

strokeColor: '#D4FF00',

setup: function() {
this._.lineWidth = 6;
},

path: [
['arc', 50, 50, 20, 360, 0]
]
},

{

100,
height: 100,

stepsPerFrame: 1,
trailLength: 1,
pointDistance: .02,
fps: 30,

fillColor: '#05E2FF',

step: function(point, index) {

this._.beginPath();
this._.moveTo(point.x, point.y);
this._.arc(point.x, point.y, index * 7, 0, Math.PI*2, false);
this._.closePath();
this._.fill();

},

path: [
['arc', 50, 50, 30, 0, 360]
]

},

{

100,
height: 100,

stepsPerFrame: 1,
trailLength: 1,
pointDistance: .05,

strokeColor: '#FF2E82',

fps: 20,

setup: function() {
this._.lineWidth = 4;
},
step: function(point, index) {

var cx = this.padding + 50,
cy = this.padding + 50,
_ = this._,
angle = (Math.PI/180) * (point.progress * 360),
innerRadius = index === 1 ? 10 : 25;

_.beginPath();
_.moveTo(point.x, point.y);
_.lineTo(
(Math.cos(angle) * innerRadius) + cx,
(Math.sin(angle) * innerRadius) + cy
);
_.closePath();
_.stroke();

},
path: [
['arc', 50, 50, 40, 0, 360]
]
}

];

var d, a, container = document.getElementById('in');

for (var i = -1, l = loaders.length; ++i < l;) {

d = document.createElement('div');
d.className = 'l';

a = new Sonic(loaders[i]);

d.appendChild(a.canvas);
container.appendChild(d);

a.play();

}

</script>

</body>
原文地址:https://www.cnblogs.com/wzzl/p/4555366.html