如何在 p5js 中的绘制循环之外执行任务
How to do a task outside of draw loop in p5js
我正在尝试将图像转换为在 p5.js 中只有一定数量颜色的图片。我通过选择 num
随机颜色来做到这一点。然后,我用 loadPixels()
遍历图像中的每个像素并给它打分。该分数取决于颜色与其中一种随机颜色的接近程度。我通过从 rgb 值中单独添加差异然后选择最低分数来做到这一点。例如,如果我有 num = [color(100, 100, 100), color(200, 200, 200)]
并且我正在查看具有 color(100, 150, 110)
的像素,那么分数将不是 240(图像像素与 200 颜色之间的差异)而是 60。这一切工作正常。接下来,我要做的是确保每个像素的分数都低于 scoreBoundary
。最初,此变量设置为 0。如果像素的分数大于 scoreBoundary
,我会更改最接近的随机颜色,使像素的分数低于 scoreBoundary
。这一切都应该工作正常。循环几次后(我还没有决定多少,可能和平均像素分数有关什么的),如果还有一个像素超过scoreBoundary
,我增加scoreBoundary
。最终,我应该拥有 num
种颜色的最佳照片。 (如果你想知道,我正在尝试制作一种十字绣克隆。)
现在解决我的问题。我想做一个临时的进度条,因为这个方法很慢。最初,我尝试放置 pixelNum + " out of " + pixels.length
的文字。但是,由于此过程处于 for 循环中,因此没有显示出来。所以,我试着把这个过程放在绘制循环中。现在文本出现了,但速度慢得令人难以忍受。大约一分钟后,我可能完成了第一个循环的 1%(记住,会有数千次),因为它每帧只执行一次计算。现在我问你两件事,两种解决方案都有帮助。
第一,有没有办法让一个进程在远离绘制循环的情况下尽可能快地工作?例如,我是否可以每帧多次执行此过程 运行(不只是添加 i < previousBoundary * howMuchFasterIWantItToBe
),同时仍被链接以绘制进度条?
第二,还有其他方法可以解决这个问题吗?将图像中的颜色数量减少到 num
?
的另一个库或方法
您没有真正显示任何可重现的代码来解释您遇到的问题。
无论如何,您正在寻找的(第一个问题)是一个异步函数。
光敏性惊厥警告
Seriously, this example sketch will wreck your eyes 但由于异步功能,您可以看到两个椭圆在不同的时间表上工作
重要的是,我必须在草图的开头附加 /*jshint esversion: 9 */
以便编辑器允许使用异步:
/*jshint esversion: 9 */
let thing = 10;
let thing2 = 10;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
drawOther();
for(let i = 0; i < 1000; i++){
if(thing <= 400){
thing += 2;
}else{
thing = 10;
}
fill(255)
stroke(0);
ellipse(width, height, thing, thing);
}
}
const drawOther = async () => {
for(let i = 0; i < 100; i++){
if(thing2 <= 400){
thing2 += 2;
}else{
thing2 = 10;
}
fill(0);
stroke(255)
ellipse(0, 0, thing2, thing2);
}
}
You can read more about async functions here 但基本上,它会做你想做的事——启动一个单独的 activity 线程,它不会阻塞你的主循环。
如果您想 return 来自异步函数的任何内容,您还需要阅读 await
和 promises
。
我正在尝试将图像转换为在 p5.js 中只有一定数量颜色的图片。我通过选择 num
随机颜色来做到这一点。然后,我用 loadPixels()
遍历图像中的每个像素并给它打分。该分数取决于颜色与其中一种随机颜色的接近程度。我通过从 rgb 值中单独添加差异然后选择最低分数来做到这一点。例如,如果我有 num = [color(100, 100, 100), color(200, 200, 200)]
并且我正在查看具有 color(100, 150, 110)
的像素,那么分数将不是 240(图像像素与 200 颜色之间的差异)而是 60。这一切工作正常。接下来,我要做的是确保每个像素的分数都低于 scoreBoundary
。最初,此变量设置为 0。如果像素的分数大于 scoreBoundary
,我会更改最接近的随机颜色,使像素的分数低于 scoreBoundary
。这一切都应该工作正常。循环几次后(我还没有决定多少,可能和平均像素分数有关什么的),如果还有一个像素超过scoreBoundary
,我增加scoreBoundary
。最终,我应该拥有 num
种颜色的最佳照片。 (如果你想知道,我正在尝试制作一种十字绣克隆。)
现在解决我的问题。我想做一个临时的进度条,因为这个方法很慢。最初,我尝试放置 pixelNum + " out of " + pixels.length
的文字。但是,由于此过程处于 for 循环中,因此没有显示出来。所以,我试着把这个过程放在绘制循环中。现在文本出现了,但速度慢得令人难以忍受。大约一分钟后,我可能完成了第一个循环的 1%(记住,会有数千次),因为它每帧只执行一次计算。现在我问你两件事,两种解决方案都有帮助。
第一,有没有办法让一个进程在远离绘制循环的情况下尽可能快地工作?例如,我是否可以每帧多次执行此过程 运行(不只是添加 i < previousBoundary * howMuchFasterIWantItToBe
),同时仍被链接以绘制进度条?
第二,还有其他方法可以解决这个问题吗?将图像中的颜色数量减少到 num
?
您没有真正显示任何可重现的代码来解释您遇到的问题。
无论如何,您正在寻找的(第一个问题)是一个异步函数。
光敏性惊厥警告 Seriously, this example sketch will wreck your eyes 但由于异步功能,您可以看到两个椭圆在不同的时间表上工作
重要的是,我必须在草图的开头附加 /*jshint esversion: 9 */
以便编辑器允许使用异步:
/*jshint esversion: 9 */
let thing = 10;
let thing2 = 10;
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
drawOther();
for(let i = 0; i < 1000; i++){
if(thing <= 400){
thing += 2;
}else{
thing = 10;
}
fill(255)
stroke(0);
ellipse(width, height, thing, thing);
}
}
const drawOther = async () => {
for(let i = 0; i < 100; i++){
if(thing2 <= 400){
thing2 += 2;
}else{
thing2 = 10;
}
fill(0);
stroke(255)
ellipse(0, 0, thing2, thing2);
}
}
You can read more about async functions here 但基本上,它会做你想做的事——启动一个单独的 activity 线程,它不会阻塞你的主循环。
如果您想 return 来自异步函数的任何内容,您还需要阅读 await
和 promises
。