How can I not draw on top of something

I’m trying to program something for my cs class.
I want to make a program that I can use to write notes with my Wacom tablet.
the problem is that I don’t know how not draw things on top of each other.
when I erased something I have drawn with the doodle() I simple set the color of to match the background, problem is, that I also “erase” de lines from grid() , if a call grid() again, it would Draw on top of the things y draw with doodle(). is there a way I could fix this??
I’ve tried calling background again, then grid() and finally a method that draws my oldPoints, but it must be a better solution.

problem:

my code:

float x1,y1,x2,y2 ; 
int col, oldCol  ; 
float weight, oldWeight ; 
int wallpaper ; 

public void grid(){
  float xMargin = width/16 ; 
  float dy = xMargin/2 ; 
  float n = height/dy ; 
  strokeWeight(2) ; 
  stroke(color(194,214,249)) ; 
  for(int i=1 ; i<n ; i++) line(0,dy*i,width,dy*i) ;
  stroke(color(250,83,83)) ;
  line(xMargin,0,xMargin,height);
}

public void doodle(float mx, float my, float pmx, float pmy, boolean mPressed, int col, float weight){
  strokeWeight(weight) ; 
  stroke(col) ; 
  if(mPressed){
    beginShape() ;
    curveVertex(x2,y2) ; 
    curveVertex(x1,y1) ; 
    curveVertex(pmx,pmy) ; 
    curveVertex(mx,my) ; 
    endShape() ; 
  }
  x2 = x1 ; 
  y2 = y1 ; 
  x1 = pmx ; 
  y1 = pmy ; 
}

public void keyPressed(){
  if(key=='e'){
    col = wallpaper ; 
    weight = 10*oldWeight ; 
  }
  if(key=='p'){
    col = oldCol ; 
    weight = oldWeight ; 
  }
  if(key=='l') grid() ; 
}

public void setup(){
  size(1280,720) ; 
  displayDensity(1) ; 
  wallpaper = color(255,253,239) ; 
  background(wallpaper) ; 
  col = color(10,100,255) ; 
  oldCol = col ; 
  weight = 4 ; 
  oldWeight = weight ; 
  grid() ; 
  x1 = 0 ; 
  y1 = 0 ; 
  x2 = 0 ; 
  y2 = 0 ; 
}

public void draw(){
  doodle(mouseX,mouseY,pmouseX,pmouseY,mousePressed,col,weight) ; 
}

I’m sorry for my broken English, tried my best.
sorry for the ugly code, I’m a n00b :3

1 Like

you can break your drawing up into multiple layers with each layer being a pgraphic. i changed a few things around but it seems to do what you want.

float x1, y1, x2, y2 ;
int col, oldCol;
float weight, oldWeight;
int wallpaper;

PGraphics layer1, layer2;

public void setup() {
  size(640, 480, P3D);
  displayDensity(1) ;
  
  wallpaper = color(255, 253, 239);
  col = color(10, 100, 255);
  oldCol = col;
  weight = 4;
  oldWeight = weight;
  x1 = 0;
  y1 = 0;
  x2 = 0;
  y2 = 0;
  
  layer1 = createGraphics(width, height);
  layer2 = createGraphics(width, height);
  grid();
}

public void grid() {
  float xMargin = width/16;
  float dy = xMargin/2;
  float n = height/dy;
  layer1.beginDraw();
  layer1.background(wallpaper);
  
  layer1.strokeWeight(2);
  layer1.stroke(color(194, 214, 249));
  
  for (int i=1; i<n; i++) 
    layer1.line(0, dy * i, width, dy * i);
  
  layer1.stroke(color(250, 83, 83));
  layer1.line(xMargin, 0, xMargin, height);
  layer1.endDraw();
}

public void draw() {
  //background(255, 0, 255);
  doodle(mouseX, mouseY, pmouseX, pmouseY, mousePressed, col, weight);

  image(layer1, 0, 0);
  image(layer2, 0, 0);
}

public void doodle(float mx, float my, float pmx, float pmy, boolean mPressed, int col, float weight) { 
  layer2.beginDraw();
  layer2.blendMode(REPLACE);
  layer2.strokeWeight(weight);
  layer2.stroke(col);
  if (mPressed) {
    layer2.beginShape();
    layer2.curveVertex(x2, y2);
    layer2.curveVertex(x1, y1);
    layer2.curveVertex(pmx, pmy);
    layer2.curveVertex(mx, my);
    layer2.endShape();
  }
  layer2.endDraw();
  x2 = x1;
  y2 = y1;
  x1 = pmx;
  y1 = pmy;
}

public void keyPressed() {
  if (key=='e') {
    col = color(255, 255, 255, 0);
    weight = 10*oldWeight ;
  }
  if (key=='p') {
    col = oldCol ;
    weight = oldWeight ;
  }
  if (key == 'c') {
    layer2.clear();
  }
}
2 Likes

Thank u very much kind sir! :slight_smile:

Hi, Ive been trying to program this using p5.js , but no its not working :c
pencil is not actually drawing, maybe is because im drawing the layer1 on draw?
if I just draw it on grid() it doesnt work either :c

let layer1,layer2 ; 
let wallpaper ; 
let pencil ; 
let pencilColr, oldPencilColr ; 
let pencilWeight, oldPencilWeight ; 

function grid(){
	let xMargin = width/16;
	let dy = xMargin/2;
	let n = height/dy;

	layer1.background(wallpaper);
	
	layer1.strokeWeight(2);
	layer1.stroke(color(194, 214, 249));
	
	for (let i=1; i<n; i++) layer1.line(0, dy * i, width, dy * i);
	
	layer1.stroke(color(250, 83, 83));
	layer1.line(xMargin, 0, xMargin, height);

	image(layer1, 0, 0);
}

