View this PageEdit this PageUploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide

nodebox examples+

Home   How To   Code Pool   Public Library   Theory   Events
ported straight from nodebox example folder. see http://nodebox.net/. all credits for these drawings to Frederik De Bleser and Tom De Smedt.

note: these are the UserView:animate versions (available in recent osx version of supercollider only)
see http://swiki.hfbk-hamburg.de:8888/MusicTechnology/871 if you use swingosc (linux/win).

//updated 100228 to use UserView:animate


//AppendingTransforms
(
	var w= Window("nodeBox - AppendingTransforms.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		Pen.translate(u.bounds.width/2, u.bounds.height/2);
		Pen.scale(5, 5);
		100.do{|i|
			var scale;
			Pen.rotate(-10.rrand(10)/360*2pi);
			scale= 0.5.rrand(1.5);
			Pen.scale(scale, scale);
			Pen.fillColor= Color(1.0.rand-0.4, 0.2, 0.2, 1.0.rand);
			Pen.translate(-5.rrand(5), -5.rrand(5));
			Pen.fillRect(Rect(-10, -10, 10, 10));
		};
	};
	w.front;
)


//Balls
(
	var w= Window("nodeBox - Balls.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		var gridSize, startval, c;
		gridSize= 40;
		Pen.translate(100, 100);
		startval= 1.0.rand;
		c= 1.0.rand;
		Array.series(10, 0, gridSize).do{|x|
			Array.series(10, 0, gridSize).do{|y|
				var deltaX, deltaY, deltaS;
				Pen.fillColor= Color(sin(startval+(y*x/100)), cos(c), cos(c), 1.0.rand);
				s= 1.0.rand*gridSize;
				Pen.fillOval(Rect(x, y, s, s));
				Pen.fillColor= Color(cos(startval+(y*x/100)), cos(c), cos(c), 1.0.rand);
				deltaX= (1.0.rand-0.5)*10;
				deltaY= (1.0.rand-0.5)*10;
				deltaS= (1.0.rand-0.5)*200;
				Pen.fillOval(Rect(x+deltaX, y+deltaY, deltaS, deltaS));
				c= c+0.01;
			};
		};
	};
	w.front;
)


