按下键盘时隐藏和显示背景图像,保留覆盖元素
Hide and show background image when keyboard pressed, preserving overlay elements
我想在单击鼠标时在图像上绘制椭圆,当我按下键盘时,交替隐藏和显示下面的图像,而不清除椭圆。
我正在使用 createGraphics() 来存储图像数据,并使用 remove() 所以当按下键盘时我发现图像消失了,但它不起作用
这是我尝试做的事情的草图:
let isMouseBeeingPressed = false;
let img;
let isShow = true
let bufferImg;
function preload() {
img = loadImage(
"https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500"
);
}
function setup() {
createCanvas(500, 500);
background(255);
loadImageBuffer();
}
function loadImageBuffer() {
bufferImg = createGraphics(400, 400);
bufferImg.image(img, 0, 0);
image(bufferImg, 0, 0);
}
function draw() {
if(isMouseBeeingPressed) {
stroke(0, 0, 0, 50);
fill(255);
ellipse(mouseX, mouseY, 20);
}
}
function keyPressed() {
if(isShow) {
bufferImg.remove();
} else {
image(bufferImg, 0, 0);
}
console.log('isShow:', isShow);
return isShow = !isShow;
}
function mousePressed() {
isMouseBeeingPressed = true;
}
function mouseReleased() {
isMouseBeeingPressed = false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
知道如何实现吗?
最好的方法可能是将椭圆绘制到单独的缓冲区 (p5.Graphics
),然后根据需要将其绘制在图像或空白背景之上。另一种方法是记录数组中每个椭圆的位置,以便可以重新绘制它们。然而,后一种方法将使用更多内存,并且在绘制许多椭圆后打开和关闭图像会有明显的延迟。
方法 #1(通过 p5.Graphics
渲染)
let img;
let graphics;
let isShow = true;
function preload() {
img = loadImage(
"https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500"
);
}
function setup() {
createCanvas(500, 500);
background(255);
image(img, 0, 0);
graphics = createGraphics(width, height);
}
function draw() {
if (mouseIsPressed) {
graphics.stroke(0, 0, 0, 50);
graphics.fill(255);
graphics.ellipse(mouseX, mouseY, 20);
background(255);
if (isShow) {
image(img, 0, 0);
}
image(graphics, 0, 0);
}
}
function keyPressed(e) {
isShow = !isShow;
background(255);
if (isShow) {
image(img, 0, 0);
}
image(graphics, 0, 0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
更新: 关于此方法需要注意的一件事是,每当按下鼠标时,都必须重新绘制整个场景(白色背景、图像(如果适用)和前景)。这样做的原因是抗锯齿和透明度。当您在 graphics
缓冲区上绘制椭圆时,由于抗锯齿,边缘将具有一些部分透明的像素。如果您重复绘制缓冲区作为覆盖层而不重新绘制其后面的内容,那么部分透明的像素将变得越来越不透明,直到它们变成黑色。这将导致您的椭圆的外边缘稍粗且像素化程度更高。
方法 #2(椭圆位置数组)
let img;
let isShow = true
let positions = [];
function preload() {
img = loadImage(
"https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500"
);
}
function setup() {
createCanvas(500, 500);
background(255);
image(img, 0, 0);
}
function draw() {
if (mouseIsPressed) {
stroke(0, 0, 0, 50);
fill(255);
ellipse(mouseX, mouseY, 20);
positions.push([mouseX, mouseY]);
}
}
function keyPressed() {
isShow = !isShow;
background(255);
if (isShow) {
image(img, 0, 0);
}
stroke(0, 0, 0, 50);
fill(255);
for (const [x, y] of positions) {
ellipse(x, y, 20);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
我想在单击鼠标时在图像上绘制椭圆,当我按下键盘时,交替隐藏和显示下面的图像,而不清除椭圆。
我正在使用 createGraphics() 来存储图像数据,并使用 remove() 所以当按下键盘时我发现图像消失了,但它不起作用
这是我尝试做的事情的草图:
let isMouseBeeingPressed = false;
let img;
let isShow = true
let bufferImg;
function preload() {
img = loadImage(
"https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500"
);
}
function setup() {
createCanvas(500, 500);
background(255);
loadImageBuffer();
}
function loadImageBuffer() {
bufferImg = createGraphics(400, 400);
bufferImg.image(img, 0, 0);
image(bufferImg, 0, 0);
}
function draw() {
if(isMouseBeeingPressed) {
stroke(0, 0, 0, 50);
fill(255);
ellipse(mouseX, mouseY, 20);
}
}
function keyPressed() {
if(isShow) {
bufferImg.remove();
} else {
image(bufferImg, 0, 0);
}
console.log('isShow:', isShow);
return isShow = !isShow;
}
function mousePressed() {
isMouseBeeingPressed = true;
}
function mouseReleased() {
isMouseBeeingPressed = false;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
知道如何实现吗?
最好的方法可能是将椭圆绘制到单独的缓冲区 (p5.Graphics
),然后根据需要将其绘制在图像或空白背景之上。另一种方法是记录数组中每个椭圆的位置,以便可以重新绘制它们。然而,后一种方法将使用更多内存,并且在绘制许多椭圆后打开和关闭图像会有明显的延迟。
方法 #1(通过 p5.Graphics
渲染)
let img;
let graphics;
let isShow = true;
function preload() {
img = loadImage(
"https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500"
);
}
function setup() {
createCanvas(500, 500);
background(255);
image(img, 0, 0);
graphics = createGraphics(width, height);
}
function draw() {
if (mouseIsPressed) {
graphics.stroke(0, 0, 0, 50);
graphics.fill(255);
graphics.ellipse(mouseX, mouseY, 20);
background(255);
if (isShow) {
image(img, 0, 0);
}
image(graphics, 0, 0);
}
}
function keyPressed(e) {
isShow = !isShow;
background(255);
if (isShow) {
image(img, 0, 0);
}
image(graphics, 0, 0);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>
更新: 关于此方法需要注意的一件事是,每当按下鼠标时,都必须重新绘制整个场景(白色背景、图像(如果适用)和前景)。这样做的原因是抗锯齿和透明度。当您在 graphics
缓冲区上绘制椭圆时,由于抗锯齿,边缘将具有一些部分透明的像素。如果您重复绘制缓冲区作为覆盖层而不重新绘制其后面的内容,那么部分透明的像素将变得越来越不透明,直到它们变成黑色。这将导致您的椭圆的外边缘稍粗且像素化程度更高。
方法 #2(椭圆位置数组)
let img;
let isShow = true
let positions = [];
function preload() {
img = loadImage(
"https://images.pexels.com/photos/20787/pexels-photo.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500"
);
}
function setup() {
createCanvas(500, 500);
background(255);
image(img, 0, 0);
}
function draw() {
if (mouseIsPressed) {
stroke(0, 0, 0, 50);
fill(255);
ellipse(mouseX, mouseY, 20);
positions.push([mouseX, mouseY]);
}
}
function keyPressed() {
isShow = !isShow;
background(255);
if (isShow) {
image(img, 0, 0);
}
stroke(0, 0, 0, 50);
fill(255);
for (const [x, y] of positions) {
ellipse(x, y, 20);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.min.js"></script>