Т-фракталы на JavaScript Canvas

t-fractal-1

На днях я прочитал пост пользователя celen и вдохновился красотой T-фракталов. Так как я немного увлекаюсь созданием растровых композиций в JavaScript Canvas, то у меня возникла идея реализовать то же самое, только на стороне клиента силами JS, освобождая сервер от нагрузки.

Он достаточно своеобразен: по-умолчанию имеет размер 300х150. Новые размеры ему лучше задавать из javascript.

var canva = document.getElementById(‘canvas’);
canva.width = window.innerWidth;
canva.height = window.innerHeight;
var ctx = canva.getContext(‘2d’);

Теперь определим несколько вспомогательных функций.

function clear() {
ctx.clearRect(0, 0, canva.width, canva.height);
ctx.fillStyle = ‘rgba(0,0,0,1)’;
ctx.fillRect(0, 0, canva.width, canva.height);
}

Функция clear() очищает всю рабочую область. Зачем там сразу clearRect и полная заливка fillRect? А чтоб наверняка.
Следующая функция отвечает за вывод одиночного узора заданного размера в указанном месте. Сам узор описан с помощью двумерного массива figure размером NxN, элементы которого принимают значения 0 и 1 (0 — прозрачный блок, 1 — цветной блок).

function PrintFigure(x, y, size, style) {
var sizeElem = Math.floor(size / N);
for (var i = 0; i < N; i++) for (var k = 0; k < N; k++) if (figure[i][k] == 1) { ctx.fillStyle = style; ctx.fillRect(x + i * sizeElem, y + k * sizeElem, sizeElem, sizeElem); } }

При просчете координат и размеров нужно быть внимательным и усекать потенциально-нецелые числа.
Границами рисования у нас будут границы канвы.

var MAX_X = canva.width,
MAX_Y = canva.height;

За них придется немного выходить, чтобы получить ровное сплошное изображение.
И, наконец, функция, которая рисует узор в заданной области, до тех пор, пока он в нее [область] помещается.

function CreateTFractal() {
clear();
var size = N;
var countByX = Math.floor(MAX_X / size),
countByY = Math.floor(MAX_Y / size);

while ((countByX > 0) && (countByY > 0)) { // пока рисунок помещается в область
for (var i = 0; i <= countByX; i++) { for (var k = 0; k <= countByY; k++) { PrintFigure(i * size, k * size, size, 'rgba(255, 255, 255, 0.3)'); } // k } // i size *= 2; // новый размер для следующей итерации countByX = Math.floor(MAX_X / size), countByY = Math.floor(MAX_Y / size); } }

Условие И в цикле while по-идее можно заменить на ИЛИ.

Стоит уделить немного внимания возможности сохранить изображение с < canvas > в PNG силами javascript:

window.open(document.getElementById(«canvas»).toDataURL(«image/png»),»tfract_save»);

Недостатком такого способа является ограничение длины строки адреса.
Вот и всё. Остальной код — банальная обработка форм и контролов.

Читайте так же:
Оставить комментарий

Последние публикации