//Clipping
//doesn't work properly.  strings are not able to clip.
(
	var w= Window("nodeBox - Clipping.py", Rect(100, 100, 300, 300), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var f= Font("Lucida Grande Bold", 72);
	var arrow= {|x, y, width, draw= true|
		Pen.use{
			var a= width*0.4, b= width*0.2;
			Pen.moveTo(Point(x, y));
			Pen.lineTo(Point(x-a, y-a));
			Pen.lineTo(Point(x-a, y-b));
			Pen.lineTo(Point(x-width, y-b));
			Pen.lineTo(Point(x-width, y+b));
			Pen.lineTo(Point(x-a, y+b));
			Pen.lineTo(Point(x-a, y+a));
			Pen.lineTo(Point(x, y));
			if(draw, {Pen.fill});
		};
	};
	u.background= Color.white;
	u.drawFunc= {
		Pen.use{
			Pen.push;
			Pen.rotate(2pi* 0.25, u.bounds.width/2, u.bounds.height/2);
			arrow.value(250, 150, 200, false);
			Pen.pop;
			Pen.clip;
			200.do{|i|
				var s;
				Pen.fillColor= Color(1.0.rand, 0.7, 0, 1.0.rand);
				s= 50.rand;
				Pen.fillOval(Rect(150+100.rand2, 150+100.rand2, s, s));
			};
		};
		Pen.use{
			Pen.font= f;
			Pen.stringCenteredIn("Clippy!", Rect(0, 270, 300, 0));
			Pen.clip;
			105.do{|i|
				var s;
				Pen.fillColor= Color(1.0.rand, 1.0.rand, 0, 1.0.rand);
				s= 50.rand;
				Pen.rotate(5.rand2/360*2pi);
				Pen.fillRect(Rect(150+100.rand2, 270+100.rand2, s, s));
			};
		};
	};
	w.front;
)


//ColorGrid
(
	var w= Window("nodeBox - ColorGrid.py", Rect(100, 100, 625, 625), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		var h= 0, s= 0.5, b= 0.9, a= 0.5;
		var size= 50;
		Pen.translate(50, 50);
		Array.series(10, 0, size).do{|x|
			Array.series(10, 0, size).do{|y|
				h= h+0.01;
				s= 1.0.rand;
				Pen.fillColor= Color.hsv(h, s, b, a);
				Pen.fillRect(Rect(x, y, size*1.5, size*1.5));
			};
		};
	};
	w.front;
)


//Copyright
(
	var w= Window("nodeBox - Copyrights.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		var white= Color(1, 1, 1, 0.9);
		var red= Color(1, 0, 0, 0.9);
		var black= Color(0, 0, 0, 0.9);
		20.do{|i|
			Pen.fillColor= [white, red, black].choose;
			Pen.font= Font("Arial Bold", 600.rand);
			Pen.stringAtPoint(170.asAscii.asString, Point(500.rand, 400.rand));
			Pen.stringAtPoint(168.asAscii.asString, Point(500.rand, 400.rand));
			Pen.stringAtPoint(169.asAscii.asString, Point(500.rand, 400.rand));
		};
	};
	w.front;
)


//CoverGen
(
	var w= Window("nodeBox - CoverGen.py", Rect(100, 100, 400, 300), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.drawFunc= {
		Pen.font= Font("Arial", 24);
		Pen.fillColor= Color.hsv(1.0.rand, 0.5, 0.5);
		Pen.fillRect(Rect(0, 0, u.bounds.width, u.bounds.height));
		10.do{|i|
			Pen.fillColor= Color.hsv(1.0.rand, 0.5, 0.5);
			Pen.fillRect(Rect(0, -200.rrand(u.bounds.height+200), u.bounds.width, -200.rrand(u.bounds.height+200)));
		};
		Pen.fillColor= Color.hsv(1, 0, 1);
		Pen.use{
			Pen.scale(8, 8);
			Pen.stringAtPoint("*", Point(40, 0));
		};
		Pen.stringAtPoint("NODEBOX", Point(10, u.bounds.height-50));
		Pen.font= Font("Arial", 13.5);
		Pen.fillColor= Color.hsv(1, 0, 1, 0.4);
		Pen.stringAtPoint("AUTUMN | WINTER 2007", Point(10, u.bounds.height-30));
	};
	w.front;
)


//Drawing
//should use quadCurveTo instead of lineTo
(
	var w= Window("nodeBox - Drawing.py", Rect(100, 100, 500, 500), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var pointList= [], px= 0, py= 0, transformList, transformPoint;
	w.acceptsMouseOver= true;
	u.animate= true;
	u.mouseOverAction= {|v, x, y|
		if(x!=px and:{y!=py}, {
			pointList= pointList.add(Point(x, y));
			px= x;
			py= y;
		});
	};
	u.background= Color(0, 0, 0.2);
	u.drawFunc= {
		if(pointList.size>0, {
			Pen.strokeColor= Color(0.9, 0.9, 1);
			Pen.width= 2;
			pointList= transformList.value(pointList, transformPoint);
			Pen.moveTo(pointList[0]);
			pointList.do{|p| Pen.lineTo(p)};
			Pen.stroke;
		});
	};
	transformList= {|list, fn|
		var size= list.size;
		list.select{|p, i| fn.value(p, i, size).notNil};
	};
	transformPoint= {|pt, index, totalLength|
		pt.x= pt.x+(sin(index/50)*(totalLength-index)/100);
		pt.y= pt.y-(cos(index/100)*(totalLength-index)/100);
		if(pt.x<0 or:{pt.x>u.bounds.width or:{pt.y<0 or:{pt.y>u.bounds.height}}}, {
			nil
		}, {
			pt
		});
	};
	w.front;
)

//Feedback
//quite different - just emulating the effect
(
	var w= Window("nodeBox - Feedback.py", Rect(100, 100, 500, 500), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		var colsAndRects= {[
			Color(1.0.rand, 1.0.rand, 0, 1.0.rand),
			Rect(u.bounds.width.rand, u.bounds.height.rand, 20, 20)
		]}.dup(1000);
		10.do{
			Pen.fillColor= Color.white;
			Pen.fillRect(Rect(0, 0, u.bounds.width, u.bounds.height));
			colsAndRects.do{|x|
				Pen.fillColor= x[0];
				Pen.fillOval(x[1]);
			};
			Pen.translate(u.bounds.width*0.1, u.bounds.height*0.1);
			Pen.scale(0.8, 0.8);
			Pen.rotate(5/360*2pi, u.bounds.width*0.1, u.bounds.height*0.1);
		};
	};
	w.front;
)


//Foliage
//note: not completely correct
(
	var w= Window("nodeBox - Foliage.py", Rect(100, 100, 700, 700), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var star= {|x, y, points= 20, outer= 100, inner= 50, draw= true|
		Pen.use{
			points.do{|i|
				Pen.moveTo(Point(x, y)+Polar(inner, i/points*2pi).asPoint);
				Pen.lineTo(Point(x, y)+Polar(outer, i/points*2pi+(pi/points)).asPoint);
				Pen.lineTo(Point(x, y)+Polar(inner, i+1/points*2pi).asPoint);
			};
			if(draw, {
				Pen.addOval(Rect.aboutPoint(Point(x, y), inner, inner));
				Pen.fill;
			});
		};
	};
	u.background= Color.white;
	u.drawFunc= {
		Pen.translate(50, 50);
		Array.series(50, 0, 12).do{|x|
			Array.series(50, 0, 12).do{|y|
				var skew;
				Pen.push;
				Pen.fillColor= Color.hsv(0.3, 1.0.rand, 0.2.rrand(0.6), 0.8);
				//skew= 50.rand2;
				//Pen.skew(skew, skew);
				star.value(x+5.rand2, y+5.rand2, 10.rand, 1.rrand(40), 15);
				Pen.pop;
			};
		};
	};
	w.front;
)


//FormFunction
(
	var w= Window("nodeBox - FormFunction.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		Pen.fillColor= Color.black;
		Array.series(30, 0, 20).do{|x|
			Array.series(30, 0, 20).do{|y|
				var form;
				if(1.0.rand>0.6, {
					form= #[\fillOval, \fillRect].choose;
					Pen.perform(form, Rect(x, y, 18, 18));
				});
			};
		};
	};
	w.front;
)


//GridGrid
(
	var w= Window("nodeBox - GridGrid.py", Rect(100, 100, 500, 500), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var f= Font("Gill Sans", 72);
	u.background= Color.white;
	u.drawFunc= {
		Pen.font= f;
		600.do{|i|
			var scale;
			Pen.push;
			Pen.fillColor= Color(1.0.rand, 0, 0, 0.5);
			Pen.translate(1.rrand(10)*50, 1.rrand(10)*50);
			Pen.rotate(2pi.rand);
			scale= 1.8.rand;
			Pen.scale(scale, scale);
			Pen.stringAtPoint("#", Point(0, 0));
			Pen.pop;
		};
	};
	w.front;
)


//HowCurvesWork
(
	var w= Window("nodeBox - HowCurvesWork.py", Rect(100, 100, 200, 200), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var x= 50, y= 50, width= 50;
	u.background= Color.white;
	u.drawFunc= {
		var dy= width/0.5pi;
		var cp1= Point(x, y+dy);
		var cp2= Point(x+width, y+dy);
		Pen.strokeColor= Color.black;
		Pen.moveTo(Point(x, y));
		Pen.curveTo(Point(x+width, y), cp1, cp2);
		Pen.line(Point(x, y), cp1);
		Pen.line(Point(x+width, y), cp2);
		Pen.stroke;
		Pen.fillColor= Color.red;
		Pen.fillOval(Rect.aboutPoint(cp1, 2, 2));
		Pen.fillOval(Rect.aboutPoint(cp2, 2, 2));
	};
	w.front;
)


//Hypnoval
(
	var w= Window("nodeBox - Hypnoval.py", Rect(100, 100, 300, 300), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var cnt= 0;
	u.background= Color.white;
	u.animate= true;
	u.drawFunc= {
		var s= 0;
		Pen.translate(29, 40);
		Array.series(5, 0, 45).do{|x|
			Array.series(5, 0, 42).do{|y|
				Pen.fillColor= Color(0, 0, sin(cnt+(s*5))/2);
				Pen.fillOval(Rect(x+(sin(cnt+s)*10), y+(cos(cnt+s)* -6), 41, 36));
				s= s+0.05;
			};
		};
		cnt= cnt+0.19;
	};
	w.front;
)


//MathSculpture
(
	var w= Window("nodeBox - MathSculpture.py", Rect(100, 100, 400, 800), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.black;
	u.drawFunc= {
		var cX, cY, x, y, s;
		cX= 1.rrand(10);
		cY= 1.rrand(10);
		x= 200;
		y= 54;
		278.do{|i|
			x= x+(cos(cY)*10);
			y= y+(log(cX)*1.85)+(sin(cX)*5);
			Pen.fillColor= Color(1.0.rand-0.4, 0.8, 0.8, 1.0.rand);
			s= 10+(cos(cX)*15);
			Pen.fillOval(Rect(x-(s/2), y-(s/2), s, s));
			cX= cX+0.25.rand;
			cY= cY+0.25.rand;
		};
	};
	w.front;
)


//Nauseating
//note: doesn't work exactly the same
(
	var w= Window("nodeBox - Nauseating.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		Pen.fillColor= Color.black;
		Array.series(20, 0, 30).do{|x|
			Array.series(20, 0, 30).do{|y|
				var scale;
				Pen.push;
				scale= 0.2.rrand(1.2);
				Pen.scale(scale, scale);
				Pen.fillOval(Rect(x, y, 30, 30));
				Pen.pop;
			};
		};
	};
	w.front;
)


//NumberTunnel
//note: something is different.  default font?
(
	var w= Window("nodeBox - NumberTunnel.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var f= Font("Arial", 60);
	u.background= Color.white;
	u.drawFunc= {
		Pen.font= f;
		Pen.translate(300, 300);
		60.do{|i|
			var scale;
			Pen.fillColor= Color.grey((75-i)*0.01);
			scale= 1.0.rrand(1.2);
			Pen.scale(scale, scale);
			Pen.rotate(10.rand/360*2pi);
			Pen.stringAtPoint(i.asString, Point(0, 0));
		};
	};
	w.front;
)


//OrganicBall
//note: skew doesn't seem to work the same
(
	var w= Window("nodeBox - OrganicBall.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var f= Font("Zapfino", 72);
	u.background= Color.black;
	u.drawFunc= {
		Pen.font= f;
		Pen.translate(u.bounds.width/2, u.bounds.height/2);
		100.do{|i|
			var scale, skew;
			Pen.push;
			Pen.fillColor= Color(1.0.rand, 0, 0);
			Pen.rotate(800.rand/360*2pi);
			scale= 2.0.rand;
			Pen.scale(scale, scale);
			skew= 200.rand;
			Pen.skew(0, 0.1);
			Pen.stringAtPoint(40.asAscii.asString, Point(0, 0));
			Pen.pop;
		};
	};
	w.front;
)


//Ovals
(
	var w= Window("nodeBox - Ovals.py", Rect(100, 100, 500, 500), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color(0.16, 0, 0);
	u.drawFunc= {
		50.do{|i|
			var radius;
			Pen.strokeColor= Color(1.0.rand, 0.31.rand, 0);
			Pen.width= 0.2.rrand(4);
			radius= 50.rand;
			Pen.addArc(Point(u.bounds.width.rand-radius, u.bounds.height.rand-radius), radius, 0, 2pi);
			Pen.stroke;
		};
	};
	w.front;
)


//Parade
(
	var w= Window("nodeBox - Parade.py", Rect(100, 100, 400, 646), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var frame= 0;
	var circle= {|x, y, size|
		Pen.fillOval(Rect(x-(size/2), y-(size/2), size, size));
	};
	var ball= {(
		\self_x: u.bounds.width.rand,
		\self_y: u.bounds.height.rand,
		\self_size: 10.rrand(72),
		\self_dx: 0, \self_dy: 0, \self_ds: 0,
		\self_color: Color(1.0.rand, 1, 0.rrand(2), 1.0.rand),
		\self_update: {|envir|
			envir.self_dx= sin(frame/1.0.rrand(100))*20;
			envir.self_dy= cos(frame/1.0.rrand(100))*20;
			envir.self_ds= cos(frame/1.0.rrand(123))*10;
		},
		\self_draw: {|envir|
			Pen.fillColor= envir.self_color;
			circle.value(envir.self_x+envir.self_dx, envir.self_y+envir.self_dy, envir.self_size+envir.self_ds);
		}
	)};
	var balls= ball.dup(30);
	u.background= Color.white;
	u.animate= true;
	u.drawFunc= {
		thisThread.randSeed= 1;
		Pen.translate(0, u.bounds.height-frame);
		balls.do{|b|
			b.self_update;
			b.self_draw;
		};
		frame= frame+1;
	};
	w.front;
)


//RandomFont
(
	var w= Window("nodeBox - RandomFont.py", Rect(100, 100, 400, 400), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var number= Window("textsize", Rect(500, 200, 300, 80), false);
	var slider= Slider(number, Rect(50, 20, 180, 20))
		.action_{|view| u.refresh}
		.value_(0.5);
	var names= #["Helvetica", "Arial", "Times", "Impact", "Verdana"];
	u.background= Color.white;
	u.drawFunc= {
		Pen.fillColor= Color(1, 0, 0);
		Pen.font= Font(names.choose, slider.value*100+1);
		Pen.stringAtPoint("Hi there!", Point(12, 10));
	};
	w.front;
	number.front;
)


//RandomText
(
	var w= Window("nodeBox - RandomText.py", Rect(100, 100, 800, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var rndText= {
		var t= "";
		10.rand.do{|i| t= t++10.rrand(120).asAscii};
		t
	};
	u.background= Color.white;
	u.drawFunc= {
		var white= Color(1, 0, 0, 0.8);
		var black= Color.hsv(0, 0, 0, 0.8);
		var red= Color.hsv(1.0.rand, 0, 0.2, 0.8);
		white.postln;
		Pen.translate(0, -200);
		100.do{|i|
			var someText;
			Pen.translate(100.rand2, 100.rand2);
			Pen.push;
			Pen.rotate(5.rand*45/360*2pi);
			Pen.font= Font("Arial Black", 800.rand);
			Pen.fillColor= [white, black, red].choose;
			someText= rndText.value;
			Pen.stringAtPoint(someText, Point(0, 0));
			Pen.pop;
		};
	};
	w.front;
)


//StarFun
(
	var w= Window("nodeBox - StarFun.py", Rect(100, 100, 600, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var star= {|x, y, points= 20, outer= 100, inner= 50, draw= true|
		Pen.use{
			points.do{|i|
				Pen.moveTo(Point(x, y)+Polar(outer, i/points*2pi).asPoint);
				Pen.lineTo(Point(x, y)+Polar(inner, i/points*2pi+(pi/points)).asPoint);
				Pen.lineTo(Point(x, y)+Polar(outer, i+1/points*2pi).asPoint);
			};
			if(draw, {
				Pen.addOval(Rect.aboutPoint(Point(x, y), outer, outer));
				Pen.fill;
			});
		};
	};
	u.background= Color.white;
	u.drawFunc= {
		100.do{|i|
			Pen.color= Color.hsv(0.8.rrand(1), 1.0.rand, 0.2.rrand(0.6), 1.0.rand);
			Pen.rotate(-3.rrand(3)/360*2pi);
			Pen.translate(-100.rrand(100), -100.rrand(100));
			star.value(300, 300, 1.rrand(100), 1.rrand(5), 1.rrand(500), true);
		};
	};
	w.front;
)


//TextFromList
(
	var w= Window("nodeBox - TextFromList.py", Rect(100, 100, 800, 600), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var txt= #[
		"DIE",
		"BUY",
		"WHY",
		"NOW",
		"!"
	];
	u.background= Color.white;
	u.drawFunc= {
		var white= Color(1, 1, 1);
		var black= Color(0, 0, 0);
		var red= Color(1, 0, 0);
		Pen.translate(0, -200);
		100.do{|i|
			var someText;
			Pen.translate(100.rand2, 100.rand2);
			Pen.push;
			Pen.rotate(5.rand*45, 400, 300);
			Pen.font= Font("Arial Black", 800.rand);
			Pen.fillColor= [white, black, red].choose;
			someText= txt.choose;
			if(2.rand==1, {
				someText= someText.toLower;
			});
			Pen.stringAtPoint(someText, Point(0, 0));
			Pen.pop;
		};
	};
	w.front;
)


//TunnelEffect
(
	var w= Window("nodeBox - TunnelEffect.py", Rect(100, 100, 800, 800), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	u.background= Color.white;
	u.drawFunc= {
		var startX= 100, startY= 100, startval= 1.0.rand, c;
		Pen.strokeColor= Color.grey(0.2);
		c= 1.0.rand;
		300.do{|i|
			var delta, x, y, s, primitive;
			delta= (1.0.rand-0.5)*0.1;
			x= 400+(sin(c+delta)*(i+ -10.rrand(10)));
			y= 400+(cos(c+delta)*(i+ -10.rrand(10)));
			s= (c*2).rand;
			Pen.fillColor= Color(1.0.rand-0.4, 0.2, 0.2, 1.0.rand);
			primitive= #[[\fillOval, \strokeOval], [\fillRect, \strokeRect]].choose;
			Pen.perform(primitive[0], Rect(x-(s/2), y-(s/2), s, s));
			Pen.perform(primitive[1], Rect(x-(s/2), y-(s/2), s, s));
			c= c+0.25.rand;
		};
	};
	w.front;
)


//WishyWorm
(
	var w= Window("nodeBox - WishyWorm.py", Rect(100, 100, 400, 400), false);
	var u= UserView(w, Rect(0, 0, w.bounds.width, w.bounds.height));
	var a= 10, b= 0;
	u.background= Color(0, 0, 0.15);
	u.animate= true;
	u.drawFunc= {
		var cX, cY, x, y, c, s;
		thisThread.randSeed= 0;
		cX= a;
		cY= b;
		x= 180;
		y= -27;
		c= 0;
		48.do{|i|
			x= x+(cos(cY)*5);
			y= y+(log(cX)*8.36)+(sin(cX)*2);
			Pen.fillColor= Color(sin(a+c), 0.3, 0, 0.5);
			s= 22+(cos(cX)*17);
			Pen.fillOval(Rect(x-(s/2), y-(s/2), s, s));
			cX= cX+0.25.rand;
			cY= cY+0.25.rand;
			c= c+0.1;
		};
		a= a+0.1;
		b= b+0.05;
	};
	w.front;
)



Link to this Page