<link href="https://fonts.googleapis.com/css?family=Oswald" rel="stylesheet">
<div id = "container">
<div id = "credit">
 <div id = "words">
 This sketch is based on the excellent L-systems solution for p5.js created by R. Luke DuBois. <a href = "https://p5js.org/examples/simulate-l-systems.html">Their original sketch can be seen here.</a>
  </div>
</div>
  <div id = "canvasHolder"> </div>
<div id = "controlPanel">
  <div id = "hideShowHolder"> </div>
  <div id = "options"> </div>
</div>
</div>

@font-face { font-family: shkoder; font-weight: bold; src: url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/255459/Shkoder%201989%20Light.otf');}

body{
/* background-color: rgba(0, 1, 13, 1); */
color: #E2DEDB;
/*   color: #444; */
font-size: 18px;
font-family: 'Oswald', sans-serif;
background-color: rgba(40, 40, 40, 1);
}

#container{
  display: grid;
  width 100vw;
  grid-template-columns: 12vw 70vw 10vw;
}

#credit{
/*   width: 25vw; */
}

#phyCanvas{
  margin: auto;
}
#hideShowHolder{
  width: 35%;
  margin: auto;
}
#hideShow{
   width: 90px;
  height:50px;
  border-radius: 5%;
  font-family: 'Oswald', sans-serif;
  background-color: transparent;
/*   background-color: red; */
  color: white;
  font-size: 16px;
  margin: .9em;
}
#controlPanel{
/*   position: absolute; */
/*   z-index:1; */
}

.controls{
/*   display: inline-block; */
  font-family: 'Oswald', sans-serif;
  background-color: transparent;
  color: white;
  font-size: 16px;
  opacity: .9;
  width: 75%;
  margin: 1.59em;
  
}


#options{
/*  padding: 1.5em; */
  margin: 1.75em;
}

a {
  color: rgb(70, 139, 140);
  display: inline-block;
  position: relative;
  text-decoration: none;
  &:before {
    background-color: rgb(70, 139, 140);
    content: '';
    height: 2px;
    position: absolute;
    bottom: -1px;
    left: 50%;
    transform: translateX(-50%);
    transition: width 0.3s ease-in-out;
    width: 100%;
  }
  &:hover {
    &:before {
       width: 0;
    }
  }
}


button:focus {outline:0;}
input[type=range] {
  -webkit-appearance: none;
  width: 100%;
  margin: 0.7px 0;
}
// TURTLE STUFF:
var x, y; // the current position of the turtle
var t = 0.1;
var c;
var currentangle = 0; // which way the turtle is pointing
var step = 20; // how much the turtle moves with each 'F'
var angle = 90; // how much the turtle turns with a '-' or '+'
var colors;
// LINDENMAYER STUFF (L-SYSTEMS)
var thestring = 'A'; // "axiom" or start of the string
var numloops = 5;
// how many iterations to pre-compute
var therules = []; // array for rules
// first rule
therules[0] = ['A', '-FBA+AB+F+F-A-'];

// second rule
therules[1] =['B', '+F-AB+BA+FB+FA-B+']

therules[2] = ['A', '-BF+AFA+FB-']; 
therules[3] = ['B', '+AF-BFB-FA+'];


var whereinstring = 0; // where in the L-system are we?

