Ajax Loader
HTML
  <canvas id="surface"></canvas>
1
  <canvas id="surface"></canvas>
2
 
 
CSS
body {
1
body {
2
    background: #222;
3
  }
 
JavaScript
var PI_BY_180 = Math.PI / 180,
1
var PI_BY_180 = Math.PI / 180,
2
  G = 20,
3
  springConstant = 0.4,
4
  dampingConstant = 0.05,
5
  friction = 0.90,
6
  epsilon = 0.2,
7
  KEYS = {
8
    LEFT: 37,
9
    UP: 38,
10
    RIGHT: 39,
11
    DOWN: 40
12
  };
13
 
14
var c = surface,
15
  ctx = c.getContext('2d'),
16
  cw = window.innerWidth,
17
  ch = window.innerHeight,
18
  last_time = Date.now(),
19
  particles = [],
20
  selectedParticle = 0,
21
  keys = {},
22
  maxStringLength = 300;
23
 
24
function drawRect(fill_color, x, y, width, height, _ctx) {
25
  _ctx = _ctx || ctx;
26
  _ctx.beginPath();
27
  _ctx.fillStyle = fill_color || '#e22';
28
  _ctx.rect(x, y, width, height);
29
  _ctx.fill();
30
}
31
 
32
function drawCircle(fill_color, x, y, radius) {
33
  ctx.beginPath();
34
  ctx.fillStyle = fill_color;
35
  ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
36
  ctx.fill();
37
}
38
 
39
function drawLine(color, x1, y1, x2, y2, thickness) {
40
  ctx.beginPath();
41
  ctx.strokeStyle = color;
42
  if (thickness !== undefined) {
43
    ctx.lineWidth = thickness;
44
  }
45
  ctx.strokeStyle = color;
46
  ctx.moveTo(x1, y1);
47
  ctx.lineTo(x2, y2);
48
  ctx.stroke();
49
}
50
 
51
function Particle (params) {
52
  this.speedX = 0;
53
  this.speedY = 0;
54
  this.thrust = 2050;
55
  _.extend(this, params);
56
  this.ox = this.x;
57
  this.oy = this.y;
58
  this.color = 'rgb(' + random(10, 350) + ', 247, 0)';
59
}
60
 
61
Particle.prototype.doThrust = function(dx, dy) {
62
  this.thrustData = {
63
    dx: dx === undefined ? 0 : dx,
64
    dy: dy === undefined ? 0 : dy
65
  };
66
};
67
 
68
Particle.prototype.update = function(dt) {
69
  var accX, accY;
70
 
71
  if (selectedParticle === this.id) {
72
    if (keys[KEYS.LEFT]) this.speedX -= this.thrust * dt;
73
    if (keys[KEYS.RIGHT]) this.speedX += this.thrust * dt;
74
    if (keys[KEYS.UP]) this.speedY -= this.thrust * dt;
75
    if (keys[KEYS.DOWN]) this.speedY += this.thrust * dt;
76
  }
77
 
78
  if (this.thrustData) {
79
    this.speedX += this.thrustData.dx * this.thrust * 0.4 * (this.mass) * dt;
80
    this.speedY += this.thrustData.dy * this.thrust * 0.4 * (this.mass) * dt;
81
    this.thrustData = null;
82
  }
83
 
84
  accX = -springConstant * (this.x - this.ox) - dampingConstant * this.speedX;
85
  accY = -springConstant * (this.y - this.oy) - dampingConstant * this.speedY;
86
 
87
  this.speedX +=  accX;
88
  this.speedY +=  accY;
89
 
90
  if (Math.abs(this.speedX) < epsilon) {
91
    this.speedX = 0;
92
  }
93
  if (Math.abs(this.speedY) < epsilon) {
94
    this.speedY = 0;
95
  }
96
  this.x += this.speedX * dt;
97
  this.y += this.speedY * dt;
98
};
99
 
100
Particle.prototype.draw = function() {
101
  // var color = 'rgb(' + random(10, 350) + ', 247, 0)';
102
  // var color = selectedParticle === this.id ? 'rgb(118, 247, 0)' : 'rgb(118, 247, 0)';
103
  drawCircle(this.color, 0, 0, 0.7 * this.mass);
104
 
105
  ctx.font = '9pt Arial';
106
    ctx.textAlign = 'center';
107
    ctx.fillStyle = '#000';
108
    // ctx.fillText(String.fromCharCode(65 + this.id), -18, 0);
109
};
110
 
111
function addListeners () {
112
  document.addEventListener('keydown', function (e) {
113
    keys[e.which] = true;
114
    if ([KEYS.UP, KEYS.DOWN, KEYS.LEFT, KEYS.RIGHT].indexOf(e.which) === -1) {
115
      selectedParticle = e.which - 65;
116
    }
117
  });
118
 
119
  document.addEventListener('keyup', function (e) {
120
    keys[e.which] = false;
121
    // selectedParticle = -1;
122
  });
123
}
124
 
125
function init () {
126
  c.width = cw;
127
  c.height = ch;
128
 
129
  var angle = 0,
130
    count = 180,
131
    angleDiff = 720 / count,
132
    displacement = 0,
133
    radius = count * 2;
134
 
135
  for(var i = count; i--; angle += angleDiff) {
136
    particles.push(new Particle({
137
      x: cw / 2 + Math.cos(angle * PI_BY_180) * radius + random(-displacement, displacement),
138
      y: ch / 2 + Math.sin(angle * PI_BY_180) * radius + random(-displacement, displacement),
139
      mass: count * 2 - i * 2,
140
      id: i
141
    }));
142
  }
143
 
144
  var pi = 0,
145
    dx = [1, -1][random(1)],
146
    dy = [1, -1][random(1)];
147
 
148
  setInterval(function () {
149
    // var p = particles[random(0, particles.length - 1)];
150
    var p = particles[pi];
151
    if (pi === particles.length) {
152
      var p = particles[pi = 0];
153
      dx = [1, -1][random(1)];
154
      dy = [1, -1][random(1)];
155
    }
156
    p.doThrust(dx, dy);
157
    pi++;
158
  }, 20);
159
 
160
  addListeners();
161
  loop();
162
}
163
 
164
function drawStrings () {
165
  var p2,
166
    dist,
167
    ratio,
168
    stringColor,
169
    stringThickness;
170
 
171
  for (var i = particles.length; i--;) {
172
    if (!i) {
173
      p2 = particles[particles.length - 1];
174
    }
175
    else {
176
      p2 = particles[i - 1];
177
    }
178
 
179
    dist = distance(particles[i].x, particles[i].y, p2.x, p2.y);
180
    ratio = dist / maxStringLength;
181
    stringColor = 'hsl(0, 0%, ' + ratio * 100 + '%)';
182
    stringThickness = parseInt(5 / ratio, 10);
183
    if (stringThickness > 5) {
184
      stringThickness = 5;
185
    }
186
    drawLine(stringColor, particles[i].x, particles[i].y, p2.x, p2.y, stringThickness);
187
  }
188
}
189
 
190
function loop () {
191
  var current_time = Date.now(),
192
    dt = (current_time - last_time) / 1000;
193
 
194
  last_time = current_time;
195
 
196
  ctx.clearRect(0, 0, cw, ch);
197
 
198
 
199
  particles.forEach(function (obj) {
200
    ctx.save();
201
    // if (!isNaN(obj.alpha)
202
    obj.update(dt);
203
 
204
    ctx.globalComposition = "overlay";
205
 
206
    !isNaN(obj.x) && !isNaN(obj.y) && ctx.translate(obj.x, obj.y);
207
    !isNaN(obj.scale_x) && !isNaN(obj.scale_y) && ctx.scale(obj.scale_x, obj.scale_y);
208
    !isNaN(obj.scale) && ctx.scale(obj.scale, obj.scale);
209
    !isNaN(obj.rotation) && ctx.rotate(obj.rotation * PI_BY_180);
210
    !isNaN(obj.alpha) && (ctx.globalAlpha = obj.alpha);
211
    obj.draw();
212
 
213
    ctx.restore();
214
  });
215
 
216
  // drawStrings();
217
 
218
  requestAnimationFrame(loop);
219
}
220
 
221
function random (start, end) {
222
  if (arguments.length < 2) {
223
    end = start;
224
    start = 0;
225
  }
226
  return ~~(Math.random() * (end - start + 1)) + start;
227
}
228
 
229
function distance (x1, y1, x2, y2) {
230
  return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
231
}
232
 
233
 
234
_ = {};
235
_.extend = function (obj) {
236
  [].slice.call(arguments, 1).forEach (function (source) {
237
    if (source) {
238
      for (var prop in source) {
239
        obj[prop] = source[prop];
240
      }
241
    }
242
  });
243
  return obj;
244
};
245
 
246
init();
 

Googly pipe

CSSDeck G+