Old 10-28-2018, 12:27 PM   #1
brainwreck
Human being with feelings
 
Join Date: Jul 2006
Posts: 20,859
Default JSFX: Good approach to making movable nodes?

Graphics makes my head hurt. :|

What's a good approach toward making movable nodes that behave well with the mouse? This is what I have so far.

My main issue is the mouse position outrunning the node position at boundaries. Hence the mouse boundaries box below. In other words, when the node approaches the node boundaries the node position becomes erratic.

Code:
desc:movable node

@init

	node1_x = 20;
	node1_y = 20;
	node_size = 10;
	node_center = node_size / 2;
	
	node_bnd_x = 20;
	node_bnd_y = 20;
	node_bnd_w = 500;
	node_bnd_h = 300;
	
	mouse_bnd_x = node_bnd_x + node_center;
	mouse_bnd_y = node_bnd_y + node_center;
	mouse_bnd_w = node_bnd_w - node_size;
	mouse_bnd_h = node_bnd_h - node_size;

@gfx 600 400

	gfx_w = 600; gfx_h = 400;
	
	// Mouse boundaries
		
		gfx_r = 1.0; gfx_g = 1.0; gfx_b = 1.0; gfx_a = 0;
		gfx_rect(mouse_bnd_x,mouse_bnd_y,mouse_bnd_w,mouse_bnd_h);
		
	// Node boundaries
	
		gfx_r = 1.0; gfx_g = 1.0; gfx_b = 1.0; gfx_a = 1.0;
		gfx_rect(node_bnd_x,node_bnd_y,node_bnd_w,node_bnd_h);
	
	// Node
		
		(mouse_x >= mouse_bnd_x &&
		(mouse_x <= (mouse_bnd_x + mouse_bnd_w)) &&
		mouse_y >= mouse_bnd_y &&
		mouse_y <= (mouse_bnd_y + mouse_bnd_h) &&
		mouse_cap == 1) ? (
			node1_x = mouse_x - node_center;
			node1_y = mouse_y - node_center;
		);
		
		gfx_r = 1.0; gfx_g = 0; gfx_b = 0; gfx_a = 1.0;
		gfx_rect(node1_x,node1_y,node_size,node_size);
__________________
It's time to take a stand against the synthesizer.

Last edited by brainwreck; 10-28-2018 at 12:43 PM.
brainwreck is offline   Reply With Quote
Old 10-28-2018, 02:41 PM   #2
argee
Human being with feelings
 
Join Date: Mar 2007
Location: Surrey, BC
Posts: 745
Default

