I am seeking a creative way to incorporate an intriguing effect into my project. Specifically, I envision drawing a floating line with dynamic curves and interactive hover effects.
To provide a visual reference, the project timeline featured on the home page of captures a similar essence through its design elements, including the loading bar.
The goal is to establish an array of points for the line's trajectory and allow it to meander unpredictably across the screen.
My initial experimentation involved utilizing Three.js and the CatmullRomCurve3 class to define crucial points along the curve (refer to code snippet below). While setting up six key points proved manageable, there are some vital components that still require fine-tuning:
- Implementing a random slow-floating animation
- Incorporating hover interactions
- Crafting a smooth line-drawing animation
If anyone has insights or suggestions on enhancing my code snippet, your input would be greatly appreciated!
Thank you! :)
const renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xffffff, 0 );
document.body.appendChild( renderer.domElement );
const camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 );
camera.position.set( 0, 0, 100 );
camera.lookAt( 0, 0, 0 );
const scene = new THREE.Scene();
const getPosFromPX = (x, y) => {
const vec = new THREE.Vector3();
const pos = new THREE.Vector3();
vec.set(
( x / window.innerWidth ) * 2 - 1,
- ( y / window.innerHeight ) * 2 + 1,
0.5 );
vec.unproject( camera );
vec.sub( camera.position ).normalize();
const distance = - camera.position.z / vec.z;
pos.copy( camera.position ).add( vec.multiplyScalar( distance ) );
return pos
}
const getLine = () => {
const curve = new THREE.CatmullRomCurve3( [
getPosFromPX(10, 50),
getPosFromPX(document.body.clientWidth - 50, 50),
getPosFromPX(document.body.clientWidth - 10, document.body.clientHeight / 2),
getPosFromPX(50,document.body.clientHeight / 2),
getPosFromPX(50,document.body.clientHeight -60),
getPosFromPX(document.body.clientWidth - 50, document.body.clientHeight - 70)
] );
const points = curve.getPoints( 80 );
const geometry = new THREE.BufferGeometry().setFromPoints( points );
const material = new THREE.LineBasicMaterial( { color : "#000000" } );
return new THREE.Line( geometry, material );
}
scene.add(getLine());
renderer.render( scene, camera );
<!DOCTYPE html>
<html>
<body>
<script src="https://threejs.org/build/three.js"></script>
</body>
</html>