Тысячеугольник или шаблон для 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 [2750 просмотров]