NB an interface to NodeBox - http://nodebox.net

Mark Polishook. Some stuff and mantainance by Andrea Valle


superclass: Object

NB writes and renders NodeBox code and has equivalents for all commands in the NodeBox API. NodeBox is an open source drawing program for rendering images  (png, jpg, gif, tiff, and pdf formats) and QuickTime movies.


For setup and installation instructions, visit the NB_setup_installation document

For a few quickstart examples some basic information about how to use NB, visit the NB-_publishing_&_syntax document. 

For general NB information (documentation about instance variables, messages/methods, etc.), read further in this document.

For information about scaling from points to millmeters, centimeters or inches, visit NB_scaling. 

For more NB examples, see NB_more_examples and NB_&_python_functions.


Instance variables


NB instance variables include:


name - the name the file to which SuperCollider writes NodeBox code.

width - the width of the (NodeBox) drawing canvas.

height - the height of the (NodeBox) drawing canvas.

publishing - whether or not NB writes code to the named file.

fileType - NodeBox renders in 6 formats:

png

gif

tiff

jpeg

pdf

mov

path - /tmp, the default directory to which NB will write (code) and render (images). Change the value to any directory/location as needed/required.

displayLatency - the minimum amount of time (in secs.) between image rendering and display. The default value is 1 (sec.). Lower values are possible.



/* ----- ----- ----- ----- */ 

/* ----- ----- ----- ----- */ 



Class Methods


*new(name, width, height, publishing, fileType, frames, fps)


name - a string that represents the name of a file to write NodeBox code.

width - an integer that represents the horizontal dimension, in points, of a NodeBox drawing window.

height - an integer that represents the vertical dimension, in points, of a NodeBox drawing window.

publishing - a boolean that describes whether or not NB writes code to a document; the default is true.

fileType- "gif", "jpg" (or "jpeg"), "png", "tiff", or "mov".

frames- number of frames and only used when fileType is "mov"

fps- frames per second and only used when fileType is "mov"


(

// the 'publishing' instance variable is set to true (by default)

n = NB("*new__example_true*", 320, 240);

n.background(0, 1, 0);

n.rect(9, 20, 300, 200);

n.fill(1, 0, 0);

n.rect(29, 49, 200, 100);

// open the NodeBox application and display the code

n.displayCode;

n.render;

n.displayImage

)

Or

(

// the publishing instance variable is set to false and code is created in an array and then

// written to a NodeBox file

n = NB("*new__example_false*", 320, 240, false);

c = [

n.background(0, 1, 0),

n.rect(9, 20, 300, 200),

n.fill(1, 0, 0),

n.rect(29, 49, 200, 100)

];

d = [

n.rect(39, 20, 300, 200),

n.fill(1, 0, 1),

n.rect(109, 49, 200, 100)

];

e = [

n.fill(0, 1, 0),

n.fontsize(52),

n.text("-Hello, world", 15, 150)

];

n.write(c ++ d ++ e);

n.displayCode;

n.render;

n.displayImage

)

Instance Methods


publishCode(... linesOfCode)


linesOfCode - arbitrary number of strings to be written to a NodeBox document.

(

n = NB.new("P-u-l-se", 540, 300).fileType("pdf");

n.publishCode(

"fill".cmd(0.25, 0, 0),

"rect".cmd(0, 0, \WIDTH, \HEIGHT),

"fill".cmd(1, 1, 0),

"oval".cmd(0, 64, 200, 100),

"fill".cmd(0, 0, 1),

"oval".cmd(200, 120, 200,100),

"fill".cmd(1, 1, 1),

"rotate".cmd(34),

"skew".cmd(-45),

"fontsize".cmd(32),

"text".cmd("Pulse.kr(100, 0.3, 0.6)", 10, 150),

"fill".cmd(0.7, 0.5, 1),

"fontsize".cmd(31),

"text".cmd("Pulse.kr(100, 0.3, 0.6)", 43, 152),

"fill".cmd(0.7, 0, 1),

"fontsize".cmd(47),

"text".cmd("Pulse.kr(100, 0.3, 0.6)", 40, 172),

"fill(1, 0, 0)",

"rect(54, 49, 200, 60)"


);

n.render;

n.displayImage

)


displayCode - display code in NodeBox.