function keyPressed(){
	
	//eraser
	if(keyCode===LEFT_ARROW){
		pencilColr = color(255, 255, 255, 0);
		pencilWeight = 5*oldPencilWeight ;
	}

	//pencil
	if(keyCode===RIGHT_ARROW){
		pencilColr = oldPencilColr ; 
		pencilWeight = oldPencilWeight ; 
	}

	if(keyCode===UP_ARROW) layer2.clear() ; 
}

function setup() {
	createCanvas(1280,720); 
	pixelDensity(1) ; 
	wallpaper = color(255,253,239); 

	layer1 = createGraphics(width,height) ; 
	layer2 = createGraphics(width,height) ; 

	pencilColr = 0 ; 
	oldPencilColr = pencilColr ; 
	pencilWeight = 2 ; 
	oldPencilWeight = pencilWeight ; 
	pencil = new Pencil(pencilWeight,pencilColr,layer2) ; 
	
	grid() ; 
}

function draw(){
	pencil.doodle(mouseX, mouseY, pmouseX, pmouseY, mouseIsPressed) ; 
	pencil.updateColor(pencilColr) ; 
	pencil.updateWeight(pencilWeight) ; 
	image(layer1, 0, 0);
	image(layer2, 0, 0);
}


function Pencil(weight,pencilColor,layer){

	this.weight = weight ;
        this.pencilColor = pencilColor ;
        this.layer = layer ; 
        this.tempX3 = 0 ;
        this.tempY3 = 0 ;
        this.tempY4 = 0 ;
	this.tempX4 = 0 ;
		
		this.doodle = function(x1,y1,x2,y2,mouseBeingPressed){
			this.layer.blendMode(REPLACE) ; 
			this.layer.noFill() ;
			this.layer.strokeWeight(this.weight) ;
			this.layer.stroke(this.pencilColor) ;
			if(mouseBeingPressed){
				this.layer.beginShape()  ;
				this.layer.curveVertex(this.tempX4,this.tempY4) ;
				this.layer.curveVertex(this.tempX3,this.tempY3) ;
				this.layer.curveVertex(x2,y2) ;
				this.layer.curveVertex(x1,y1) ;
				this.layer.endShape() ;
			}
			this.tempX4 = this.tempX3 ; 
			this.tempY4 = this.tempY3 ; 
			this.tempX3 = x2 ; 
			this.tempY3 = y2 ;
		}

		this.updateColor = function(otherCol){
			this.pencilColor = otherCol ; 
		}

		this.updateWeight = function(otherWeight){
			this.weight = otherWeight ; 
		}
}

you are drawing layer1 twice i believe just change this

function draw(){
	pencil.doodle(mouseX, mouseY, pmouseX, pmouseY, mouseIsPressed) ; 
	pencil.updateColor(pencilColr) ; 
	pencil.updateWeight(pencilWeight) ; 
	image(layer1, 0, 0);
	image(layer2, 0, 0);
}

to

function draw(){
	pencil.doodle(mouseX, mouseY, pmouseX, pmouseY, mouseIsPressed) ; 
	pencil.updateColor(pencilColr) ; 
	pencil.updateWeight(pencilWeight) ; 
	//image(layer1, 0, 0);
	image(layer2, 0, 0);
}

edit: just noticed that the eraser doesn’t work now i’ll be back -

so blendMode REPLACE doesn’t consider alpha in p5js so you will need a different approach… what that is i’m not sure. i’ll post again if i find something but maybe someone else will be able to help.

edit2: looks like you will have to get into the pixels to create an eraser of the type you want.

2 Likes

ohh ok :c , its gonna be a bit harder that way :c
thank u for ur help! :smile:

I was the reading the p5.js and processing reference of blendMode(REPLACE) and the both look the same, maybe is a bug?

well then i cannot really comment on that but it probably has to do with implementation differences between pgraphics and creategraphics. this is about the best setup i could develop that works within your requirements. hopefully someone else will chime in with a much better way to handle layered drawing in both processing and p5js. best of luck.

2 Likes

omg that index formula is so smart!!
thank 4 all ur help!

:exploding_head::exploding_head:

what do u mean by “replace this with circle fill or whatever shape I guess” ??

bc what u did works but when the canvas is too big, its very hard to erase.

is there any other way?

you could just add a slider to control the pencil weight like so as for the circle thing i was just saying instead of the pencil being just a rectangle you could draw with ellipse function and erase using something like brensenham circle alg.

2 Likes

Loved the slider idea! so much faster haha, thank u very much.

im about to read the wiki on brensenham circle alg.
thank 4 all ur help! :3

Linking the algorithm mentioned above:

1 Like

hey! your solution works perfectly, but only when I have pixelDensity(1)
is there any to use that with pixelDensity(2) ? :sweat_smile:

What, specifically, is the problem when you have pixelDensity(2)? What is happening, and what do you want to happen instead?

it is not working on the “erase” part of the program.
but only when the pixel density is set to 2
it is important for me to loose as little of quality as I can , that is why I need the pixel density set to 2
(I have a MacBook Pro 2018, it is because of the Retina display)

What, specifically, is happening?

(And is this still the version that you are doing in p5.js, not Processing(Java)?)

I am using p5.js now.
the problem is that is not changing the pixels (from mouse trail) to 0

you need to change the way you are addressing the pixels if you change the pixeldensity. there is a page which will show you what to replace the erase code with to accommodate any pixeldensity here and another here

1 Like