Olá pessoal, tudo certo?!
No post de hoje, mostro uma variação do fractal “tree” que apresentei há alguns dias. Basicamente, adicionei alguma “aleatoriedade” e cor. Veja alguns resultados:
Bacana, não?! Outro exemplo:
Mais um …
Último:
Agora, vamos ver como é o código.
Aliás, o código-fonte está em https://gist.github.com/1323773 e há um live demo em http://users.cjb.net/livedemoelemarjr/amazingtrees.htm
CanvasAdapter
Mais uma vez, construo uma classe para “interfacear” com o elemento Canvas. Observe:
function CanvasAdapter(canvas, context) {
this.canvas = canvas;
this.context = context;
this.canvasWidth = canvas.width;
this.canvasHeight = canvas.height;
this.clear = function () {
this.context.clearRect(0, 0,
this.canvasWidth,
this.canvasHeight
);
};
this.drawLine = function (x1, y1, x2, y2, pen) {
with (this.context) {
beginPath();
moveTo(x1, this.canvasHeight - y1);
lineTo(x2, this.canvasHeight - y2);
lineWidth = pen;
lineCap = "round";
stroke();
}
};
}
var canvas = $('#target');
var context = canvas.get(0).getContext('2d');
var ca = new CanvasAdapter(canvas, context);
Como pode ver, crio uma camada para as funções da api do elemento canvas. Assim, penso eu, acabo “isolando” a complexidade acidental.
Perceba, no código acima, que crio imediatamente uma instância dessa classe. Esse objeto é atualizado, constantemente, no “handler” do evento resize (que venho usando há algum tempo nos meus exemplos). Observe:
function resizeCanvas() {
canvas.attr("width", $(window).get(0).innerWidth);
canvas.attr("height", $(window).get(0).innerHeight);
ca.canvasWidth = canvas.width();
ca.canvasHeight = canvas.height();
ca.clear();
drawTree(12, ca.canvasWidth / 2, 10, ca.canvasHeight / 8, Math.PI / 2, 12);
};
$(window).resize(resizeCanvas);
resizeCanvas();
canvas.click(function () {
ca.clear();
drawTree(12, ca.canvasWidth / 2, 10, ca.canvasHeight / 8, Math.PI / 2, 12);
});
São apenas dois eventos mapeados. Um para o resize, outro para o clique. Em ambos, chamo a rotina que efetiva o desenho.
Vamos explicar o método drawTree?!
O método drawTree
Como desenho a árvore?! Simples. Observe:
var drawTree = function (depth, x, y, length, theta, branchWidth) {
if (depth < 0) return;
var rand = Math.random;
var maxAngle = Math.PI / 2;
var x2 = x + length * Math.cos(theta);
var y2 = y + length * Math.sin(theta);
ca.context.strokeStyle = (depth <= 2) ?
'rgb(0,' + parseInt(rand() * 64 + 128) + ',0)' :
'rgb(' + parseInt(rand() * 64 + 64) + ',50,25)';
ca.drawLine(x, y, x2, y2, branchWidth);
var subBranches = rand() * 2 + 1;
for (var i = 0; i < subBranches; i++) {
drawTree(
depth - 1,
x2, y2,
length * (0.7 + rand() * 0.3),
theta + rand() * maxAngle - 0.5 * maxAngle,
branchWidth * 0.7
);
}
};
Como você pode perceber, o método é muito parecido com aquele que mostrei no post explicando o fractal tree. As diferenças:
- Utilizo tons de verde nas pontas (final da recursão), e marrom nos demais níveis;
- Os galhos iniciais são mais “espessos”;
- Em cada nível, o número de galhos varia entre 1 e 3;
- o redução do comprimento dos “galhos”, em cada nível, está entre 0% a 30%;
- o ângulo de “abertura” dos galhos filhos é variável (nunca maior que 90 graus).
Bacana.
Era isso;
![]()



Publicado em 28/10/2011
0