← All elements

Helix

Abstract

Two glowing strands winding around each other in a slowly spinning double helix.

Usage
Install: three @react-three/fiber @react-three/drei
Drop <Helix /> inside your own <Canvas>.
Mood
Scientific, elegant, hypnotic. A strand of light.
Colors
One cyan strand and one magenta strand, both emissive with a bloom glow, on near-black.
Motion
The double helix spins steadily around its vertical axis.
View component source
import { useMemo, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
import type { Group } from 'three';

class HelixCurve extends THREE.Curve<THREE.Vector3> {
  phase: number;
  constructor(phase = 0) {
    super();
    this.phase = phase;
  }
  getPoint(t: number, target = new THREE.Vector3()) {
    const a = this.phase + t * 3 * Math.PI * 2;
    return target.set(Math.cos(a) * 0.7, (t - 0.5) * 2.6, Math.sin(a) * 0.7);
  }
}

export default function Helix({ color = '#22e0ff', scale = 1 }: { color?: string; scale?: number }) {
  const g = useRef<Group>(null);
  const geoA = useMemo(() => new THREE.TubeGeometry(new HelixCurve(0), 220, 0.045, 12, false), []);
  const geoB = useMemo(() => new THREE.TubeGeometry(new HelixCurve(Math.PI), 220, 0.045, 12, false), []);
  useFrame((_, dt) => {
    if (g.current) g.current.rotation.y += dt * 0.5;
  });
  return (
    <group ref={g} scale={scale}>
      <mesh geometry={geoA}>
        <meshStandardMaterial color={color} emissive={color} emissiveIntensity={1.3} roughness={0.3} metalness={0.5} />
      </mesh>
      <mesh geometry={geoB}>
        <meshStandardMaterial color="#ff2fd0" emissive="#ff2fd0" emissiveIntensity={1.3} roughness={0.3} metalness={0.5} />
      </mesh>
    </group>
  );
}