A puffy translucent glass arrow that refracts and shifts color as it turns.
Tip: pick a preset, use the custom picker, or paste your brand hex to preview this element in your colors. Some elements use a fixed multi-color palette.
three @react-three/fiber @react-three/drei<GlassArrow /> inside your own <Canvas>.import { useMemo, useRef } from 'react';
import { useFrame } from '@react-three/fiber';
import * as THREE from 'three';
import type { Mesh } from 'three';
function makeArrowGeometry() {
const s = new THREE.Shape();
s.moveTo(-1.0, 0.35);
s.lineTo(0.15, 0.35);
s.lineTo(0.15, 0.8);
s.lineTo(1.15, 0);
s.lineTo(0.15, -0.8);
s.lineTo(0.15, -0.35);
s.lineTo(-1.0, -0.35);
s.closePath();
const geo = new THREE.ExtrudeGeometry(s, {
depth: 0.55,
bevelEnabled: true,
bevelThickness: 0.22,
bevelSize: 0.2,
bevelSegments: 8,
curveSegments: 16,
});
geo.center();
return geo;
}
export default function GlassArrow({ color = '#c9b3ff', scale = 1 }: { color?: string; scale?: number }) {
const ref = useRef<Mesh>(null);
const geo = useMemo(() => makeArrowGeometry(), []);
useFrame((state) => {
if (!ref.current) return;
ref.current.rotation.y = Math.sin(state.clock.elapsedTime * 0.4) * 0.5;
ref.current.rotation.z = Math.sin(state.clock.elapsedTime * 0.3) * 0.12;
});
return (
<mesh ref={ref} geometry={geo} scale={scale}>
<meshPhysicalMaterial
color={color}
transmission={0.45}
thickness={1.6}
roughness={0.28}
ior={1.4}
iridescence={1}
iridescenceIOR={1.3}
clearcoat={1}
clearcoatRoughness={0.2}
metalness={0}
emissive={color}
emissiveIntensity={0.12}
transparent
/>
</mesh>
);
}