Javascript en Max MSP
Javascript en Max MSP
Javascript in Max
Version 4.6/7 August 2006
Table of Contents
2
jsui, Sketch and OpenGL.................................................................................................................47
jsui Specific Properties............................................................................................... 49
jsui Specific Methods ................................................................................................. 49
jsui Event Handler methods........................................................................................ 49
Sketch Constructor ..................................................................................................... 51
Sketch Properties........................................................................................................ 51
Sketch Methods.......................................................................................................... 51
Shape Methods........................................................................................................... 53
Sketch Shape Attribute Methods ................................................................................ 55
Sketch Text Methods.................................................................................................. 55
Sketch Pixel Methods................................................................................................. 56
Sketch Stroke Methods............................................................................................... 57
Basic 2D Stroke Style Parameters .............................................................................. 58
Line Stroke Style Parameters...................................................................................... 59
Sketch Setup Methods ................................................................................................ 60
Sketch OpenGL Methods ........................................................................................... 62
Image Constructor...................................................................................................... 65
Image Properties ........................................................................................................ 65
Image Methods........................................................................................................... 66
3
Copyright and Trademark Notices
This manual is copyright 2000-2006 Cycling 74.
Credits
Javascript in Max Documentation: David Zicarelli and Joshua Kit Clayton
4
Basic Javascript programming for the js and jsui objects
Introduction
The js and jsui objects run Javascript version 1.5 inside of Max. This topic covers
information about the functions added to the Javascript language that are specific to the js
and jsui object implementation. This topic is not a general reference on Javascript
programming. A good on-line resource on Javascript is available here:
http://developer.mozilla.org/en/docs/JavaScript
The Javascript language used by the js and jsui objects does not include web browser-
specific functions and properties.
User interface functions and properties specific to the jsui object are covered in the
Javascript Graphics topic. In this topic, unless specifically noted, all information covers
both js and jsui even though we will refer only to the js object.
Javascript is a textual language that is compiled into a script. Scripts have global code
and functions. Any Javascript expressions and statements that arent inside functions are
considered to be in global code.
Example:
Global code is executed immediately after a Javascript source file is compiled. This allows
you to initialize a global variable or property. Functions can be called by global code, but
they can also be called via messages sent to the js object. This makes implementing new
Max objects in Javascript very straightforward because the name you give to a function is
the same as the message name a Max user would use to invoke it.
5
For example, if the Javascript source above were compiled into a js object, we could click
on the message box in the patch shown below to invoke the assign() function with an
argument of 10.
The js object only uses Javascript saved in a text file. You can write Javascript code using a
separate editor, or use the text window built into Max. If you use the built-in window, the
js object will recompile its Javascript source each time you save the file. If you use another
text editor, you can recompile the source from the text file by sending the message compile
to the js object. Or you can send the message autowatch 1 to the js object, and every time the
file is saved, the object will recompile it automatically.
In order to understand the script context in the Max js object, it is important to realize
that there is a Javascript model of the Max world that you will be manipulating. Perhaps
the most important aspect of this model is that there is a Javascript version of the Max js
object itself. This object, which we refer to in this documentation as the jsthis object, is the
base on which you build properties and methods when you write functions and global
code. Some examples should make this clear. Consider the Javascript we listed above
again:
6
The function assign() becomes a method of jsthis, and the variable a becomes its
property. In Javascript a method can be invoked by using a dot notation on an object. We
could rewrite the above example as follows using the optional Javascript this keyword to
make the object-oriented nature of the environment more apparent. Weve also added a
new function provoke() that invokes assign().
function provoke()
{
this.assign(1000);
}
However, you shouldnt really need to concern yourself with these semantic details if you
have an irrational hatred of object-oriented terminology and concepts.
The Javascript jsthis object has certain built-in properties and methods you will need to
use in order to work within the Max environment. For example, there is an outlet()
method to send data out an outlet. You can also access the Max js objects typed-in
arguments, find out which inlet received a message, and define the number of inlets and
outlets the object has. These features are documented in the section on the jsthis object
below.
While the word this in generally optional, you may need to use it when passing the
current jsthis instance to functions. For example, you can send a reference to your jsthis
object out an outlet, or use it in creating a Task object (see below for more about Tasks).
In addition to jsthis, the notion of a Javascript Max model is completed with a series of
Javascript classes defined as part of the context. One of the primary reasons for the js
object was to provide a more powerful interface for the patcher scripting features where
you can create, connect and move new objects. The Max, Patcher, Wind, and Maxobj
classes are used in scripting and Max application control. The Task object provides a
convenient Javascript interface to the Max scheduler. The Folder class allows you to
enumerate files. And the Global class allows different js instances to communicate with
each other and share data, as well as interface to Max send and receive objects.
Before we enumerate the properties and functions for these Javascript classes, well review
how you handle Javascript source text files for the js and jsui objects.
7
Assigning a File to js and jsui
Applies to the js object only: If you type js into an object box with no arguments, you will
get an object that cant do anything and has a single inlet and outlet. The first argument to
the js object is a filename of some Javascript source. By convention, Javascript source files
end in the extension .js. In fact, if you like, you can name a file something like myscript.js
and type js myscript. Assuming the file myscript.js is in the Max search path, the js object
will find it.
Applies to the jsui object only: There are several ways to assign a Javascript source file to
the jsui object.
Select the jsui object. Choose Get Info from the Object menu to open the jsui
Inspector. Type the filename or use the Choose button to select it from a standard
open file dialog window.
Right-click or control-click on a selected jsui object to see a contextual menu. You will
see several choices specific to the jsui object, including the names of Javascript source
files in the jsui-library folder inside the Cycling 74 folder. Choose one of these files,
or choose Load New File to select another file using a standard open file dialog
window.
Basic Techniques
In this section, we describe some general information about writing Javascript code for
the js and jsui objects.
Arguments
After supplying a filename after the word js, you can type in additional arguments; these
are available to your scripts global code or any function in an array property called
jsarguments[]. jsarguments[0] is the filename of your script, jsarguments[1] is
the first typed-in argument. jsarguments.length is the number of typed-in
arguments plus one. In other words, if there are no typed-in arguments, the value of
jsarguments.length will be 1.
8
The jsui inspector contains an arguments field: enter the arguments you wish to use here.
The first argument you type into the field can be accessed as jsarguments[1].
For most messages, a message received in an inlet of the Max js object will invoke a
method with the same name defined for the Javascript jsthis object, passing anything after
the beginning symbol as arguments to the function. Within Max, sending the message foo
1 2 3 to the js object invokes the foo() method of the jsthis object; in other words, it looks
for a function property of jsthis called foo, passing 1, 2, and 3 as arguments to the
function. If foo were defined as follows, the output in the Max window would be 1 2 3.
function foo(a,b,c)
{
post(a,b,c);
}
post() is a function of the js object that writes the value of one or more Javascript items
to the Max window, described in more detail in the jsthis Methods section below.
function msg_int(a)
{
post(a);
}
If you define only msg_int(), any float received will be truncated and passed to
msg_int(). Similarly, if only msg_float() exists, an int received will be
passed to the msg_float() function.
9
list
To handle Max lists, i.e., a message that begins with a number, call your function
list. In implementing a list function, youll probably want to use the Javascript
arguments property, since otherwise you couldnt handle input of varying
length. Example:
function list(a)
{
post("the list contains",arguments.length,
"elements");
}
You can define an anything() function that will run if no specific function is
found to match the message symbol received by the js object. If you want to know
the name of the message that invoked the function, use the messagename
property. If you want to know what inlet received the message, use the inlet
property. Both of these properties are discussed below in the jsthis Properties
section.
loadbang
To invoke a function when a patcher file containing the js or jsui object is loaded,
define a function called loadbang(). This function will not be called when you
instantiate a new js or jsui object and add it to a patcher; it will only be called when
a pre-existing patcher file containing a js object is loadedin other words, at the
same time that loadbang objects in a patcher are sending out bangs. You may wish
to test the loadbangdisabled property of the max object and do nothing in your
loadbang function if it is true. See the section entitled The Max Object below for
more information.
getvalueof
Defining a function called getvalueof() permits pattr and related objects to
attach to and query an object's current value. The value of an object returned can
be a Number, a String, or an Array of numbers and/or Strings. Example:
setvalueof
Defining a function called setvalueof() permits pattr and related objects to
attach to and set an object's current value, passed as argument(s) to the function.
10
Values passed will be of type Number or String. For a value that consists of more
than one Number or String, the setvalueof() method will receive multiple
arguments. The jsthis objects arrayfromargs() method is useful to handle
values that can contain a variable number of elements. Example:
function setvalueof(v)
{
myvalue = v;
}
save
Defining a function called save() allows your script to embed state in a patcher
file containing your js object. You can then restore the state when the patcher is
reloaded.
Saving your state consists of storing a set of messages that your script will receive
shortly after the js object containing it is recreated. These messages are stored
using a special method of jsthis called embedmessage that only works inside your
save function. An example will make this scheme clearer.
Suppose you have a message cowbells that sets the number of cowbells your object
currently has.
var numcowbells = 1;
function cowbells(a)
{
numcowbells = a;
}
When the patch containing the js object is saved, you would like to preserve the
current number of cowbells, so you define a save() function as follows:
function save()
{
embedmessage("cowbells",numcowbells);
}
Suppose the saved number of cowbells is 5. When it is reloaded, the js object will
call your cowbell function with an argument of 5.
The first argument to embedmessage is the name of the function you want to call
as a string. Additional arguments to embedmessage supply the arguments to this
function. These additional arguments will typically be the values of the state you
want to save.
See the description of the embedmessage message to the jsthis object below for
additional information.
11
Reserved Words
The Max js object also responds to special messages that control the object itself, such as
open, read, etc. Refer to the js and jsui pages in the Max Reference manual for details. If you
define, for example, a function named read inside your script, it cant be executed directly
via a message sent to the js object. However, you can still name a function read and call
the function from another Javascript function you define.
Global Code
Global code, as weve mentioned before, consists of any Javascript statements that exist
outside of any function definition. Your global code is always executed when your script
is loaded or recompiled after you edit it. When a js or jsui object is being created, the
global code is executed before the object is completely created. It wont have any inlets or
outlets, nor does it know about its context within a patcher. This means you can use the
global code to define how many inlets and/or outlets youd like to have. However, it also
means that, since outlets dont exist yet, you cant use them. If you want to perform some
kind of initialization after your object has outlets, youll need to write a loadbang()
function mentioned in the previous section.
Set the number of inlets and outlets you would like (see js Object Properties)
Access the arguments the user typed in with the jsarguments[] property
Use the Max object to access and control the global application environment
Declare function properties local (see below) and immediate (discussed in the
Controlling a Functions Thread of Execution section below).
Refer to your objects Patcher (see below for the capabilities of the Patcher object)
12
Private (Local) Functions
If you do not want a method to be invoked outside of Javascript via a message to js from
Max, you can set its local property to 1. For example, suppose the function foo() is not
something we wish to expose to the outside world.
foo.local = 1;
function foo()
{
post("what does Pd *really* stand for?");
}
Now, when we send the message foo to the js object, we see the following error in the Max
window:
messnamed("flower","bang);
a = new Array(900,1000,1100);
post(1,2,3,"violet",a);
post();
post(4,5,6);
13
These statements produce the following output in the Max window:
1 2 3 violet 900 1000 1100
456
If you want a line break in the middle of a call to post() you can use "\n" within
a string (this is now a general feature of Max). Also, post() begins a new line if
the last person to write to the Max window was not the js object.
jsthis Properties
14
inlet (Number, get)
During the execution of a function, the inlet property reports the inlet number
that received the message that triggered the function, starting at 0 for the leftmost
inlet. This propertys value is 0 within global code.
15
the section on js Max Object Properties below. Here is an example of sending the
max object the preempt message to turn Overdrive on:
max.preempt(1);
var stuff;
function anything(val)
{
if (arguments.length) // were there any arguments?
stuff[messagename] = val;
}
jsthis Methods
The important methods of the jsthis object are outlet() and post(). The others listed
here are typically for more advanced applications.
16
Array functions such as sort() on the arguments property, or send the
arguments property out an outlet as a list of values. The arrayfromargs()
method will convert the arguments property to an Array, optionally with
message as the zeroth element of the array. This message usage is useful for
processing messages as though they are lists beginning with a symbol, as would be
typical in your anything function. Here is an example of a function that allows its
arguments to be sorted. Note that messagename is a property of the jsthis object
that returns the name of the message that invoked the function.
function anything()
{
var a = arrayfromargs(messagename,arguments);
a.sort();
outlet(0,a);
}
// default getter/setter
var foo=2;
declareattribute("foo"); //simple
// explicit getter/setter
declareattribute("foo","getfoo","setfoo");
17
function setfoo(v)
{
foo = v;
}
function getfoo()
{
return foo;
}
function bang()
{
outlet(0,foo);
}
function save()
{
embedmessage("numchairs",20);
embedmessage("numtables",2);
embedmessage("roomname","diningroom");
}
When the js object containing this script is recreated, the function numchairs will
be called with an argument of 20, followed by the numtables function with an
argument of 2. Finally, the roomname function will be called with an argument of
the String diningroom.
18
notifyclients()
Notifies any clients (such as the pattr family of objects), that the objects current
value has changed. Clients can then take appropriate action such as sending a js
instance the message getvalueof to invoke the getvalueof() method (if defined
see the special function names section above for more information). The
notifyclients() method is useful for objects that define setvalueof() and
getvalueof() functions for pattr compatibility.
19
setoutletassist (number, object)
Associates either a number, string, or function with the numbered outlet (starting
at 0 for the left outlet). If -1 is passed as the outlet number, the object argument is
used for all outlets. In order to produce any assistance in the patcher, the
assistance function needs to call the assist() method described above.
Example:
// assistance function
function describe_it(num)
{
assist("this is outlet number",num);
}
// global code to set it up
setoutletassist(-1,describe_it);
Max Properties
20
loadbangdisabled (Number, get)
1 if the user has disabled loadbang for the currently loading patch. If your object
implements a loadbang method, it can test this property and choose to do nothing
if it is true.
mainthread (Number, get)
1 if the function is currently executing in the main (low-priority) thread, 0 if the
function is executing in the timer (high-priority) thread. See the section entitled
Controlling a Functions Thread of Execution below for more details.
os (String, get)
The name of the platform (e.g., windows or macintosh)
21
Max Methods
The Max object can be accessed as a property of a jsthis object (see jsthis Properties
above). Any message you can send to the max object using the semicolon notation in a
message box can be invoked within Javascript using Javascript syntax. For example, the
following in a message box:
; max preempt 1
max.preempt(1);
For a list of current messages that can be sent to the Max object, refer to the Messages to
Max topic.
There are currently three ways to get a Patcher, use the Constructor, access the patcher
property of a jsthis (accessed as this.patcher), or use the subpatcher() method of a
Maxobj object.
Patcher Constructor
var p = new Patcher(left,top,bottom,right);
left, top, bottom, right: global screen coordinates of the Patcher window
22
Patcher Properties
prev = 0;
owner = this.patcher.box;
while (owner) {
prev = owner;
owner = owner.patcher.box;
}
if (prev)
post("top patcher is",prev.name);
23
parentpatcher (Patcher, get)
If the patcher is a subpatcher, this returns the parent patcher. Otherwise it returns
a nil value.
Patcher Methods
Any message to a patcher that you can send in Max (via the thispatcher object) you can
send in Javascript in js.
Examples:
p = this.patcher;
p.fullscreen(1); // makes the patcher take up the whole
screen
p.dirty(); // make an editable patcher dirty
The Patcher methods listed below present a slighly more usable implementation of
patcher scripting. You can still script a patcher using the script message, since, as shown
above, a Javascript Patcher object can accept any message you can send to a thispatcher
object.
newobject (classname,params)
Creates a new object of Max class classname in a patcher using the specified
parameters and returns a Maxobj (see below) that represents it.
Example:
a = patcher.newobject("toggle",122,90,15,0);
24
Example:
a = patcher.newdefault(122,90,"toggle");
The newdefault() method also accepts additional arguments for non-user
interface objects that represent the created objects typed-in arguments.
Example:
p = this.patcher;
a = p.newobject("toggle",122,90,15,0);
b = p.newobject("toggle",122,140,15,0);
p.connect(a,0,b,0);
25
apply (function)
For all objects in a patcher, calls the function with the each object's Maxobj as an
argument. Does not recurse into subpatchers. The following example prints the
name of each object's class in the Max window:
function printobj(a)
{
post(a.maxclass);
post();
return true;
// iterfun must return true to continue
// iterating, else stops
}
this.patcher.apply(printobj);
applydeep (function)
Same as apply() except that applydeep() recurses into subpatchers (depth
first).
remove (object)
Removes the object (a Maxobj passed as an argument) from a patcher
getnamed (name)
Returns the first object found in a patcher with the given name. The name is a
local name as specified by the Name... dialog in a patcher, not the name of a send
or receive object. You can also set an object's name using the varname property of
a Maxobj.
getlogical (function)
Calls the function on each object in a patcher, passing it as a Maxobj argument to
the function. If the function returns true, the iteration stops and the Maxobj object
is returned as the value of the getlogical() method. Otherwise
getlogical() returns a nil value.
26
Example:
bringtofront (object)
Moves the object to the front of the current layer to which it is assigned (either
background or foreground). You can change the layer by setting the background
property of a Maxobj.
sendtoback (object)
Moves the object to the back of the current layer to which it is assigned (either
background or foreground). You can change the layer by setting the background
property of a Maxobj.
Maxobj Properties
The location of an object in a patcher. When the object's rectangle is changed, it will
move on screen if it is visible. The coordinates are stored in the following order: left, top,
right, bottom.
27
maxclass (String, get)
The Max class (as opposed to the Javascript class, which is "Maxobj" and accessed
via the standard class property) of the object.
js (jsthis, get)
If the Maxobj refers to an object is of Max class js, this returns the associated jsthis
object
28
valid (Boolean, get)
Returns whether the Maxobj refers to a valid Max object
Maxobj Methods
Perhaps the most powerful thing about a Maxobj is that you can send any message to a
Maxobj that you can send to a Max object in Max as if you were invoking a method on
the object in Javascript. For example, if you had a number box Maxobj and you wanted to
set its value to 23 without outputting the value, you could do this:
n.set(23);
Note that certain words such as int, float, and delete are keywords in Javascript, and
you will need to use either array notation or the message method for such reserved words.
For example:
n["int"] = 23;
//or
n.message("int", 23);
message(string, )
Sends the object the message specified by the string, followed by any additional
arguments provided. This is useful for sending messages to object which
dynamically dispatch messages with the anything message, as is the case for
instances of js, jsui, lcd, and others.
help ()
Opens a help file describing the object, if it exists
subpatcher (index)
If the object contains a patcher, this function returns a (Javascript) Patcher object.
The optional index is used for specifying an instance number, which only applies
to poly~ objects. If the object does not contain a subpatcher, a nil value is returned.
understands (string)
Returns a Boolean value if the object has an entry in its message list for the
message specified by the string. If the entry is not a message that can be sent by a
user within Max (i.e., it's a C-level untyped message), false is returned. This
29
doesnt work for messages which are dynamically dispatched with the anything
message, as is the case for instances of js, jsui, lcd, and others.
Wind Properties
30
next (Wind, get)
The Wind object of the next patcher visible in the applications list of windows
The first Wind object can be accessed using the frontpatcher property of the
Max object (as max.frontpatcher.wind).
Wind Methods
bringtofront ()
Moves the window in front of all other windows
scrollto (x, y)
Scrolls the window so that x and y are at the top-left corner.
sendtoback ()
Moves the window behind all other windows
setlocation (left,top,bottom,right)
Set the global location of the window according to the coordinates passed in as
arguments
31
Global Constructor
g = new Global(name);
A Global is basically a reference to a Javascript object that you can't access directly. The
object is connected to the Max symbol with the name you supplied as an argument (this
allows it to be accessed from Max, as we'll discuss below). Every time you access a Global,
it hands off the access to the secret hidden Javascript object. This means you can create
any number of Global objects in your code, in any number of js instances, and if they all
have the same name, they will all share the same data. In this way, a Global resembles a
namespace.
Example:
g = new Global("name");
g.bob = 12;
h = new Global("name");
post(h.bob); // will print 12
Global Properties
There are no fixed properties for a Global object. Instead, as described above, you assign
properties to a Global object so that they can be accessed by multiple js object instances.
Global Methods
g = new Global("xyz");
g.ethyl = 1000;
g.sendnamed("fred","ethyl");
Any receive objects named fred will send 1000 out their outlets.
To use Max to send a message to a named object, type a semicolon followed by the name
of the receiver and the message you want to send into a message box. To set a property of
a js Global object, send the property name followed by one or more values (multiple
32
values set the value of the property to an array). Assuming you have already created a
Global xyz object...
; xyz george 30
This sets the value of the frank property to an array of three strings containing "x" "y"
and "z"
; xyz frank x y z
You can also use the message sendnamed from Max to output property values to named
receive objects. This sends the current value of the frank property in the js Global object
xyz to any receive objects named hubert.
Note a subtle distinction. When setting property values using Max, the Javascript
properties are changed but no further action happens. When using sendnamed(), receive
objects take action and output the property values.
Task Constructor
var tsk = new Task(function, object, arguments);
The object argument represents the this during the execution of the function. Use the
this keyword (referring to the jsthis object) to be able to use outlets and other js object
features. The function argument represents the function you want to execute, and
arguments (an array) represents the arguments to pass to the function. The object
and arguments arguments are optional. If not present, the parent of the function object
(typically jsthis) will be assumed, and there will be no arguments supplied to the function.
33
Example:
function ticker(a,b,c)
{
post("tick");
}
args = new Array(3);
args[0] = 1;
args[1] = 2;
args[2] = 3;
t = new Task(ticker,this,args);
Although the overall timing accuracy of a Task function is high, the latency between the
scheduled time and the actual execution time of a Task function is variable because the
function runs in a low-priority thread. Therefore you should avoid using a Task function
in a time-critical operation.
Task Properties
For convenience, a Task object is a property of the function executed in a Task. To access
the Task from within its function, use the following standard Javascript syntax:
arguments.callee.task
We'll show you an example of this syntax for a Task that changes its interval below.
34
interval (Number, get/set)
The time in milliseconds between repeats of the task function. The default interval
is 500 ms. Here is an example of a Task with a function that causes the Task to run
10% more slowly each time the function is called, which uses the
arguments.callee.task syntax mentioned above:
function taskfun()
{
var intv = arguments.callee.task.interval;
arguments.callee.task.interval = intv + (intv * 0.1);
}
arguments.callee.task.object.outlet(1,"bang");
outlet(1,"bang");
this.outlet(1,"bang");
Task Methods
35
Example:
function repeater_function()
{
post(arguments.callee.task.iterations);
}
In the above example, the Max window output would be:
1
2
3
execute ()
Run the task once, right now. Equivalent to calling the task function with its
arguments.
schedule (delay)
Run the task once, with a delay. The optional delay argument sets the time (in
milliseconds) before the task function will be executed.
cancel ()
If a task is scheduled or repeating, any future executions are cancelled. This
method can be used within a task function for a self-canceling Task. The following
example is a task function that will run only once, even if it is started using the
repeat() function.
function once()
{
arguments.callee.task.cancel();
}
36
Folder Constructor
f = new Folder(pathname);
pathname can either be the name of a folder in the search path or a complete pathname
using Max path syntax.
Example:
f = new Folder("patches");
// would try to find the patches folder in the search path
f = new Folder("Disk:/folder1/folder2");
// uses an absolute path
After creating a Folder object, you'll probably want to restrict the files you see while
traversing it by setting the typelist property:
Check the file max-fileformats.txt inside the init folder in the Cycling 74 folder for
filetype codes and their associated extensions.
As a Folder object traverses through the files, you can find out information about the
current file using its file properties. You can also determine whether you've looked at all
properties by testing the end property. The following code prints the names of all files
found in the folder.
while (!f.end) {
post(f.filename);
post();
f.next();
}
To finish with the Folder object, you can either delete it, or send it the close message if you
might want to reuse it.
f.close ();
Folder Properties
Two types of properties of a Folder are available: some refer to the current file within the
folder, and some refer to the Folder objects state. Most of these properties are read-only.
37
Folder State Properties:
38
Folder Methods
reset ()
Start iterating at the beginning of the list of files. Re-opens the folder if it was
previously closed with the close() function.
next ()
Moves to the next file.
close ()
Closes the folder. To start using it again, call the reset() function.
File Constructor
f = new File(filename, access, typelist);
filename can be a file in the Max search path, an absolute path, or a relative path.
Acceptable values for access can be "read", "write", or "readwrite". The default value for
access is "read". Acceptable values for typelist are four character filetype codes listed in the
file max-fileformats.txt, which is located at /Library/Application Support/Cycling 74 on
Macintosh and C:\Program Files\Common Files\Cycling 74 on Windows. By default,
typelist is empty. If able to, the File constructor opens the file specified by filename,
provided it is one of the types in typelist.
File Properties
File Methods
open (filename)
Opens the file specified by the filename argument. If no argument is specified, it
will open the last opened file.
close ()
Closes the currently open file.
writeline (string)
Writes the characters contained in the string argument as characters to the file,
starting at the current file position, and inserts a line break appropriate to the
linebreak property. The file position is updated accordingly.
40
readline (maximum_count)
Reads and returns a string containing up to maximum_count characters or up to
the first line break as read from the file, starting at the current file position. The
file position is updated accordingly.
writestring (string)
Writes the characters contained in the string argument as characters to the file,
starting at the current file position. Unlike writeline(), no line break is inserted.
The file position is updated accordingly.
readstring (char_count)
Reads and returns a string containing up to char_count characters as read from
the file, starting at the current file position. Unlike readline(), line breaks are not
considered. The file position is updated accordingly.
writebytes (byte_array)
Writes the numbers contained in the byte_array argument as bytes to the file,
starting at the current file position. The file position is updated accordingly.
readbytes (byte_count)
Reads and returns an array containing up to byte_count numbers, read as bytes
from the file, starting at the current file position. The file position is updated
accordingly.
writechars (char_array)
Writes the single character strings contained in the char_array argument as
characters to the file, starting at the current file position. The file position is
updated accordingly.
readchars (char_count)
Reads and returns an array containing the single character strings, read as
characters from the file, starting at the current file position. The file position is
updated accordingly.
writeint16 (int16_array)
Writes the numbers contained in the int16_array argument as signed 16-bit
integers to the file, starting at the current file position. The byteorder property is
taken into account when writing these values. The file position is updated
accordingly.
41
readint16 (int16_count)
Reads and returns an array containing the numbers read as signed 16-bit integers
from the file starting at the current file position. The byteorder property is taken
into account when reading these values. The file position is updated accordingly.
writeint32 (int32_array)
Writes the numbers contained in the int32_array argument as signed 32-bit
integers to the file, starting at the current file position. The byteorder property is
taken into account when writing these values. The file position is updated
accordingly.
readint32 (int32_count)
Reads and returns an array containing the numbers read as signed 32-bit integers
from the file starting at the current file position. The byteorder property is taken
into account when reading these values. The file position is updated accordingly.
writefloat32 (float32_array)
Writes the numbers contained in the float32_array argument as 32-bit floating
point numbers to the file, starting at the current file position. The byteorder
property is taken into account when writing these values. The file position is
updated accordingly.
readfloat32 (float32_count)
Reads and returns an array containing the numbers read as 32-bit floating point
numbers from the file starting at the current file position. The byteorder property
is taken into account when reading these values. The file position is updated
accordingly.
writefloat64 (float64_array)
Writes the numbers contained in the float64_array argument as 64-bit floating
point numbers to the file, starting at the current file position. The byteorder
property is taken into account when writing these values. The file position is
updated accordingly.
readfloat64 (float64_count)
Reads and returns an array containing the numbers read as 64-bit floating point
numbers from the file starting at the current file position. The byteorder property
is taken into account when reading these values. The file position is updated
accordingly.
42
Controlling a Functions Thread of Execution
A thread is akin a continuously executing program running on a computer. Threads are
managed by the computers operating system: the system is constantly pausing and
resuming threads to create the effect of many simultaneous activities running on a single
processor. For example, you can be downloading a song from the internet in one thread
while reading your e-mail in another. When the Overdrive option is turned on, Max uses
two threads and asks the operating system to ensure that one of the threads, which we call
the high-priority thread, runs as regularly as possible (usually every millisecond). In
exchange, Max tries to ensure that what happens in this thread uses as little of the
computers time as possible. Time-consuming and user-interaction tasks are assigned to
the low-priority thread.
The two threads allow you to use Max to do things that require high timing accuracy
(such as MIDI) at the same time as you do things that are computationally expensive
(such as decompress video) or involve user input.
Now, how does js fit into this multi-threaded scenario? By default, the js object executes
all Javascript code in the low-priority thread. In particular, if it finds itself running in the
high-priority thread, it will defer execution of whatever it was supposed to do to the low-
priority thread. You can, however, tell js not to do this by setting the immediate property
of a function.
Lets say you have a function bang that you intend to run when someone hooks up your js
object to a metro, as follows:
43
Your bang function does something simple such as sending the value of a number out its
outlet.
var value = 1;
function bang()
{
outlet(0,value);
}
The timing accuracy of this function will be improved if you execute it immediately when
the bang is received, rather than deferring it to the low-priority thread, where it will
execute at some unspecified later time. In order to do this, you place the following
statement in your global code.
bang.immediate = 1;
However, just because a functions immediate property is set does not mean that it will
always execute at high-priority. This depends on the context in which the js object
received a request to execute your function. For example, if I click on a bang button
connected to the js object described above, the bang function will run in the low-priority
thread, because mouse clicks are always handled at low priority.
Another example that is a bit more subtle: lets say I write a function slowbang that does
not have its immediate property set. It merely calls the bang function I wrote above.
function slowbang()
{
bang();
}
Suppose we make a new patch in which the metro is hooked up to the slowbang message,
as shown here:
Now the bang function will no longer execute in the high-priority thread, because
slowbang was deferred to the low-priority thread before bang is executed.
44
You can determine the current thread of execution for your Javascript code by testing the
mainthread property of the max object. The mainthread property will be 1 if the code is
running in the low-priority thread.
and
or
Posting messages to the Max window using post (although the order in which the
messages appear is not guaranteed)
The following actions are not guaranteed to work if you attempt to perform them in the
high-priority thread. In most cases, there is no protection against doing any of these
things, which may result in unexpected behavior, including Max crashing (although if
you find such cases, we will do our best to prevent them).
45
Any use of jsui features such as creating a Sketch or Image object or invoking
methods of those objects
Using the scripting or application control features in the Patcher, Maxobj, or Wind
objects and their methods.
46
jsui, Sketch and OpenGL
Javascript files loaded by the jsui object have access to the Sketch object, which may be
used for drawing graphics. We will refer to the Sketch object and the methods it exposes
as the Sketch API. The Sketch API is built upon the cross platform OpenGL API, and
can be divided into two categories: "OpenGL Methods" and "High Level Methods". The
"OpenGL Methods" are a direct binding for a large portion of the low level OpenGL API,
and the "High Level Methods" are extensions built upon lower level OpenGL calls.
1. The Sketch methods are all lowercase, and only exist within the context of a sketch
object. For example, this means that glBegin() will be sketch.glbegin(), and
glClearColor() will be sketch.glclearcolor(). Javascript's "with" statement may
be used to avoid having to type "sketch." for every method call.
2. All symbolic constants are lowercase Javascript strings, and have no "GL_" prefix. For
example the constant GL_LIGHTING will be the Javascript string "lighting", and
GL_LINE_STRIP is replaced with "line_strip".
3. There are no special versions of vector calls. Only floating point values are supported,
and sketch will fill in extra values with defaults. For example glColorv4fv(),
glColorv3fv(), etc. will simply be sketch.glcolor().
47
Colors and Coordinates
As is the convention in OpenGL, color values should be specified with each component as
a floating point number in the range of 0.-1., as opposed to an integer in the range 0-255.
For example red would be (1.,0.,0.), rather than (255,0,0). OpenGL also supports the use
of an alpha channel for transparency and other types of blending modes. Colors with
alpha channel values may be specified as RGBA, for example, green with 25% opacity
would be (0.,1.,0.,0.25). If there is no alpha channel value present, it is assumed to be 1.--
i.e. 100% opaque. By default, alpha blending is enabled. To turn off blending, use
sketch.gldisable("blend"). When working in 3D, depth buffering is turned on by
default, and will typically interfere with attempts to blend transparent objects. To turn off
depth buffering, use sketch.gldisable("depth_test").
Unlike some graphics APIs, the OpenGL API does not distinguish between 2D and 3D
drawing. Conventional 2D drawing is simply a subset of 3D drawing calls with specific
graphics state--e.g. no lighting, no depth testing, orthorgraphic projection, et cetera. High
level utility methods are provided as a convenience to setup up the OpenGL graphics state
to something typically used for 2D or 3D graphics. If assuming 2D drawing conventions,
one can ordinarily use z coordinates of zero for all methods that require them.
Coordinates in OpenGL are also given in terms of floating point relative world
coordinates, rather than absolute pixel coordinates. The scale of these world coordinates
will change depending on the current graphics transformation--i.e. translation, rotation,
scaling, projection mode, viewport, etc. However, our default mapping is that Y
coordinates are in the range -1. to 1 from bottom to top, and X coordinates are in the
range -aspect to aspect from left to right, where aspect is equal to the ratio of
width/height. In the default case, (0,0) will be center of your object, (-aspect,1.) will be the
upper left corner, and (aspect,-1.) will be the lower right corner.
Note that user events are typically provided in terms of absolute screen coordinates.
Please see the sketch.screentoworld() and sketch.worldtoscreen() methods
for converting between absolute screen coordinates and relative world coordinates.
48
jsui Specific Properties
function bang()
{
sketch.glclear();
sketch.glcolor(0.5,0.7,0.3);
sketch.moveto(0.25,-0.25);
sketch.circle(0.3);
refresh();
}
refresh ()
copies the contents of this.sketch to the screen.
Since the jsui object is a user interface object, it can receive and process user interface
events. Currently the only user interface events which are supported are related to mouse
activity and resizing off the jsui object. If the following methods are defined by your
Javascript code, they will be called to handle these user interface events. All mouse events
handlers should be defined with have a standard form of
The modifier1 argument is the command key state on Macintosh, and the control key
state on PC, and the modifier2 argument is the control key state on Macintosh, and the
right button state on PC. Modifier state is 1 if down/held, or 0 if not. If your event
handler is not concerned with any trailing arguments, they can be omitted.
One potentially confusing thing is that mouse events are in absolute screen coordinates,
with (0,0) as left top, and (width, height) as right bottom corners of the jsui object, while
Sketch's drawing coordinates are in relative world coordinates, with (0,0) as the center, +1
49
top, -1 bottom, and x coordinates using a uniform scale based on the y coordinates. To
convert between screen and world coordinates, use sketch.screentoworld(x,y)
and sketch.worldtoscreen(x,y,z). For example,
50
Sketch Constructor
var mysketch = new Sketch(); // create a new instance of
Sketch with default width and height
var mysketch = new Sketch(width,height); // create a new
instance of sketch with specified width and height
Sketch Properties
Sketch Methods
Sketch Simple Line and Polygon Methods
moveto (x, y, z)
Moves the drawing position to the location specified by the x, y, and z arguments.
point (x, y, z)
Draws a point at the location specified by the x, y, and z arguments. After this
method has been called, the drawing position is updated to the location specified
by the x, y, and z arguments.
51
lineto (x, y, z)
Draws a line from the current drawing position to the location specified by the x,
y, and z arguments. After this method has been called, the drawing position is
updated to the location specified by the x, y, and z arguments.
tri (x1, y1, z1, x2, y2, z2, x3, y3, z3)
Draws a filled triangle with three corners specified by the x1, y1, z1, x2, y2, z2, x3,
y3, and z3 arguments. After this method has been called, the drawing position is
updated to the location specified by the x3, y3, and z3 arguments.
frametri (x1, y1, z1, x2, y2, z2, x3, y3, z3)
Draws a framed triangle with three corners specified by the x1, y1, z1, x2, y2, z2,
x3, y3, and z3 arguments. After this method has been called, the drawing position
is updated to the location specified by the x3, y3, and z3 arguments.
quad (x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4)
Draws a filled quadrilateral with four corners specified by the x1, y1, z1, x2, y2, z2,
x3, y3, z3, x4, y4, and z4 arguments. After this method has been called, the
drawing position is updated to the location specified by the x4, y4, and z4
arguments.
framequad (x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4)
Draws a framed quadrilateral with four corners specified by the x1, y1, z1, x2, y2,
z2, x3, y3, z3, x4, y4, and z4 arguments. After this method has been called, the
drawing position is updated to the location specified by the x4, y4, and z4
arguments.
52
Shape Methods
53
frameellipse (radius1, radius2, theta_start, theta_end)
Draws a framed ellipse with radii specified by the radius1 and radius2 arguments.
If theta_start and theta_end are specified, then an arc will be drawn instead of a
full ellipse. The theta_start and theta_end arguments are in terms of degrees(0-
360). The current shapeorient, shapeslice, and shapeprim values will also affect the
drawing.
54
Sketch Shape Attribute Methods
with (sketch) {
glmatrixmode("modelview");
glpushmatrix();
glrotate(rotation_x,1.,0.,0.);
glrotate(rotation_y,1.,1.,0.);
glrotate(rotation_z,0.,0.,1.);
torus(0.5,0.2);
glpopmatrix();
}
shapeprim (draw_prim)
Sets the OpenGL drawing primitive to use within any of the "shape" drawing
methods. Acceptable values for the draw_prim argument are the following strings:
lines, line_loop, line_strip, points, polygon, quads, quad_grid, quad_strip,
triangles, tri_grid, tri_fan, tri_strip.
font (fontname)
Sets the current font to the fontname specified by the fontname argument.
fontsize (points)
Sets the fontsize to the size specified by the points argument. Note that this size is
an absolute, rather than relative value.
gettextinfo (string)
Returns an array containing the width and height of the given string in absolute
screen coordinates, taking into account the current font and fontsize.
55
text (string)
Draws the text specified by the string argument at the current drawing position,
taking into account the current font, fontsize, and text alignment. Text is strictly
2D, and does not take into account any world transformations. After calling the
text method, if the x axis text alignment is set to "left", the current drawing
position will be updated to reflect the world position associated with the end of
the string. If the x axis text alignment is set to "right", the current drawing position
will be updated to reflect the world position associated with the end of the string.
If the x axis text alignment is set to "center", the current drawing position will
remain unchanged.
depthatpixel (x, y)
Returns the depth value associated with the currently rendered pixel at a given
absolute screen coordinate.
freepeer ()
Frees the image data from the native c peer, which is not considered by the
JavaScript garbage collector, and may consume lots of memory until the garbage
56
collector decides to run based on JS allocated memory. Once called, the Sketch
object is not available for any other use.
getpixel (x, y)
Returns an array containing the pixel value at the specified location. This array is
ordered RGBA, i.e. array element 0 is red, 1, green, 2, blue, 3 alpha. Color values
are floating point numbers in the range 0.-1.
screentoworld (x,y)
Returns an array containing the x, y, and z world coordinates associated with a
given screen pixel using the same the depth from the camera as 0,0,0. Optionally a
third depth arg may be specified, which may be useful for hit detection and other
applications. The depth value is typically specified in the range 0.-1. where 0 is the
near clipping plane, and 1. is the far clipping plane. The worldtoscreen method
can be used to determine the depth value of a given world coordinate, and the
depthatpixel method can be used to determine the depth value associated with the
currently rendered pixel at a given absolute screen coordinate.
worldtoscreen (x, y, z)
Returns an array containing the x, y, and depth screen coordinates associated with
a given world coordinate. The depth value is typically specified in the range 0.-1.
where 0 is the near clipping plane, and 1. is the far clipping plane.
beginstroke (stroke_style)
Begin definition of a stroked path of the style specified by the stroke_style
argument. Currently supported stroke styles are "basic2d" and "line".
endstroke ()
End definition of a stroked path, and render the path.
57
strokeparam (parameter_name, parameter_values, ...)
Set the current value of the parameter specified by the parameter_name argument
to be the value specified by parameter_values argument(s). Some parameters are
global for the extent of a stroked path definition, while others may vary on a point
by point basis.
strokepoint (x, y, z)
Defines an anchor point at the location specified by the x, y, and z arguments.
Some stroke styles such as "basic2d" will ignore the z coordinate.
color
May vary point to point. Values are specified as red, green, blue, and alpha values.
order
Global. Value is specified as interpolation order. The default order is 3, or bi-cubic
interpolation.
outline
Global. Value is specified as on/off (0/1). The default is 1.
outcolor
May vary point to point. Values are specified as red, green, blue, and alpha values.
If no outcolor has been specified, then the current color is assumed.
scale
May vary point to point. Value is specified as an width value. This value controls
how wide the stroked path is.
slices
Global. Value is specified as number of slices per curve section. The default is 20.
58
Line Stroke Style Parameters
alpha
May vary point to point. Value is specified as an alpha value. Useful if alpha is the
only color channel which will vary throughout the path.
color
May vary point to point. Values are specified as red, green, blue, and alpha values.
order
Global. Value is specified as interpolation order. The default order is 3, or bi-cubic
interpolation.
slices
Global. Value is specified as number of slices per curve section. The default is 20.
59
Sketch Setup Methods
default2d ()
The default2d method is a simple way to set the graphics state to default
properties useful for 2D graphics. It is called everytime your object is resized if
default2d() has been called more recently than default3d(). It is essentially
equivalent to the following set of calls:
with (sketch) {
glpolygonmode("front_and_back","fill");
glpointsize(1.);
gllinewidth(1.);
gldisable("depth_test");
gldisable("fog");
glcolor(0.,0.,0.,1.);
glshademodel("smooth");
gldisable("lighting");
gldisable("normalize");
gldisable("texture");
glmatrixmode("projection");
glloadidentity();
glortho(-aspect, aspect, -1, 1, -1,100.);
glmatrixmode("modelview");
glloadidentity();
glulookat(0.,0.,2.,0.,0.,0.,0.,0.,1.);
glclearcolor(1., 1., 1., 1.);
glclear();
glenable("blend");
glblendfunc("src_alpha","one_minus_src_alpha");
}
60
default3d ()
The default3d method is a simple way to set the graphics state to default
properties useful for 3D graphics. It is called everytime the jsui object is resized if
default3d() has been called more recently than default2d().
It is essentially equivalent to the following set of calls:
with (sketch) {
glpolygonmode("front_and_back","fill");
glpointsize(1.);
gllinewidth(1.);
glenable("depth_test");
glenable("fog");
glcolor(0.,0.,0.,1.);
glshademodel("smooth");
gllightmodel("two_side", "true");
glenable("lighting");
glenable("light0");
glenable("normalize");
gldisable("texture");
glmatrixmode("projection");
glloadidentity();
gluperspective(default_lens_angle, aspect, 0.1, 100.);
glmatrixmode("modelview");
glloadidentity();
glulookat(0.,0.,2.,0.,0.,0.,0.,0.,1.);
glclearcolor(1., 1., 1., 1.);
glclear();
glenable("blend");
glblendfunc("src_alpha","one_minus_src_alpha");
}
61
ortho3d ()
The orth3d method is a simple way to set the graphics state to default properties
useful for 3D graphics, using an orthographic projection (i.e. object scale is not
affected by distance from the camera). It is called every time the jsui object is
resized if ortho3d() has been called more recently than default2d(), or
default3d().
It is essentially equivalent to the following set of calls:
with (sketch) {
glpolygonmode("front_and_back","fill");
glpointsize(1.);
gllinewidth(1.);
glenable("depth_test");
glenable("fog");
glcolor(0.,0.,0.,1.);
glshademodel("smooth");
gllightmodel("two_side", "true");
glenable("lighting");
glenable("light0");
glenable("normalize");
gldisable("texture");
glmatrixmode("projection");
glloadidentity();
glortho(-aspect, aspect, -1, 1, -1,100.);
glmatrixmode("modelview");
glloadidentity();
glulookat(0.,0.,2.,0.,0.,0.,0.,0.,1.);
glclearcolor(1., 1., 1., 1.);
glclear();
glenable("blend");
glblendfunc("src_alpha","one_minus_src_alpha");
}
glbegin (draw_prim)
glclear ()
glcleardepth (depth)
62
glclipplane (plane, coeff1, coeff2, coeff3, coeff4)
glcullface (face)
gldepthmask (on)
gldisable (capability)
gldrawpixels (image)
gledgeflag (on)
glenable (capability)
glend ()
glfinish ()
glflush ()
gllinewidth (width)
glloadidentity ()
63
glloadmatrix (matrix_array)
gllogicop (opcode)
glmaterial
glmatrixmode (mode)
glmultmatrix (matrix_array)
glnormal (x, y, z)
glpointsize (size)
glpopattrib ()
glpopmatrix ()
glpushattrib ()
glpushmatrix ()
glrotate (angle, x, y, z)
glshademodel (mode)
gltexcoord (s, t)
64
gltexparameter (parameter_name, val1, val2, val3, val4)
glulookat (eye_x, eye_y, eye_z, center_x, center_y, center_z, up_x, up_y, up_z)
glvertex (x, y, z)
Image Constructor
var myimg = new Image(); // create a new Image instance
with default width + height
var myimg = new Image(width,height); // create a new Image
instance with the specified witdth + height
var myimg = new Image(filename); // create a new Image
instance from a file from disk
var myimg = new Image(imageobject); // create a new Image
instance from another instance of Image
var myimg = new Image(sketchobject); // create a new Image
instance from an instance of Sketch
Image Properties
size(Array[2], get/set)
size[0] is width size[1] is height.
65
Image Methods
66
copychannel (source_object, source_channel, destination_channel)
Copies the channel values from the source object's channel specified by the
source_channel argument to the destination object's channel specified by the
destination_channel argument. The source object can only be an instance of
Image (not Sketch). If the source object is not the same size as the destination
object, then rectangle composed of the minimum width and height of each, is the
rectangle of values which will be copied. Acceptable values for the channel
arguments are the strings: "red", "green", "blue", or "alpha".
freepeer ()
Frees the image data from the native c peer, which is not considered by the
JavaScript garbage collector, and may consume lots of memory until the garbage
collector decides to run based on JS allocated memory. Once called, the Image
object is not available for any other use.
fromnamedmatrix (matrixname)
Copies the pixels from the jit.matrix specified by matrixname to the image.
getpixel (x, y)
Returns an array containing the pixel value at the specified location. This array is
ordered RGBA, i.e. array element 0 is red, 1, green, 2, blue, 3 alpha. Color values
are floating point numbers in the range 0.-1.
67
swapxy ()
Swaps the axes of the image so that width becomes height and vice versa. The
effective result is that the image is rotated 90 degrees counter clockwise, and then
flipped vertically.
tonamedmatrix (matrixname)
Copy the pixels from the image to the jit.matrix specified by matrixname.
68