#javascript #performance #canvas #p5.js
#javascript #Производительность #холст #p5.js
Вопрос:
Позвольте мне начать с того, что я не уверен, существует ли вообще решение, но было бы здорово, если бы я мог его найти.
Я делаю школьный проект по моделированию солнечной системы. Не было конкретного требования, чтобы вещи были даже отдаленно масштабируемыми, но, поскольку я немного более продвинутый, чем другие студенты (и немного космический энтузиаст) Я решил бросить вызов самому себе.
Мы обязаны использовать Processing.js или p5.js библиотеки для нашего графического рендеринга, и когда я попытался загрузить большой холст (ширина браузера x 13000 пикселей), это заняло значительное количество системных ресурсов и привело к падению частоты кадров примерно на 2-3 кадра в секунду.
Стоит отметить, что эта проблема НЕ возникает НИ на одной машине с дискретным графическим процессором, но поскольку этот проект предназначен для класса, я хотел бы оптимизировать его для запуска в любом браузере, даже на машинах с низким энергопотреблением.
Скриншот моей вкладки производительности Chrome dev tools
и рассматриваемый код:
let sun, mercury, venus, earth, mun, mars, ab1, ab2, ab3, jupiter, io, europa, ganymede, callisto, saturn, satRings, uranus, urRings, neptune, nepRings;
const mid = window.innerWidth/2;
const scale = 6000;
let stopper = 1;
let stuff = [];
function setup() {//all distance and diameter inputs are the real-world measurements in km
createCanvas(mid*2, 13000);
stuff.push(sun = new Sun(1392684, 'yellow', 'The Sun'));
stuff.push(mercury = new Planet(sun,57909000, 4880, 'brown', 88, 'Mercury', 0.2056));
stuff.push(venus = new Planet(sun,108160000, 12104, 'orange', 224, "Venus", 0.006772));
stuff.push(earth = new Planet(sun,149600000, 12756, 'blue', 365, 'Earth', 0.0167086));
stuff.push(mun = new Moon(earth, 385000, 3474, 'white', 30, 'The Moon', 0.05));
stuff.push(mars = new Planet(sun,227990000, 6792, 'red', 687, 'Mars', 0.0934));
stuff.push(ab1 = new Rings(sun,374000000, 299200000,374000000, 299200000, 'brown'));
stuff.push(ab2 = new Rings(sun, 418880000, 388960000, 418880000, 388960000, 'tan' ));
stuff.push(ab3 = new Rings(sun, 493680000, 448800000, 493680000, 448800000, 'lightgreen'));
stuff.push(jupiter = new Planet(sun,778360000, 142984, 'red', 4332, "Jupiter", 0.0489));
stuff.push(io = new Moon(jupiter, 421800, 3645, 'white', 1.77, "Io", 0.0041));
stuff.push(europa = new Moon(jupiter, 671100, 3121, 'white', 3.5, "Europa", 0.0094));
stuff.push(ganymede = new Moon(jupiter, 1070400, 5268, 'white', 7.15, "Ganymede", 0.0011));
stuff.push(callisto = new Moon(jupiter, 1882700, 4820, 'white', 16.69, "Callisto", 0.0074));
stuff.push(saturn = new Planet(sun,1433500000, 120536, 'yellow', 10759, 'Saturn', 0.0565));
stuff.push(satRings = new Rings(saturn, 180000*30, 66900*30, 480000*30, 74500*30, 255));
stuff.push(uranus = new Planet(sun, 2869000000, 50724, 'grey', 30685, "Uranus", 0.0461));
stuff.push(urRings = new Rings(uranus, 51170,51149,51249,51149 , 255));
stuff.push(neptune = new Planet(sun, 4497100000, 49244, 'grey', 60189, "Neptune", 0.01));
stuff.push(nepRings = new Rings(neptune, 62934,42900,62930,40900 , 255));
}
function mouseClicked() {
stopper === 1 ? stopper = 0 : stopper = 1;
console.log(stopper);
}
function draw() {
let pointer = window.innerHeight/2 window.scrollY;
let blurb = '';
console.log(pointer);
blurbSetter();
background(0);
stuff.forEach(thing => thing.show());
textSize(50);
fill(255);
text("Erik's Final", 20, 50);
textSize(18);
text("A scale model of our solar system. n 1 pixel = 10000km scale, n and orbital distances have been further divided by 60. n Orbital eccentricities are normalized along the vertical axis for viewability, n and orbital periods have been accelerated equally. n Click to pause at any time.", 20, 68);
text(Math.floor(pointer) *scale*60 " KM ----------- nn" blurb, 20, pointer - 20);
function blurbSetter(){
if(pointer <= 650){
blurb = 'The Inner Solar System: n Home to your favorite elevated primates, n the Inner Solar System harbors the 'Goldilocks Zone',n the area where the suns rays do not scorch the earth,n and also still keep us from freezing. nIt is the only area where carbon based life can flourish.';
}else if(pointer > 650 amp;amp; pointer < 1600){
blurb = 'The Asteroid Belts: n Home to the dwarf planet Ceres, nour Asteroid Belt is divided into three distinct bands. nBetween each band, the resonant frequency of Jupiter's nimmense gravity well has caused orbits to destabilize, nit's victims most often falling into the sun';
}else if(pointer > 1600 amp;amp; pointer < 3000){
blurb = 'Though only the 4 largest are represented here, nJupiter is home to more than 70 Moons!n These 4 were discovered by Galileo Galilei, nthe inventor of the modern refracting telescope, in 1609.';
}else if(pointer > 3000 amp;amp; pointer < 4800){
blurb = 'Saturn's rings are its most distinctive feature, nvisible from hundreds of millions of kilometers away. nHowever, they are less than 10 meters thick! nIf saturn was the size of a basketball, nits rings would be over 100 times nthinner than a single sheet of paper!';
}if(pointer > 4800 amp;amp; pointer < 7800){
blurb = 'You might think there isn't much out this far, nand for the most part you're right, but there is one major thing. nThe Solar Wind, a constant stream of radiation and particles nour sun is shedding, can still be felt out here. nNASA has even designed deep space probes that utilize nsolar sails instead of traditional engines, nriding the wind like the seafaring explorers of history.';
}
}
}
Любая помощь была бы признательна, но в худшем случае мне просто придется отказаться от своей идеи, что это будет масштабироваться.
Комментарии:
1. Элемент холста HTML5 имеет проблемы, когда он большой. Возможно ли для вас использовать что-то вроде github.com/zenozeng/p5.js-svg , что позволяет вам использовать svg, который лучше справляется с большими размерами?
2. Не лучше ли было бы просто иметь холст шириной с браузер и каким-то образом прокручивать содержимое холста, например, с помощью клавиш со стрелками или чего-то еще?
3. Пожалуйста, сообщите своему учителю, что Processing.js это больше не поддерживаемый проект, и я заархивировал его в начале декабря 2018 года. Новые проекты и назначения больше не должны ее использовать. Тем не менее, SVG — безусловно, лучшее решение здесь, которое может использовать преимущества встроенной в браузер системы рендеринга, основанной на простых
<g transform>
элементах. Использование холста будет ужасно медленным (если только это не холст webgl, но тогда вам придется иметь дело с камерами, и все становится намного сложнее, чем нужно)