今天來整理在一個網頁中 顯示多個canvas的方法
在p5.js中,一般預設的模式是 Global Mode,
在此模式下只會有一個p5的實體,且setup(), draw() 只能對應到一個p5的實體
程式碼如下
function setup() {
createCanvas(400,400);
background(0);
}
function draw() {
noStroke();
fill(255);
ellipse(mouseX, mouseY, 50, 50);
}
如果想要同時用立多個p5在一個網頁中的話,
就要使用 Instance Mode
程式碼如下
const s = ( sketch ) => {
sketch.setup = () => {
sketch.createCanvas(400,400);
sketch.background(0);
};
sketch.draw = () => {
sketch.noStroke();
sketch.fill(255);
sketch.ellipse(mouseX, mouseY, 50, 50);
};
};
let myp5 = new p5(s);
先使用 const s = () => {}; 建立要執行的功能項目,也像是將函式物件化,
這種常見的函式的寫法是這樣 function s(){} 不過這種寫法不能變成像參數一般,
傳送到另一個物件或是函式中,因此,改寫成 const s = () => {}; 後,
就可以將s傳入到 let myp5 = new p5(s); 而 new p5(s) 就是 建立一個獨立的p5 instance 物件,
並且將 sketch 回傳給 s ,就形成了 const s = ( sketch ) => {}; 一旦取得p5的 sketch 後,
就可以設定 sketch.setup() 及sketch.draw() 的內容了。 並採用箭頭符號的語法 () => {} 來編寫。
sketch是回傳的p5 instance的命名,可以設定為簡單的名稱 p ,調整後如下。
const s = (p) => {
p.setup = () => { };
p.draw = () => { };
};
let myp5 = new p5(s);
//-- 精簡寫法 ---
let myp5 = new p5((p) => {
p.setup = () => { };
p.draw = () => { };
});
因此,如果要產生2個canvas的話,等於要產生2個p5的 instance。
//-- 產生2個p5的 instance ---
let p5_1 = new p5((p) => {
p.setup = () => { };
p.draw = () => { };
});
let p5_2 = new p5((p) => {
p.setup = () => { };
p.draw = () => { };
});
從 chrome的主控台,查看 console.log(p);
結果顯示 p 就是 p5 的 instance。
在instance模式中,原本可以直接呼叫的指令,都要加上 instance的物件名稱
如下
let p5_1 = new p5((p) => {
p.setup = () => {
p.createCanvas(400,400);
p.background(0);
};
p.draw = () => {
p.noStroke();
p.fill(255);
p.ellipse(p.mouseX, p.mouseY, 50, 50);
};
});
產生的DOM的canvas如下
<main>
<canvas id="defaultCanvas0" class="p5Canvas" width="800" height="800" style="width: 400px; height: 400px;"></canvas>
<canvas id="defaultCanvas1" class="p5Canvas" width="800" height="800" style="width: 400px; height: 400px;"></canvas>
</main>
如果要將 p5 instance 產生在想要的div元件下的話
如下設定
<body>
<div id="p5sketch_1"></div>
<div id="p5sketch_2"></div>
</body>
let p5_1 = new p5( (p) => {
p.setup = () => {
p.createCanvas(400,400);
p.background(0);
};
p.draw = () => {
p.noStroke();
p.fill(255);
p.ellipse(p.mouseX, p.mouseY, 50, 50);
};
}, "p5sketch_1");
let p5_2 = new p5((p) => {
p.setup = () => {
p.createCanvas(400,400);
p.background(0);
};
p.draw = () => {
p.noStroke();
p.fill(255, 255, 0);
p.ellipse(p.mouseX, p.mouseY, 50, 50);
};
}, "p5sketch_2");
或是
const s1 = (p) => {
p.setup = () => { };
p.draw = () => { };
};
let p5_1 = new p5(s1, "p5sketch_1");
const s2 = (p) => {
p.setup = () => { };
p.draw = () => { };
};
let p5_2 = new p5(s2, "p5sketch_2");
執行結果
座標 mouseX, mouseY 在多個p5 instance中,是以各別的canvas的左上角為原點基準,當游標在p5sketch_1時,對p5sketch_2來說,就等於是超出範圍。2個 p5 instance的mouseX, mouseY數值各不相同。
參考資料
p5.js Global and Instance mode
https://github.com/processing/p5.js/wiki/Global-and-instance-mode