Сегодня я прочитал пост пользователя celen и вдохновился красотой T-фракталов. Так как я немного увлекаюсь созданием растровых композиций в JavaScript Canvas, то у меня возникла идея реализовать то же самое, только на стороне клиента силами JS, освобождая сервер от нагрузки.
В теле HTML-документа необходимо создать тег <canvas>
:
<canvas id="canvas"></canvas>
Он достаточно своеобразен: по-умолчанию имеет размер 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
по-идее можно заменить на ИЛИ.
демонстрация / скачать HTML-страницу и JS-код архивом
Поитерационная отрисовка изображения (слева направо и сверху вниз):
Стоит уделить немного внимания возможности сохранить изображение с <canvas>
в PNG силами javascript:
window.open(document.getElementById("canvas").toDataURL("image/png"),"tfract_save");
Недостатком такого способа является ограничение длины строки адреса.
Вот и всё. Остальной код — банальная обработка форм и контролов.
Автор: nikpro