function reSize(){
  
  canvasSelector = select('#canvasHolder')
  window_height = windowHeight;
  window_width = windowWidth;
      x = window_width/4;
  y = window_height/2;
    c = createCanvas(window_width/1.7, 700);
  c.parent(canvasSelector)
    var startX = (windowWidth - width) / 2;
  var startY = (windowHeight - height) / 2;
    c.position(startX, startY);
  
  // c.background("rgba(219, 43, 57, .6)")
  c.id("phyCanvas");
        pg = createGraphics(1000, 1000);
  // pg.background("rgba(49, 93, 127, .6)");
  pg.background("rgba(79, 0, 16, .7)");
  
  image(pg, 0, 0 );
  

}
function setup() {
  

  reSize()
  var controlsY = 100;
  let flag = false;
    // start the x and y position at lower-left corner


  // COMPUTE THE L-SYSTEM
  for (var i = 0; i < numloops; i++) {
    thestring = lindenmayer(thestring);
  }
  let panelSelector = $('#hideShowHolder')
  // let panelSelector = $('#controlPanel')
  
  console.log(panelSelector)

  /* CONTROL PANEL */
    /* CONTROL PANEL */
  var hideShowButton = createButton('controls')
  hideShowButton.id('hideShow')
  var hsSelector = $("#hideShow")
  panelSelector.prepend(hsSelector)
  
  hideShowButton.mousePressed(hideShow)
  function hideShow(){
  var selector = select('#options')
    if(flag){
  selector.hide()
    flag = !flag;
    }
  else {
    selector.show()
    flag = !flag
    }
  }
  
  let optionsSelector = $('#options')
 
 
  var button = createButton('STOP')
  button.id('myButton')
  button.addClass('controls')
  var buttonSelector = $('#myButton')
  optionsSelector.append(buttonSelector)
  button.mousePressed(stop)

  var startButton = createButton('START')
  startButton.id('startButton')
  startButton.addClass('controls')
  var buttonSelectorTwo = $('#startButton')
  optionsSelector.append(buttonSelectorTwo)
  startButton.mousePressed(start)
  
  
  var saveButton = createButton("SAVE");
  saveButton.id('saveButton')
  saveButton.mousePressed(saveMe);
  saveButton.addClass('controls')
  var buttonSelectorThree = $('#saveButton')
  optionsSelector.append(buttonSelectorThree)
  optionsSelector.hide()
  

  function saveMe() {
    console.log("working")
    saveCanvas(c, "myCanvas", "jpg");
  }
  
  function stop(){
noLoop()
}
function start(){
loop()
console.log('bye')
}
  
 /* Creating Colors */
   
    hotYellow =color('rgba(248, 250, 15, .09)');
    hotMagenta =color('rgba(206, 108, 128,.09)');
    hotPurple =color('rgba(93, 44, 153, .09)');
    hotPink =color('rgba(177, 67, 161, .09)');
    hotBeige =color('rgba(233, 176, 133, .09)');
    frameColor = color('rgba(252, 252, 252, .01)');
    ocOrange =color('rgba(245, 78, 101, .5)');
    deepBlue = color('rgba(9, 14, 103, .09)');
    briteAqua = color('rgba(7, 225, 255, .09)');
    pPink = color('rgba(187, 0, 194, .`09)');
  greatGrey = color('rgba(49, 59, 74,.1)')
  lWhite = color('rgba(246, 247, 241, .09)')
  anotherPink = color('rgba(218, 40, 101, .09)')
  spaceYellow = color('rgba(251,171,82, .1)')
  spaceRed = color('rgba(107,23,13, .1)')
  spaceLiteRed = color('rgba(184,83,73, .1)')
  spaceWhite = color('rgba(247, 243, 232, .1)')
  spaceGrey = color('rgba(213, 225, 221, .1)')
  spaceBlue = color('rgba(119, 190, 210, .6)')
  explodingOrange = color('rgba(246, 73, 74, .1)')
  jellyfishPink = color('rgba(228, 210, 228, .09)')
  jellyfishDarkPink = color('rgba(175, 142, 190, .09)')
  jellyfishPurple = color('rgba(103, 100, 149, .09)')
  jellyfishBlue = color('rgba(27, 54, 80, .09)')
  jellyfishAqua = color('rgba(45, 103, 133, .09)')
  jellyfishTeel = color('rgba(45, 103, 133, .09)')
  


}

function draw() {
  // background("rgba(246, 73, 74, .9)")

  
// translate(window_width/2, window_height/2);
  // draw the current character in the string:
  drawIt(thestring[whereinstring]); 
  // increment the point for where we're reading the string.
  // wrap around at the end.
  whereinstring++;
  if (whereinstring > thestring.length-1) whereinstring = 0;

}

// interpret an L-system
function lindenmayer(s) {
  var outputstring = ''; // start a blank output string
  
  // iterate through 'therules' looking for symbol matches:
for (var i = 0; i < s.length; i++) {
    var ismatch = 0; // by default, no match
    for (var j = 0; j < therules.length; j++) {
      if (s[i] == therules[j][0])  {
        outputstring += therules[j][1]; // write substitution
        ismatch = 1; // we have a match, so don't copy over symbol
        break; // get outta this for() loop
      }
    }
    // if nothing matches, just copy the symbol over.
    if (ismatch == 0) outputstring+= s[i]; 
  }
  
  return outputstring; // send out the modified string
}
   
// this is a custom function that draws turtle commands
function drawIt(k) {
  

  if (k=='F') { // draw forward
    // polar to cartesian based on step and currentangle:
    var x1 = x + step*cos(radians(currentangle));
    var y1 = y + step*sin(radians(currentangle));
    // line(x, y, x1, y1); // connect the old and the new
        // strokeWeight(.1)

    beginShape();
    
    stroke(spaceYellow)
  fill(jellyfishDarkPink)
      // stroke(jellyfishDarkPink)
      noFill()
     vertex(x1, y1);
     quadraticVertex(x1, y1, x, y);

     fill(hotPurple);
    // rect(x, y, 5, 5)
  // ellipse(x1, y1, TWO_PI, TWO_PI);
    endShape(CLOSE); 
    

    // update the turtle's position:
    x = x1;
    y = y1;
  } else if (k == '+') {
    currentangle += angle; // turn left
  } else if (k == '-') {
    currentangle -= angle; // turn right   
  }


  console.log(colors)
  // give me some random color values:
  var r = random(48, 175);
  var g = random(40, 155);
  var b = random(40, 190);
  var a = random();

  // pick a gaussian (D&D) distribution for the radius:
  var radius = 0;
  radius += random(0, 15);
  radius += random(0, 15);
  radius += random(0, 15);
  radius = radius/3;
  ellipseMode(CORNER);
  // draw the stuff:
  fill(r, g, b, a);
  stroke(r,g,b,a)
  ellipse(x, y, radius, radius);
  // ellipseMode(RADIUS);
  
  // ellipse(x, y, 5, 5);
  
    beginShape();
  //   stroke(pPink)
  // fill(briteAqua)
   // vertex(x, y); 
   // point(x, y);
  
  endShape(CLOSE)
}
//function to recenter the canvas everytime the window is resized to make responsive on desktop
function windowResized() {
reSize()
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js
  2. https://s3-us-west-2.amazonaws.com/s.cdpn.io/255459/chroma.js