In p5, use mouseClicked() function only when the canvas is clicked - p5.js

In p5 I have a code with mouseClicked() function.
I want this function to be called only when the canvas is clicked.
Any idea ?

I found the answer. When creating the canvas, link it to a function like this:
function setup() {
var canvas = createCanvas(width, height);
canvas.mouseClicked(my_function);
...
}
function my_function(){
...
}

Related

How do I create a line that recedes as you draw more in p5.js?

Currently working on a site that features some line drawing while hovering. How can I make the line recede naturally as you draw more? Right now I've figured out how to draw a continual line.
var canvas;
var button;
function windowResized() {
console.log('resized');
resizeCanvas(windowWidth, windowHeight);
}
function setup () {
canvas = createCanvas(windowWidth, windowHeight);
canvas.position(0,0);
canvas.style('z-index', '-1')
background(175);
// button = createButton("Start Your Walk");
}
function draw () {
strokeWeight(4);
console.log('button')
line(pmouseX, pmouseY, mouseX, mouseY)
}
You may store the values of your mouse position in an array and then draw the points of the array in order. When the array is updated, if it is full, you will have to erase the last point of the array, move all the points one position backwards and add the new point. The following would be an example code. I recomend you to consult this page for documentation and also the p5 reference.
var mousePositions = [];
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
v = createVector(mouseX, mouseY);
mousePositions.push(v);
noFill();
beginShape();
for(var i = 0; i < mousePositions.length; i++){
vertex(mousePositions[i].x, mousePositions[i].y);
}
endShape();
if(mousePositions.length > 25){
mousePositions.shift();
}
}

Clearing createGraphics() canvas from p5js renderer

p5js has a clear() function which clears everything from the screen. I want to keep the canvas created by createCanvas() but clear the createGraphics() one only. How can I do this ?
//something like this
var canvas2;
function setup() {
createCanvas(400, 400);
canvas2 = createGraphics(400,400);
canvas2.clear()
noLoop()
}
function draw() {
fill(255,0,0)
rect(60,60,40,40)
canvas2.fill(20,44,240);
canvas2.rect(20,20,40,40);
image(canvas2,0,0)
}
function mousePressed() {
//something which clears the createGraphics() canvas only and keeps the createCanvas() one
}
You can clear the content of a graphics object using its clear() function. Here's an example:
var canvas2;
function setup() {
createCanvas(400, 400);
canvas2 = createGraphics(400,400);
canvas2.fill(20,44,240);
canvas2.rect(20,20,40,40);
}
function draw() {
background(255);
fill(255,0,0)
rect(60,60,40,40)
image(canvas2,0,0)
}
function mousePressed() {
canvas2.clear();
}
I moved the canvas2.rect(20, 20, 40, 40) call to be inside the setup() function, because otherwise you're redrawing to the canvas even after you clear it. I also removed your noLoop() call so that you could see the result of clearing the canvas.

How do I save a p5.js canvas as a very large PNG?

I know how to save the canvas using p5.js. However I want to save the canvas as a very large png (for example 8000x8000) so that I can use it in Photoshop and scale down the image to the appropriate size. Is there a simple way of doing this besides creating a new canvas behind the scenes that is too large for the browser window?
You could use the createGraphics() function to create an off-screen buffer. Then you can draw it to the screen using the image() function, or you can call its save() function to store it as a file. Here's an example:
let pg;
function setup() {
createCanvas(400, 400);
pg = createGraphics(4000, 4000);
pg.background(32);
}
function draw() {
pg.ellipse(random(pg.width), random(pg.height), 100, 100);
image(pg, 0, 0, width, height);
}
function mousePressed(){
pg.save("pg.png");
}
Draw everything into a pGraphics object.
Normally you draw this "output" just as an image to the canvas.
But if you want to export a high-res version of it, you scale it up first.
let scaleOutput = 1;
let output;
let canvas;
// setup
function setup() {
// other stuff...
output = createGraphics(1000, 640);
canvas = createCanvas(1000, 640);
}
// the draw loop
function draw() {
// Clear Canvas
background(255);
output.clear();
// Set scale
output.push();
output.scale(scaleOutput);
// Draw to your output here...
output.pop();
// Show on canvas
image(output, 0, 0);
}
// Scale up graphics before exporting
function exportHighRes() {
// HighRes Export
scaleOutput = 5;
output = createGraphics(scaleOutput * 1000, scaleOutput * 640);
draw();
save(output, "filename", 'png');
// Reset Default
scaleOutput = 1;
output = createGraphics(1000, 640);
draw();
}
// Export when key is pressed
function keyReleased() {
if (key == 'e' || key == 'E') exportHighRes();
}

