Forums > Javascript

horizontal slider

September 16, 2007 | 6:52 pm

hi

Trying to modify the vertical jsui slider in max as a horizontal slider. I think i am nearly there but I can’t figure out the final math to get the mouse sensitivity to be correct. can anyone see where I am going wrong? Thanks in advance.

a+
gar

/*

a simple slider

arguments: fgred fggreen fgblue bgred bggreen bgblue linered linegreen lineblue mode

foreground red (0 – 255), foreground green (0 – 255), foreground blue (0 – 255),
background red (0 – 255), background green (0 – 255), background blue (0 – 255),
line red (0 – 255), line green (0 – 255), line blue (0 – 255),
use knob (1 – ellipse, 2 – triangle)

*/

sketch.default2d();
var val = 0;
var vbrgb = [1.,1.,1.];
var vfrgb = [0.2,0.2,0.2];
var vrgb2 = [0.5,0.5,0.5];
var vmode = 0;
var voutline = 1;

// process arguments
if (jsarguments.length>1)
vfrgb[0] = jsarguments[1]/255.;
if (jsarguments.length>2)
vfrgb[1] = jsarguments[2]/255.;
if (jsarguments.length>3)
vfrgb[2] = jsarguments[3]/255.;
if (jsarguments.length>4)
vbrgb[0] = jsarguments[4]/255.;
if (jsarguments.length>5)
vbrgb[1] = jsarguments[5]/255.;
if (jsarguments.length>6)
vbrgb[2] = jsarguments[6]/255.;
if (jsarguments.length>7)
vrgb2[0] = jsarguments[7]/255.;
if (jsarguments.length>8)
vrgb2[1] = jsarguments[8]/255.;
if (jsarguments.length>9)
vrgb2[2] = jsarguments[9]/255.;
if (jsarguments.length>10)
vmode = jsarguments[10];
if (jsarguments.length>11)
voutline = jsarguments[11];

draw();

function draw()
{
var width = box.rect[2] – box.rect[0];
var height = box.rect[3] – box.rect[1];
var aspect = width/height;

with (sketch) {
//scale everything to box size
glmatrixmode("modelview");
glpushmatrix();
glscale(aspect,1,1);
glenable("line_smooth");

// erase background
glclearcolor(vbrgb);
glclear();

//draw line
//this is the slider background with border
glcolor(vrgb2);
shapeslice(1,1);
moveto(0,0);
plane(0.8,0.15);
if (voutline) {
glcolor(0,0,0);
glpolygonmode("front_and_back","line");
plane(0.8,0.15);
glpolygonmode("front_and_back","fill");
}

// draw marker
//the slider knob, there are three types, triangle / ellipse / rectangle
glcolor(vfrgb);
switch (vmode) {
case 2: // triangle
shapeslice(1,1);
moveto(1.6*val-0.8,0.5); //on screen in range -0.8 to 0.8
plane(0.2,0.,0.2,0.1); //triangle
if (voutline) {
glcolor(0,0,0);
glpolygonmode("front_and_back","line");
plane(0.2,0.,0.2,0.1); //triangle
glpolygonmode("front_and_back","fill");
}
break;
case 1: // ellipse
shapeslice(40,1);
moveto(1.6*val-0.8,0); //on screen in range -0.8 to 0.8
ellipse(0.6,0.05);
if (voutline) {
glcolor(0,0,0);
frameellipse(0.6,0.05);
}
break;
default: // rectangle
shapeslice(1,1);
//moveto(1.6*val-0.7,0); //on screen in range -0.8 to 0.8
moveto(1.6*val-0.8,0.); //on screen in range -0.8 to 0.8
plane(0.05,0.8);
if (voutline) {
glcolor(0,0,0);
glpolygonmode("front_and_back","line");
plane(0.05,0.8);
glpolygonmode("front_and_back","fill");
}
}
//reset transformation matrix
glmatrixmode("modelview");
glpopmatrix();
}
}

function bang()
{
draw();
refresh();
outlet(0,val);
}

function msg_float(v)
{
val = Math.min(Math.max(0,v),1);
notifyclients();
bang();
}

function fsaa(v)
{
sketch.fsaa = v;
bang();
}

function frgb(r,g,b)
{
vfrgb[0] = r/255.;
vfrgb[1] = g/255.;
vfrgb[2] = b/255.;
draw();
refresh();
}

function rgb2(r,g,b)
{
vrgb2[0] = r/255.;
vrgb2[1] = g/255.;
vrgb2[2] = b/255.;
draw();
refresh();
}

function brgb(r,g,b)
{
vbrgb[0] = r/255.;
vbrgb[1] = g/255.;
vbrgb[2] = b/255.;
draw();
refresh();
}

function mode(v)
{
vmode = v;
draw();
refresh();
}

