iT邦幫忙

2022 iThome 鐵人賽

DAY 10
0
Modern Web

從新開始學習p5.js畫出一片天系列 第 10

D10_Graphics圖層操作

  • 分享至 

  • xImage
  •  

Graphics圖層操作

今天來整理在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


上一篇
D09_Video元件的YouTube影片操作
下一篇
D11_文字與字型操作
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言