(

n = NB("publishing", 320, 240);

n.background(0, 1, 0);

n.cmt("Hello, NodeBox");

// this loop of 120 times is relatively fast

// 1200 iteration is slower, and 12000 is slower still

// 120000 hasn't (yet) been tried

120.do({

n.fill(1.0.rand, 0, 0, 1.0.rand);

n.rect(5.rrand(200), 5.rrand(100), 10, 10);

n.oval(20.rrand(200), 20.rrand(200), 10, 10);

n.arrow(40.rrand(200), 40.rrand(300), 10);

n.star(0.rrand(300), 0.rrand(300), 10, 50, 10);

});

n.displayCode;

n.render;

n.displayImage

)

publishAndDisplayCode - for convenience, combine the previous two messages.


write(code) - write code (an array of strings) to a NodeBox document. In this case, the publishing instance variable is set to false.


(

// this may take a few secs.

n = NB("+write---------------code+", 600, 600);

n.background(0.1, 0.9, 0.3);

n.publishing_(false);


a = [];

x = -22; y = 0; z = 40;

w = 87; h = 54; j = 2;

///////////////////////////////////////////////

16.do({

a = a.add(

n.fill(1.0.rand, 1.0.rand, 1.0.rand)

);

a = a.add(

n.rect(

x = x + z, 

y = y + z, 

w = w - j, 

h = h - j

)

);

j = [1, 2, 3, 4, 5].choose;

});

///////////////////////////////////////////////

1000.do({

a = a.add(

n.fill(1.0.rand, 1.0.rand, 1.0.rand, 0.0.rrand(0.4))

);

a = a.add(

n.rect(

580.rand, 

580.rand, 

2.rrand(6), 

2.rrand(6)

)

);

});

///////////////////////////////////////////////

a = a.add(n.fontsize(24););

a = a.add(n.fill(1, 1, 1));

4.rrand(11).do({

a = a.add(

n.text(

"2008.do({ \"Resolution.newYear\".compile})", 

[99, 100, 100].choose, 

500.rand 

)

);

});

///////////////////////////////////////////////

n.write(a);

n.renderAndDisplayImage(2);

)


render - ask NodeBox to render an image.


displayImage (dur)


Ask a helper application to display an image. The 'dur' argument (a value in secs.) temporarily resets the the latencyDisplay instanceVariable. The latencyDisplay instance variable, by default, is 1 sec.


renderAndDisplayImage(dur) - for convenience, combine the previous two messages. 


renderInBackground  - background rendering possibly is faster.


(

n = NB("+write---------------code+", 600, 600);

n.background(0.1, 0.9, 0.3);

n.publishing_(false);


a = [];

x = -22; y = 0; z = 40;

w = 87; h = 54; j = 2;

///////////////////////////////////////////////

16.do({

a = a.add(

n.fill(1.0.rand, 1.0.rand, 1.0.rand)

);

a = a.add(

n.rect(

x = x + z, 

y = y + z, 

w = w - j, 

h = h - j

)

);

j = [1, 2, 3, 4, 5].choose;

});

///////////////////////////////////////////////

1000.do({

a = a.add(

n.fill(1.0.rand, 1.0.rand, 1.0.rand, 0.0.rrand(0.4))

);

a = a.add(

n.rect(

580.rand, 

580.rand, 

2.rrand(6), 

2.rrand(6)

)

);

});

///////////////////////////////////////////////

a = a.add(n.fontsize(24););

a = a.add(n.fill(1, 1, 1));

4.rrand(11).do({

a = a.add(

n.text(

"2008.do({ \"Resolution.newYear\".compile})", 

[99, 100, 100].choose, 

500.rand 

)

);

});

///////////////////////////////////////////////

n.write(a);

n.displayCode;

n.renderInBackground;

// allow plenty of time between rendering and display

// experimentation likely will allow the argument to displayImage to be set to a lower value

n.displayImage(5);

)


(

// display the image (when, exactly, is rendering finished?)

"open /tmp/+write---------------code+.png".systemCmd;

)


finishMovieCode


Only for rendering Quicktime movies.

(

n = NB("finishMovieCode", 400, 300, true, "mov", 20, 10);

n.background(0.1, 0, 1);

n.fill(0.84, 1, 1);

n.oval(100, 64, 100, 200);

n.fill(0, 0, 1);

n.oval(200, 64, 100, 200);

n.fill(1, 0.5, 1, 0.84);

n.skew("random(0, 100)");

n.rect(100, 40, 200, 125);

n.fill(1, 0.3, 1);

n.text("finish_movie_code", 10, 26);

n.fontsize(43);

n.rotate(34);

n.fill(0, 0, 0.6, 0.5);

n.text("SinOsc.ar(440)", 170, 228);

n.fill(1, 0, 0.1, 0.07);

n.rect(0, 0, 50, 300);

n.oval(0, 267, "HEIGHT", 200);

n.finishMovieCode;

n.displayCode;

)


