JSFiddle - React, Tailwind, and code Playground

by matas_bitbybitdev

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Runner Example - IO from Rete editor</title>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <script type="importmap">
      {
        "imports": {
          "three": "https://cdn.jsdelivr.net/npm/three@v0.171.0/build/three.module.js",
          "three/addons/controls/OrbitControls": "https://cdn.jsdelivr.net/npm/three@v0.171.0/examples/jsm/controls/OrbitControls.min.js"
        }
      }
    </script>
    <script type="module">
      import * as THREEJS from 'three';
      import { OrbitControls } from 'three/addons/controls/OrbitControls';
      window.THREEJS = THREEJS;
      window.OrbitControls = OrbitControls;
    </script>
    <script
      defer
      src="https://cdn.jsdelivr.net/gh/bitbybit-dev/bitbybit-assets@0.19.1/runner/bitbybit-runner-lite-threejs.js"
    ></script>
   
  </head>
  <body>
    <div class="logo">
      <a href="/">
        <img
          src="https://bitbybit.dev/assets/logo-gold-small.png"
          width="50px"
          height="50px"
        />
      </a>
      <div>
        Made with <a href="https://bitbybit.dev">bitbybit.dev</a> &
        <a href="https://threejs.org">threejs.org</a>
      </div>
      <div>
        Source code on
        <a
          href="https://github.com/bitbybit-dev/app-examples/blob/main/runner/threejs/lite/threejs-logo/index.html"
          >github</a
        >
      </div>
      <div>
        Code on
        <a href="https://codepen.io/matas-bitbybit-dev/pen/yyBebgr">CodePen</a>
      </div>
      <div>Powered by bitbybit runner for ThreeJS</div>
    </div>
    <canvas id="myCanvas"></canvas>
    <img
      class="bottom-img"
      src="https://app.bitbybit.dev/assets/homepage/lg/parametric-design-bottom.png"
    />
  </body>
</html>

CSS

body {
  background-color: rgb(26, 28, 31);
  margin: 0px;
  color: #ffffff;
  overflow-y: hidden;
  overflow-x: hidden;
}

a {
  color: #f0cebb;
}

a:visited {
  color: #f0cebb;
}

#myCanvas {
  display: block;
  overflow-y: hidden;
  overflow-x: hidden;
  width: 100%;
  height: 100vh;
}

.logo {
  padding: 20px;
  background-color: rgb(26, 28, 31, 0.8);
  font-family: Arial, Helvetica, sans-serif;
  font-size: 12px;
  position: absolute;
  bottom: 10px;
  left: 10px;
}

.logo img {
  margin-bottom: 5px;
}

.lds-ellipsis {
  z-index: 2;
  top: calc(50% - 32px);
  left: calc(50% - 32px);
  display: inline-block;
  position: absolute;
  width: 64px;
  height: 64px;
}

.lds-ellipsis div {
  position: absolute;
  top: 27px;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.8);
  animation-timing-function: cubic-bezier(0, 1, 1, 0);
}

.lds-ellipsis div:nth-child(1) {
  left: 6px;
  animation: lds-ellipsis1 0.6s infinite;
}

.lds-ellipsis div:nth-child(2) {
  left: 6px;
  animation: lds-ellipsis2 0.6s infinite;
}

.lds-ellipsis div:nth-child(3) {
  left: 26px;
  animation: lds-ellipsis2 0.6s infinite;
}

.lds-ellipsis div:nth-child(4) {
  left: 45px;
  animation: lds-ellipsis3 0.6s infinite;
}

@keyframes lds-ellipsis1 {
  0% {
    transform: scale(0);
  }

  100% {
    transform: scale(1);
  }
}

@keyframes lds-ellipsis3 {
  0% {
    transform: scale(1);
  }

  100% {
    transform: scale(0);
  }
}

@keyframes lds-ellipsis2 {
  0% {
    transform: translate(0, 0);
  }

  100% {
    transform: translate(19px, 0);
  }
}

.bottom-img {
  position: absolute;
  top: 0;
  left: 0;
  width: 1920px;
  z-index: -1;
  overflow-y: hidden;
  overflow-x: hidden;
}

JavaScript

import GUI from 'https://cdn.jsdelivr.net/npm/lil-gui@0.20/+esm';

const current = {
  group: undefined,
  gui: undefined,
};

let finalShape = undefined;
let shapesToClean = [];

const domNode = document.getElementById('myCanvas');

const camera = new THREEJS.PerspectiveCamera(
  70,
  domNode.clientWidth / domNode.clientHeight,
  0.01,
  1000
);
const scene = new THREEJS.Scene();
const light1 = new THREEJS.HemisphereLight(0xffffff, 0x000000, 10);
scene.add(light1);
const light2 = new THREEJS.HemisphereLight(0xffffff, 0x000000, 10);
light2.position.y = -1;
scene.add(light2);

const renderer = new THREEJS.WebGLRenderer({
  antialias: true,
  canvas: domNode,
});
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);

const controls = new OrbitControls(camera, renderer.domElement);
camera.position.set(0, 20, 0);
controls.update();
controls.target = new THREEJS.Vector3(0, 0, 0);
controls.enableDamping = true;
controls.dampingFactor = 0.1;
controls.zoomSpeed = 1;

renderer.shadowMap.enabled = true;

const onWindowResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
};
window.addEventListener('resize', onWindowResize, false);

renderer.setClearColor(new THREEJS.Color(0x1a1c1f), 0);

function adjustShadowSettings(light) {
  light.castShadow = true;
  light.shadow.camera.near = 0;
  light.shadow.camera.far = 1000;
  const dist = 8;
  light.shadow.camera.right = dist;
  light.shadow.camera.left = -dist;
  light.shadow.camera.top = dist;
  light.shadow.camera.bottom = -dist;
  light.shadow.mapSize.width = 3000;
  light.shadow.mapSize.height = 3000;
}
const dirLight1 = new THREEJS.DirectionalLight(0xffeeff, 50);
dirLight1.position.set(35, 12, -15);
const dirLight2 = new THREEJS.DirectionalLight(0xffeeff,...