在 p5.js 中主动绘制 "under" 个半透明区域
Actively drawing "under" a translucent area in p5.js
我 运行 在开发更大的 p5.js 草图时遇到了一个令人费解的问题,我的解决方案并不适合我。所以,我把它归结为这个(诚然是蹩脚的)草图。
此 p5.js 草图每帧绘制几个 运行domly 大小和颜色的点。在 canvas 的中心是一个 t运行 半透明的蓝色填充矩形,看起来位于观察者和点之间。问题出在 t运行slucent 蓝色区域。草图有效,但我忍不住认为有更好的方法来实现 t运行slucency.
var cells;
var cellsz = 10;
var wid, hgt;
function setup()
{
wid = floor(windowWidth / cellsz);
hgt = floor(windowHeight / cellsz);
createCanvas(windowWidth, windowHeight);
frameRate(15);
cells = new Array(wid);
for (x = 0; x < wid; x++) {
cells[x] = new Array(hgt);
for (y = 0; y < hgt; y++) {
cells[x][y] = false;
}
}
}
function cell_draw(c)
{
strokeWeight(1);
stroke(c.r, c.g, c.b);
fill(c.r, c.g, c.b);
ellipse(c.x, c.y, c.w, c.w);
}
function cell_new()
{
var x = int(floor(random(wid)));
var y = int(floor(random(hgt)));
var c = {
x: x * cellsz,
y: y * cellsz,
w: random(cellsz * 2),
r: floor(random(256)),
g: floor(random(256)),
b: floor(random(256))
};
cells[x][y] = c;
cell_draw(c);
}
// draw a translucent blue filled rectangle in the center of the window
function overlay()
{
strokeWeight(1);
stroke(0, 0, 255, 75);
fill(0, 0, 255, 75);
var w = windowWidth / 4;
var h = windowHeight / 4;
rect(w, h, w * 2, h * 2);
}
// erase what's in the center of the window, then redraw the underlying cells
function underlay()
{
strokeWeight(1);
stroke(255);
fill(255);
var w = windowWidth / 4;
var h = windowHeight / 4;
rect(w, h, w * 2, h * 2);
var x0 = floor((w / cellsz) - 2);
var y0 = floor((h / cellsz) - 2);
var x1 = floor(x0 + 3 + ((w * 2) / cellsz));
var y1 = ceil(y0 + 3 + ((h * 2) / cellsz));
for (x = x0; x <= x1; x++) {
for (y = y0; y <= y1; y++) {
if (cells[x][y]) {
cell_draw(cells[x][y]);
}
}
}
}
function draw()
{
underlay();
for (i = 0; i < 5; i++) {
cell_new();
}
overlay();
}
body {padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>
代码背后的基本思想是 canvas 被量化为固定大小 cells
。每个单元格包含零个或一个点对象(它的位置、直径和颜色)。当每个新的 运行dom 点被选中时,它被保存到适当的单元格中。这用作 canvas 中内容的逻辑内存。 (虽然它并不完美,因为它不处理绘制点的顺序。但是,无论如何,我们都是这里的朋友。)
我一直在为 t运行slucent 区域的基本问题而苦苦挣扎。最初,我每次都重新绘制整个框架,似乎是处理方式......但是对象太多了。绘制每一帧花费的时间太长了。最后,我吹掉了 t运行slucent 矩形下方的区域,只重新绘制了受影响的对象,然后在顶部放置了一个新的 t运行slucent 矩形。
有没有我可以在这里应用的技术,性能更好,或者使用更少的代码,或者...(喘气)两者都有?
您的方法非常合理,但您可以通过使用缓冲图像而不是二维数组来存储底层来简化它。在上面画点,然后每一帧将整个缓冲区绘制到屏幕上,然后在其上绘制矩形覆盖。这样做的好处是不局限于数组位置,将来也可以解决类似的分层问题。
查看我的回答 了解更多信息,但方法是这样的:
var buffer;
function setup() {
createCanvas(windowWidth, windowHeight);
frameRate(15);
buffer = createGraphics(width, height);
//start with white background
buffer.background(255);
}
function drawRandomCircleToBuffer() {
buffer.noStroke();
buffer.fill(random(255), random(255), random(255));
var diameter = random(5, 20);
buffer.ellipse(random(buffer.width), random(buffer.height), diameter, diameter);
}
function overlay() {
strokeWeight(1);
stroke(0, 0, 255, 75);
fill(0, 0, 255, 75);
rect(mouseX, mouseY, 200, 200);
}
function draw() {
drawRandomCircleToBuffer();
image(buffer, 0, 0);
overlay();
}
body {padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>
我 运行 在开发更大的 p5.js 草图时遇到了一个令人费解的问题,我的解决方案并不适合我。所以,我把它归结为这个(诚然是蹩脚的)草图。
此 p5.js 草图每帧绘制几个 运行domly 大小和颜色的点。在 canvas 的中心是一个 t运行 半透明的蓝色填充矩形,看起来位于观察者和点之间。问题出在 t运行slucent 蓝色区域。草图有效,但我忍不住认为有更好的方法来实现 t运行slucency.
var cells;
var cellsz = 10;
var wid, hgt;
function setup()
{
wid = floor(windowWidth / cellsz);
hgt = floor(windowHeight / cellsz);
createCanvas(windowWidth, windowHeight);
frameRate(15);
cells = new Array(wid);
for (x = 0; x < wid; x++) {
cells[x] = new Array(hgt);
for (y = 0; y < hgt; y++) {
cells[x][y] = false;
}
}
}
function cell_draw(c)
{
strokeWeight(1);
stroke(c.r, c.g, c.b);
fill(c.r, c.g, c.b);
ellipse(c.x, c.y, c.w, c.w);
}
function cell_new()
{
var x = int(floor(random(wid)));
var y = int(floor(random(hgt)));
var c = {
x: x * cellsz,
y: y * cellsz,
w: random(cellsz * 2),
r: floor(random(256)),
g: floor(random(256)),
b: floor(random(256))
};
cells[x][y] = c;
cell_draw(c);
}
// draw a translucent blue filled rectangle in the center of the window
function overlay()
{
strokeWeight(1);
stroke(0, 0, 255, 75);
fill(0, 0, 255, 75);
var w = windowWidth / 4;
var h = windowHeight / 4;
rect(w, h, w * 2, h * 2);
}
// erase what's in the center of the window, then redraw the underlying cells
function underlay()
{
strokeWeight(1);
stroke(255);
fill(255);
var w = windowWidth / 4;
var h = windowHeight / 4;
rect(w, h, w * 2, h * 2);
var x0 = floor((w / cellsz) - 2);
var y0 = floor((h / cellsz) - 2);
var x1 = floor(x0 + 3 + ((w * 2) / cellsz));
var y1 = ceil(y0 + 3 + ((h * 2) / cellsz));
for (x = x0; x <= x1; x++) {
for (y = y0; y <= y1; y++) {
if (cells[x][y]) {
cell_draw(cells[x][y]);
}
}
}
}
function draw()
{
underlay();
for (i = 0; i < 5; i++) {
cell_new();
}
overlay();
}
body {padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>
代码背后的基本思想是 canvas 被量化为固定大小 cells
。每个单元格包含零个或一个点对象(它的位置、直径和颜色)。当每个新的 运行dom 点被选中时,它被保存到适当的单元格中。这用作 canvas 中内容的逻辑内存。 (虽然它并不完美,因为它不处理绘制点的顺序。但是,无论如何,我们都是这里的朋友。)
我一直在为 t运行slucent 区域的基本问题而苦苦挣扎。最初,我每次都重新绘制整个框架,似乎是处理方式......但是对象太多了。绘制每一帧花费的时间太长了。最后,我吹掉了 t运行slucent 矩形下方的区域,只重新绘制了受影响的对象,然后在顶部放置了一个新的 t运行slucent 矩形。
有没有我可以在这里应用的技术,性能更好,或者使用更少的代码,或者...(喘气)两者都有?
您的方法非常合理,但您可以通过使用缓冲图像而不是二维数组来存储底层来简化它。在上面画点,然后每一帧将整个缓冲区绘制到屏幕上,然后在其上绘制矩形覆盖。这样做的好处是不局限于数组位置,将来也可以解决类似的分层问题。
查看我的回答
var buffer;
function setup() {
createCanvas(windowWidth, windowHeight);
frameRate(15);
buffer = createGraphics(width, height);
//start with white background
buffer.background(255);
}
function drawRandomCircleToBuffer() {
buffer.noStroke();
buffer.fill(random(255), random(255), random(255));
var diameter = random(5, 20);
buffer.ellipse(random(buffer.width), random(buffer.height), diameter, diameter);
}
function overlay() {
strokeWeight(1);
stroke(0, 0, 255, 75);
fill(0, 0, 255, 75);
rect(mouseX, mouseY, 200, 200);
}
function draw() {
drawRandomCircleToBuffer();
image(buffer, 0, 0);
overlay();
}
body {padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>