我有一个网页,里面有一些草图,都是用P5.JS写的
每个草图都使用自己的名称空间,这样它就可以独立地运行。
我注意到,对于每一个草图,性能水平都比我在单独的网页中单独运行时得到的要低。
我的问题是:我能做些什么来阻止所有的草图同时运行?例如,只有当鼠标悬停在画布上时,才能激活草图吗?它可能会腾出资源。
谢谢你的帮助。
发布于 2021-08-23 08:29:41
您可以调用noLoop()和loop()来停止并重新启动草图。没有任何内置的p5.js事件可以帮助您在鼠标离开草图或草图在屏幕外滚动时触发noLoop(),但是有几种方法可以依赖于使用底层浏览器功能:
构建在events
mouseleave中的winMouseX和winMouseY在每个对draw()的调用中根据草图画布getBoundingClientRect()构建
function makeSketch(...colorArgs) {
return (p) => {
let bgColor;
let black;
let c;
p.setup = () => {
c = p.createCanvas(p.windowWidth, p.windowHeight / 3);
bgColor = p.color(...colorArgs);
black = p.color(0);
c.elt.addEventListener('mouseenter', () => {
p.loop();
});
c.elt.addEventListener('mouseleave', () => {
p.noLoop();
});
let bounds = c.elt.getBoundingClientRect();
// Just in case the mouse is already over the canvas when it is created.
// This is also how you would use getBoundingClientRect from the draw()
// and mouseMoved() functions instead of the mouseenter/mouseleave events.
if (p.winMouseX < bounds.left ||
p.winMouseX > bounds.right ||
p.minMouseY < bounds.top ||
p.winMouseY > bounds.bottom) {
p.noLoop();
}
};
p.draw = () => {
p.background(p.lerpColor(
bgColor,
black,
p.abs((p.frameCount % 240 - 120) / 120)
));
let bounds = c.elt.getBoundingClientRect();
p.fill('white');
p.noStroke();
p.text(`${p.winMouseX}, ${p.winMouseY} :: ${bounds.left}, ${bounds.top}, ${bounds.right}, ${bounds.bottom}`, 10, 10);
}
};
}
let sketch1 = new p5(makeSketch('red'));
let sketch2 = new p5(makeSketch(0, 255, 0));
let sketch3 = new p5(makeSketch('blue'));<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
您可能还会发现,暂停屏幕外的草图就足够了:
function makeSketch(...colorArgs) {
return (p) => {
let bgColor;
let black;
let c;
let isLooping;
p.setup = () => {
c = p.createCanvas(p.windowWidth, p.windowHeight);
bgColor = p.color(...colorArgs);
black = p.color(0);
let bounds = c.elt.getBoundingClientRect();
isLooping = true;
if (bounds.bottom < 0 ||
bounds.top > p.windowHeight) {
p.noLoop();
isLooping = false;
}
// Might need to check this on resize as well.
document.addEventListener('scroll', () => {
let bounds = c.elt.getBoundingClientRect();
// Note this only checks verticle scrolling, but you could check horizontal as well
if (bounds.bottom > 0 &&
bounds.top <= p.windowHeight) {
if (!isLooping) {
isLooping = true;
console.log(`sketch ${colorArgs.join(',')}: loop`);
p.loop();
}
} else if (isLooping) {
isLooping = false;
console.log(`sketch ${colorArgs.join(',')}: noLoop`);
p.noLoop();
}
});
};
p.draw = () => {
p.background(p.lerpColor(
bgColor,
black,
p.abs((p.frameCount % 240 - 120) / 120)
));
p.fill('white');
p.noStroke();
p.text(`${p.frameCount}`, 10, 10);
}
};
}
let sketch1 = new p5(makeSketch('red'));
let sketch2 = new p5(makeSketch(0, 255, 0));
let sketch3 = new p5(makeSketch('blue'));<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
https://stackoverflow.com/questions/68875645
复制相似问题