Рисуем деревья с листьями на Javascript
Я за свою жизнь посадил, наверное, целый лес, скажем, на "трудовых практиках" в сельской школе. С годами мои деревья стали, в основном, виртуальными, но такие палки, как по этой ссылке, вдохновляют мало, давайте сделаем лучше небольшую рощицу.
вид приложения "Деревья" в работе (скриншот)
Открыв приложение, можно выбрать настройки из списков и перерисовать картинку или нажать "Сохранить", чтобы вывести в новую вкладку понравившуюся картинку (а оттуда сохраните её средствами браузера, например, нажав комбинацию клавиш (см. замечание в конце). Ниже - ссылка и исходники.Ctrl+S
)
Выполнить приложение "Деревья" онлайн, новое окно/вкладка
Исходники приведены на момент написания, онлайн-версия может чем-то отличаться. Предполагается, что оба файла сохранены в кодировке Юникода UTF-8.
Файл index.html
<!DOCTYPE html> <html lang="ru-RU"> <head> <meta charset="utf-8"> <style> #redrawItem { text-decoration: underline; cursor: pointer; } #canvas { border: 1px dotted #c0c0c0; } </style> <title>Trees</title> </head> <body> <div align="center" id="canvasContainer"> <canvas id="canvas"></canvas> </div> <div align="center" id="formContainer"> <form> <p> <span id="redrawItem">Перерисовать</span> <label class="description" for="spread">Разрастание:</label> <select id="spread" name="spread"> <option value="0.3">Сильное</option> <option value="0.6" selected>Среднее</option> <option value="0.9">Слабое</option> </select> <label for="leaveType">Листья:</label> <select id="leaveType"> <option value="50">Маленькие</option> <option value="250" selected>Обычные</option> <option value="650">Большие</option> <option value="1000">Узкие</option> </select> <label for="treeCnt">Деревьев:</label> <select id="treeCnt"> <option value="1">Одно</option> <option value="2">Два</option> <option value="3" selected>Три</option> <option value="4">Четыре</option> <option value="5">Пять</option> </select> </p> </form> </div> <script type="text/javascript" src="treelib.js"></script> <script type="text/javascript"> var width = 800; var height = 400; var intervalId = 0; function init() { var canvas = document.getElementById('canvas'); if (canvas.getContext('2d')) { document.getElementById('redrawItem').onclick = function() { drawTree(); } canvas.width = width; canvas.height = height; ctx = canvas.getContext('2d'); drawTree(); } else { document.getElementById('canvasContainer').innerHTML = 'Извините, Ваш браузер не поддерживает тег canvas'; } }; function drawTree() { var treeSpread = document.getElementById('spread').value; var leaveType = parseInt(document.getElementById('leaveType').value); var treeCnt = parseInt(document.getElementById('treeCnt').value); ctx.save(); tree.draw(ctx,height,width,treeSpread,leaveType,treeCnt); ctx.restore(); } init(); </script> <noscript><div align="center">Извините, нужен Javascript для работы приложения</div></noscript> </body> </html>
Файл treelib.js (из той же папки)
var tree = { canvas: '', ctx: '', width: 0, height: 0, spread: 0.6, //степень разрастания листьев, ]0,1[ leavesColor: '', leaveType: 250, //ширина прямоугольников-листьев MAX_BRANCH_DEPTH: 12, //макс."глубина" ветви (уровень рекурсии) MAX_BRANCH_WIDTH: 16, //макс.ширина ветви (пикселы) BRANCH_ROTATE_COEFF: 0.125, //коэффициент для поворота ветвей, ]0,1[ draw : function(ctx, h, w, spread, leaveType, treeCnt) { //рисуем дерево this.ctx = ctx; this.width = w; this.height = h; this.spread = spread; this.leaveType = leaveType; this.ctx.clearRect (0,0,this.width,this.height); for (var cnt = 1; cnt <= treeCnt; cnt++) { this.ctx.save(); this.ctx.translate (this.width/(treeCnt+1)*cnt,this.height); this.leavesColor = '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6); this.ctx.lineWidth = 1 + Math.round (Math.random() * this.MAX_BRANCH_WIDTH); this.ctx.lineJoin = 'round'; this.branch (0); this.ctx.restore(); } }, branch : function(depth) { //рисование ветки if (depth < this.MAX_BRANCH_DEPTH) { //В этйо ветке баловаться с числами аккуратней, красота - вещь хрупкая this.ctx.beginPath(); this.ctx.moveTo (0,0); this.ctx.lineTo (0, -(this.height)/10); this.ctx.stroke (); this.ctx.translate (0,-this.height/10); var rand01 = - (Math.random() * this.BRANCH_ROTATE_COEFF) + this.BRANCH_ROTATE_COEFF; this.ctx.rotate (rand01); //поворот if (Math.random() < this.spread) { //вероятность выпустить ветку //Ветки слева: this.ctx.rotate (-0.35); this.ctx.scale (0.69,0.69); this.ctx.save(); this.branch (depth+1); //Ветки справа: this.ctx.restore(); this.ctx.rotate (0.5); this.ctx.save(); this.branch (depth + 1); this.ctx.restore(); } else this.branch(depth); } else { //листья var lengthFactor = 100; if (this.leaveType === 1000) lengthFactor = 10; //если "узкие" листья this.ctx.fillStyle = this.leavesColor; this.ctx.fillRect(0, 0, this.leaveType, lengthFactor); this.ctx.stroke(); } } };
В IE младше 11 версии скрипт может и не работать вообще, а говнобраузер Chrome может блокировать всплывающие окна, и, соответственно, ссылку "Сохранить". Возможно, поможет добавление моего сайта в "Доверенные", или как там у них это называется. В "Огнелисе" всё работает :)
Зато девушки могут также погадать по деревцам, получающимся при первом открытии документа.
Если Ваши деревца сцепились кронами, быть Вам удачливой в любви.
А если деревце выросло выше верхнего края канвы, то богатой быть.
Ну, если толстое, значит, муж будет толстым... и т.д. 100500 раз.
P.S. Убрана функция "Сохранить" с кодом вида
<span id="saveItem">Сохранить</span> //... document.getElementById('saveItem').onclick = function() { window.open ( canvas.toDataURL ('image/png'), '_blank'); }
вот из-за этого.
Для сохранения картинки в современных браузерах достаточно нажать правую кнопку мыши на канве и выбрать пункт меню "Сохранить картинку как..."
Зато стало работать и в Internet Explorer, по крайней мере, в 11-м :)
14.02.2019, 18:38 [2298 просмотров]