Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URL's added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using it's URL and the proper URL extention.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Save Automatically?

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <svg id="canvas">

</svg>
              
            
!

CSS

              
                * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  min-height: 100vh;
  display: grid;
  place-items: center;
  background: #e9edeb;
}

svg {
  width: 75vmin;
  height: 75vmin;
  background: #141b3d;
  box-shadow: 1px 4px 32px 0px #141b3d;
}

              
            
!

JS

              
                import { SVG } from "https://cdn.skypack.dev/@svgdotjs/svg.js@3.1.1";
import {
  map,
  pointsInPath,
  random
} from "https://cdn.skypack.dev/@georgedoescode/generative-utils@1.0.37";

// set the width / height of our drawing space (viewBox!)
const width = 1024;
const height = 1024;

// create an svg.js instance
const svg = SVG("#canvas").viewbox(0, 0, width, height);

// create an initial tree
generateTree();

// every 0.5 seconds, clear the <svg> and create a new tree!
setInterval(() => {
  svg.clear();

  generateTree();
}, 1000);

function generateTree() {
  // what color should our background be?
  // all colors in this pen are from a book about old paints!
  const backgroundColor = "#141B3D";

  // what color should our branches be?
  const branchColor = "#E9EDEB";

  // what color should the little specks in the background be?
  const speckColors = ["#E9EDEB", "#CEA003", "#B52F36"];

  // render the background in the form of a <rect>
  svg.rect(width, height).fill(backgroundColor);

  // set the tree height to be 75% of the viewBox
  const treeHeight = height * 0.75;

  // create the center trunk using a <line>
  const trunk = svg
    .line(width / 2, 0, width / 2, treeHeight)
    .cy(height / 2)
    .stroke({
      color: "#E9EDEB",
      width: 4
    });

  // define how many branches we have, by splitting the trunk into equidistant points
  // this function uses svg's getTotalLength/getPointAtLength methods
  const trunkPoints = pointsInPath(trunk.node, random(16, 32, true));

  // where should we start drawing branches? startOffset is the top of the trunk
  const startOffset = random(0, trunkPoints.length / 8, true);

  // where should we stop drawing branches? endOffset is the bottom of the trunk
  const endOffset = random(0, trunkPoints.length / 4, true);

  // in degrees, define a random angle or rotation for all little branches
  const branchAngle = random(24, 48);

  // what is the largest size our branches could be?
  const maxBranchLength = random(treeHeight / 6, treeHeight / 3);

  // iterate over the range of trunk points selected
  for (let i = startOffset; i < trunkPoints.length - endOffset; i++) {
    // store the point
    const point = trunkPoints[i];

    // map current point's index to a branch length value, higher branches are smaller!
    // add a little sprinkle of randomness to the branch length
    const branchLength =
      map(
        i,
        startOffset,
        trunkPoints.length - endOffset,
        maxBranchLength / 8,
        maxBranchLength
      ) * random(0.75, 1);

    // draw the right-hand branch
    svg
      .line(point.x, point.y, point.x + branchLength, point.y)
      .stroke({
        color: branchColor,
        width: 4
      })
      .rotate(-branchAngle, point.x, point.y);

    // draw the left-hand branch
    svg
      .line(point.x, point.y, point.x - branchLength, point.y)
      .stroke({
        color: branchColor,
        width: 4
      })
      .rotate(branchAngle, point.x, point.y);
  }

  // draw lots of random circles for the background
  for (let i = 0; i < 128; i++) {
    svg
      .circle(random(1, 4))
      .cx(random(0, width))
      .cy(random(0, height))
      .fill(random(speckColors));
  }
}

              
            
!
999px

Console