This question already has answers here:
How to remove previous shape after draw() in Processing
(2 answers)
Closed 5 years ago.
I want to make the old shape disappear when the new shape is made. Please help me. Basically, I want to create a rectangle on click but when I click again circle should disappear. This should happen with equal probablity.
void setup()
{
size(400, 400);
background(255);
}
void draw()
{
fill(255);
tileAp();
}
void tileAp()
{
if (mousePressed && mouseY >= 0 && mouseY <= 200)
{
drawM(true);
}
else
{
}
}
void drawM(boolean b)
{
int prob = int(random(0, 2));
if (b == true)
{
if (prob == 0)
{
rect(mouseX, mouseY, 50, 50);
}
if (prob == 1)
{
ellipse(mouseX, mouseY, 50, 50);
}
}
}
Like the suggested duplicate says, you need to call the background() function to clear out old frames.
Compare this sketch:
<script src="https://cdnjs.cloudflare.com/ajax/libs/processing.js/1.6.6/processing.min.js"></script>
<script type="application/processing">
void setup(){
size(200, 200);
background(64);
}
void draw(){
ellipse(mouseX, mouseY, 20, 20);
}
</script>
<canvas> </canvas>
To this one:
<script src="https://cdnjs.cloudflare.com/ajax/libs/processing.js/1.6.6/processing.min.js"></script>
<script type="application/processing">
void setup(){
size(200, 200);
}
void draw(){
background(64);
ellipse(mouseX, mouseY, 20, 20);
}
</script>
<canvas> </canvas>
Related
I already made a custom shape (myFunction), and I also made patterns using simpler shapes. I want to know how to replace those simple shapes with my custom shape while maintaining the pattern drawn on processing...
You're already calling functions such as noFill(), noStroke(), etc.
It's the same for your function: call it by simply using it's name and () (because it has no arguments): myFunction();
Let's say you want to draw it in pattern 1, you could do something like:
if (pattern==1) {
for (int x=50; x<width; x+=100) {
for (int y=20; y<height; y+=100) {
myFunction();
}
}
}
You will need to pay attention to rendering though.
Running the above will not display anything you call in noFill() in myFunction() and also noStroke() in draw(), right after background(): you won't be able to see a shape with no fill and no stroke :)
One suggestion is to add a stroke:
void myFunction() {
noFill();
stroke(255);
ellipse(300, 300, 200, 400);
ellipse(300, 300, 400, 200);
translate(300, 300);
rotate(radians(130));
ellipse(0, 0, 200, 400);
translate(0, 0);
rotate(radians(0));
ellipse(0, 0, 400, 200);
}
Of course feel free to experiment and make this look nicer.
Here's a modified version of your sketch that uses a few key presses to change the pattern type and shape type at runtime:
int pattern = 1;
// 0 = pluseEllipseCluser, 1 = blobs, 2= myFunction spirograph circles
int shape = 0;
void setup() {
size(600, 600);
println("press 1,2 to change pattern");
println("press p/b/c to change shapes");
}
void draw() {
background(30);
noStroke();
if (pattern==1) {
for (int x=50; x<width; x+=100) {
for (int y=20; y<height; y+=100) {
drawSelectedShapes(x, y);
}
}
}
if (pattern==2) {
float rando = random(10, 90);
for (float x= rando; x >= 0; x-=random(2.5)) {
for (float y= rando; y >= 0; y-=random(2.5)) {
drawSelectedShapes(x, y);
}
}
}
}
void drawSelectedShapes(float x, float y){
if(shape == 0){
plusEllipseCluser(x, y);
}
if(shape == 1){
blobs();
}
if(shape == 2){
myFunction();
}
}
void plusEllipseCluser(float x, float y){
fill(random(255), random(255), random(255), random(255));
ellipse(x, y+30, 50, 20); //plus ellipse cluster
ellipse(x, y+30, 20, 50);
}
void blobs(){
noStroke();
fill(random(250), random(120), random(100));
ellipse(random(width), random(height), 20, 50);
noFill();
stroke(random(255));
ellipse(random(width), random(height), 50, 20);
}
void myFunction() {
noFill();
stroke(255);
ellipse(300, 300, 200, 400);
ellipse(300, 300, 400, 200);
translate(300, 300);
rotate(radians(130));
ellipse(0, 0, 200, 400);
translate(0, 0);
rotate(radians(0));
ellipse(0, 0, 400, 200);
}
void keyPressed(){
if(key == '1') {
pattern = 1;
}
if(key == '2') {
pattern = 2;
}
if(key == 'p'){
shape = 0;
}
if(key == 'b'){
shape = 1;
}
if(key == 'c'){
shape = 2;
}
}
Notice that the example above also calls plusEllipseCluser() passing two arguments: it's a basic example of defining and calling a function that takes two arguments. Of course you've already called functions with arguments before (e.g. random(min,max), ellipse(x,y,w,h), etc.)
Have fun with shapes and patterns.
when i click the region it continually draws instead of when im holding the mouse. also ill figure out how to toggle the pencil when clicked later on. i am very new.
void mousePressed() {
if (mouseX > 772 && mouseX < 864 && mouseY > 1 && mouseY < 74) {
//button 1 was just clicked, show button 2 instead
drawPencil = true;
}
}
}
void draw() {
if (drawPencil) {
stroke(255);
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
I've written a small program which should give you an idea
boolean drawPencil;
void mousePressed() {
drawPencil = true;
}
void mouseReleased()
{
drawPencil = false;
}
void setup(){
size(800,800);
}
void draw() {
if (drawPencil) {
stroke(255);
line(mouseX, mouseY, pmouseX, pmouseY);
}
}
That's not how you do this. Here's a code snippet for you to experiment with. It'll react as follow:
float lastX, lastY;
void setup() {
size(800, 600);
}
void draw() {
background(0);
if (mousePressed) { // is true whenever a mouse button is held down
stroke(255);
line(mouseX, mouseY, lastX, lastY);
}
}
void mousePressed() { // run once every click
lastX = mouseX;
lastY = mouseY;
}
Have fun!
I made a simple drawing program to draw lines and increase/decrase the thickness of the line:
float strokeWeight = 2;
void setup() {
size(640, 360);
noSmooth();
fill(126);
background(255);
strokeWeight(strokeWeight);
}
void draw() {
background(0);
ellipse(mouseX, mouseY, strokeWeight/2, strokeWeight/2);
background(255);
if (mousePressed) {
stroke(0);
line(mouseX, mouseY, pmouseX, pmouseY);
}
if (keyPressed) {
if (key == '+') {
strokeWeight = strokeWeight + 0.5;
}
if (key == '-') {
strokeWeight = strokeWeight - 0.5;
}
if (strokeWeight >= 0.5) {
strokeWeight(strokeWeight);
}
}
}
Now I want to move a circle with my cursor that indicates the current thickness of the line. I tried something like this:
ellipse(mouseX, mouseY, strokeWeight/2, strokeWeight/2)
But this way it draws ellipses over and over again. Is there a way to "erase" the circle made before?
I am not 100% sure that I've understood your question, but you probably want to use PGrahics, on one you keep the lines, on the other you draw the circle.
float strokeWeight = 2;
PGraphics canvas;
PGraphics thickness_circle;
void setup() {
size(640, 360);
canvas = createGraphics(width, height);
thickness_circle = createGraphics(width, height);
thickness_circle.beginDraw();
thickness_circle.noFill();
thickness_circle.strokeWeight(1);
thickness_circle.stroke(255, 0, 0);
thickness_circle.endDraw();
}
void draw() {
background(255);
if (keyPressed) {
if (key == '+') {
strokeWeight += 0.5;
}
if (key == '-') {
strokeWeight -= 0.5;
}
strokeWeight = strokeWeight >= 0.5 ? strokeWeight : 0.5;
}
if (mousePressed) {
canvas.beginDraw();
canvas.strokeWeight(strokeWeight);
canvas.line(mouseX, mouseY, pmouseX, pmouseY);
canvas.endDraw();
}
image(canvas, 0, 0);
thickness_circle.beginDraw();
thickness_circle.clear();
thickness_circle.ellipse(mouseX, mouseY, strokeWeight, strokeWeight);
thickness_circle.endDraw();
image(thickness_circle, 0, 0);
}
I'm trying to program an intro. I want the canvas to erase itself after it. I already have the trigger, but I do not know how to clear the canvas. Would just changing the background work? I still want to make stuff after it.
Here is the code:
void setup () {
frameRate(10);
stroke(255, 255, 255);
noFill();
rect(100,155,300,300);
size(500, 500);
}
void square () {
for (int x = 100; x <= 300; x += 100) {
for (int y = 155; y <= 355; y += 100) {
fill(random(0, 255), random(0, 255), random(0, 255));
rect(x, y,100,100);
}
}
};
void draw () {
int time = 0;
int logoLength = 100;
if (time < logoLength) {
fill(255, 255, 255);
background(0, 0, 0);
textFont(createFont("Lucida console", 19));
textAlign(CENTER,CENTER);
text("Ghost Cube Games presents",250,59);
time++;
print(time);
square();
} else if (time == logoLength) {
background(255, 255, 255);
}
}
You can simply call the background() function.
background(0); draws a black background.
background(255); draws a white background.
background(255, 0, 0); draws a red background.
More info can be found in the reference.
For a more specific example, if you want to show an intro screen, you can simply keep track of whether the intro screen is showing in a boolean variable. If that variable is true, then draw the intro screen. If not, then draw whatever else you want to draw. If you do this from the draw() function, then you don't really have to worry about clearing the screen, since calling the background() function will do that for you:
boolean showingIntro = true;
void draw() {
background(0);
if (showingIntro) {
text("INTRO", 20, 20);
} else {
ellipse(50, 50, 25, 25);
}
}
void mouseClicked() {
showingIntro = false;
}
I am trying to get my gif to do something similar to this gif.
I have been able to get the line to draw, and the 'planets' to orbit, but can't figure out how to keep the line connecting the two circles, like the gif does.
Here's the basic code:
int x = 500;
int y = 500;
int radius = y/2;
int cX = x/2;
int cY = y/2;
String text1;
int lg_xBall;
int lg_yBall;
int sm_xBall;
int sm_yBall;
void setup() {
size(x, y);
smooth();
colorMode(RGB);
}
void draw() {
background(0);
stroke(255);
float t = millis()/1000.0f;
drawSmBallOrbit(100);
drawLgBallOrbit(100);
moveSmBall(t);
moveLgBall(t);
sun();
// showMouse();
connectingLines();
}
void drawCircle() { // This will draw a simple circle
stroke(1);
// x1=a+r*cos t, y1=b+r*sin t
ellipse(x/2, y/2, x/2, y/2);
}
void drawLines() { // This will draw lines from the center of the circle.
stroke(1);
line(x/2, y/2, radius/2, radius); // line from 6 to center
line(x/2, y/2, x/2, y/4); // line from 12 to center
for (int i = 0; i <= 5; i+=2.5) {
float x1 = x/2+radius/2*cos(i);
float y1 = y/2+radius/2*sin(i);
line(x/2, y/2, x1, y1);
}
}
void moveSmBall(float ky) { // This will create, and move, a small 'planet'
pushStyle();
stroke(100);
sm_xBall = (int)(cX+radius*cos(ky));
sm_yBall = (int)(cY+radius*sin(ky));
fill(190, 0, 0);
// background(0);
ellipse(sm_xBall, sm_yBall, 10, 10);
popStyle();
}
void drawSmBallOrbit(float opacity) {
pushStyle();
stroke(255, opacity);
strokeWeight(1);
noFill();
ellipse(x/2, y/2, cX+radius, cY+radius);
popStyle();
}
void moveLgBall(float kx) {
kx = kx/.7;
pushStyle();
lg_xBall = (int)(cX+radius*cos(kx)*.6);
lg_yBall = (int)(cY+radius*sin(kx)*.6);
fill(0, 0, 230);
ellipse(lg_xBall, lg_yBall, 30, 30);
popStyle();
}
void drawLgBallOrbit(float opacity) {
pushStyle();
stroke(255, opacity);
strokeWeight(1);
noFill();
ellipse(x/2, y/2, (cX+radius)*.6, (cY+radius)*.6);
popStyle();
}
void sun() {
pushStyle();
fill(250, 250, 0);
ellipse(cX, cY, 40, 40);
popStyle();
}
void connectingLines() {
line(sm_xBall, sm_yBall, lg_xBall, lg_yBall);
}
void showMouse() {
text("X: " + mouseX, x/2, y/2-30);
text("Y: " + mouseY, x/2, y/2-50);
}
Thanks for any help/advice!
The problem is that you're calling background() during every frame, which will clear away anything you've already drawn.
So you either need to stop calling background(), or you need to redraw the old lines every frame.
If you simply move the call to background() out of your draw() function and into your setup() function, you're about 50% there already:
void setup() {
size(x, y);
smooth();
colorMode(RGB);
background(0);
}
void draw() {
// background(0);
stroke(255);
float t = millis()/1000.0f;
drawSmBallOrbit(100);
drawLgBallOrbit(100);
moveSmBall(t);
moveLgBall(t);
sun();
// showMouse();
connectingLines();
}
However, the original animation does not show the previous positions of the ellipses. So you need to clear away the previous frame by calling the background() function, and then redraw previous line positions. You'd do that by having an ArrayList that holds those previous positions.
Here's a simple example that uses an ArrayList to redraw anywhere the mouse has been:
ArrayList<PVector> points = new ArrayList<PVector>();
void setup() {
size(500, 500);
}
void draw() {
background(0);
stroke(255);
points.add(new PVector(mouseX, mouseY));
for(PVector p : points){
ellipse(p.x, p.y, 10, 10);
}
}
You would need to do something very similar, but you'd have to keep track of two points at a time instead of one, since you're tracking two ellipses and not just the mouse position.