Source for demo by Dan Steinman.
D=document
D.body.style.margin=0
W=self.innerWidth
H=self.innerHeight
C=D.getElementById('c')
C.width=W
C.height=H
C=C.getContext('2d')
M=Math
S=M.max(W,H)
R=M.random
F=M.floor
v=0
sz=[]
function g(s1,s2,c,a,b) {
i=0
do {
sz.push(new Z(s1+R()*s2,c()))
i++
} while (i<N(a,b))
}
function N(a,b) {return a*S/10+R()*S/10*b}
function p() {return F(R()*S*1.3)}
function z() {return 120+F(R()*136)}
function m() {return 'rgb('+z()+','+z()+','+z()+')'}
function o() {return 'rgba('+z()+','+z()+','+z()+','+(0.3+R()*0.7)+')'}
function Z(s,c) {
var t=this
t.x=p()
t.y=p()
t.s=s
t.c=c
}
b="#000"
C.fillStyle=b
C.fillRect(0, 0, W, H)
g(0.6, 1.9, m, 1, 5)
g(0.4, 0.7, o, 4, 8)
d=R()>0.5?1:-1
setInterval(function() {
v+=d*0.02
C.fillStyle=b
C.fillRect(0, 0, W, H)
C.save()
C.translate(W/2,H/2)
C.rotate(v)
R=S*1.3/2
sz.forEach(function(s) {
C.beginPath()
C.arc(s.x-R,s.y-R,s.s,0,M.PI*2,1)
C.fillStyle=s.c
C.fill()
})
C.restore()
},50)