function outline(v)
{
voutline = v;
draw();
refresh();
}

function setvalueof(v)
{
msg_float(v);
}

function getvalueof()
{
return val;
}

function onclick(x,y,but,cmd,shift,capslock,option,ctrl)
{
ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
}
onclick.local = 1; //private. could be left public to permit "synthetic" events

function ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
{
var f,a;

a = sketch.screentoworld(x,y);
//detect horizontal movement
f = ((a[0] + 0.8) / 2.0) + 0.2;

//post(f);

msg_float(f); //set new value with clipping + refresh
}
ondrag.local = 1; //private. could be left public to permit "synthetic" events

function onresize(w,h)
{
draw();
refresh();
}
onresize.local = 1; //private


September 16, 2007 | 8:48 pm

On 16 sept. 07, at 20:52, Garrett Lynch wrote:

> hi
>
> Trying to modify the vertical jsui slider in max as a horizontal
> slider. I think i am nearly there but I can’t figure out the final
> math to get the mouse sensitivity to be correct. can anyone see
> where I am going wrong? Thanks in advance.

The x axis is between -aspect and +aspect which depends on the width/
height ratio. So you just have to calculate the aspect and scale your
f value to be between 0 and 1:

function ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
{
var f,a, height, width, aspect;

height = box.rect[3] – box.rect[1];
width = box.rect[2] – box.rect[0];
aspect = width/height;

a = sketch.screentoworld(x,y);
//detect horizontal movement
f = (a[0] + aspect) / (2*aspect);

msg_float(f); //set new value with clipping + refresh
}

HTH,
ej


September 17, 2007 | 6:34 pm

Hi

thanks for this, definitely seems to work better than mine but the slider itself doesn’t seem to follow the cursor pixel for pixel at ether end of the slider – does it need some sort of offset??

a+
gar

/*

a simple slider

arguments: fgred fggreen fgblue bgred bggreen bgblue linered linegreen lineblue mode

foreground red (0 – 255), foreground green (0 – 255), foreground blue (0 – 255),
background red (0 – 255), background green (0 – 255), background blue (0 – 255),
line red (0 – 255), line green (0 – 255), line blue (0 – 255),
use knob (1 – ellipse, 2 – triangle)

*/

sketch.default2d();
var val = 0;
var vbrgb = [1.,1.,1.];
var vfrgb = [0.2,0.2,0.2];
var vrgb2 = [0.5,0.5,0.5];
var vmode = 0;
var voutline = 1;

// process arguments
if (jsarguments.length>1)
vfrgb[0] = jsarguments[1]/255.;
if (jsarguments.length>2)
vfrgb[1] = jsarguments[2]/255.;
if (jsarguments.length>3)
vfrgb[2] = jsarguments[3]/255.;
if (jsarguments.length>4)
vbrgb[0] = jsarguments[4]/255.;
if (jsarguments.length>5)
vbrgb[1] = jsarguments[5]/255.;
if (jsarguments.length>6)
vbrgb[2] = jsarguments[6]/255.;
if (jsarguments.length>7)
vrgb2[0] = jsarguments[7]/255.;
if (jsarguments.length>8)
vrgb2[1] = jsarguments[8]/255.;
if (jsarguments.length>9)
vrgb2[2] = jsarguments[9]/255.;
if (jsarguments.length>10)
vmode = jsarguments[10];
if (jsarguments.length>11)
voutline = jsarguments[11];

draw();

function draw()
{
var width = box.rect[2] – box.rect[0];
var height = box.rect[3] – box.rect[1];
var aspect = width/height;

with (sketch) {
//scale everything to box size
glmatrixmode("modelview");
glpushmatrix();
glscale(aspect,1,1);
glenable("line_smooth");

// erase background
glclearcolor(vbrgb);
glclear();

//draw line
//this is the slider background with border
glcolor(vrgb2);
shapeslice(1,1);
moveto(0,0);
plane(0.8,0.15);
if (voutline) {
glcolor(0,0,0);
glpolygonmode("front_and_back","line");
plane(0.8,0.15);
glpolygonmode("front_and_back","fill");
}

// draw marker
//the slider knob, there are three types, triangle / ellipse / rectangle
glcolor(vfrgb);
switch (vmode) {
case 2: // triangle
shapeslice(1,1);
moveto(1.6*val-0.8,0.5); //on screen in range -0.8 to 0.8
plane(0.2,0.,0.2,0.1); //triangle
if (voutline) {
glcolor(0,0,0);
glpolygonmode("front_and_back","line");
plane(0.2,0.,0.2,0.1); //triangle
glpolygonmode("front_and_back","fill");
}
break;
case 1: // ellipse
shapeslice(40,1);
moveto(1.6*val-0.8,0); //on screen in range -0.8 to 0.8
ellipse(0.6,0.05);
if (voutline) {
glcolor(0,0,0);
frameellipse(0.6,0.05);
}
break;
default: // rectangle
shapeslice(1,1);
//moveto(1.6*val-0.7,0); //on screen in range -0.8 to 0.8
moveto(1.6*val-0.8,0.); //on screen in range -0.8 to 0.8
plane(0.05,0.8);
if (voutline) {
glcolor(0,0,0);
glpolygonmode("front_and_back","line");
plane(0.05,0.8);
glpolygonmode("front_and_back","fill");
}
}
//reset transformation matrix
glmatrixmode("modelview");
glpopmatrix();
}
}

