- Author:
- Rauri Rochford
- Twitter:
- @
- GitHub:
- Facebook:
- Google+:
- +
- Reddit:
- /r/
- Pouet:
- Website:
- esquemedia.com
- Compo:
- classic
- Demo link:
- https://js1k.com/2012-love/demo/1071
- Shortlink:
- https://js1k.com/1071
- Blog post:
- please update here!
- Bytes:
- 886
- Chars:
- 886
- Submission
e=[];h=[];O=c.width=innerWidth;Q=c.height=innerHeight;v=32;M=Math;R=M.random;C=M.cos;Y=6.3;for(i=0;i<Y;i+=0.2)h.push([O/2+180*M.pow(M.sin(i),3),Q/2+10*-(15*C(i)-5*C(2*i)-2*C(3*i)-C(4*i))]);
for(i=0;i<v;){x=R()*O;y=R()*Q;H=80*(i/v)+280;S=40*R()+60;B=60*R()+20;f=[];for(k=0;k<v;)f[k++]={x:x,y:y,X:0,Y:0,R:1-k/v+1,S:R()+1,q:~~(R()*v),D:2*(i%2)-1,F:0.2*R()+0.7,f:"hsla("+~~H+","+~~S+"%,"+~~B+"%,.1)"};e[i++]=f}
function _(d){a.fillStyle=d.f;a.beginPath();a.arc(d.x,d.y,d.R,0,Y,1);a.closePath();a.fill()}
setInterval(function(){a.fillStyle="rgba(0,0,0,.2)";a.fillRect(0,0,O,Q);for(i=v;i--;){f=e[i];u=f[0];q=h[u.q];D=u.x-q[0];E=u.y-q[1];G=M.sqrt(D*D+E*E);10>G&&(0.95<R()?u.q=~~(R()*v):(0.99<R()&&(u.D*=-1),u.q+=u.D,u.q%=v,0>u.q&&(u.q+=v)));u.X+=-D/G*u.S;u.Y+=-E/G*u.S;u.x+=u.X;u.y+=u.Y;_(u);u.X*=u.F;u.Y*=u.F;for(k=0;k<v-1;)T=f[k],N=f[++k],N.x-=0.7*(N.x-T.x),N.y-=0.7*(N.y-T.y),_(N)}},25);
- Description
- Trails of particles describe a heart.
- Base64 encoded
ZT1bXTtoPVtdO089Yy53aWR0aD1pbm5lcldpZHRoO1E9Yy5oZWlnaHQ9aW5uZXJIZWlnaHQ7dj0zMjtNPU1hdGg7Uj1NLnJhbmRvbTtDPU0uY29zO1k9Ni4zO2ZvcihpPTA7aTxZO2krPTAuMiloLnB1c2goW08vMisxODAqTS5wb3coTS5zaW4oaSksMyksUS8yKzEwKi0oMTUqQyhpKS01KkMoMippKS0yKkMoMyppKS1DKDQqaSkpXSk7DQpmb3IoaT0wO2k8djspe3g9UigpKk87eT1SKCkqUTtIPTgwKihpL3YpKzI4MDtTPTQwKlIoKSs2MDtCPTYwKlIoKSsyMDtmPVtdO2ZvcihrPTA7azx2OylmW2srK109e3g6eCx5OnksWDowLFk6MCxSOjEtay92KzEsUzpSKCkrMSxxOn5+KFIoKSp2KSxEOjIqKGklMiktMSxGOjAuMipSKCkrMC43LGY6ImhzbGEoIit+fkgrIiwiK35+UysiJSwiK35+QisiJSwuMSkifTtlW2krK109Zn0NCmZ1bmN0aW9uIF8oZCl7YS5maWxsU3R5bGU9ZC5mO2EuYmVnaW5QYXRoKCk7YS5hcmMoZC54LGQueSxkLlIsMCxZLDEpO2EuY2xvc2VQYXRoKCk7YS5maWxsKCl9DQpzZXRJbnRlcnZhbChmdW5jdGlvbigpe2EuZmlsbFN0eWxlPSJyZ2JhKDAsMCwwLC4yKSI7YS5maWxsUmVjdCgwLDAsTyxRKTtmb3IoaT12O2ktLTspe2Y9ZVtpXTt1PWZbMF07cT1oW3UucV07RD11LngtcVswXTtFPXUueS1xWzFdO0c9TS5zcXJ0KEQqRCtFKkUpOzEwPkcmJigwLjk1PFIoKT91LnE9fn4oUigpKnYpOigwLjk5PFIoKSYmKHUuRCo9LTEpLHUucSs9dS5ELHUucSU9diwwPnUucSYmKHUucSs9dikpKTt1LlgrPS1EL0cqdS5TO3UuWSs9LUUvRyp1LlM7dS54Kz11Llg7dS55Kz11Llk7Xyh1KTt1LlgqPXUuRjt1LlkqPXUuRjtmb3Ioaz0wO2s8di0xOylUPWZba10sTj1mWysra10sTi54LT0wLjcqKE4ueC1ULngpLE4ueS09MC43KihOLnktVC55KSxfKE4pfX0sMjUpOw==
- Original source
e = [];// trails
h = [];// heart path
O = c.width = innerWidth;
Q = c.height = innerHeight;
v = 32; // num trails, num particles per trail & num nodes in heart path
M = Math;
R = M.random;
C = M.cos;
Y = 6.3;// close to 44/7 or Math.PI * 2 - 6.3 seems is close enough.
for( i = 0; i <Y; i+= .2 ) { // calculate heart nodes, from http://mathworld.wolfram.com/HeartCurve.html
h.push([
O/2 + 180*M.pow(M.sin(i), 3),
Q/2 + 10 * (-(15*C(i) - 5*C(2*i) - 2*C(3*i) - C(4*i)))
])
}
i = 0;
while (i < v ) {
x = R() * O;
y = R() * Q;
//r = R() * 50 + 200;
//b = R() * r;
//g = R() * b;
H = i/v * 80 + 280;
S = R() * 40 + 60;
B = R() * 60 + 20;
f = []; // create new trail
k = 0;
while ( k < v ) {
f[k++] = { // create new particle
x : x, // position
y : y,
X : 0, // velocity
Y : 0,
R : (1 - k/v) + 1, // radius
S : R() + 1, // acceleration
q : ~~(R() * v), // target node on heart path
//D : R()>.5?1:-1,
D : i%2*2-1, // direction around heart path
F : R() * .2 + .7, // friction
//f : "rgba(" + ~~r + "," + ~~g + "," + ~~b + ",.1)"
f : "hsla("+~~H+","+~~S+"%,"+~~B+"%,.1)" // colour
}
}
e[i++] = f; // dots are a 2d array of trails x particles
}
function render(_) { // draw particle
a.fillStyle = _.f;
a.beginPath();
a.arc(_.x, _.y, _.R, 0, Y, 1);
a.closePath();
a.fill();
}
setInterval(function(){
a.fillStyle = "rgba(0,0,0,.2)"; // clear screen
a.fillRect(0,0,O,Q);
i = v;
while (i--) {
f = e[ i ]; // get worm
u = f[ 0 ]; // get 1st particle of worm
q = h[ u.q ]; // get current node on heart path
D = u.x - q[0]; // calc distance
E = u.y - q[1];
G = M.sqrt( (D * D) + (E * E) );
if ( G < 10 ) { // has trail reached target node?
if (R() > .95 ) { // randomly send a trail elsewhere
u.q = ~~(R() * v);
} else {
if ( R() > .99) u.D *= -1; // randomly change direction
u.q += u.D;
u.q %= v;
if ( u.q < 0 ) u.q += v;
}
}
u.X += -D / G * u.S; // calculate velocity
u.Y += -E / G * u.S;
u.x += u.X; // apply velocity
u.y += u.Y;
render(u); // draw the first particle
u.X *= u.F; // apply friction
u.Y *= u.F;
k = 0;
while ( k < v-1 ) { // loop through remaining dots
T = f[ k ]; // this particle
N = f[ ++k ]; // next particle
N.x -= (N.x - T.x) * .7; // use zenos paradox to create trail
N.y -= (N.y - T.y) * .7;
render(N);
}
}
}
, 25);