Mr. Doobs Harmony Drawing Application ported to Max MSP

    Sep 14 2010 | 1:02 pm
    Hello people,
    I fall in love with the brush style of Mr. Doobs drawing app Harmony ( ). I am Interactive Art Developer and quite new in Max/MSP. Motivated by extending my skills I ported it to Javascript in Max MSP. Now I want to share my results with you. You can download and see my code on my blog
    or just have a short look on my vimeo introduction video
    I would be happy about some feedback from you.
    Best regards, Florian

    • Sep 14 2010 | 6:39 pm
      Hi Florian,
      Very cool! Thanks for sharing. Since JSUI uses the software renderer, I've taken a minute to quickly convert your code to work with, which is hardware accelerated. I've attached to this post. The main differences are:
      - define jit.window,,, in the JS code - create a resetsketch() function to appropriately create and simulate the sketch.default2d() method - create a JitterListener and callback function to simulate the onclick and ondrag behavior of JSUI, and reset the sketch if the window is resized
      Hopefully this is of general use for people trying to port these sort of JSUI based applications to
      Cheers, Joshua
    • Sep 14 2010 | 7:52 pm
      this is really great florian!
      thanks for the sketch port joshua.
      fyi, it looks like setting the brush to ribbon breaks the javascript (causes an error that requires re-instantiation). didin't really investigate, but thought i'd pass that along.
    • Sep 14 2010 | 8:28 pm
      Thanks for pointing this out Rob. I've solved the ribbon and a few other problems (blending for squares and rounded squares, z-axis issues for squares, and potential window lingering on patcher close).
      Here's the revised version.
    • Sep 18 2010 | 8:26 pm
      Hey Joshua
      thanks for the improvement! The use of the Code depends on the GNU General Public License Version 3. Mr Doob was a little bit sad how people used his code. For more information here is his blog post about it
    • Sep 20 2010 | 5:50 pm
      thanks a lot for sharing harmony...
      Joshua, i just change your last code to have alpha background. I change the harmony name to 'Draw' cause i m using 'harmony' name for sound effect.
      Now i need to make a texure to use it in an other gl context. using object seem to be a bad way. May be it's possible to do that inside the javascript... but i don't know how...
      Thanks for you for your help and sorry for my bad english !
    • Oct 05 2010 | 12:56 pm
      Joshua, where could one read the documentation of the javascript interface to jitter that you have used here? I have several pretty complex jsui based application (with many different jsui objects working together for better life on earth) and I would love to get my CPU cycles back.
      will this approach work with jit.pwindow instead of jit.window? I have my jsui's all layout inside one patch and I would like to keep it this way.
    • Oct 05 2010 | 5:11 pm
      See the jitter JavaScript tutorials. Yes it will work with a named jit.pwindow created in the patch.
    • Feb 23 2011 | 4:33 pm
      I extended the harmony component a little bit more. Now you can use multiple brushes at the same time. Source code and an introduction video are on my blog:
      I used this component for my installation: Sound Drawings
      It worked quite good. But after 30min had to restart the application. It depends what you want to do. In my case it was stable enough...
      Greetz Flo
    • Mar 01 2011 | 12:55 pm
      Hello, I have tried to go out from the window jsui, but i can't find the way to keep the quality of the window jsui.
      somebody could help me? Thank's a lot!
    • Mar 14 2011 | 10:26 am
      I try to manage the definition of the image I try to have : · a small window of drawing 640/480 · a rendu of 1200/800
      I find no runway Could use me?
    • Apr 05 2011 | 2:03 pm
      Very interesting but maybe it will be more interesting to superpose drawing to video.
    • Sep 06 2011 | 1:41 pm
      Great example!
      I am stumbling on transferring this to a jit.pwindow that already exists in the patch. I'm probably making a basic error. What is the correct way of getting a reference to the underlying Jitter object of a jit.pwindow?
      I'm trying the following: start the global code with
      var pWindow = null, pListener = null;
      I don't try to get a reference to pWindow until loadbang time, on the basis that the jit.pwindow may not exist earlier than that. So, in my loadbang method I have
      pWindow = this.patcher.getnamed(pWindowVarName); // Wrong?? pListener = new JitterListener(pWindow.getregisterdname(), WindowCallback);
      with pWindowVarName as the jit.pwindow's scripting name (attribute varname). WindowCallback is defined elsewhere in the code.
      However I'm getting a Javascript TypeError on pWindow.getregisteredname().
    • Sep 06 2011 | 4:56 pm
      OK, after more searching I found this thread as an example of Javascript handling all the Jitter stuff except for the jit.pwindow.
      It seems what I was doing wrong was assuming that I needed to access the jit.pwindow from inside my Javascript code. I already have the OpenGL context symbol, so I can just
      pListener = new JitterListener(pGLContext, WindowCallback);
      I had wanted to be able to set some of the attributes of the jit.pwindow inside my Javascript, but aside from getregisteredname() I think I can get at everything from the Max wrapper object that this.patcher.getnamed() returns.
      Sorry if this seems terribly confusing. I'm plowing through a lot of JScript/Jitter right now and I'm a bit confused myself.
    • May 28 2012 | 5:00 pm
      I have two questions regarding Joshua's latest implementation:
      1) When using any brush other than "Simple, Squares, and Round_Squares" the colors are really pale as if the alpha was set very low, although alpha is set to 1. How can I deal with this issue? so that colors appear as vivid as selected by the color-picker.
      2) When an area of the canvas has been colored, and a new brushstroke is performed over that colored area, the new brushstroke will not overlay the old ones. How can I ensure that new brushstrokes are rendered over older ones.
      Any help will be much appreciated.
    • May 29 2012 | 1:48 pm
      Regarding my earlier post (please see above) I resolved these issues and I thought of sharing the solutions:
      1) For some reason passing the alpha value procedurally would not work for me, so I hard code the alpha value to 1. and it works fine: function mapColor2RGBA(r,g,b,a) { var rgbaArray = new Array(); rgbaArray[0] = r/255.; rgbaArray[1] = g/255.; rgbaArray[2] = b/255.; rgbaArray[3] = 1.; return rgbaArray; }
      2) In order to overlay new brush strokes over older ones you need to add the following command on the "resetsketct(){}" function: gldepthmask();
      Please see attached file
    • May 22 2013 | 12:39 pm
      Hello Forum
      looking at this patch has lead me to joy and confusion. I really like this patch and i would like to do my own sound drawings. following this thread and trying out things resulted in many different files on my computer and personal confusion cause: some js scripts change their behavior for example the js. from joshua and the ones adapted from it put out errors when using the ribbon brush (which i like very much and dont want to miss it) (error=js executing without a valid JS object). but i am not sure if the did this always? sometimes they worked...
      I am very new to js. Actually this patch made me start to get into and i went through the basic tutorials in order to modify this; for exmaple i wanted to fuse the gl.script with the capability of multi brushes. To get a good working foundation i wanted to use harmonyDrawingJitter2.js (which seemed to be rid of all "bugs"), but as i mentioned before i didn't achieve to get it working properly. I tried to copy paste the js to new names to exclude mismatch errors, tested it on win and mac (newest max version 32bit) and didn't succeed with my simple goal to have a js. which makes use of gl and th e multi brushes!
      so my question is if some experienced programmer could help me ? could i hire someone? also to the ongoing thread about the new forum software i would appreciate a marking system for open questions and solved and unsolved problems, cause i have the feeling often some threads will be overlooked cause somebody allready replied...and also it would be interesting how old forum topics due to old max version changed or could be made more effectively? for example i would be interested if something like this could be done more effeciently with the new jit.mgraphics object?
      kind regards!
    • May 29 2013 | 11:28 am
      can somebody help me??
    • May 30 2013 | 5:38 pm
      This rocks. Can't wait to try it out.
    • May 15 2016 | 1:57 pm
      HI i’m working one a spray simulator, Harmony is perfect. I really like this patch But i’m looking for add a brush like :Edge smoothing with radial gradient. I know nothing at JavaScrip. Maybe someone can help me ? thanks
    • May 15 2016 | 4:57 pm
      I remember Nesa posting a great patch using different brush tips for drawing that might help you out, see if you can find it!
    • Aug 30 2016 | 2:39 am
      Any one can help me to know what i need to to change in js script to change the background color in real time? I add this line below to enter in fullscreen and works great :
      // To listen jitter.window
      var listener = new JitterListener(window.getregisteredname(), windowcallback); function fullscreen(v)
      // function to send the [jit.window] into fullscreen mode { window.fullscreen = v; } But when i make a listener for and the function erase_color, didn't work
    • Feb 09 2017 | 4:20 pm
      Been playing with this again and after some fumbling I managed to get it to use an external render and window and add a fullscreen function. I still can't get ribbon to work and really I want to render to a node or a videoplane, but I can't seem to get that going (did I mention I don't really know what I am doing?). I wanted to use it with a mapping patch that already has all the render stuff going on. Anyway, here 'tis if anyone wants it.