JSFiddle - React, Tailwind, and code Playground

by tfoller

HTML

<canvas id="main_canvas" width="550" height="550"></canvas>
<div id="ui">
  <button id="psw">...</button>
</div>
  <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
  <script type="importmap">
    {
      "imports": {
        "three": "https://unpkg.com/three@0.145.0/build/three.module.js",
        "three/addons/": "https://unpkg.com/three@0.145.0/examples/jsm/",
        "alikim/": "https://alikim.com/"
      }
    }
  </script>

CSS

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

.noselect {
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

#ctrl_over {
  position: absolute;
  opacity: 0.5;
  bottom: 9px;
  right: 5px;

  color: #aaa;
  font-family: Arial, Helvetica, sans-serif;
  font-size: 13px;
}

#ctrl_sw {
  border: solid 1px #aaa;
  padding: 3px;
  margin-left: 10px;
  cursor: pointer;
  font-size: 11px;
  text-transform: uppercase;
}

#canv_wrap {
  position:relative;
  margin: 0px;
  padding: 0px;
  display: inline-block;
}

body {
  background: #112233;
  width: 100vw;
  height: 100vh;
}

button {
  padding: 3px;
  margin-left: 10px;
  color: #333;
  filter: invert(100%);
  cursor: pointer;
}

canvas {
  display: block;
  border: solid 1px grey;
  box-sizing: content-box;
  margin: 10px;
}

JavaScript

import * as THREE from 'three'

import * as CONTROLS from 'alikim/_v1_jsm/controls.js'

import { log, slog, get, getHTML } from 'alikim/_v1_jsm/utils.js'

import { makeSwitchBtn } from 'alikim/_v1_jsm/ui.js'

import { LatheGeom } from 'alikim/_lush/tree/js/lpf.js'

const html = getHTML();

// 3D

const canvas = get('main_canvas');
const [w, h] = [canvas.width, canvas.height];
const renderer = new THREE.WebGLRenderer({
  antialias: true,
  canvas: canvas,
});
renderer.setSize(w, h);

const [near, far] = [1, 700];
const mid = -0.5 * (near + far);
const camera = new THREE.PerspectiveCamera(45, w / h, near, far);

const scene = new THREE.Scene();
scene.background = new THREE.Color(0, 0, 0.3);

const dirLight = new THREE.DirectionalLight(0xffffff, 0.5);
dirLight.position.set(1, 1, 1);
scene.add(dirLight);

const src = "<Path data='M144.5 217Q137.22246 215.06074 126.75 27.85 178.1 25.7 187.45 5.15 194.3543 15.131641 201.625 31 194.55664 42.027344 207.45 44.5 211.04824 53.310156 214.725 63.5 206.63516 76.032227 220.3 79.5 223.52441 89.185937 226.825 99.9 247.83535 168.1 259.1 264.75 280.15 446.25 249.75 433.8 237.7 423.45 222.9 406.2 208.15 388.9 181.45 394.7 154.75 400.45 138.65 213.75'>";

const lathe = LatheGeom({src, quality: 0.33});
const points = lathe[0][0].data.map(a => new THREE.Vector2(a[0], a[1]));

const geo = new THREE.LatheGeometry(points, 32);
const mat4 = new THREE.Matrix4().makeScale(0.25, 0.5, 0.2);
mat4.elements[1] = -0.05; // shear
geo.applyMatrix4(mat4);

const sz = 100;
const dune = new THREE.Mesh(
  geo,
  new THREE.MeshLambertMaterial({ color: 0xeef0f8, side: THREE.DoubleSide }),
);
dune.position.set(0, -100, mid);

scene.add(dune);

const hlp = new THREE.AxesHelper(110);
hlp.position.z = mid;
scene.add(hlp);

const anim = () => {
  cube.rotation.x += 0.013;
  cube.rotation.y += 0.007;
};

const framerate = 60;
const fpsint = 1000 / framerate;
let elapsed, now, then;

const state = { 
  play: true, 
  flip: function() { 
    this.play =...