JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
HTML
<script src="https://unpkg.com/[email protected]/build/three.min.js"></script>
<script src="https://unpkg.com/[email protected]/examples/js/controls/OrbitControls.js"></script>
<div class="sketchpadContainer">
<canvas id="sketchpad"></canvas>
<div class="sketchpadLabel">Draw on me!</div>
</div>
CSS
body {
margin: 0;
}
.sketchpadContainer {
position: fixed;
top: 10px;
left: 10px;
}
#sketchpad {
background: #a0a0a0;
border-radius: 3px;
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
}
.sketchpadLabel {
color: #ccc;
text-shadow: 0 1px 4px black;
text-align: center;
font-family: sans-serif;
font-size: 14px;
}
JavaScript
const scene = new THREE.Scene();
let curve = null;
let surface = null;
function update3DCurve(points) {
let lineSegments = [];
for (let i = 0; i < points.length; i++) {
const a = points[i];
const b = points[(i + 1) % points.length];
lineSegments.push(new THREE.LineCurve3(
new THREE.Vector3(a[0], a[1], 0),
new THREE.Vector3(b[0], b[1], 0)
));
}
const curvePath = new THREE.CurvePath();
curvePath.autoClose = true;
curvePath.curves = lineSegments;
// White curve
if (curve !== null) {
curve.geometry.dispose();
curve.material.dispose();
scene.remove(curve);
}
const curveGeometry = new THREE.TubeGeometry(curvePath, 200, 0.01, 10, true);
const curveMaterial = new THREE.MeshBasicMaterial({
color: 0xffffff,
side: THREE.DoubleSide,
depthTest: false,
});
curve = new THREE.Mesh(curveGeometry, curveMaterial);
curve.renderOrder = Number.MAX_SAFE_INTEGER;
curve.position.set(0, 0, -0.25);
scene.add(curve);
// Blue 3D Surface
if (surface !== null) {
surface.geometry.dispose();
surface.material.dispose();
scene.remove(surface);
}
const surfaceMaterial = new THREE.MeshStandardMaterial({
color: 0x49ef4,
side: THREE.DoubleSide,
opacity: 0.5,
transparent: true,
});
const surfaceGeometry = new THREE.ParametricGeometry((u, v, vec) => {
u = (u + v) % 1;
const point1 = curvePath.getPoint(u);
const point2 = curvePath.getPoint(v);
vec.addVectors(point1, point2).divideScalar(2);
vec.z = point1.distanceTo(point2);
}, 50, 50);
surface = new THREE.Mesh(surfaceGeometry, surfaceMaterial);
surface.position.set(0, 0, -0.25);
scene.add(surface);
}
const sketchpadCanvas = document.querySelector("#sketchpad");
const sketchpadCtx = sketchpadCanvas.getContext("2d");
sketchpadCanvas.width = 150;
sketchpadCanvas.height = 150;
let sketchpadPoints =...