function bang()
{
draw();
refresh();
outlet(0,val);
}

function msg_float(v)
{
val = Math.min(Math.max(0,v),1);
notifyclients();
bang();
}

function fsaa(v)
{
sketch.fsaa = v;
bang();
}

function frgb(r,g,b)
{
vfrgb[0] = r/255.;
vfrgb[1] = g/255.;
vfrgb[2] = b/255.;
draw();
refresh();
}

function rgb2(r,g,b)
{
vrgb2[0] = r/255.;
vrgb2[1] = g/255.;
vrgb2[2] = b/255.;
draw();
refresh();
}

function brgb(r,g,b)
{
vbrgb[0] = r/255.;
vbrgb[1] = g/255.;
vbrgb[2] = b/255.;
draw();
refresh();
}

function mode(v)
{
vmode = v;
draw();
refresh();
}

function outline(v)
{
voutline = v;
draw();
refresh();
}

function setvalueof(v)
{
msg_float(v);
}

function getvalueof()
{
return val;
}

function onclick(x,y,but,cmd,shift,capslock,option,ctrl)
{
ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
}
onclick.local = 1; //private. could be left public to permit "synthetic" events

function ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
{
var f,a, height, width, aspect;

height = box.rect[3] – box.rect[1];
width = box.rect[2] – box.rect[0];
aspect = width/height;

a = sketch.screentoworld(x,y);

//detect horizontal movement
f = (a[0] + aspect) / (2*aspect);

msg_float(f); //set new value with clipping + refresh
}
ondrag.local = 1; //private. could be left public to permit "synthetic" events

function onresize(w,h)
{
draw();
refresh();
}
onresize.local = 1; //private


September 17, 2007 | 8:21 pm

On 17 sept. 07, at 20:34, Garrett Lynch wrote:

> Hi
>
> thanks for this, definitely seems to work better than mine but the
> slider itself doesn’t seem to follow the cursor pixel for pixel at
> ether end of the slider – does it need some sort of offset??

Then it’s 80 % of the aspect ;-)

function ondrag(x,y,but,cmd,shift,capslock,option,ctrl)
{
var f,a, height, width, aspect;

height = box.rect[3] – box.rect[1];
width = box.rect[2] – box.rect[0];
aspect = width/height;

aspect *= 0.8; // 80 % of the aspect

a = sketch.screentoworld(x,y);

//detect horizontal movement
f = (a[0] + aspect) / (2*aspect);

msg_float(f); //set new value with clipping + refresh
}

Cheers,
ej


September 17, 2007 | 9:08 pm

that does the trick! :)
thanks for your help.

a+
gar


February 21, 2010 | 10:22 am

hello, i find this post and i tried to understand how it works.

I’m not very clear with this part of code

// process arguments
if (jsarguments.length>1)
vfrgb[0] = jsarguments[1]/255.;
if (jsarguments.length>2)
vfrgb[1] = jsarguments[2]/255.;
if (jsarguments.length>3)
vfrgb[2] = jsarguments[3]/255.;
if (jsarguments.length>4)
vbrgb[0] = jsarguments[4]/255.;
if (jsarguments.length>5)
vbrgb[1] = jsarguments[5]/255.;
if (jsarguments.length>6)
vbrgb[2] = jsarguments[6]/255.;
if (jsarguments.length>7)
vrgb2[0] = jsarguments[7]/255.;
if (jsarguments.length>8)
vrgb2[1] = jsarguments[8]/255.;
if (jsarguments.length>9)
vrgb2[2] = jsarguments[9]/255.;
if (jsarguments.length>10)
vmode = jsarguments[10];
if (jsarguments.length>11)
voutline = jsarguments[11];

I understood about jsarguments.length at a js but i don’t have a clue how it works on a jsui.

"After supplying a filename after the word js, you can type in additional arguments; these are available to your script’s 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."

thanks


February 21, 2010 | 4:36 pm

It works exactly the same. In this case it initialises some variables to set the colour of the object.

lh


February 22, 2010 | 5:13 am

you can change the jsarguments jsui via the inspector or with a message: ‘jsarguments $1 $2 etc’


Viewing 8 posts - 1 through 8 (of 8 total)