Fill background with color from array when clicked on rectangle - processing

I've made several rectangles by using a loop.
The color of the rectangles are provided from an array.
I want on clicking one of the rectangles, that background fills with the color I selected.
I'm new to processing so i'm a bit confused on how to do it.
color[] backgrounds = {#e8be55, #ff8827, #eb5051, #00b4cc, #005f6b, #7c6753, #edeaee};
int bgLength = backgrounds.length;
int xPos;
int yPos;
int size;
void setup(){
background(255);
size(1024, 768);
}
void draw(){
size = 40;
xPos = guide + 10;
yPos = 167;
for(int i = 0; i < bgLength; i++) {
noStroke();
fill(backgrounds[i]);
rect(xPos, yPos, size, size);
xPos = xPos + size + 4;
if(xPos>180){
xPos = guide + 10;
yPos += size + 4;
}
}
}
Thanks.

You need to check the bounds. First I suggest you organize the variables a bit.
For example some variables never change(so there's no reason to assign them in draw()).
This should make it easier to see what the coordinates are.
I suggest this:
color[] backgrounds = {#e8be55, #ff8827, #eb5051, #00b4cc, #005f6b, #7c6753, #edeaee};
int bgLength = backgrounds.length;
int xOffset = 10;
int yOffset = 167;
int xPos;
int yPos;
int size = 40;
int guide = 10;
int cols = 4;//4 columns
color selectedBackground = backgrounds[backgrounds.length-1];//default to last element in the list/array
void setup(){
background(255);
size(1024, 768);
noStroke();
}
void draw(){
background(selectedBackground);
for(int i = 0; i < bgLength; i++) {
xPos = xOffset + ((i % cols) * (size+guide));//since % is returns the remainder of division, we use it to compute x position in the grid
yPos = yOffset + ((i / cols) * (size+guide));//and we divide by the number of columns to compute the y position in the grid
fill(backgrounds[i]);
//check if a box is clicked
if((mouseX >= xPos && mouseX <= xPos+size) && //check horizontal bounds(left/right)
(mouseY >= yPos && mouseY <= yPos+size)){ //check vertical bounds(top/bottom)
if(mousePressed){//if mouse is over/within a boxes bounds and clicked
selectedBackground = backgrounds[i];//set the colour based on id
}else{//just hovering
fill(backgrounds[i],127);//draw transparent colour, just to high light selection, not actually needed, but now an easy option
}
}
rect(xPos, yPos, size, size);//we draw at the end because the fill colour might have changed if a box was hovered
}
}
You can run a javascript demo bellow. (Although there are minor differences in syntax, the core concept is the same):
var backgrounds;// = [color('#e8be55'), color('#ff8827'), color('#eb5051'), color('#00b4cc'), color('#005f6b'), color('#7c6753'), color('#edeaee')];
var bgLength;// = backgrounds.length;
var xOffset = 10;
var yOffset = 67;
var xPos = 0;
var yPos = 0;
var ssize = 40;
var guide = 10;
var cols = 4;//4 columns
var selectedBackground;// = backgrounds[backgrounds.length-1];//default to last element in the list/array
function setup(){
createCanvas(1024, 768);noStroke();
backgrounds = [color('#e8be55'), color('#ff8827'), color('#eb5051'), color('#00b4cc'), color('#005f6b'), color('#7c6753'), color('#edeaee')];
bgLength = backgrounds.length;
selectedBackground = backgrounds[backgrounds.length-1];//default to last element in the list/array
}
function draw(){
background(selectedBackground);
for(var i = 0; i < bgLength; i++) {
xPos = xOffset + ((i % cols) * (ssize+guide));//since % is returns the remainder of division, we use it to compute x position in the grid
yPos = yOffset + (floor(i / cols) * (ssize+guide));//and we divide by the number of columns to compute the y position in the grid
fill(backgrounds[i]);
//check if a box is clicked
if((mouseX >= xPos && mouseX <= xPos+ssize) && //check horizontal bounds(left/right)
(mouseY >= yPos && mouseY <= yPos+ssize)){ //check vertical bounds(top/bottom)
if(isMousePressed){//if mouse is over/within a boxes bounds and clicked
selectedBackground = backgrounds[i];//set the colour based on id
}else{//just hovering
fill(backgrounds[i].rgba[0]+50,backgrounds[i].rgba[1]+50,backgrounds[i].rgba[2]+50);//draw transparent colour, just to high light selection, not actually needed, but now an easy option
}
}
rect(xPos, yPos, ssize, ssize);//we draw at the end because the fill colour might have changed if a box was hovered
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.4.4/p5.min.js"></script>

Related

Colored Letters with Colorcycle | Processing

I found a program, that generates random letters in a grid and gives them a random color.
How can I have the letters cange in color or brightness while the program is running?
(sourcecode: https://happycoding.io/examples/processing/for-loops/letters)
I tried making the fill(r, g, b) have a 'r' that cycles from 1 to 255 and back while having 'g' and 'b' at 0, but I could´t get it to update the color. Im cinda new to programming so I´d love to know how I could make that happen.
First, let's change the fill method to accept RGB values:
fill(random(256),random(256),random(256));
To change the colors while the program is running, the changes must be made inside the draw() method, that will constantly loop and update the canvas. Further information about draw here I believe the following code outputs what you asked for:
int rows = 10;
int cols = 10;
int cellHeight;
int cellWidth;
void setup(){
size(500, 500);
cellHeight = height/rows;
cellWidth = width/cols;
textAlign(CENTER, CENTER);
textSize(28);
}
void draw(){
background(32);
for(int y = 0; y < rows; y++){
for(int x = 0; x < cols; x++){
//get a random ascii letter
char c = '!';
c += random(93);
//calculate cell position
int pixelX = cellWidth * x;
int pixelY = cellHeight * y;
//add half to center letters
pixelX += cellWidth/2;
pixelY += cellHeight/2;
fill(random(256),random(256),random(256));
text(c, pixelX, pixelY);
}
}
delay(100);
}

How to make an (moving) ellipse clickable? Processing

So I started learning processing since a week ago and I'm trying to get a moving ellipse clickable. I followed the processing API, but I can't figure it out. I removed all the code relating to the clickable ellipse because it was a mess.
In the section where I declare all my vars you can see me using:
int breedte = 600;
int hoogte = 600;
These are suppose to be:
int breedte = width;
int hoogte = height;
But for some reason the width and height don't output the width and height declared in:
size(600,600)
So what I'm asking is:
How can I make the (moving) ellipse clickable?
Why I can't use width and height on 'int hoogte' and 'int breedte'?
Thanks in advace.
Main file:
int x = 0;
int leftSide = 0;
int rightSide = width;
int bottomSide = height;
int totalHits = 0;
int totalMiss = 0;
boolean start = false;
int circelSize = 100;
int circelRings = 24;
int circelSpeed = 1;
int circelPositionY = 0;
int breedte = 600;
int hoogte = 600;
String[] buttonText = {"Start","Stop"};
String buttonTextActive = buttonText[0];
int[] buttonColor = {0,90};
int buttonColorActive = buttonColor[0];
int buttonHighlight = 50;
int buttonSize = 80;
int buttonY = breedte - (buttonSize /2);
int buttonX = hoogte / 2 - 40;
void setup() {
size(600, 600);
smooth();
noStroke();
}
void draw() {
if (start) {
circelPositionY = circelPositionY + circelSpeed;
drawCircel(circelPositionY);
if (circelPositionY == (width + circelSize)) {
circelPositionY = 0;
}
}
drawButton();
}
Events file:
void mousePressed() {
// Start or Stop button
if(mouseX > buttonX & mouseX < buttonX + buttonSize & mouseY > buttonY & mouseY < buttonY + (buttonSize / 2)){
if(start) {
start = false;
buttonColorActive = buttonColor[0];
buttonTextActive = buttonText[0];
println("Game stoped");
} else {
start = true;
buttonColorActive = buttonColor[1];
buttonTextActive = buttonText[1];
println("Game started");
}
}
//HERE SHOULD GO THE CLICKABLE ELLPISE
}
Functions file:
void drawCircel(int circelPositionY) {
background(204);
for (int i = 0; i < circelRings; i = i+1) {
int even = i % 2;
if (even == 0) {
fill(255,0,0);
ellipse(-(circelSize / 2) + circelPositionY, height / 2 - (circelSize / 2), circelSize - (i * (circelSize / circelRings)), circelSize - (i * (circelSize / circelRings)));
} else {
fill(255);
ellipse(-(circelSize / 2) + circelPositionY, height / 2 - (circelSize / 2), circelSize - (i * (circelSize / circelRings)), circelSize - (i * (circelSize / circelRings)));
}
}
}
void drawButton() {
fill(buttonColorActive);
rect(buttonX,buttonY, buttonSize, buttonSize / 2);
fill(255);
textAlign(CENTER, CENTER);
text(buttonTextActive, buttonX + (buttonSize / 2),buttonY + (buttonSize / 4));
}
In the future, please try to post a MCVE instead of a bunch of disconnected snippets or your whole project. Also please only ask one question per post.
To make your circle clickable, you're going to have to write code that checks whether the circle is being clicked. That's actually two separate checks. First you have to detect when the mouse is pressed. One way to do that is by defining a mousePressed() function:
void mousePressed(){
// mouse is pressed
}
Then you have to check whether the mouse is currently inside the circle. You can use the dist() function for that: if the distance between the mouse and the center of the circle is less than the radius of the circle, then the mouse is inside the circle. That might look like this:
void mousePressed(){
if(dist(mouseX, mouseY, circleX, circleY) < circleRadius){
// mouse is pressed inside the circle
}
}
Shameless self-promotion: I wrote a tutorial on collision detection in Processing, including point-circle collision, available here.
As for why you can't use width and height at the top of your sketch, that's because code at the top of your sketch is executed before the setup() function fires, and the width and height variables aren't set until after you call size() from the setup() function. So you have to move that code to after you call size().
If you have follow-up questions, please post an updated MCVE in a new question post, and we'll go from there. Good luck.
Processing does not provide an api for hit detection, so you need to implement this by yourself, which I think is a great learning exercise. You can explore the mathematics of an ellipse here.
But the general approach is to use a function like the one below to check that the point you clicked on was indeed inside the ellipse you provided.
boolean InsideEllipse(
float x, float y,
float xc, float yc,
float width, float height
) {
// First half the width and height to get the ellipse parameters
float a = width / 2;
float b = height / 2;
// Now calculate the deltas:
float xd = x - xc;
float yd = y - yd;
// Now the equation of an ellipse is given by
// x^2 / a ^ 2 + y^2 / b ^ 2 = 1
// So if we are inside the ellipse, we would expect the left hand
// side of this expression to be less than one
boolean inside = xd * xd / (a * a) + yd * yd / (b * b) <= 1.0
return inside
}

modification in the animation of vertical lines with processing

i have modified the code for the animation of vertical lines which was given by . In the recent code I need to change the value between the two arrays of lines which are generated by the code and also make the disappearing of lines gradual. All the lines leaving or coming should have the same spacing between them. Below is the code.
//float[] linePositions = new float[10];
ArrayList<Integer> linePositions = new ArrayList<Integer>();
int lineWidth = 50;
int lineSpacing = 25;
int lineSpeed = 1;
int totalwidth;
int pixelperframe = 0;
int arraySize = 0;
void setup() {
size(640, 360);
println("Setup");
totalwidth = lineWidth+lineSpacing;
for (int i = 0; i < width; i=i +totalwidth) {
//Float value = 0 + (lineWidth+lineSpacing)*i;
linePositions.add(i);
}
arraySize = linePositions.size();
}
Boolean drawn = false;
void draw() {
println("Draw");
background(51);
//loop through the lines
//println("before Draw ka forloop"+linePositions.size());\
pixelperframe = ((lineSpeed - 10) > 1) ? (lineSpeed-10) : 1;
for (int i = 0; i < arraySize; i++) {
//println("Draw ka forloop");
rect(linePositions.get(i), 0, lineWidth, width);
int newPosition = linePositions.get(i) - pixelperframe ;
linePositions.set(i, newPosition);
//linePositions[i] -= lineSpeed;
//wrap the line
if ( linePositions.get(i) < 0) {
println("Wrapping the line");
linePositions.set(i, width);
// drawn = true;
}
}
//int temp = (width - linePositions.get(arraySize - 1)) - totalwidth;
//println(temp);
}
For the spacing between the lines to always be the same, you have to make sure that the total line spacing adds up to the total width of your screen. Right now each line takes up 75 pixels (50 for the line itself and 25 for the space after it), but your width is 640. That will always leave you with extra space, which will mess up your spacing after the lines start over.
So the easiest thing to do is to simply make your window a multiple of the line spacing. Let's go with 600, which is enough room for exactly 8 lines.
However, since you want your lines to slide off the screen, you actually need 9 lines, since you'll often see half of one line going off the screen while half of another line enters the screen. Draw some pictures to see exactly what I'm talking about
If I understand what you mean by making the lines "gradually" restart, you just have to restart them when their right side goes off the screen. In other words, when their x position is negative enough to be off the screen.
Putting it all together, it looks like this:
float[] linePositions = new float[9];
float lineWidth = 50;
float lineSpacing = 25;
float lineSpeed = 1;
void setup() {
size(600, 360);
for (int i = 0; i < linePositions.length; i++) {
linePositions[i] = (lineWidth+lineSpacing)*i;
}
}
void draw() {
background(51);
for (int i = 0; i < linePositions.length; i++) {
linePositions[i] -= lineSpeed;
rect(linePositions[i], 0, lineWidth, height);
if ( linePositions[i] < -(lineWidth+lineSpacing)) {
linePositions[i] = width;
}
}
}

animation of vertical bars using processing

I am basically trying to make a animation of vertical bars across the screen which should be equally spaced and continue until some key is pressed etc.. in the processing.org tool for animation.
I was able to get a kind of animation, but with hard coded values and had to write the same code again and again to generate the animation of bars for the whole frame/screen. I need to make it generic, so that changing the screen width or the size of the bars would not make me change the whole code but just the variables which control the parameters. Below is my code. I have written the code for three vertical bars but that needs to be done for the whole screen..
int a;
int i;
int j;
void setup() {
size(640, 360);
a = width/2;
i = 0;
}
void draw() {
background(51);
//need to avoid these repetitions each time for each bar
rect(a , 0, 25, width);
a = a - 1;
if (a < 0) {
a = width;
}
rect(i= a+50, 0, 25, width);
i = i - 1;
if (i < 0) {
i = width + a;
}
rect(j = i + 50, 0, 25, width);
j = j - 1;
if (a < 0) {
j = width + i;
}
}
It sounds like you're looking for an array.
An array is like a variable, only it can hold multiple values in its indexes. You can then use a for loop to iterate over the array and do stuff based on the values in the array.
Here's an example that uses an array to keep track of the line positions:
float[] linePositions = new float[10];
float lineWidth = 25;
float lineSpacing = 25;
float lineSpeed = 1;
void setup() {
size(640, 360);
for (int i = 0; i < linePositions.length; i++) {
linePositions[i] = width/2 + (lineWidth+lineSpacing)*i;
}
}
void draw() {
background(51);
//loop through the lines
for (int i = 0; i < linePositions.length; i++) {
//draw the line
rect(linePositions[i], 0, lineWidth, width);
//move the line
linePositions[i] -= lineSpeed;
//wrap the line
if ( linePositions[i] < 0) {
linePositions[i] = width;
}
}
}
More info on arrays can be found in the Processing reference.

Get shapes on screen

I have created a grid of thumbs. When a certain thumb is pressed I want the image that is linked to the thumb added on screen. I know i'm supposed to write the loadImages in setup(), but i'm a bit confused on how to do this.
PShape[] Quotes = new PShape[6];
int qLength = Quotes.length;
setup() {
size(1024, 768);
}
draw() {
stroke(bruin);
strokeWeight(5);
fill(wit);
rectMode(CORNER);
rect(guide, 280, bBorder, 145);
noStroke();
fill(bruin);
rect(guide, 280, bBorder, 40);
textFont(kaffeesatzFont);
textSize(30);
fill(wit);
text("Quotes", 80, 308);
createGridQ();
}
void createGridQ(){
xOffset = 30;
yOffset = 325;
xSize = 50;
ySize = 38;
padding = 10;
xPos = padding + xOffset;
yPos = yOffset;
cols = 3;
for(int j = 0; j < qLength; j++){
// Grid
xPos = xOffset + ((j % cols) * (xSize+padding));
yPos = yOffset + ((j / cols) * (ySize+padding));
Quotes[j] = loadShape("Q" + j + ".svg");
shape(Quotes[j], xPos, yPos);
if((mouseX >= xPos) && (mouseX <= xPos+xSize) &&
(mouseY >= yPos) && (mouseY <= yPos+ySize)){
cursor(HAND);
if (mousePressed){
cursor(HAND);
Quotes[j] = loadShape("Q" + j + "groot" + ".svg");
shape(Quotes[j], width/5, height/2-200);
}
}
}
}
You can load an image by declaring a PImage and loading it from a web url or by placing it into your data or source directory (where your .pde files are) and then loading it from there.
PImage img;
img = loadImage("laDefense.jpg");
Processing loadImage Reference
So, replace "laDefense.jpg" with the name of the image you want to use and place that image into your data folder. After that, you can place the image in the scene and manipulate it as you would a shape.

Resources