Using js p5
trying to make an ellipse that when i click on it I get a small window with som data or text in it, and i want to be able to hide this small window when i click anywhere else this small window.
Somthing like when you press on a place on google maps and you get place information, and when you click anywhere else this infromation window get hided, så you can try to click on another place.
I want to get this using JS P5
thank you
I think a way you could do this. You could create an object, call it whatever, and have an x and y variable in it (like this.x and this.y i cant think of the name rn) and a clicked variable that will be true or false. outside of the main draw loop you can use the function mousePressed and write something like this:
function mousePressed() {
if (mouseX > this.x - [the width of the ellipse / 2] && mousex < this.x + [width of ellipse / 2] && mouseY > this.y - [height of the ellipse / 2] && mouseY < this.y + [height of ellipse / 2]) {
if (!ellipse.clicked) {
ellipse.clikced = true;
}
} else {
ellipse.clicked = false;
}
}
(excuse the length of the if statement its just checking around the ellipse if im correct)
you could have a for loop if you want multiple
and then have something like this in a function called display inside of the object
display() {
ellipse(this.x, this.y, [width], [lenght]);
// placeholder for the menu
if (this.clicked) {
rect(this.x, this.y, 30, 50);
}
}
or something of the sort.
i hope this works and has helped you out!
Related
This is my first week playing with P5js and Processing so be gentle.
I've got the following P5js code where I'm looking at touch values. By pressing multi-points on a touch screen brings up more circles anchored to a central position.
What I'd like to know is how do I call the x value for object 1 that's printed in the console? or y value for object 0? how would i state them in the code?
What I'd like to do is use these values to change the dimensions of a shape in the middle of the screen, like something in object 0 driving the height of the shape or object 1 on the the x or y values driving strokeWeight or colour . However I'm in my first week and completely lost to how to use these values in the code.
function setup() {
createCanvas(windowWidth, windowHeight);
background(200);
}
function draw() {
background(255);
fill(255, 0, 0);
strokeWeight(0)
for (var i = 0; i < touches.length; i++) {
fill(255);
strokeWeight(3)
ellipse(touches[i].x, touches[i].y, 50, 50);
line(touches[i].x, touches[i].y, windowWidth / 2, windowHeight / 2);
fill(255);
ellipse(windowWidth / 2, windowHeight / 2, 10, 10);
print(touches);
}
}
// do this prevent default touch interaction
function mousePressed() {
return false;
}
document.addEventListener('gesturestart', function(e) {
e.preventDefault();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.2/p5.min.js"></script>
or Sketch file is here
any help would be muchly muchly appreciated, i'm a newb trying to find my way
There is only one mistake in it which I found till now, the color of the background and the fill colors are the same! you may change them to actually see the shapes, lines etc.
So I'm working in p5.js and my task is when i press my mouse down it needs to draw circles and I've got that working. But the extra thing is that this only can happen in a certain rectangle and I'm a bit lost, does anyone know how I can achieve this?
function setup() {
createCanvas(400, 400);
}
var circles = [];
function draw() {
background(220);
rect(100, 100, 200, 200)
var index = 0;
while(index < circles.length) {
ellipse(circles[index].x, circles[index].y, circles[index].d);
index += 1;
}
if (mouseIsPressed) {
// add a circle where the mouse is
// not this: ellipse(mouseX, mouseY, 10);
circles[circles.length] = { x: mouseX, y: mouseY, d: 30 };
}
}
This is what it needs to look like:
enter image description here
For now your code generates a circle when the mouse is pressed no matter where the mouse is on the screen. What you want is to generate the new circle only when your mouse is in your rectangle, so this is only a matter of adding a condition to make sure your mouse is not outside of the rectangle.
To make this test you first need to know what are the boundaries of your rectangle. You created it with rect(100, 100, 200, 200) which means the top left corner is on position x:100, y:100 and it's width and length are 200 so its bottom right corner is on position x:(100+200)=300, y:(100+200)=300.
So you want to create your circles only is 100 < mouseX < 300 and 100 < mouseY < 300 you would write it this way:
Do to so you code would be changed to this:
if (mouseIsPressed && mouseX > 100 && mouseX < 300 && mouseY > 100 && mouseY < 300 ) {
// add a circle where the mouse is
circles[circles.length] = { x: mouseX, y: mouseY, d: 30 };
}
Now when you click outside of the rectangle no circle is added.
Note that since the circle is centered on the position of the click, your circles (which are of radius 30/2=15) will be drawn out of the rectangle if you click too close from the border of the rectangle.
So maybe you'd rather want a condition like this:
if (mouseIsPressed && mouseX > 100+15 && mouseX < 300-15 && mouseY > 100+15 && mouseY < 300-15 ) {
You can see it working here
Also it would be better to have all these measures (the rectangle position, its width and height, the circle diameter) in variables so that you don't have to hard code the different values, but you'll be able to do that later on when your program works properly.
I have a question. How do I change the color of a rectangle from white to black step by step, when I move my mouse away? I'm kinda new to this.
I've tried a bit:
void setup () {
size (200,200);
}
void draw () {
background (0);
stroke (255);
line (100,0,100,200);
line (0,100,200,100);
// Fill a black color
noStroke ();
fill (255);
// Depending on the mouse location, a different rectangle is displayed.
if (mouseX < 100 && mouseY < 100) {
rect (0,0,100,100);
} else if (mouseX > 100 && mouseY < 100) {
rect (100,0,100,100);
} else if (mouseX < 100 && mouseY > 100) {
rect (0,100,100,100);
} else if (mouseX > 100 && mouseY > 100) {
rect (100,100,100,100);
}
}
I would appreciate that, if anyone could help me.
Thanks.
The call fill(255); is setting the rectangle color to white. Use fill(0); to set the rectangle to black, or fill(x); for any value x between 0 and 255 for shades of grey.
To make a fade, you'll need to draw multiple rectangles (drawing all of them is easiest) on each draw() call. The current box will be in white, where the mouse is. Others will be fading to black. So you'll need variables for each box indicating its current color.
Here's my version:
int boxColor1;
int boxColor2;
int boxColor3;
int boxColor4;
void setup () {
size (200,200);
boxColor1 = boxColor2 = boxColor3 = boxColor4 = 0;
}
void draw () {
background (0);
// Fill a black color
noStroke ();
// Subtrack 10 from each box color, but don't go below zero
boxColor1 = max( 0, boxColor1-10 );
boxColor2 = max( 0, boxColor2-10 );
boxColor3 = max( 0, boxColor3-10 );
boxColor4 = max( 0, boxColor4-10 );
// Depending on the mouse location, a different rectangle is displayed.
if (mouseX < 100 && mouseY < 100) {
boxColor1 = 255;
} else if (mouseX > 100 && mouseY < 100) {
boxColor2 = 255;
} else if (mouseX < 100 && mouseY > 100) {
boxColor3 = 255;
} else if (mouseX > 100 && mouseY > 100) {
boxColor4 = 255;
}
fill (boxColor1);
rect (0,0,100,100);
fill (boxColor2);
rect (100,0,100,100);
fill (boxColor3);
rect (0,100,100,100);
fill (boxColor4);
rect (100,100,100,100);
// Draw edge lines last, over the top
stroke (255);
line (100,0,100,200);
line (0,100,200,100);
}
If there are a lot of boxes, you should use an array, or some data structure instead of many different variables like boxColor1, boxColor2 etc.
If I understand your question, you want to show a grid of rectangles, and you want a rectangle to turn white and stay white when the mouse exits that rectangle. Is that right?
If so, then you need to keep track of whether each rectangle should be black or white. The simplest approach might be a 2D array of boolean values. Each cell in the array will represent a single square in your grid.
Set the corresponding cell in the array to true when you want that square to turn white. Then loop over the array and draw each square using the values in the array to determine the color.
I have written this code which, on a mouse button press, increases or decreases the number of circles visible, equally spaced around a circle.
int nbr_circles = 2;
void setup() {
size(600, 600);
smooth();
background(255);
}
void draw() {
background(255);
float cx = width/2.0;
float cy = height/2.0;
fill(0);
//float x, y; //
for (int i = 0; i < nbr_circles; i++)
{
float angle = i * TWO_PI / nbr_circles;
float x = cx + 110.0 * cos(angle);
float y = cy + 110.0 * sin(angle);
ellipse(x, y, 20, 20);
}
}
void mousePressed() {
if (mouseButton == LEFT) {
if (nbr_circles < 20)
nbr_circles = nbr_circles + 1;
} else if (mouseButton == RIGHT) {
if (nbr_circles > 2)
nbr_circles = nbr_circles - 1;
}
}
I would like to alter the code so that, with nbr_circles fixed at 10, only one circle is visible at a time, each in turn in successive frames.
I have changed the code a little. The mouse buttons do nothing and the nbr_circles is fixed at 10.
How can I now show one circle at a time?
show circle #1 -> hide circle #1, show circle #2 -> hide circle #2, show circle #3 … -> hide circle #9, show circle #10 -> hide circle #1, show circle #1…
Adjusted code - where is it going wrong?
int nbr_circles = 2;
int i = 1;
void setup () {
size (600, 600);
}
void draw () {
background (255);
fill (0);
float cx = width/2.0;
float cy = height/2.0;
float angle = i * TWO_PI / nbr_circles;
float x = cx + 110.0 * cos(angle);
float y = cy + 110.0 * sin(angle);
ellipse(x, y, 20, 20);
}
if (mouseButton == LEFT) {
if (ellipse(x,y,20,20))
rotate (angle);
}
Thanks in advance.
Taking a step back, I really suggest you start a bit smaller, instead of posting a new question every time you get stuck. It looks like you've got a fundamental misunderstanding of the basic syntax of Processing, so maybe you should go back and do some tutorials until you're more comfortable in it. That's probably the most "correct" answer I can give you, even though it's probably not what you're looking for.
To answer the question of why your adjusted code doesn't work, it's because none of the syntax makes sense. First of all, you've got an if statement outside of a function, which isn't valid. When do you expect that if statement to be executed?
Secondly, you've got the ellipse() function inside an if statement, but the ellipse() function doesn't return a boolean. What do you expect that to do? And finally, what do you expect that rotate function to do?
It seems like you're trying to copy-paste code you found on the internet without really understanding any of it. That's not going to work. You have to take a step back and understand the basics before you can expect to make a program that actually does what you want it to do.
If you edit your "adjusted code" to fix the problems I pointed out, I'll try to help you through the process, but you really should consider going back and starting smaller before trying to get somebody else's code you found on the internet to work.
I've tried on this and this, but I found they only work for mouse events. I would like to drop some pictures on the canvas and let the user to
"touch" on it to drag and drop. But it seems that the picture doesn't receive user's touch event, only the canvas receives the event.
Any suggestion or plugin?
ps: I develop the application on Phonegap and Android system.
you also need to take care of MSPointer events, that are events from Microsoft to manage touch (it was introduced with Win8 and WinPhone 8).
The steps needed, each frame:
detect mouse, touch and MSPointer events
check the cursor position colliding the images
move the image
For the first point:
function getCursorPositions (event, canvas) {
var element = canvas, offsetX = 0, offsetY = 0, positions = [];
if (element.offsetParent) {
do {
offsetX += element.offsetLeft;
offsetY += element.offsetTop;
} while ((element = element.offsetParent));
}
// Add padding and border style widths to offset
/*offsetX += stylePaddingLeft;
offsetY += stylePaddingTop;
offsetX += styleBorderLeft;
offsetY += styleBorderTop;*/
var touch = event;
//if multi-touch, get all the positions
if (event.targetTouches) { // or changedTouches
var touchPoints = (typeof event.targetTouches !== 'undefined') ? event.targetTouches : [event];
for (var i = 0; i < touchPoints.length; i++) {
touch = touchPoints[i];
positions.push({touch.pageX - offsetX, touch.pageY - offsetY});
}
}
else {
positions.push({touch.pageX - offsetX}, {touch.pageY - offsetY});
}
//return positions for mouse or fingers
return positions;
}
For the second point, you have at least 2 ways to detect the collision:
you can check whether the mouse position is inside the bounding box of your item :
function pointIsInRegion (point, targetRegion, threshold) {
return point.x >= (targetRegion.position.x - threshold) &&
point.y >= (targetRegion.position.y - threshold) &&
point.x <= (targetRegion.position.x + targetRegion.dimension.width + threshold) &&
point.y <= (targetRegion.position.y + targetRegion.dimension.height + threshold);
}
Or you can be more accurate by checking the pixels collision.
To achieve this second method, you have to render your items in a temporary canvas and check if there is at least pixels from your 2 items that collide (it can be accelerated by using masks).
For the third point (move the image), all you have to do is to move your image from "currentCursorPosition - previousCursorPosition". That's ths easiest part.
Anyway, I suggest you to use a framework. The code is already done and It will help you to go faster.
cgSceneGraph, (I'm the designer of this framework) will do the Job for you in just few lines.
Have a look at the "planner 2D" and "collision" examples (http://gwennaelbuchet.github.com/cgSceneGraph/examples.html)
Hope this can help you.