Instance Methods that wrap the NodeBox API


The NodeBox reference manual, available with the NodeBox application or online at 

http://nodebox.net/code/index.php/Reference

documents every NodeBox commands.


In NodeBox, WIDTH and HEIGHT are global variables that represent the width and height (in points) of the drawing canvas. In NB, 'width' and 'height' instance variables contain the same information. 


Shape


rect ( x, y, width, height, roundness, draw )


x - a number, a string, or a function that evaluates to a number or a string.

y - a number, a string, or a function that evaluates to a number or a string.

width - a number, a string, or a function that evaluate to a number or a string.

height - a number, a string, or a function that evaluate to a number or a string.

roundness - a number, a string, or a function that evaluates to a number or a string.

draw - a boolean (true or false)


(

n = NB("rect_example");

n.publishCode(

"rect(HEIGHT / 5, HEIGHT / 8, HEIGHT / 13,  HEIGHT / 21)"

);

n.displayCode;

// Command-r in NodeBox to render the image

)


oval ( x, y, width, height, draw )


(

n = NB("rect_example1");

n.background("random() * 0.1 + 0.9", 0, 0);

n.cmt("Command-r to draw and redraw - move and recolor the oval");

n.fill("random()", "random()", "random()");

n.oval("random(20, 300)", "random(20, 120)", 30, n.height * 0.35);

n.fill("random()", "random()", "random()");

n.oval("random(20, 300)", "random(20, 120)", 30, n.height * 0.35);

n.fill("random()", "random()", "random()");

n.oval("random(20, 300)", "random(20, 120)", 30, n.height * 0.35);

n.cmt("Export rendered image(s) as a Quicktime movie [yes] [no] ??");

n.displayCode;

// Command-r in NodeBox to render the image

)


line ( x1, y1, x2, y2, draw )


(

n = NB("line_example1");

n.stroke(0.79, 1);

n.line(0, 0, 50, 90);

n.stroke(0.5, 1);

n.line(50, 90, 320, 0);

n.stroke(0.8, 1);

n.line(50, 90, 0, 240);

n.stroke(0.1, 1);

n.line(50, 90, 320, 240);

n.renderAndDisplayImage

)


arrow ( x, y, width, type, draw )


(

n = NB("arrow_example1");

n.publishCode(

"fill(0, 1, 0, 0.7)",

"rect(0, 0, WIDTH, HEIGHT)",

"fill(0, 0, 1)",

"arrow(200, 100, 200)",

"fill(1, 0, 0)",

"fontsize(38)",

"text".cmd("STOP!", 202, 113)

);

n.renderAndDisplayImage;

)


star ( x, y, points, outer, inner, draw )


(

n = NB("star_example");

n.publishCode(

"for i in range(45):

fill(random(), random(), random(), random())

star(

random(20, choice((200, 300))), 

random(20, 220), 

choice((40, random(10, 30))), 

random(3, 20)

)"

);

n.renderAndDisplayImage;

)


Path


beginpath ( x, y )


