JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<script src="https://cdn.babylonjs.com/babylon.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<ul class="menu">
  <li data-type="reef">Reef</li>
  <li data-type="deep-pockets">Deep Pockets</li>
  <li data-type="new-one">New One</li>
</ul>
<canvas id="renderCanvas" width="1024" height="600"></canvas>

CSS

body{
  background-color: black;
  font-family: helvetica;
  overflow: hidden;
}
canvas.heightmap{
  display: none;
}
canvas#renderCanvas{
  background-size: cover;
  outline: none;
}
ul.menu{
  margin: 0px;
  padding: 0px;
  display: block;
  margin-bottom: 10px;
}
ul.menu>li{
  padding: 6px;
  display: inline-block;
  background-color: #333;
  color: #fff;
  cursor: pointer;
}

JavaScript

class HeightmapGenerator {

	constructor(size,algorithm){
  
  	this.size = size;
  
  	this.canvas = document.createElement('canvas');
    
    this.canvas.width = size;
    this.canvas.height = size;
    this.canvas.classList.add('heightmap');
    
    document.body.appendChild(this.canvas);
    
    this.ctx = this.canvas.getContext("2d");
    
    //const grad=ctx.createRadialGradient(150,75,15,150,75,150);
	 // grad.addColorStop(0,"lightblue");
	  //grad.addColorStop(1,"darkblue");
    
    this.ctx.fillStyle = "black";
		this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
    
    
    let angle = this._randomNumberBetween(0,Math.PI);
    
    switch(algorithm){
    
    	case "reef":
      this._mountainRange(30,angle,0.03,20,20,35,0.03, 350, 0.3, 44, 255,255,255,true);
      this._mountainRange(20,angle,0.03,30,40,11,0.02, 350, 0.2, 4, 255,255,255,true);
    	this._mountainRange(10,angle,0.37,30,60,37,0.004, 1450, 0.1, 3, 255,255,255,false);
      break;
      
      case "deep-pockets":
      this._mountainRange(14,angle,0.2,0,0,500,0.04, 12, 0, 500, 255,255,255,false);
      this._mountainRange(160,angle,0.5,10,10,35,0.06, 20, 0, 15, 255,255,255,false);
      this._mountainRange(160,angle,1.7,10,10,15,0.06, 20, 0, 10, 255,255,255,false);
      this._mountainRange(85,angle,0.8,20,40,11,0.05, 60, 0, 4, 255,255,255,false);
      break;
      
      case "new-one":
      this._mountainRange(14,angle,0.2,120,130,50,0.9, 112, 0, 111, 255,255,255,false);
      break;
    
    }
    
  }
  
  _mountainRange(mountains,angle,meander,minValley,maxValley,distanceAcross,baseElevation,range,slope,scatter,r,g,b,reefMode){
  
  	
  	let y = 0;
    let minSpan = minValley
    let maxSpan = maxValley
    
    let thickness = distanceAcross;
    let opacity = baseElevation;
    
    for(let i=0;i<mountains;i++){
    
    	this._drawMountain(this._generatePath( 
        { 
          x: this._randomNumberBetween(0,this.size), 
          y: y 
        } , 
      ...