This graphical demo will show plasma with a kaleidoscope effect, which sometimes produces flower shapes; click on the image to randomize the plasma generation.
_='mLwidthLheight=600;dh=/3e=dfk=2*hg=fl=2*k;n=p=q=x=[],B=1.2,C=0.4,D=O,E=-6,F=0.6;y=g.creem,m9512;A--;)x[A]=1E3*A*/256G#ad,^S>S>40U H#j@_$WearRect(m,m`0begXPh(mov 8k +k8l +l)Wip(r@A?3*n:-_rotref,A?m-400:^--Ub.YWick=){B/4;C/2;D;E-10;F/10-1}; setInterval(){s=y.da;w=0;v=q;94*m*m;A;)A%(4*m)?0:(t=p,u=v=v+O,w=w+D),t=t+4,u=u+1,z=x[t!u!v!w],511,0<z?(QB,QE,QC):(D,E,Oputy,Jp@E;q@E;H(JV,5*Vl,0ZhK-hK0Z-hKh`m,0scal-1,A=1gf,J$hk G(JKhZkll,hZlKkn@0.01},70Mh.=*random());s[--A]=eTo(1*jJ,functiY(G( ),1*j.draw|mX(-z/.getCYtext("2d"e.40sX(,255)*FLWYeNodPIe(&511|eDa(20g.H(cos(transl100+0*(atl,!]+x[#=r,j){$restor8)lX+9for(A=>n+j)),@+=J0Kk,L=c.O3.2Qz/Sn+r)+U0)};V/4-nWclXinYonZ^_n;e.`sav|Imag';for(Y=0;$='|`_^ZYXWVUSQOLKJ@>98$#! '[Y++];)with(_.split($))_=join(pop());eval(_)
Xz0nbUx3aWR0aExoZWlnaHQ9NjAwO2QTaD0ULzMDZT1kDmYTaz0yKmgDZz1mDmw9MiprO249cD1xPQZ4PVtdLEI9MS4yLEM9MC40LEQ9TyxFPS02LEY9MC42O3k9Zy5jcmUeZRdtLG0DOTUxMjtBLS07KXhbQV09MUUzKhFBKhQvMjU2A0cjYQtkLF4dG1MbPh0RUxE+NDBVIEgjakBfJA9XZWFyUmVjdCgGBm0sbQ9gDxwYBhgwD2JlZ1hQHmgoD21vdgUJOGsJK2s4bAkrbCkPV2lwKANyQEE/MypuOi1fcm90HhVyA2ULZixBP20tNDAwOl4tGAYtGBBVYi5ZV2ljaz0HKXtCAi80O0MCLzI7RAI7RQItMTA7RgIvMTAtMX07IHNldEludGVydmFsKAcpe3M9eS5kHmE7dz0wO3Y9cTs5NCptKm07QTspQSUoNCptKT8wOih0PXAsdT0Gdj12K08WLHc9dytEFiksdD10KzQWLHU9dSsxFix6PXhbdCF1IXYhd10sBDUxMSwwPHo/KFFCLFFFLFFDKTooDEQSLAxFEiwMTxIZcHV0F3ksSgNwQEU7cUBFO0goSghWLDUqVhpsLDBaaAhLFB8taBpLMFotaAhLaB8UGWAZHG0sMBlzY2FsFS0xLEE9MQNnC2YsShkkGgZoH2sDIEcoShpLaFprH2wabCxoWmwIS2sDbkAwLjAxfSw3MAMBTR5oLgI9GCoBcmFuZG9tKCkDKTsEc1stLUFdPQVlVG8oGDEqG2pKLAdmdW5jdGlZKAgDRygJKSwYMSoRagsuZHJhd3wVDAQBbVgoLXovDi5nZXRDWXRleHQoIjJkIgMPA2UuEAY0MBEBc1goEiwyNTUpKkYTTFdZZU5vZBUUAVBJFWUoFiY1MTEXfGVEHmEoGDIwGQNnLhoDSCgbAWNvcygcdHJhbnNsHhUdMTAwKxgwKigeYXQfCGwsIV0reFsjPQdyLGopeyRyZXN0b3IVOCkPbFgFKzlmb3IoQT0+bitqKSksQCs9SgYwS2ssTD1jLk8zLjJRBHovU24rcikrVRAwKX07VhQvNC1uV2NsWGluWW9uWggGXgYQEAZfbjtlLmBzYXYVfEltYWcnO2ZvcihZPTA7JD0nfGBfXlpZWFdWVVNRT0xLSkA+OTgkIyEfHh0cGxoZGBcWFRQTEhEQDw4MCwkIBwYFBAMCASdbWSsrXTspd2l0aChfLnNwbGl0KCQpKV89am9pbihwb3AoKSk7ZXZhbChfKQ==
// triangleCanvas it a temporary canvas for creating mirror segments
var triangleCanvas = c.cloneNode();
var triangleContext = triangleCanvas.getContext('2d');
// Create canvases for plasma and mirror
var plasmaCanvas = c.cloneNode();
var plasmaContext = plasmaCanvas.getContext('2d');
var angle60 = Math.PI / 3, // 60 degrees in raidans
angle120 = angle60 * 2, // 120 degrees in radians
angle240 = angle120 * 2, // 120 degrees in radians
plasmaSize = c.width = c.height = 600,
destA = 0,
p1 = 0,
p2 = 0,
p3 = 0,
p4 = 0,
cdData,
kaleidoSize = 400,
kaleidoHalf = kaleidoSize/2,
kaleidoHalfExtra = kaleidoHalf+1, // To avoid subpixel rendering artifacts
destOffset = 100;
var t1, t2, t3, t4,
aSin = [],
cd,
x,
idx,
as = 1.2, fd = 0.4, as1 = 3.2, fd1 = 3.2, ps = -6, plasmaReverseFactor=.6;
var cd = plasmaContext.createImageData(plasmaSize, plasmaSize);
idx = 512;
while (idx--) {
aSin[idx] = Math.sin(idx * Math.PI / 256) * 1E3;
}
var paintKal=function (b, c) {
a.drawImage(
triangleCanvas,
0,
0,
kaleidoSize,
kaleidoSize,
destOffset + kaleidoHalf * (Math.cos(destA+b) + Math.cos(destA+c)),
destOffset + kaleidoHalf * (Math.sin(destA+b) + Math.sin(destA+c)),
kaleidoSize,
kaleidoSize);
}
var paintPlasma=function (b, c) {
// Build clip
c += destA;
triangleContext.restore();
triangleContext.clearRect(0, 0, plasmaSize, plasmaSize);
triangleContext.save();
triangleContext.translate(kaleidoHalf, kaleidoHalf);
triangleContext.beginPath();
triangleContext.moveTo(kaleidoHalfExtra * Math.cos(c), kaleidoHalfExtra * Math.sin(c));
triangleContext.lineTo(kaleidoHalfExtra * Math.cos(c + angle120), kaleidoHalfExtra * Math.sin(c + angle120) );
triangleContext.lineTo(kaleidoHalfExtra * Math.cos(c + angle240), kaleidoHalfExtra * Math.sin(c + angle240));
triangleContext.clip();
// Paint plasma
b += idx?destA*3:-destA;
triangleContext.rotate(b);
triangleContext.drawImage(
plasmaCanvas,
idx ? plasmaSize - kaleidoSize : 0,
0,
kaleidoSize,
kaleidoSize,
-kaleidoHalf,
-kaleidoHalf,
kaleidoSize,
kaleidoSize);
}
var draw=function(b,c) {
// Begin plasma effect
cdData = cd.data;
t4 = p4;
t3 = p3;
idx = plasmaSize*plasmaSize*4;
while (idx) {
(idx%(plasmaSize*4))?0:(t1=p1,t2=p2,t3=t3+fd1&511,t4=t4+as1&511);
t1=(t1+4)&511;
t2=(t2+1)&511;
x = aSin[t1] + aSin[t2] + aSin[t3] + aSin[t4];
cdData[--idx] = 511;
if (x>0) {
cdData[--idx] = x/as;
cdData[--idx] = x/ps;
cdData[--idx] = x/fd;
} else {
cdData[--idx] = Math.min(-x/as1,255)*plasmaReverseFactor;
cdData[--idx] = Math.min(-x/ps,255)*plasmaReverseFactor;
cdData[--idx] = Math.min(-x/fd1,255)*plasmaReverseFactor;
}
}
plasmaContext.putImageData(cd, 0, 0);
p1 += ps;
p3 += ps;
// Centre triangle
paintPlasma(0,0);
paintKal((Math.PI/4-destA), (5*Math.PI/4 - destA));
// Triangle -120 degrees
paintPlasma(angle240,0);
paintKal(0, angle60);
paintKal(angle120, Math.PI);
paintKal(angle240, -angle60);
// Triangle +120 degrees
paintPlasma(angle120,0);
paintKal(0, -angle60);
paintKal(angle120, angle60);
paintKal(angle240, Math.PI);
// Mirror the newly generated plasma
plasmaContext.save();
plasmaContext.translate(plasmaSize, 0);
// Set idx to 1 to indicate we're mirrowing
plasmaContext.scale(-1, idx=1);
plasmaContext.drawImage(plasmaCanvas, 0, 0);
plasmaContext.restore();
// First triangle
paintPlasma(0,angle60);
paintKal(angle240,angle120);
paintKal(0, 0);
// Second triangle
paintPlasma(angle120,angle60);
paintKal(0, angle120);
paintKal(angle240, angle240);
// Third triangle
paintPlasma(angle240,angle60);
paintKal(0, angle240);
paintKal(angle120, angle120);
destA += .01;
}
b.onclick = function(a,b){
as = Math.random()*20/4;
fd = Math.random()*20/2;
as1 = Math.random()*20;
ps = Math.random()*20-10;
plasmaReverseFactor = Math.random()*20/10-1;
};
setInterval(function() { draw(); }, 70);