今天來整理在p5.js中圖層的操作。
在p5.js中圖層的概念可以用 p5.Graphics, createGraphics()來建立不同的圖層。
createCanvas()所建立的為一個畫布般的容器,在畫布上可以有 Graphic,Image,Shape,Font,Video,Capture 等等。最後用 image(img, x, y, w, h)呈現在canvas畫布上。
let can;
let pg1;
let pg2;
function setup() {
can = createCanvas(400, 400); //-- 建立等物件是 Renderer2D
can.id("can1");
can.class("c1");
can.position(0, 0);
background(100);
pg1 = createGraphics(400, 400); //-- 建立等物件是 Graphics
pg1.background(0, 0);
pg1.fill(255, 0, 0, 100);
pg1.rect(10, 10, 300, 300);
pg2 = createGraphics(400, 400);
pg2.background(0, 0);
pg2.fill(255, 255, 0, 100);
pg2.rect(10, 10, 250, 250);
image(pg1, 0, 0);
image(pg2, 100, 100);
console.log(pg1.elt);
console.log(pg2.elt);
console.log(can.elt);
}
產生的元件標籤
<!-- Graphics -->
<canvas width="400" height="400" style="display: none; width: 400px; height: 400px;"></canvas>
<!-- Canvas -->
<canvas id="can1" class="c1" width="400" height="400" style="width: 400px; height: 400px; position: absolute; left: 0px; top: 0px;"></canvas>
let pg = createGraphics(400, 400); 產生的是一個隱藏的canvas元件
再用 image(pg, 0, 0); 繪入canvas,
也就是將pg1, pg2繪入canvas中。
在p5.js中 Graphics的元件是 Graphics,在DOM的元件中是隱藏的canvas元件
另外一操作方式,是直接以Graphics當作是canvas元件,這樣等於是同時有3個canvas元件出現在body中
3個canvas的出現順序,是按照 createCanvas, createGraphics 建立的順序,由下而上堆疊。
若要設定不同的堆疊順序,可以利用
pg1.style('z-index', 20);
pg2.style('z-index', 10);
就是 z-index屬性來調整圖層的高度,數字越大代表越上層。
2種操作整理如下
pg1 = createGraphics(400, 400, P2D);
pg1.background(0, 0);
pg1.fill(255, 0, 0, 100);
pg1.rect(10, 10, 300, 300);
pg1.id("pg1");
pg1.style('z-index', 20);
pg1.position(0, 0);
pg1.show();
pg1 = createGraphics(400, 400, P2D);
pg1.background(0, 0);
pg1.fill(255, 0, 0, 100);
pg1.rect(10, 10, 300, 300);
image(pg1, 0, 0);
從產生的canvas元件中就可以看出差異
<canvas width="400" height="400" style="display: block; width: 400px; height: 400px; z-index: 20; position: absolute; left: 0px; top: 0px;" id="pg1"></canvas>
<canvas width="400" height="400" style="display: none; width: 400px; height: 400px;"></canvas>
執行結果
在Graphics中繪製的圖形的原點座標是以Graphics的左上角為基準
Graphics本身若是繪入到Canvas,則以Canvas左上角為原點
Canvas本身則以body左上角為原點
Graphics若是加上id的設定後,就會變成是DOM的canvas,則會以body左上角為原點
看似差不多,但是如果沒有釐清2者的差異,在圖像座標及呈現上,
往往會發現跟想像中的結果不一樣
在呈現的模式上,有分P2D及WEBGL,在座標的設定上也是不相同的
pg1 = createGraphics(400, 400, P2D); //-- 原點座標在Graphics的左上角
pg1 = createGraphics(400, 400, WEBGL); //-- 原點座標在Graphics的中央
如果想要使用WEBGL繪圖模式,又想要P2D的座標模式
可以寫成如下程式碼
pg1 = createGraphics(400, 400, WEBGL);
pg1.background(0, 0);
pg1.translate(-pg1.width/2, -pg1.height/2);
pg1.fill(255, 0, 0, 100);
pg1.rect(10, 10, 300, 300);
附上原P2D的程式碼
pg1 = createGraphics(400, 400, P2D);
pg1.background(0, 0);
pg1.fill(255, 0, 0, 100);
pg1.rect(10, 10, 300, 300);
有關繪圖的內容,DOM的方式是
let can = createCanvas(400, 500);
let ctx = can.elt.getContext("2d");
console.log(ctx);
p5.js 是 直接使用 drawingContext
console.log(drawingContext);
所產生的物件都是 CanvasRenderingContext2D
canvas.elt.getContext("2d");, CanvasRenderingContext2D
有關畫素的操作
p5.js的方式是
pg1.loadPixels();
console.log(pg1.pixels);
DOM的方法
let ptx = pg1.elt.getContext("2d");
let imgData_p = ptx.getImageData(0, 0, 400, 400);
console.log(imgData_p.data);
//----------------------------
let can = createCanvas(400, 400);
let pg1 = createGraphics(400, 400, P2D);
let pg2 = createGraphics(400, 400, P2D);
let vid = createVideo(['assets/small.mp4'], () => {
vid.loop();
vid.volume(0);
});
//--------------------------------
loadPixels();
console.log(pixels);
pg1.loadPixels();
console.log(pg1.pixels);
pg2.loadPixels();
console.log(pg2.pixels);
vid.loadPixels();
console.log(vid.pixels);
//------------------------------------
let ctx = can.elt.getContext("2d");
let imgData = ctx.getImageData(0, 0, width, height);
console.log(imgData.data);
let ptx = pg1.elt.getContext("2d");
let imgData_p = ptx.getImageData(0, 0, 400, 400);
console.log(imgData_p.data);
let ptx2 = pg2.elt.getContext("2d");
let imgData_p2 = ptx2.getImageData(0, 0, 400, 400);
console.log(imgData_p2.data);
let vtx = vid.drawingContext;
let imgData_v = vid.imageData;
console.log(imgData_v.data);
console.log(drawingContext.getImageData(0, 0, 400, 400).data);
參考資料
Canvas API
https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API
drawingContext
https://p5js.org/reference/#/p5/drawingContext
createGraphics()
https://p5js.org/reference/#/p5/createGraphics
HTML canvas getImageData() Method
https://www.w3schools.com/tags/canvas_getimagedata.asp