Little JS Syntax Bible in Max/MSP
Here I want to collect all the less intuitive Javascript syntax and techniques for Max.
Feel free to comment everything that comes to your mind related to the subject, I'll add it to the list.
Max JS uses ES5 version, so features like "let" and Classes added in ES6 will not work.
Max's documentation for JS:
https://docs.cycling74.com/max8/vignettes/javascriptinmax
Tim's JS Reference:
http://max-javascript-reference.tim-schenk.de/
Get keys pressed in JS:
https://github.com/cskonopka/maxJS
Max Scripting
Create a new Max object:
var myObj = this.patcher.newdefault(<obj_pos_x>, <obj_pos_y>, "<max_obj_name>");
Add arguments to Object when creating it:
var anotherObject = p.newdefault(100, 100, "combine", "text", "::", "moretext")
Add Object to Presentation:
maxObject.presentation(1); // note that it's a function
Move Object:
maxObject.message("patching_position", [posX, posY]);
Create a new "bpatcher" object with attributes:
var myNewObject = p.newdefault(100, 100, "bpatcher", "@name", "myPatch", "@args", name);
Get patcher file path:
var filepath = this.patcher.filepath;
Rescale Max Object:
this.patcher.script("sendbox", <max_obj>.varname, "patching_rect", [ <obj_pos_x>, <obj_pos_y>, <obj_size_x>, <obj_size_y> ]);
Hide a Max Object:
<max_obj>.hidden = val;
Rescale Max Object in Presentation:
this.patcher.script("sendbox", <max_obj>.varname, "presentation_rect", [ <obj_pos_x>, <obj_pos_y>, <obj_size_x>, <obj_size_y> ]);
Bring to Front/Back Max Object:
this.patcher.script("bringtofront" / "sendtoback", <max_obj>.varname);
Connect two Max objects:
this.patcher.connect(<max_obj_1>, <outlet_index>, <max_obj_2>, <inlet_index>);
Connect two Max objects with hidden cable:
this.patcher.hiddenconnect(<max_obj_1>, <outlet_index>, <max_obj_2>, <inlet_index>);
Connect the JS object itself with a Max object in the same patch:
this.patcher.connect(this.box, <outlet_index>, <max_obj>, <inlet_index>)
Send a message to a Max "receive" object from within JS:
messnamed("<receive_obj_name>");
Get a named Max object and assign it to a JS object:
var myMaxObj = this.patcher.getnamed("<obj_varname>");
Get the value of an attribute of a Max object:
obj.getboxattr("<attr_name>");
Resize a BPatcher that contains the JS object:
this.patcher.box.rect = [<leftTopX>, <leftTopY>, <bottomRightX>, <bottomRightY>]
Change size of Max patcher:
this.patcher.window( "size", x, y, x + w, y + h );
this.patcher.window( "exec" );Get the size of the current patcher:
var size = this.patcher.wind.size;
Get the rect of the current patcher:
var rect = this.patcher.wind.location;
JSUI
Get the rect of the JSUI object box:
var objRect = box.rect.slice();
Get size of box.rect =var objSize = [box.rect[2] - box.rect[0], box.rect[3] - box.rect[1]];
box.rect can also be set.
Folder Object
Create a Folder object and read the file names in the folder:
var myFolder = new Folder(<folder_path>);
Set Folder typelist (an empty typelist will make the Folder object read every file type):myFolder.typelist = ["<file_type>", "<file_type>", etc...];
Read the Folder file names:while (!myFolder.end)
{
post(myFolder.filename);
myFolder.next();
}
Dict Object
Basic querying:
function dictionary(dictname)
{
var d = new Dict(dictname);
outlet(0, d.get('layer1key::layer2key');
}Iterating through layers of a Dict:
function dictionary(dictname)
{
var d = new Dict(dictname);
var layer1 = d.getkeys();
layer1.forEach(function(key)
{
var layer2 = d.get(key).getkeys();
}
}
Max Object Listener
Listen to a Max Object for attributes or value changes:
var myListener = new MaxobjListener(<max_obj>, <callback_function>);
The Callback function can be used like this:function MyCallback(data)
{
data.value; // the output of the Max object
data.maxobject; // the object itself
}To make the "this" inside a callback refer to the current object, you can write the callback directly inside the object in this way:
var MyCallback = (function(data)
{
post(this.myObjProperty);
} ).bind(this);
MaxobjListener tutorial:
Jitter in Javascript
Create Jitter Matrix:
var myMatrix = new JitterMatrix("<name_optional>", <int_number_of_planes>, "<type>", [<int_dim_0>, <int_dim_1>, ... ] );
Get name of object as registered from Max:
var objRegName = <jsJitterObj>.getregisteredname();
Create Jitter Object:
var myJitterObj = new JitterObject("<obj_name>", <argument>);
Example:var myJitterObj = new JitterObject("jit.gl.gridshape", "<drawto>");
Free Jitter Object Memory (must be done every time a Jitter object is deleted in JS):
myJitterObj.freepeer();
Use a "jit.gl.pix" object within JS (same for "jit.gl.slab"):
var myGLPix = new JitterObject("jit.gl.pix");
myGLPix.gen = "<genjit_file_path>";
Set the input you want to send the next texture:myGLPix.activeinput = <int_input_index>
Set parameters:
Get the processed texture:
myGLPix.param("<param_name>", <param_value> / [<array_of_param_values>]);
myGLPix.jit_gl_texture("<texture_to_process_name>");
myGLPix.draw(); // IMPORTANT, the jit.gl.pix obj needs also to draw
var myProcessedTexture = myGLPix.out_name;
Play a movie with "jit.movie" and get a texture output from within JS:
First create a dummy matrix, the dimensions don't matter:var dummyMat = new JitterMatrix(4, "char", 320, 240);
jit.movie needs output_texture enabled:var moviePlayer = new JitterObject("jit.movie");
moviePlayer.output_texture = 1;
Get new frame and output texture:function LoadNewFrame()
{
moviePlayer.matrixcalc(dummyMat, dummyMat);
outlet(0, moviePlayer.texture_name);
}
Get the new frame as texture: newFrame = moviePlayer.texture_name;
Get texture output from jit.gl.node:
var texOut = myNode.out_name;
Use a JitterListener to listen to change of state in Jitter Objects:
https://docs.cycling74.com/max8/tutorials/jitterchapter47?q=jitterlistenerOUTPUTMATRIX from GL objects in JS:
check out the example patch js.gl.matrixoutput.maxpat in the Files Browser.JIT.CONCAT in JS:
var concat = new JitterObject("jit.concat");
concat([leftMat, rightMat], outMat);Get the TEXTURE name from JIT.GL.NODE:
return myNode.out_name;
Or:myNode.out_names;
Max 4 Live
Max 4 Live JS guide by Adam Murray:
http://compusition.com/writings/js-live-api-setup
Hi, I think the real bible is this https://docs.cycling74.com/max8/vignettes/javascriptinmax, isn't it ?
btw: the JitterListener link doesn't work.
Thank you Olsen, that's a great resource, will pin it to the top.
However I find that it's still useful to collect all the Jitter syntax and the more esoteric things (like "activeinput" for jit.gl.pix and jit.gl.slab) which are not immediately recollected from the documentation.
If nothing else, I will use this post to note things I encounter and that I wish to remember.
Oh yes, Tim's website is a bit funky, thanks for noting
try this link for Tim's JS site - http://max-javascript-reference.tim-schenk.de/
(and thanks much for collecting these Federico, hugely helpful)
Thank you Rob, wanted to point to a precise article, but will pin Tim's website as well as a resource.
Might be nice to have some more advanced new object examples
Here are some from my own patchesvar myNewObject = p.newdefault(100, 100, "bpatcher", "@name", "myPatch", "@args", name);
var anotherObject = p.newdefault(100, 100, "combine", "text", "::", "moretext")
Feel like Dict stuff needs a section, too. Some examples:
Basic querying: function dictionary(dictname) {
var d = new Dict(dictname);
outlet(0, d.get('layer1key::layer2key');
}
Iterating through layers of a Dict:
function dictionary(dictname) {
var d = new Dict(dictname);
var layer1 = d.getkeys();
layer1.forEach(function(key) {
var layer2 = d.get(key).getkeys();
}
}
Awesome NTRM, both added.
This thread is going to be very helpful, as js in max related informations are pretty much spread and scarce along a lot of years, and probably under documented, even in the forum, so the learning start might seem scary for our community while i find js in max is powerful,
I m looking forward to see this growing. Thx Federico!
Roald Baudoux collected some examples of buffer~ operations with js in this thread.
Thanks everyone.
When you arrive in js, it is sometimes complicated to identify script errors that are related to specificities of js in max. It would be helpfull for js beginners (like me) if we could collect here the things to know about these little particularities that your max logic won't help to figure out :)
Two examples :
For jit.gl.text , 2d or 3d has to be specified in the var attribute, and not in the object argument itself (unlike the max externals)
var mytext = new JitterObject ("jit.gl.text","context");
mytext.mode = 2d ; // or 3d
For jit.gl.light, the drawing context has to be specified in the drawto attribute (not in the object argument)
var mylight = new JitterObject ("jit.gl.light");
mylight.drawto = "mycontext";
Context set in the argument will generate console error "#N: extra arguments for message "jit_gl_light"
Sharing this pretty interesting thread, which links to comprehensive tutorials on how to use Ableton Api in js/m4l.
It worths to share it again here:
https://cycling74.com/forums/tutorial-using-the-javascript-live-api-in-max-for-live
http://compusition.com/writings/js-live-api
Awesome! Loving the contributions
some useful links referenced in here :
https://cycling74.com/forums/looking-for-good-inforeference-on-js
I guess the documentation on my site is pretty outdated, guess I made it almost 10 years ago. Is it still helpful? Did not try the node integration of max ever. So I don't know what changed lately. Are there any updates needed?
Recently found this resource for people getting started (like me) and I believe it's great.
http://hems.io/max.js/#/
* you have to use the cursor. :)
@loadmess: that is indeed a very compact guide - apart from showing the title is does do nothing here :)
* yes I used the cursor :)
Ah! Was working on my phone but not on pc, it was looking great tho!
@JAN Perhaps try giving a click in the area where information is shown before using the cursor. It works for me. I'm using chrome by the way.
On the phone you can just swipe up to change the slides, and then when you reach the end you swipe left to go to next column. On the computer you can press ESC key to see the overview of all the columns ;)
OCH
One thing I can never remember is how to get the arguments typed into another object box (ie not jsarguments)..
Hey LYSDEXIC!
I think it would work like this:
var myNewObject = p.newdefault(100, 100, "objName", "@argName", argValue);
Hey Federico!
Yep - that looks like what you'd want to do to create a new object.. What I mean is to query an existing object for its args.
ie:
// walk the patchcord and get the arguments from the object connected to the first outlet
ourself = this.box;
destobj = ourself.patchcords.outputs[0].dstobject;
// destobj.getattr("text"); ?
Hi, here you go:destobj.getboxattr("boxatoms");
brilliant! it works! cheers - something I look for all the time! :D
Awesome!!
I did try to do this for a while without success.
Straight in the list.
Posted this a couple threads the other, but it also seems revelant here. This tutorial provides a lot of great examples for declaring classes in Javascript with the old syntax used in the Max js object. https://www.newthinktank.com/2015/09/object-oriented-javascript/
I will make sure it's available from somewhere safe soon after some optimisations since the original Ircam website seem to be dead or sth!
Thank you, Federico, for this useful guide.
I just found a pitfall, encapsulating File into a function, if using an argument as a path, needs to be converted to string again or it will not work. I.e.:
function fileExists(filePath) {
this.f = new File(String(filePath));
}