You might have better luck if you just limit the node x and y positions separately with combined max() and min() functions, for example :
Code:
nodeX = max(minXvalue,min(mouse_x,maxXvalue));
nodeY = max(minYvalue,min((mouse_y,maxYvalue));
with the values in italics being the values at the limits of the rectangular box. You may need to apply some factors to the mouse_x and y values in the expression so that they will equate to the min/max values when the mouse is at the limits of the rectangle.

That way, if the user strays off the boundary, the opposing direction will still reflect the mouse position.

In other words, if the user goes off either of the rectangle's side boundaries, the vertical mouse movement is still affecting the nodeY value but the horizontal mouse movement no longer affects the nodeX value. The opposite applies at the rectangle's top/bottom boundaries.

I think this makes for a more expected result for the user.

I used this method for this JS plugin GUI:
https://forum.cockos.com/showthread.php?t=35957

Hope this helps!
argee is offline   Reply With Quote
Old 10-28-2018, 03:58 PM   #3
brainwreck
Human being with feelings
 
Join Date: Jul 2006
Posts: 20,859
Default

Thanks argee! I ended up using max() and min() inside a couple of if's, but I didn't think to put min() inside max() as a parameter. What I had going was only working for bounding to two sides of a box. I'm still not sure why. But this is working:

Code:
desc:bounded draggable node

@init

	node1_x = 20;
	node1_y = 20;
	node_size = 10;
	
	bbox_x = 10;
	bbox_y = 10;
	bbox_w = 500;
	bbox_h = 300;

@gfx 600 400

	gfx_w = 600; gfx_h = 400;
	
// Bounding box
	
	gfx_r = 1.0; gfx_g = 1.0; gfx_b = 1.0; gfx_a = 1.0;
	gfx_rect(bbox_x,bbox_y,bbox_w,bbox_h);
	
// Detect left-mouse click within node

	mouse_cap == 1 && (
		mouse_x >= node1_x &&
		mouse_x <= (node1_x + node_size) &&
		mouse_y >= node1_y &&
		mouse_y <= (node1_y + node_size)
	) ? (
		node1_click = 1;
	);
	
// Keep node within within bounding box
	
	node1_click == 1 && (
		node1_x >= bbox_x &&
		node1_x <= (bbox_x + bbox_w) &&
		node1_y >= bbox_y &&
		node1_y <= (bbox_y + bbox_h)
	) ? (
		node1_x = max(bbox_x,min(mouse_x,bbox_w));
		node1_y = max(bbox_y,min(mouse_y,bbox_h));
	    );
		
// Detect left-mouse release
	
	mouse_cap == 0 ? node1_click = 0;
	
// Node
	gfx_r = 1.0; gfx_g = 0; gfx_b = 0; gfx_a = 1.0;
	gfx_rect(node1_x, node1_y, node_size, node_size);
By the way, that is a swank looking gui on that plugin.
__________________
It's time to take a stand against the synthesizer.
brainwreck is offline   Reply With Quote
Old 10-28-2018, 04:25 PM   #4
brainwreck
Human being with feelings
 
Join Date: Jul 2006
Posts: 20,859
Default

Still lots to do on this, but I'm stoked to have gotten this far. It's just a couple of draggable nodes that behave as expected (thanks again argee!) and a joining line, which will hopefully end up as a multi-node envelope tool.

Code:
desc:bounded draggable node 1 and node 2

@init

	node1_x = 20;
	node1_y = 20;
	node2_x = 100;
	node2_y = 20;
	node_size = 10;
	node_center = node_size / 2;
	
	bbox_x = 10;
	bbox_y = 10;
	bbox_w = 500;
	bbox_h = 300;

@gfx 600 400

	gfx_w = 600; gfx_h = 400;
	
// Bounding box
	
	gfx_r = 1.0; gfx_g = 1.0; gfx_b = 1.0; gfx_a = 1.0;
	gfx_rect(bbox_x,bbox_y,bbox_w,bbox_h);
	
// Detect left-mouse click within node 1

	mouse_cap == 1 && (
		mouse_x >= node1_x &&
		mouse_x <= (node1_x + node_size) &&
		mouse_y >= node1_y &&
		mouse_y <= (node1_y + node_size)
	) ? (
		node1_click = 1;
	);
	
// Keep node 1 within bounding box
	
	node1_click == 1 && (
		node1_x >= bbox_x &&
		node1_x <= (bbox_x + bbox_w) &&
		node1_y >= bbox_y &&
		node1_y <= (bbox_y + bbox_h)
	) ? (
		node1_x = max(bbox_x,min(mouse_x,bbox_w));
		node1_y = max(bbox_y,min(mouse_y,bbox_h));
	    );
		
// Detect left-mouse click within node 2

	mouse_cap == 1 && (
		mouse_x >= node2_x &&
		mouse_x <= (node2_x + node_size) &&
		mouse_y >= node2_y &&
		mouse_y <= (node2_y + node_size)
	) ? (
		node2_click = 1;
	);
	
// Keep node 2 within bounding box
	
	node2_click == 1 && (
		node2_x >= bbox_x &&
		node2_x <= (bbox_x + bbox_w) &&
		node2_y >= bbox_y &&
		node2_y <= (bbox_y + bbox_h)
	) ? (
		node2_x = max(bbox_x,min(mouse_x,bbox_w));
		node2_y = max(bbox_y,min(mouse_y,bbox_h));
	    );
		
// Detect left-mouse release
	
	mouse_cap == 0 ? (
		node1_click = 0;
		node2_click = 0;
	);
	
// Draw nodes and lines

	gfx_r = 0; gfx_g = 0; gfx_b = 0; gfx_a = 1.0;
	gfx_line(node1_x + node_center, node1_y + node_center, node2_x + node_center, node2_y + node_center);
	gfx_r = 1.0; gfx_g = 0; gfx_b = 0; gfx_a = 1.0;
	gfx_rect(node1_x, node1_y, node_size, node_size);
	gfx_rect(node2_x, node2_y, node_size, node_size);
__________________
It's time to take a stand against the synthesizer.
brainwreck is offline   Reply With Quote
Old 10-29-2018, 08:37 AM   #5
brainwreck
Human being with feelings
 
Join Date: Jul 2006
Posts: 20,859
Default

Just some small changes gets us a basic fader graphic. Woo ha.

Code:
desc:graphics fader with path click

@init

	cap_x = 10;
	cap_y = 100;
	cap_w = 10;
	cap_h = 20;
	
	path_x = 10;
	path_y = 10;
	path_w = 10;
	path_h = 300;
	
	path_click = 0;

@gfx 600 400

// Background

	gfx_r = 0.3; gfx_g = 0.3; gfx_b = 0.3; gfx_a = 1.0;
	gfx_rect(0,0,600,400);
	
// Fader path
	
	gfx_r = 1.0; gfx_g = 1.0; gfx_b = 1.0; gfx_a = 1.0;
	gfx_rect(path_x,path_y,path_w,path_h);
	
// Detect left-mouse click within path

	mouse_cap == 1 && (
		mouse_x >= path_x &&
		mouse_x <= (path_x + path_w) &&
		mouse_y >= path_y &&
		mouse_y <= (path_y + path_h)
	) ? path_click = 1;
		
//  Keep cap within path and move cap to path click position
	
	path_click == 1 && (
		cap_x >= path_x &&
		cap_x <= (path_x + path_w) &&
		cap_y >= path_y &&
		cap_y <= (path_y + path_h)
	) ? (
		cap_x = max(path_x,min(mouse_x,path_w));
		cap_y = max(path_y,min(mouse_y,path_h));
	    );
		
// Detect left-mouse release
	
	mouse_cap == 0 ? path_click = 0;
	
// Cap

	gfx_r = 0.1; gfx_g = 0.4; gfx_b = 1.0; gfx_a = 1.0;
	gfx_rect(cap_x, cap_y, cap_w, cap_h);
__________________
It's time to take a stand against the synthesizer.

Last edited by brainwreck; 10-29-2018 at 10:11 AM.
brainwreck is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 02:15 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.