Growing tree
How do I make an growing tree?
Growing and interactive fractal tree.. What is a growing tree? How do you make a growing tree? This script and codes were developed by Endre Simo on 28 November 2022, Monday.
Growing tree - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Growing tree</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="canvas_wrapper"> <canvas id="canvas"></canvas>
</div> <script src="js/index.js"></script>
</body>
</html>
Growing tree - Script Codes CSS Codes
body { margin: 0; padding: 0; overflow: hidden;
}
Growing tree - Script Codes JS Codes
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Canvas = function () { function Canvas(canvas, id) { var _this = this; _classCallCheck(this, Canvas); this.canvas = canvas; this.elem = document.getElementById(id); this.ctx = this.elem.getContext('2d'); this.dx = 0; this.dy = 0; this.cx = 0; this.cy = 0; this.lastX = 0; this.lastY = 0; this.elem.setAttribute('width', window.innerWidth); this.elem.setAttribute('height', window.innerHeight); this.width = this.elem.width; this.height = this.elem.height; this.elem.addEventListener('mousemove', function (e) { return _this.onMouseMove(e); }, false); window.addEventListener('resize', function (e) { return _this.onWindowResize(e); }, false); } Canvas.prototype.clear = function clear() { this.ctx.clearRect(0, 0, this.width, this.height); }; Canvas.prototype.getScrollX = function getScrollX() { return window.pageXOffset || window.document.documentElement.scrollLeft; }; Canvas.prototype.getScrollY = function getScrollY() { return window.pageYOffset || window.document.documentElement.scrollTop; }; Canvas.prototype.getPosition = function getPosition(event) { event.preventDefault(); this.dx = event.pageX - (this.getScrollX() + this.elem.getBoundingClientRect().left); this.dy = event.pageY - (this.getScrollY() + this.elem.getBoundingClientRect().top); this.lastX = event.pageX - (this.getScrollX() + this.elem.getBoundingClientRect().left) - this.cx; this.lastY = event.pageY - (this.getScrollY() + this.elem.getBoundingClientRect().top) - this.cy; return { x: this.lastX, y: this.lastY }; }; Canvas.prototype.getTouchPos = function getTouchPos(event) { event.preventDefault(); this.dx = event.changedTouches[0].pageX - (this.getScrollX() + this.elem.getBoundingClientRect().left) - this.lastX; this.dy = event.changedTouches[0].pageY - (this.getScrollY() + this.elem.getBoundingClientRect().top) - this.lastY; this.lastX = event.changedTouches[0].pageX - (this.getScrollX() + this.elem.getBoundingClientRect().left); this.lastY = event.changedTouches[0].pageY - (this.getScrollY() + this.elem.getBoundingClientRect().top); this.lastX = this.lastX > 0 ? this.lastX < this.elem.width ? this.lastX : this.elem.width : 0; this.lastY = this.lastY > 0 ? this.lastY < this.elem.height ? this.lastY : this.elem.height : 0; return { x: this.lastX, y: this.lastY }; }; Canvas.prototype.animate = function animate() { var _this2 = this; requestAnimationFrame(function () { return _this2.animate(); }); this.cx = this.cx - 0.8 * Math.cos(this.canvas.angle); this.cy = this.cy - 0.8 * Math.sin(this.canvas.angle); this.canvas.update({ x: this.cx, y: this.cy }); }; Canvas.prototype.onMouseMove = function onMouseMove(e) { this.cx = e.pageX - (this.getScrollX() + this.elem.getBoundingClientRect().left) - this.lastX; this.cy = e.pageY - (this.getScrollY() + this.elem.getBoundingClientRect().top) - this.lastY; this.canvas.update({ x: e.clientX - this.getPosition(e).x, y: e.clientY - this.getPosition(e).y }); }; Canvas.prototype.onWindowResize = function onWindowResize(e) { this.clear(); this.elem.setAttribute('width', window.innerWidth); this.elem.setAttribute('height', window.innerHeight); this.canvas.draw(); }; return Canvas;
}();
var FractalTree = function () { function FractalTree(canvas_id) { _classCallCheck(this, FractalTree); // initialize the tree. this.canvas = new Canvas(this, canvas_id); this.ctx = this.canvas.ctx; this.ctx.strokeStyle = 'black'; this.ctx.lineCap = 'round'; this.max_ratio = 1.6; this.min_ratio = 1.38; this.max_angle = Math.PI / 2; this.angle = Math.PI / 5; this.max_order = 12; this.max_color = 8; this.order_colors = Gradient("#e4d700", "#126845", this.max_color); this.start_length = this.canvas.height / 3; this.start_width = 30; // actually initialize the canvas this.draw(); this.canvas.animate(); } FractalTree.prototype.update = function update(pos) { this.canvas.clear(); this.updateAngle(pos); this.updateRatio(pos); this.draw(); }; FractalTree.prototype.updateAngle = function updateAngle(pos) { var x = -Math.abs(pos.x - this.canvas.width / 2), y = pos.y - (this.canvas.height - this.start_length); this.angle = Math.PI / 2 - Math.atan(y / x); }; FractalTree.prototype.updateRatio = function updateRatio(pos) { var x = pos.x - this.canvas.width / 2, y = pos.y - (this.canvas.height - this.start_length), d = Math.min(1, Math.sqrt(x * x + y * y) / (this.canvas.width / 2)); this.ratio = (this.max_ratio - this.min_ratio) * (1 - d) + this.min_ratio; }; FractalTree.prototype.draw = function draw() { // fill the canvas background, add opacity this.ctx.globalCompositeOperation = "lighter"; this.ctx.globalAlpha = 0.98; this.ctx.fillStyle = 'black'; this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.width); // draw the trunk of the tree. this.ctx.save(); this.ctx.translate(this.canvas.width / 2, this.canvas.height); //actually draw the trunk. this.ctx.strokeStyle = this.order_colors[0]; this.drawBranch(this.start_length, this.start_width); this.ctx.save(); this.ctx.translate(0, -this.start_length); this.drawBranches(1); this.ctx.restore(); this.ctx.restore(); }; FractalTree.prototype.drawBranch = function drawBranch(length, width) { this.ctx.lineWidth = !width || width < 1 ? 1 : width; this.ctx.beginPath(); this.ctx.moveTo(0, 0); this.ctx.lineTo(0, -length); this.ctx.stroke(); }; FractalTree.prototype.drawBranches = function drawBranches(order) { var ratio = Math.pow(this.ratio, order); var new_length = this.start_length / ratio; var new_width = this.start_width / ratio; if (new_length < 3 || order > this.max_order) { return; } this.ctx.strokeStyle = this.order_colors[Math.floor(order)]; //draw the right branch this.ctx.save(); this.ctx.rotate(this.angle); this.drawBranch(new_length, new_width); this.ctx.save(); this.ctx.translate(0, -new_length); this.drawBranches(order + 1); this.ctx.restore(); this.ctx.restore(); //draw the left branch this.ctx.save(); this.ctx.rotate(-this.angle); this.drawBranch(new_length, new_width); this.ctx.save(); this.ctx.translate(0, -new_length); this.drawBranches(order + 1); this.ctx.restore(); this.ctx.restore(); }; return FractalTree;
}();
function Gradient(stop1_hex, stop2_hex, num) { // stop1 and stop2 must be strings that rep hex color vals. stop1_hex = stop1_hex.replace("#", "").toUpperCase(); stop2_hex = stop2_hex.replace("#", "").toUpperCase(); var stops = new Array(num), stop1_rgb = { r: 0, g: 0, b: 0 }, stop2_rgb = { r: 0, g: 0, b: 0 }, steps = { r: 0, g: 0, b: 0 }, i, r, g, b; //parse the two input strings into rgb values stop1_rgb.r = parseInt(stop1_hex.substr(0, 2), 16); stop1_rgb.g = parseInt(stop1_hex.substr(2, 2), 16); stop1_rgb.b = parseInt(stop1_hex.substr(4, 2), 16); stop2_rgb.r = parseInt(stop2_hex.substr(0, 2), 16); stop2_rgb.g = parseInt(stop2_hex.substr(2, 2), 16); stop2_rgb.b = parseInt(stop2_hex.substr(4, 2), 16); steps.r = (stop2_rgb.r - stop1_rgb.r) / num; steps.g = (stop2_rgb.g - stop1_rgb.g) / num; steps.b = (stop2_rgb.b - stop1_rgb.b) / num; stops[0] = "#" + stop1_hex; for (i = 1; i < num - 1; i++) { r = Math.round(stop1_rgb.r + i * steps.r).toString(16); g = Math.round(stop1_rgb.g + i * steps.g).toString(16); b = Math.round(stop1_rgb.b + i * steps.b).toString(16); r = r.length != 2 ? "0" + r : r; g = g.length != 2 ? "0" + g : g; b = b.length != 2 ? "0" + b : b; stops[i] = "#" + (r + g + b).toUpperCase(); } stops[num - 1] = "#" + stop2_hex; return stops;
}
var fractalTree = new FractalTree('canvas');
Developer | Endre Simo |
Username | esimov |
Uploaded | November 28, 2022 |
Rating | 4.5 |
Size | 5,833 Kb |
Views | 12,144 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Fractal Tree | 2,790 Kb |
404 canvas page | 7,078 Kb |
DeJong attractor | 6,155 Kb |
Minecraft map generator | 7,723 Kb |
Spirograph | 2,519 Kb |
Perlin metaball | 7,396 Kb |
Perlin Noise based Minecraft Tunnel | 9,853 Kb |
Landscape | 3,792 Kb |
Navier Stoke Fluid Simulation | 8,584 Kb |
Flipping Clock | 3,804 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Material design buttons | Fischaela | 4,381 Kb |
Rrremark.com Overlay Highlighter | Derickruiz | 4,438 Kb |
Slider css only | Armandobau | 2,161 Kb |
Improve | Gavra | 1,652 Kb |
Ripples in water | Nobitagit | 2,704 Kb |
Impress JS Algorhytmic Generator | Jeffscottward | 7,906 Kb |
Animated bar chart | CreativePunch | 3,124 Kb |
A Bouncy Menu Toggle | Billyysea | 4,563 Kb |
Learning canvas drawing | Aurer | 2,204 Kb |
SVG email test v2.0 | M_J_Robbins | 2,090 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!