Giter Site home page Giter Site logo

l-system-tools's Introduction

L System Tools

This is a JavaScript-based implementation of Lindenmayer systems.

It consists of two key pieces:

  • A parse function that takes an axiom and a set of production rules, and returns a generated command string.
  • A number of different renderers that take a command string and output graphics. The renderers use a class-based system that allows them to be extended with custom graphics rules. Renderers are provided for canvas and SVG (though the base renderer could be extended for other uses.)

Installation

npm i l-system-tools

Parse Function

The core concept of L systems is that you can take a starting string (an axiom) and iteratively replace characters in that string following a set of production rules. This outputs a longer, generated string composed of repeating patterns that mimic natural, organic structures.

Here's an example of using the parser:

import { parse } from "l-system-tools";

const commandString = parse({
  // Starting string
  axiom: "F",
  // Object containing production rules
  production_rules: {
    // The character to replace
    F: {
      // What to replace the character with
      replacement: "F[-F][+F]",
      // Optionally include a decimal chance of the rule applying
      chance: "1",
    },
  },
  // How many times to iterate over the string
  iterations: 2,
});

This would output the following command string:

F[-F][+F][-F[-F][+F]][+F[-F][+F]]

Renderers

The renderer takes a command string and outputs graphics. There are currently three main renderers:

  • Renderer — A base renderer. Does not actually output graphics. (Contains core functionality that can be extended for various graphic outputs.)
  • SvgRenderer — Renders a command string's output to an existing SVG element
  • CanvasRenderer — Renders a command string's output to an existing canvas element.

Using the SVG Renderer

Here's an example of using the SVG renderer:

import { parse, SvgRenderer } from "l-system-tools";

// The renderer expects to be passed an SVG element when initialized
const renderer = new SvgRenderer(document.querySelector("svg"));

renderer.render({
  commandString: parse({
    axiom: "F",
    productions: {
      F: {
        replacement: "F[-F][+F]",
      },
    },
    iterations: 2,
  }),
  // Optionally define a starting rotation (determines starting direction)
  // Defaults to 90 (degrees)
  startRotation: 90,
  // Optionally define a rotation for how far to turn when a turn command is encountered
  // Defaults to 30 (degrees)
  turnRotation: 30,
  // Optionally define a distance to move when a forward command is encountered
  // Defaults to 10
  distance: 10,
  // Optionally define a starting poition
  // Defaults to { x: 50, y: 50 }
  startPosition: { x: 50, y: 50 },
});

Using the Canvas Renderer

The canvas renderer has the same syntax, but takes a canvas element instead of an SVG.

import { parse, CanvasRenderer } from "l-system-tools";

// The renderer expects to be passed an SVG element when initialized
const renderer = new CanvasRenderer(document.querySelector("canvas"));

renderer.render({
  // The Canvas Renderer takes the same options as the SVG Renderer above
});

Extending Renderers

Any of the renderers can be extended to add additional functionality or styles. Here's an example of extending the SVG renderer to add a special rendering rule for the letter 'C':

import { SvgRenderer } from "../renderer.js";

export class ExperimentalSvgRenderer extends SvgRenderer {
  customCommand = (command) => {
    if (command === "C") {
      // The SVG renderer builds a `markup` string containing the SVG markup
      this.markup += `
        <circle
          cx="${this.position.x}" 
          cy="${this.position.y}" 
          r="${this.distance / 5}"
        />`;
    }
  };
}

Here's a similar example for the canvas Renderer:

import { canvasRenderer } from "../renderer.js";

export class ExperimentalCanvasRenderer extends canvasRenderer {
  customCommand = (command) => {
    if (command === "C") {
      // Canvas renderers expose a canvas 2d context property.
      this.context.arc(
        this.position.x,
        this.position.y,
        this.distance / 5,
        0,
        2 * Math.PI,
        false
      );
    }
  };
}

For further information about extending renderers I recommend you review the source code and see how the SVG Renderer and Canvas Renderer are coded.

Examples

You can see an example of using this library with rollup here: https://github.com/Paul-Hebert/l-system-tools-test

You can view an interactive demo here: https://l-system-tools.netlify.app/src/demo/

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.