БлогNot. Тысячеугольник или шаблон для canvas-программы

Тысячеугольник или шаблон для canvas-программы

В моём блоге за последнее время появилось немало примеров на такой популярный сейчас вид интернет-приложений, как canvas-эффекты на Javascript, например, это текучие частицы и летучие частицы, лопающиеся пузыри, жизнь частиц, снежинки, квадратичные фракталы и т.д.

В сущности, все эти приложения построены по одному и тому же шаблону.

А можно ли привести сам шаблон? :) Эта заметка как раз служит данной цели, потому что все действия прилагаемого листинга подробно закомментированы.

Так как просто отражать кругляшки-частицы от "стен" было бы скучно, сделаем в скрипте сознательную "ошибку", собственно, и создающую ту картину, которую вы видите.

В исходнике даже есть подсказка, что нужно изменить, чтобы получить просто вот такой скучный эффект:

просто движущиеся частицы, скриншот одного кадра анимации
просто движущиеся частицы, скриншот одного кадра анимации

У нас же будет целая "колыхающаяся пелена":

а вот наше приложение, скриншот одного кадра анимации
а вот наше приложение, скриншот одного кадра анимации

А вы сумеете найти нужные строчки и объяснить, почему совсем небольшая коррекция кода так сильно изменяет наблюдаемую картину? :)

Ниже прилагается ссылка на приложение в работе и его листинг на момент написания (который можно сохранить как файл типа .html в кодировке Юникода UTF-8).

 SimpleParticles.html, открыть приложение в текущем окне (вкладке) (4 Кб)

<!DOCTYPE html>
<html lang="ru-RU">
<head>
 <meta charset="utf-8">
 <title>1000-угольник</title>
 <style>
  .canvasbox {
   display: block; 
   text-align: center;
   margin: 0; padding: 0; border: 0;
  }
  .canvasfield {
  }
 </style>
</head>
<body>

<div id="canvasbox">
 <canvas id="canvasfield"></canvas>
</div>

<script>
 var canvas = document.getElementById("canvasfield"); //получить элемент канвы
 var ctx = canvas.getContext("2d"); //...и контекст рисования из него
 canvas.width = window.innerWidth; //установить ширину и высоту канвы во весь экран
 canvas.height = window.innerHeight;

 var vertices = []; //Массив вершин
 var num_vertices = 1000;//Количество вершин
 var Color = GetRandomColor(); //Цвет
 var cnt = 0; //Счётчик шагов отрисовки

 function GetRandomColor() { //выбор случайного цвета с интенсивностями компонент не выше limit
  var r, g, b, limit = 200;
  r = Math.floor (Math.random() * limit);
  g = Math.floor (Math.random() * limit);
  b = Math.floor (Math.random() * limit);
  return 'rgb(' + r + ',' + g + ','  + b + ')';
 }

 var Vertex = function () { //Задать свойства вершины, опишем для этого объект Vertex
  this.x = canvas.width * Math.random(); //Координаты
  this.y = canvas.height * Math.random();
  this.vx = -15 + 30 * Math.round(Math.random()); //Скорость [-15;15]
  this.vy = -15 + 30 * Math.round(Math.random());
 }

 Vertex.prototype.Draw = function (ctx) { //добавить к объекту Vertex метод отрисовки на канве ctx
  //?
  ctx.arc (this.x, this.y, 3, 0, 2*Math.PI, true); //рисуем вершину как кружок радиусом 3 пикселя
  //?
 }

 Vertex.prototype.Update = function () { //добавить к объекту Vertex метод обновления свойств вершины
  this.x += this.vx; //меняем положение вершины в зависимости от её скорости
  this.y += this.vy;
  if (this.x<0 || this.x > canvas.width) this.vx = -this.vx; //отражать от стенок
  if (this.y < 0 || this.y > canvas.height) this.vy = -this.vy;
 }

 function loop() { //главный игровой цикл
  ctx.clearRect(0, 0, canvas.width, canvas.height); //очистить канву
  ctx.fillStyle = Color; //установить цвет
  ctx.beginPath(); //?
  for (var i = 0; i < num_vertices; i++) { //Перебрать в цикле все вершины
   vertices[i].Update(); //Обновить очередную вершину
   vertices[i].Draw(ctx); //...и отрисовать её
  }
  ctx.fill(); //?
  cnt++; //Увеличить счётчик шагов
  if (cnt%100==0) Color = GetRandomColor(); //Раз в 100 шагов меняем цвет :)
  requestAnimationFrame(loop); //организовать повторное выполнение функции loop
 }

 window.addEventListener('load', function () { //На загрузку страницы
  for (var i = 0; i < num_vertices; i++) vertices.push(new Vertex()); //Создать вершины
  loop(); //и начать игровой цикл 
 }, false); //false - юзер не желает создать захват

 window.addEventListener('resize', function () { //На изменение размеров окна
  canvas.width = window.innerWidth; //установить ширину и высоту канвы во весь экран
  canvas.height = window.innerHeight;
 });
</script>
<noscript><div align="center">Извините, нужен Javascript для работы приложения</div></noscript>

</body></html>

Замечания:

window.innerWidth и window.innerHeight - это не совсем клиентская часть окна браузера, так что полосы прокрутки вполне могут появляться. Как вариант, можно использовать постоянный размер канвы заданный атрибутами width и height тега <canvas> или убрать полосы прокрутки через CSS, как сделано в следующей статье.

06.02.2019, 12:54 [2612 просмотров]


теги: программирование javascript графика

К этой статье пока нет комментариев, Ваш будет первым