1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
var canvas, ctx;
var canvasW, canvasH;
var particle;
var attractors = [];
var maxDistance;
document.addEventListener( 'DOMContentLoaded', init, false );
function init() {
canvas = document.querySelector('canvas');
ctx = canvas.getContext('2d');
// set size
canvasW = canvas.width = window.innerWidth - 20;
canvasH = canvas.height = window.innerHeight - 80;
canvas.addEventListener( 'mousedown', onMousedown, false );
particle = new Particle( canvasW / 2, canvasH / 2 );
var x0 = canvasW * 0.2;
var x1 = canvasW * 0.8;
attractors.push( new Attractor( x0, canvasH / 2 ) );
attractors.push( new Attractor( x1, canvasH / 2 ) );
maxDistance = Math.abs( x1 - x0 ) * 0.5;
animate();
}
// -------------------------- animate, render, update -------------------------- //
;
function animate() {
// apply force of attractors to particle
if ( !isDragging ) {
for ( var i=0, len = attractors.length; i < len; i++ ) {
var attractor = attractors[i];
var distance = attractor.x - particle.x;
var sign = distance < 0 ? -1 : 1;
// normalize
var force = Math.abs( distance ) < maxDistance ?
Math.abs( distance ) / maxDistance : 0;
force *= 8;
force = distance < 0 ? -force : force;
// var force = Math.abs( distance ) <= maxDistance ? distance : 0;
// force *= 0.05;
particle.applyForce( force );
}
}
particle.update();
// wrap around
if ( !isDragging ) {
particle.x = ( particle.x + canvasW ) % canvasW;
}
render();
rAF( animate );
}
function render() {
ctx.clearRect( 0, 0, canvasW, canvasH );
// render particle
ctx.fillStyle = 'hsla(0, 100%, 50%, 0.5)';
ctx.beginPath();
ctx.arc( particle.x, particle.y, 15, 0, Math.PI * 2, true );
ctx.fill();
ctx.closePath();
// render attractor
ctx.fillStyle = 'hsla(240, 100%, 50%, 0.5)';
for ( var i=0, len = attractors.length; i < len; i++ ) {
var attractor = attractors[i];
ctx.beginPath();
ctx.arc( attractor.x, attractor.y, 8, 0, Math.PI * 2, true );
ctx.fill();
ctx.closePath();
}
}
// -------------------------- mouse -------------------------- //
var isDragging = false;
function onMousedown( event ) {
event.preventDefault();
isDragging = true;
window.addEventListener( 'mousemove', onMousemove, false );
window.addEventListener( 'mouseup', onMouseup, false );
particle.x = event.pageX;
particle.velocity = 0;
}
var previousX;
var previousTime;
var currentTime;
function onMousemove( event ) {
// previous
previousX = particle.x;
previousTime = currentTime;
// current
particle.x = event.pageX;
currentTime = new Date();
}
function onMouseup( event ) {
if ( previousX ) {
particle.velocity = ( particle.x - previousX ) / ( currentTime - previousTime );
particle.velocity *= 17;
previousX = null;
}
// console.log( particle.velocity );
isDragging = false;
window.removeEventListener( 'mousemove', onMousemove, false );
window.removeEventListener( 'mousemove', onMouseup, false );
}
|