Files
thrive/src/lib/glow.js
T

36 lines
1.4 KiB
JavaScript

import * as THREE from 'three';
// Keeps the gradient's bright spot gravitating toward the projection wall as
// the camera orbits: the wall centre (x = -10 in every scene) is projected into
// screen space each frame and eased into the CSS gradient position.
const WALL_CENTRE = new THREE.Vector3( -10, 0, 0 );
export function bindGlow( camera ) {
const projected = new THREE.Vector3();
let x = 12;
let y = 50;
let writtenX = null;
let writtenY = null;
return function update() {
projected.copy( WALL_CENTRE ).project( camera );
// when the wall goes behind the camera the projection flips sides;
// leave the glow where it last was until the wall swings back
if ( projected.z < 1 ) {
const targetX = THREE.MathUtils.clamp( ( projected.x + 1 ) * 50, -40, 140 );
const targetY = THREE.MathUtils.clamp( ( 1 - projected.y ) * 50, -40, 140 );
x += ( targetX - x ) * 0.08;
y += ( targetY - y ) * 0.08;
}
// writing the property repaints the whole gradient, so only touch the
// DOM while the glow is actually moving
if ( writtenX !== null && Math.abs( x - writtenX ) < 0.05 && Math.abs( y - writtenY ) < 0.05 ) return;
writtenX = x;
writtenY = y;
document.body.style.setProperty( '--glow-x', `${x.toFixed( 2 )}%` );
document.body.style.setProperty( '--glow-y', `${y.toFixed( 2 )}%` );
};
}