How do I resize a p5.Graphic object?

In p5.js resizeCanvas(x, y) is a function for p5 objects but if I made a p5.Graphics object, can I resize it with a similar function?
Interestingly, p5.Graphics objects can run resizeGraphics() but nothing happens (including no error) and the height and width remain the same in the console.
g = createGraphics(50, 50); //creates p5.Graphics
g.resizeCanvas(100, 100); //fails: silently without error
g.resize(100, 100); //fails: resize has not been defined
Is there another function or would I need to actually extract the cooresponding graphics canvas and call a native javascript function instead?
Thanks!
If you want to resize a P5.Graphics, you can just create a new one, then draw the old one to the new one.
Here is an example:
var pg;
function setup() {
createCanvas(1000, 1000);
pg = createGraphics(100, 100);
pg.background(100);
pg.noStroke();
pg.ellipse(pg.width/2, pg.height/2, pg.width, pg.height);
}
function draw() {
background(200);
image(pg, 0, 0);
}
function mouseClicked(){
var newPG = createGraphics(mouseX, mouseY);
newPG.image(pg, 0, 0, newPG.width, newPG.height);
pg = newPG;
}
Using resizeCanvas on a graphics object created with "createGraphics" seems to stretch the graphics rather than resize the buffer.
Right now the best way to resize a graphics object is to simply set the width and height properties directly.
// Some graphics object
let graphics = createGraphics(w,h);
// Now simply resize like this
graphics.width = gWidth;
graphics.height = gHeight;
As suggested here:
https://github.com/processing/p5.js/issues/2064#issuecomment-315503533

How to execute a function when using the createGraphics function in P5js?

I want to use the createGraphics function to draw something on another screen... and then paste that into my main sketch..
in the docu, the example they give is doing something like:
var vignette;
function setup(){
createCanvas(710, 400);
vignette = createGraphics(400, 250);
}
function draw(){
ellipse(mouseX, mouseY, 60, 60);
pg.background(51);
pg.noFill();
pg.stroke(255);
pg.ellipse(mouseX-150, mouseY-75, 60, 60);
//Draw the offscreen buffer to the screen with image()
image(pg, 150, 75);
}
But what i want to do is more complex than pg.background(51)
I want to run this function which creates a radial gradient:
function drawGradient() {
for (let r = canvasX; r > 0; --r) {
let lightnes = map(r,0,canvasX,360,0)
fill(360, 360, lightnes)
ellipse(0, 0, r, r)
}
}
But if i do vignette.drawGradient() i get the error: vignette.drawGradient is not a function...
So how can i then execute things like whats inside the drawgradient function inside the createGraphics function?
Here is the codepen: https://codepen.io/giorgiomartini/pen/ZJjWbw?editors=0010
You wouldn't put anything "inside" the createGraphics() function. The createGraphics() function returns an instance of p5.Renderer. You then call functions on that instance.
You were going in the right direction by trying to call vignette.drawGradient(), but like you've discovered, p5.Renderer does not contain a drawGradient() function. Only your sketch contains that function, because it's something you created.
p5.Renderer contains the drawing functions: stuff like background(), fill(), rect(), and ellipse(). So if you want to draw your gradient to your vignette renderer, you have to call the functions that actually draw things on your vignette variable. Like this:
function drawGradient() {
for (let r = canvasX; r > 0; --r) {
let lightnes = map(r,0,canvasX,360,0)
vignette.fill(360, 360, lightnes)
vignette.ellipse(0, 0, r, r)
}
}

Resources