Фрактали, эти загадочные фигуры, которые есть везде, но не могут быть видны нетренированным глазом.Сегодня мы нарисуем один из самых известных Фрактали, используя только Ваниллу JS и API HTML5 Canvas. Чему вы научитесь Что такое фрактальное дерево? Написание фрактального дерева в ваниле JS За пределами фрактального дерева Что такое фрактальное дерево? Чтобы определить фрактальное дерево, в первую очередь, мы должны знать определение фрактального, конечно. Фрактали - это бесконечные модели, созданные повторяющимися математическими уравнениями, которые на любой шкале, на любом уровне увеличения выглядят примерно одинаково. Таким образом, если мы разделим фракталь, мы увидим уменьшенную копию целого. Бенуа Мандельброт, который придумал термин «фрактал» в 1975 году, сказал: Фрактал - это форма, состоящая из частей, похожих на целое в некотором роде. Фрактал - это форма, состоящая из частей, похожих на целое в некотором роде. Довольно ясно, не так ли? Вот некоторые примеры: Что такое фрактальное дерево? Представьте себе ветвь и ветви, выходящие из нее, а затем две ветви, выходящие из каждой ветви, и так далее... так выглядит фрактальное дерево. Его форма происходит от треугольника Sierpinski (или Sierpinski gasket). Как видите, один становится другим при изменении угла между ветвями: Сегодня мы закончим с фигурой, похожей на окончательную форму этого GIF. Написание фрактального дерева в ваниле JS Прежде всего, вот конечный продукт (вы можете настроить его по дороге): Теперь рассмотрим это, шаг за шагом. Прежде всего, мы инициализируем наш файл index.html с полотенцем любых разумных размеров и тегом скрипта, где будет находиться весь наш JS-код. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script></script> </body> </html> Затем мы начинаем писать наш JavaScript. Мы инициализируем наш элемент пленки на JS, получая доступ к нему через переменную myCanvas и создавая 2D-контекст рендеринга с переменной ctx (контекст). <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); </script> </body> </html> Так что да, метод getContext добавляет свойства и методы, которые позволяют рисовать, в данном случае, в 2D. Как мы можем определить алгоритм для рисования фрактального дерева? Давайте посмотрим, мы знаем, что ветви становятся все меньше, и что каждая ветвь заканчивается двумя ветвями, выходящими из нее, одной слева, другой справа. Другими словами, когда ветвь достаточно длинная, прикрепите к ней две более мелкие ветви. Кажется, что мы должны где-то использовать рекурсивное заявление, не так ли? Вернувшись к коду, мы теперь определяем нашу функцию Для этого должны быть использованы как минимум четыре аргумента: координаты X и Y, где начинается ветвь, длина ее ветви и ее угол. fractalTree Внутри нашей функции мы начинаем чертеж с метода beginPath() , а затем сохраняем состояние полотна с методом save() . <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle) { ctx.beginPath(); ctx.save(); } </script> </body> </html> Метод beginPath часто используется, когда вы начинаете новую строку или фигуру, которая имеет фиксированный стиль, например, один и тот же цвет вдоль всей строки или одинаковой ширины. Теперь мы нарисуем наше фрактальное дерево, нарисуя линию (отрасль), поворачивая полотно, нарисуя следующую ветвь и так далее. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle) { ctx.beginPath(); ctx.save(); ctx.translate(startX, startY); ctx.rotate(angle * Math.PI/180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); if(len < 10) { ctx.restore(); return; } draw(0, -len, len*0.8, -15); draw(0, -len, len*0.8, +15); ctx.restore(); } draw(400, 600, 120, 0) </script> </body> </html> Так что мы сначала добавляем три метода, переводим, вращаемся и перемещаем к, которые «перемещают» полотно, его происхождение и наш «оловник», чтобы мы могли нарисовать ветвь под нужным углом. Последние два метода перед высказыванием if являются lineTo и stroke; первый добавляет прямую линию к текущему пути, а второй делает его. Теперь у нас есть высказывание если, которое говорит, когда прекратить рекурсию, когда прекратить рисование. , «восстанавливает последнее сохраненное состояние пленки, отображая верхнюю запись в стеке состояния рисования». MDN Docs После заявления if у нас есть рекурсивный звонок и еще один звонок к методу восстановления, а затем звонок к функции, которую мы только что закончили. Теперь запустить код в своем браузере. Вы увидите, наконец, фрактальное дерево! Удивительно, не правда ли?Давайте сделаем это еще лучше. Мы добавим новый параметр к нашей функции рисования, BranchWidth, чтобы сделать наше фрактальное дерево более реалистичным. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle, branchWidth) { ctx.lineWidth = branchWidth; ctx.beginPath(); ctx.save(); ctx.translate(startX, startY); ctx.rotate(angle * Math.PI/180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); if(len < 10) { ctx.restore(); return; } draw(0, -len, len*0.8, angle-15, branchWidth*0.8); draw(0, -len, len*0.8, angle+15, branchWidth*0.8); ctx.restore(); } draw(400, 600, 120, 0, 10) </script> </body> </html> Так что в каждой итерации мы делаем каждую ветвь тоньше.Я также изменил параметр угла в рекурсивном вызове, чтобы сделать более «открытое» дерево. Теперь давайте добавим немного цвета! и тени, почему бы и нет. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle, branchWidth) { ctx.lineWidth = branchWidth; ctx.beginPath(); ctx.save(); ctx.strokeStyle = "green"; ctx.fillStyle = "green"; ctx.translate(startX, startY); ctx.rotate(angle * Math.PI/180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); ctx.shadowBlur = 15; ctx.shadowColor = "rgba(0,0,0,0.8)"; if(len < 10) { ctx.restore(); return; } draw(0, -len, len*0.8, angle-15, branchWidth*0.8); draw(0, -len, len*0.8, angle+15, branchWidth*0.8); ctx.restore(); } draw(400, 600, 120, 0, 10) </script> </body> </html> Оба метода цвета самообъясняются (strokeStyle и fillStyle). также тени, shadowBlur и shadowColor. Сохраните файл и откройте его с помощью браузера, чтобы увидеть конечный продукт. Теперь я призываю вас играть с кодом! изменить теньColor, fillStyle, сделать более короткий или более длинный Фрактальное дерево, изменить угол, или попытаться добавить листья, что должно быть сложно 😉 За пределами фрактального дерева Как я показал вам в начале этого сообщения, есть разные фрактали. Ain't gonna быть легким, чтобы сделать все те с Canvas API, но это должно быть возможно. я сделал некоторые из них на языке программирования C, и я также играл вокруг с p5.js. p5.js - это библиотека JavaScript с открытым исходным кодом, созданная художниками, для художников, на основе Вы можете нарисовать или анимировать что угодно.Если вы заинтересованы в создании искусства с помощью кода, это обязательно. Страница, которую вы можете проверить . Обработка языка стартовал здесь Спасибо, что читаете, комментируете любые вопросы, и увидимся в моем следующем посте! Обложка от socialtrendspr0 от Pixabay Обложка от socialtrendspr0 от Pixabay