Reputation: 553
I want to factorize code for drawing same thing in a graphics or in the standard canvas.
( In my real program, i want to have autonomous class that draw themselves in some context given at construction time )
I cannot find some equivalent from canvas that can match graphics instructions except line.
In the following, i try to give either a canvas or a graphics object to the drawing method someDraw , but only line appears on canvas, while whole drawing appears in graphics.
let canvas;
let myGraph;
function setup() {
canvas = createCanvas(200,300,WEBGL);
canvas.parent('sketch-div');
myGraph = createGraphics(200,300,WEBGL);
stroke('red');
noFill();
noLoop();
}
function draw(){
// direct draw on canvas / doesn't work correctly
someDraw(canvas);
// indirect draw on graphics, then show image
someDraw(myGraph);
// show result
image(myGraph,100,100);
}
function someDraw(pg){
pg.clear();
pg.background(color(0,0,200));
// as webgl set 0,0 upper left
pg.translate(-pg.width/2, -pg.height/2);
pg.stroke('red');
pg.line(0,0,100,50);
pg.rect(0,0,60,60);
pg.ellipse (25,50,50,100);
}
You can see the (red) line drawn in canvas but not the rect or the ellipse. The graphics is correct.
Another effect: if this small prog loops ( see noLoop() in setup ), the graphics appears fleeting first time then is no more displayed.
So, canvas and graphics are not in the same hierarchy, but is there a common way to draw on both without duplicating all code ?
Upvotes: 1
Views: 177
Reputation: 553
After exploring previous solution, i learn two things :
The following gives a solution derived from previous. Have a look on push()/pop() around the call of graphics
let myGraph;
function setup() {
myGraph = createGraphics(100, 100, WEBGL);
canvas = createCanvas(200, 200, WEBGL);
frameRate(0.5);
}
function draw() {
// coordinates of window are reset at each draw.
translate(-width / 2, -height / 2);
someDraw(this);
// graphics coordinates cumulate at each draw.Protect:
myGraph.push();
myGraph.translate(-myGraph.width / 2, -myGraph.height / 2);
someDraw(myGraph);
myGraph.pop();
// draw myGraph on canvas
image(myGraph, 100, 100);
}
function someDraw(pg) {
pg.clear();
pg.background('blue');
// origin will be now restored in main draw
translate(10, 10);
pg.stroke('red');
pg.noFill();
pg.line(0, 0, 100, 100);
pg.rect(0, 0, 60, 60);
pg.ellipse(25, 50, 50, 50);
}
Upvotes: 1
Reputation: 210889
Use Instantiation:
var sketch = function( p ) {
let canvas;
let myGraph;
p.setup = function() {
canvas = p.createCanvas(200,300, p.WEBGL);
canvas.parent('sketch-div');
myGraph = p.createGraphics(200,300,p.WEBGL);
p.noLoop();
}
p.draw = function(){
// [...]
}
}
var test_3d = new p5(sketch);
Pass either the p5 instance to someDraw
someDraw(p);
or the p5.Renderer object:
someDraw(myGraph);
Complete example:
var sketch = function( p ) {
let canvas;
let myGraph;
p.setup = function() {
canvas = p.createCanvas(200,300,p.WEBGL);
canvas.parent('sketch-div');
myGraph = p.createGraphics(200,300,p.WEBGL);
p.noLoop();
}
p.draw = function(){
// direct draw on canvas / doesn't work correctly
someDraw(p);
// indirect draw on graphics, then show image
someDraw(myGraph);
// show result
p.image(myGraph,100,100);
}
function someDraw(pg){
pg.clear();
pg.background(pg.color(0,0,200));
// as webgl set 0,0 upper left
pg.translate(-pg.width/2, -pg.height/2);
pg.stroke('red');
pg.noFill();
pg.line(0,0,100,50);
pg.rect(0,0,60,60);
pg.ellipse (25,50,50,100);
}
}
var test_3d = new p5(sketch);
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.0.0/p5.min.js"></script>
<div id="sketch-div"></div>
Upvotes: 1