JSFiddle - React, Tailwind, and code Playground

by Richard

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r69/three.min.js"></script>

JavaScript

'use strict';

/* global THREE */

var base = {
    y: 0,
    length: 2000,
    angle: Math.PI,
    theta: 0,
    width: 200,
    color: 'brown',
    limbs: [],
    generation: 0,
    hasLeaves: false
};

var maxGeneration = 3;
var maxLimbs = 2;

var randBetween = function (min, max) {
    return Math.random() * (max - min) + min;
};

var createLimb = function () {
    return {
        y: this.y - this.length * Math.cos(this.angle) / 2,
        length: randBetween(this.length / 2, this.length),
        angle: randBetween(Math.PI * 0.5, Math.PI * 1.5),
        theta: randBetween(Math.PI * 0.5, Math.PI * 1.5),
        width: this.width - this.width * 0.3,
        color: this.color,
        limbs: [],
        generation: this.generation + 1,
        hasLeaves: true
    };
};

var createLimbs = function (limb) {
    if (limb.generation < maxGeneration) {
        var n = Math.round(Math.random() * maxLimbs) + 1;
        for (var i = 0; i < n; i++) limb.limbs.push(createLimb.call(limb));
        limb.limbs.forEach(createLimbs);
    }
};

var iterateLimbs = function (root, cb) {
    cb(root);
    root.limbs.forEach(function (limb) {
        cb(limb);
        iterateLimbs(limb, cb);
    });
};

var woodMat = new THREE.MeshLambertMaterial({
    color: 0x53231B
});

var darkLeafMat = new THREE.MeshLambertMaterial({
    color: 0x556910,
    transparent: true,
    opacity: 0.8
});

var lightLeafMat = new THREE.MeshLambertMaterial({
    color: 0x889F57,
    transparent: true,
    opacity: 0.8
});

var createLimbMesh = function (limb) {
    var cylinder = new THREE.CylinderGeometry(limb.width, limb.width, limb.length);
    var mesh = new THREE.Mesh(cylinder, woodMat);
    mesh.rotation.x += limb.angle;
    var dx = limb.length * Math.sin(limb.angle) / 2;
    var dy = limb.length * Math.cos(limb.angle) / 2;
    mesh.position.set(0, limb.y - dy, -dx);
    var dummy = new THREE.Object3D();
    dummy.add(mesh);
    dummy.rotation.y += limb.theta;
    if (limb.hasLeaves) {
       ...