JSFiddle - React, Tailwind, and code Playground
by Paul West
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
CSS
body {
overflow: hidden;
margin: 0;
}
JavaScript
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var cylGeom = new THREE.CylinderBufferGeometry(1, 1, 10, 32, 50);
var uniforms = {
mouse: {
value: new THREE.Vector3()
},
radius: {
value: 3
}
};
var cylMat = new THREE.PointsMaterial({
size: 0.125,
color: "aqua"
});
cylMat.onBeforeCompile = shader => {
shader.uniforms.mouse = uniforms.mouse;
shader.uniforms.radius = uniforms.radius;
//console.log(shader.vertexShader);
shader.vertexShader = `
uniform vec3 mouse;
uniform float radius;
` + shader.vertexShader;
shader.vertexShader = shader.vertexShader.replace(
`#include <begin_vertex>`,
`#include <begin_vertex>
vec3 dir = transformed - mouse;
float dist = length(dir);
if (dist < radius){
float ratio = 1. - dist / radius;
vec3 shift = dir * 2. * (ratio * ratio);
transformed += shift;
}
`
);
}
var cyl = new THREE.Points(cylGeom, cylMat);
scene.add(cyl);
var plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
window.addEventListener("mousemove", event =>{
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
raycaster.setFromCamera(mouse, camera);
raycaster.ray.intersectPlane(plane, uniforms.mouse.value);
});
renderer.setAnimationLoop(() => {
renderer.render(scene, camera)
});