createGraphics on mobile device

so working with createGraphics and hi DPI screens is a known issue which apparently has been fixed. However, I still have some struggles with working with Graphics on mobile devices.

I have this code where stuff is drawn on a graphics layer and there is a button to save said graphics layer. However, I haven’t found any possibility to display the graphics layer on the canvas in high resolution (so setting pixelDensity to 1 is not an option). It’s always cropped when displaying with the image() function. Weirdly, when I save graphics with save(), the whole graphics canvas is saved. Am I doing something wrong?

var buttonTxt = ["back", "save", "next"];
var strokeWght = 4;
var textS = 24;
var timeSt;
var buttons = [];
var graphL;


function setup() {
	createCanvas(windowWidth, windowHeight);
	colorMode(HSB, 360, 100, 100, 100);
	graphL = createGraphics(windowWidth, windowHeight);
	//graphL.scale(1/pixelDensity());
	graphL.colorMode(HSB, 360, 100, 100, 100);
	
	textSize(textS);
	
	textClr = color(0, 0, 0); 
	strokeClr = color(0, 0, 0);
	bgClr = color(0, 0, 100);
	
	for (var i=0; i<3; i++) {
		buttons[i] = new Button(i);
	}
}

function draw() {


	graphL.rectMode(CORNER);
	graphL.background(180, 100, 100);
	graphL.fill(0, 100, 100);
	graphL.strokeWeight(10);
	graphL.rect(windowWidth*.1, windowHeight*.1, windowWidth*.8, windowHeight*.8);
	
	graphL.textSize(16);
	graphL.fill(0, 0, 100);
	graphL.stroke(0, 0, 0);
	graphL.strokeWeight(1);
	graphL.text("windowWidth: " + windowWidth + "\ngraphL.width: " + graphL.width  + "\npixelDensity: " + pixelDensity() +	"\ngraphL.pixelDensity: " + graphL.pixelDensity(), 50, 70);

	image(graphL, 0, 0);
	buttons[1].show();
	
	var dd=day();
	var mm=month();
	var yy=year();
	var hh=hour();
	var mi=minute();
	var ss=second();
	timeSt = nf(yy, 4) + nf(mm, 2) + nf(dd, 2) + nf(hh, 2) + nf(mi, 2) + nf(ss, 2);
}


function saveCnv() {
	save(graphL, "layer" + timeSt + ".png");
}


class Button {
	constructor(indexB) {
		this.indexB = indexB;
		this.x = (width/6)*(this.indexB*2+1);
		this.y = windowHeight*.9;
		this.w = 70;
		this.h = 40;
		this.textMarg = 10;
	}
	show() {
		rectMode(CENTER);
		stroke(strokeClr);
		fill(bgClr);
		strokeWeight(strokeWght);
		rect(this.x, this.y, this.w, this.h);
		
		textAlign(LEFT);
		textSize(textS);
		noStroke();
		fill(textClr);
		text(buttonTxt[this.indexB], this.x-(this.w/2)+this.textMarg, this.y+(textS/2));
	}
	clicked() {
		if (mouseX>=this.x-(this.w/2)&&mouseY>=this.y-(this.h/2)&&mouseX<=this.x+(this.w/2)&&mouseY<=this.y+(this.h/2)) {
			return(this.indexB);
		}
	}
}

function mouseClicked() {
	for (var i=0; i<buttons.length; i++){
		buttons[i].clicked();
		if (buttons[i].clicked()==1) {
			saveCnv();
		}
	}
}

This results in the following:
screenshot:

saved Image:

When I scale the graphics layer to

	graphL.scale(1/pixelDensity());

it gets blurry.

I’d appreciate any help! Thank you

I don’t have a mobile to test on, but perhaps this information is useful for narrowing down the issue. I’m testing on a laptop with pixelDensity 3. On this device both the screen and the saved image are displayed properly (so no cropped results).

When I run the program it shows a windowWidth of 851 pixels. Once I save it however it gets multiplied by the pixelDensity, giving me an image file of 2553 pixels wide. Perhaps this is the same for your saved image; could you check whether your saved image on your mobile is (360 x 4 =) 1440 pixels wide?
If so, what’s being displayed on your canvas is an unscaled 1440px graphics, while the sketch interprets your screen as a 360px wide display.

In the link you provided BenjaminHabert suggests using copy() instead of image() for drawing the graphic on your canvas. Have you tried that?

Thanks for trying it out.
Yes, the saved image is 1440p. But even though the sketch thinks it’s a 360p screen, it should know about the screen’s pixelDensity, so I don’t understand why it’s rendering the image too big…

Anyways, I tried the copy function, and oddly enough, that worked when specifying the target width and height. Thanks for pointing that answer out, I thought I’d tried that already :relieved:

The problem with copy() (and also with image) was the low fps in my sketch, so now I just draw it on the default canvas and when “save” is pressed, draw the image again on my graphics layer, which is then saved.