(

n = NB("beginpath");

n.background(0, 1, 0, 0.3);

n.publishCode(

"

fill(random(), random(), random())

beginpath(10, 10)

lineto(110, 10)

lineto(110, 110)

lineto(10, 110)

lineto(10, 10)

endpath()

fontsize(18)

text(\"fill(random(), random(), random())\", 25, 140)

fill(0, 0, 1, 0.5)

beginpath(0, 0)

lineto(50, 78)

lineto(200, 220)

lineto(10, 4)

lineto(100, 200)

endpath()

fontsize(11)

text(\"fill(random(), random(), random())\", 60, 200)

"

);

n.renderAndDisplayImage;

)

moveto ( x, y )


lineto ( x, y )


curveto ( h1x, h1y, h2x, h2y, x, y )


endpath ( draw )


findpath ( list, curvature )


(

// From NodeBox Help

n = NB("findpath");

n.py(

"points = [

    (100, 100),

    (200, 200),

    (350, 200)]

 

for x, y in points:

    oval(x-2, y-2, 4, 4)

 

autoclosepath(False)    

path = findpath(points)

drawpath(path)"

);

n.renderAndDisplayImage;

)


drawpath ( path )


beginclip ( path )


endclip ( write )


Transform


transform ( mode ) - set registration point for offset, scale, and/or skew to "CENTER" or "CORNER"


// ... this will take a few secs., eg, spinning beach ball, etc.

(

var path;

path = "/tmp/";

// if the localhost server is running

NB.satie(12);

// Render 3 images

NB.matrixDemo("1");

NB.matrixDemo("2");

NB.matrixDemo("3");

// Transform the images and tile them (vertically)

n = NB("__________________transform", 401, 450);

n.transform("CORNER");


n.scale(1, 0.5);

n.image(path ++ "1.png", 0, 0);


n.image(path ++ "2.png", 0, 500);

n.scale(1, 0.25);


n.image(path ++ "3.png", 0, 1570);

n.renderAndDisplayImage(2);

)


translate ( x, y )


rotate ( degrees, radians )


(

n = NB("rotate", 900, 600);

n.publish("

fontsize(44)

text(\"Rotation phase\", 580, 44)

fill(random(), random(), random(), 0.3)

rect(0, 0, WIDTH, HEIGHT)

for x in range(33):

rotate(11)

translate(random() * 19, random() * 18)

fill(random(), random(), random(), random())

fontsize(random(8, 35))

text(\"Saw.ar(111, 0.137, 438787)\", 400, 350)

for x in range(33):

rotate(11)

translate(random() * 19, random() * 18)

fill(random(), random(), random(), random())

fontsize(random(4, 11))

text(\"LFNoise3.ar(111, 0.137, 438787)\", 55, 222)

for x in range(33):

rotate(11)

translate(random() * 19, random() * 18)

fill(random(), random(), random(), random())

fontsize(random(3, 5))

text(\"SinOsc.ar(111, 0.137, SinOsc.ar(4, 3, 7))\", 66, 500)

fill(0, 0, 0)

fontsize(111)

rotate(200, 46)

skew(433)

fill(1, 0, 0)

text(\"Rotation phase\", 77, 400)"

);

n.renderAndDisplayImage(2)

)


scale ( x, y )


skew ( x, y )


(

n = NB("skew_skew_skew", 400, 400);

n.publish("

fill(random(), random(), random(), 0.3)

rect(0, 0, WIDTH, HEIGHT)

fill(0, 0, 0)

text(\"SKEW:::SKEW::SKEW:::SKEW\", 10, 30)

for x in range(5):

skew(random(-40, 40), random(-40, 40))

fill(random(), random(), random(), random())

fontsize(random(24, 32))

text(\"Saw.ar(1, 0.1)\", 60, 120)"

);

n.renderAndDisplayImage

)


push


pop


Use push and pop as a pair to localize rotation and skew values to code they enclose. For example:


push()

...NodeBox code with rotation and/or skew commands

pop()


(

t = "a sample text, this, that, etc.";

x = 50;

y = 100;

z = { 12.rrand(36) };

n = NB("push_and_pop", 640, 480);

i = 50;


n.fontsize(z.value);

n.fill(0, 0, 0);


// an original text

n.text("1. " ++ t, x, y);


n.fontsize(z.value);

n.fill(0, 1, 0);

// ROTATE THE TEXT 45 degrees and offset it vertically by the variable i

n.rotate(45);

n.text("2. " ++ t, x, y+i);


n.fontsize(z.value);

n.fill(0, 0, 1);

// RETURN THE TEXT TO THE ORIGINAL ROTATION VALUE

n.rotate(-45);

n.text("3. " ++ t, x, y+i+i);


n.fontsize(z.value);

n.fill(1, 0, 0);

// PUSH and POP

n.push;

n.rotate(-45);

n.text("4. " ++ t, x, y+i+i+i + i);

n.pop;


n.fontsize(z.value);

// the original text - PUSH and POP localize the -45 rotation value to the previous code

// that they enclose

n.fill(0, 0, 0);

n.text("5. " ++ t, x, y+i+i+i+i);


n.renderAndDisplayImage

)


reset


Color


colormode ( mode, range )


color ( a, b, c, d, e )


fill ( a, b, c, d, e )


nofill


stroke ( a, b, c, d, e )


nostroke


strokewidth ( width )


background (r, g, b, a)


(

n = NB("background");

n.background(1, 0, 0, 0.6);

n.fill(0, 1, 0);

n.rect(4, 4, 40, 50);

n.renderAndDisplayImage;

)


Type


font ( fontname, fontsize )


fontsize ( fontsize )


text ( txt, x, y, width, height, outline )


(

r = SCWindow.screenBounds;

w = r.right;

h = r.bottom;

n = NB("fullscreen", w, h);

t = n.openRead("/Applications/SuperCollider/nb_test/this.txt");

n.assign(\t, t);

n.rect(10, 10, 100, 100);

n.fontsize(18);

n.text(\t, 10, 160);

n.fill(0.73, 0.73, 0.73);

n.text(\t, 16, 167);

n.skew(23);

n.fill(0, 0, 0);

n.fontsize(14);

n.text(\t, 600, 160);

n.render;

n.displayImage(12) // delay image display for (min.) 12 secs. ... to give NodeBox time to

// render)


textpath ( txt, x, y, width, height )


textwidth ( txt, width )


textheight ( txt, width )


textmetrics ( txt, width )


lineheight ( height )


align ( align )


Image


image ( path, x, y, width, height, alpha, data )


imagesize ( path )


Utility


size ( w, h ) - usually the first line in a NodeBox script (to set the size of the drawing canvas). 


The size command runs automatically during NB instance creation. The 2nd and 3rd arguments in instance creation go to NB code that writes a NodeBox size command as the first line in a new document - the NB size message is here for completeness but generally isn't needed.


variable ( name, type, default, min, max )


(

// make a gui for the circle variable

var code;

n = NB("variable", 320, 240);

n.variable(\circle, "NUMBER", 42, 0, n.width);

n.oval(\circle, 120, 20, 20);

n.displayCode;

// Command-r in NodeBox to render

)


random ( v1, v2 )


choice ( list )


grid ( cols, rows, colsize, rowsize )


openRead ( path )


(

// file reading - in one chunk

var text;

n = NB("ex__15", 320, 240);

text = n.openRead("/Applications/NodeBox/Changes.txt");

n.assign(\txt, text);

n.print(\txt);

n.displayCode;

// Command-r in NodeBox to render

)


openReadlines ( path )


files ( path )


autotext ( path )


assign(name, value)


name - a symbol to which to bind a value

value - a number, a string, or a function (that evaluates to a number of a string)

(

var color;

n = NB("assign_example", 320, 240);

n.background(0.11, 0.2, 0.3, 0.4);

color =  "color(random(), random(), random(), 1)";

n.assign(\color1, color);

n.assign(\color2, color);

n.assign(\color3, color);

n.fill(\color1);

n.rect(5, 5, "WIDTH - 11", 100);

n.fill(\color2);

n.rect(5, 109, "WIDTH - 11", 110);

n.fill(\color3);

n.oval(60, 40, 50, 30); n.oval(210, 40, 50, 30);

n.assign(\color4, color);

n.fill(\color4);

n.fontsize(34);

n.text("h e  l   l    o", 13, 100);

n.renderAndDisplayImage;

)


fromImport(lib ... args)


lib - a Python library

args - library functions that will be imported

(

n = NB.new("import_example", 10, 30);

n.fromImport(\math, \sin, \cos);

n.displayCode

)

cmt(theComment)


theComment -  a string

(

n = NB.new("comment_example", 200, 200);

n.cmt("comment, comment, comment, comment");

n.displayCode

)


cmts(.... comments)


comments - strings

// from http://www.schoenberg.at/6_archiv/voice/voice18_e.htm"

(

n = NB.new("cmts", 1000, 1000);

n.cmts(

"Recording date: 1947 May 22",

"Duration: 4:27",

"Description: On Schoenberg\'s struggle to follow his musical instincts in", 

"composition. Also known as the \"Boiling water\" speech. In English.", 

"ASC call nos.: 22/C (3:46); 40/C (4:27); 48/R7 (4:27); 105/R7 (4:21) ",

"Publications: none",

"\n",

"Transcription:",

"\n",

"SCHOENBERG: Mr. President, ladies and gentlemen. I am proud about the", 

"formulation under which this award has been given to me.", 

"\n",

"That all I have endeavoured to accomplish during these fifty years is now", 

"evaluated as an achievement seems in some respects to be an overestimation.",

"\n",

"At least not before I could sum it up--that is: while it still looked to", 

"me like a pell-mell of incoherent details, at least then did I fail to", 

"understand it as a direction leading toward an accomplishment. Personally", 

"I had the feeling as if I had fallen into an ocean of boiling", 

"water, and not knowing how to swim or to get out in another", 

"manner, I tried with my legs and arms as best as I could.", 

"\n",

"I do not know what saved me; why I was not drowned or cooked alive. I have ", 

"perhaps only one merit: I never gave up! But how could I give up in the",  

"middle of an ocean. Whether my wriggling was very economical or", 

"entirely senseless, whether it helped me to survive or counteracted it--", 

"there was nobody to help me, nor were there many who would not have liked", 

"to see me succomb.",

"\n",

"I do not contend it was envy--of what was there", 

"to be envious? I doubt also that it was absence of good will--or,",  

"worse--presence of ill wishing.",

"\n",

"It might have been the desire to get rid of this nightmare, of this", 

"unharmonious torture, of these unintelliglble ideas, of this methodical", 

"madness--and I must admit: there were not bad men who felt this way--", 

"though, of course, I never understood what I had done to them to make them", 

"as malicious, as furious, as cursing, as agressive. I am still", 

"certain that I had never taken away from them something they owned; I had", 

"never interfered with their rights, with their prerogatives; I never", 

"did trespass their property; I even did not know where it was", 

"located, which were the boundaries of their lots and who had given them", 

"title to these possessions.",

"\n",

"Maybe I didn't care enough about such problems, maybe I myself failed to", 

"understand their viewpoints, was not considerate enough, was rough when I", 

"should have been soft, was impatient when they were worried by time", 

"pressure, was ridiculing them, when indulgence was advisable, laughed when", 

"they were distressed. I see only that I was always in the red; but", 

"I have one excuse: I had fallen into an ocean, into an ocean of", 

"overheated water and it burned not only my skin, it burned also", 

"internally. And I could not swim.", 

"\n",

"At least: I could not swim with the tide, all I could do was to swim", 

"against the tide--whether it saved me or not. I see that I was always in", 

"the red and when you call this an achievement, so--forgive me--I do not", 

"understand of what it might consist. That I never gave up? I could not--I", 

"would have liked to. I am proud to receive this award under the", 

"assumption that I have achieved something. Please do not call it false", 

"modesty if I say: Maybe something has been achieved, but it was not I who", 

"deserves the credit for that. The credit must be given to my", 

"opponents. They were the ones who really helped me. Thank you."

);

n.displayCode

)


print(statement)


statement -  a symbol

(

var text;

n = NB("print2", 320, 240);

text = ["i", "am", "a", "statement"];

text.do({ arg aLine;

n.print(aLine)

});

n.displayCode;

n.display;

)


(

// ... NodeBox will likely be slow when rendering this example ...

// ... It may appear to freeze (spinning beachball, etc.) ...

// ... Just wait; all (most likely, hopefully) will be well ...

var text;

n = NB("print_a_sc_class_def", 400, 600);

text = n.openRead(

"/Applications/SuperCollider/SCClassLibrary/Common/Core/Boolean.sc"

);

n.assign(\txt, text);

n.print(\txt);

n.fontsize(11);

n.fill(1, 0, 0);

n.text(\txt, 5, 5);

n.renderAndDisplayImage(2)

)

python(oneLineOfCode)


oneLineOfCode - a string to be written as a line of Python code.

py(linesOfCode)


linesOfCode - strings that will be transformed into lines of Python code

quote(aString)


(

// is the server booted? if not, please start it

var text;

var result;

var color;

var num = 8;

n = NB("asldkfj", 1200, 500);

color = { n.fill(n.random, n.random, n.random, n.random(0.5, 1)) };

n.fontsize(10);

n.text("qwertyasdfg", 1120, 490);

text = n.quote("Thanks for trying NB");

n.fill(0, 0, 0);

n.fontsize(46);

n.assign(\txt, text);

n.text(\txt, 10, 120);

n.push;

n.skew(45, 23);

n.text(\txt, 500, 300);

n.pop;

num.do({

color.value;

n.fontsize(8.rrand(32));

n.rotate(n.random(-180, 180));

n.assign(\txt, text);

n.text(\txt, 60, 220)

});

num.do({

color.value;

n.fontsize(8.rrand(32));

n.rotate(n.random(-180, 180));

n.assign(\txt, text);

n.text(\txt, 400, 300)

});

num.do({

color.value;

n.fontsize(8.rrand(32));

n.rotate(n.random(-180, 180));

n.assign(\txt, text);

n.text(\txt, 12, 60)

});


n.renderAndDisplayImage(2);

// if the localhost server is running ...

NB.satie(6);

)


/* ----- ----- ----- ----- */

/* ----- ----- ----- ----- */

/*

- NB.sc and CmdString.sc and CmdStringPlusString by Mark Polishook

- Thanks to Andrea Valle for much help and a plethora of excellent suggestions

- polishook@optonline.net

1.2008

*/