StringSpotlight Module
Simulate a directional spotlight that follows the cursor. StringSpotlight analyses pointer vectors, eases the angle/distance, and writes CSS variables you can wire into lighting, shadows, or 3D transforms.
Activation primer: Add
string="spotlight"to every element you wantStringSpotlightto illuminate. Supplystring-id="your-id"when you need a stable handle for events, mirrors, orstring-copy-from; otherwise StringTune generates one automatically.
HTML Attributes
| Attribute | Type | Default | Controls | Practical notes |
|---|---|---|---|---|
string-lerp | number | 0.2 | Smoothing factor for angle and distance interpolation (adapts to 0.05–0.65) | Smaller values feel floaty, larger ones track more tightly |
string-angle-threshold | number | 0.2 | Minimal degrees change before CSS variables update | Raise to reduce rapid updates on high-DPI devices |
string-distance-threshold | number | 0.5 | Minimal distance delta before emitting updates | Great for throttling analytics or shader sync |
string-deadzone | number | 4 | Pixel radius around the element centre where angle stays fixed | Prevents jitter when the cursor is almost centred |
string-dist-max | number | 0 (no cap) | Optional clamp for measured distance | Useful when distance should top out for shading falloffs |
string-target-disable | boolean | false | Opt-out of spotlight processing even if string="spotlight" is present | Ideal for nested mirrors or debug states |
string-target-style-disable | boolean | false | Skip writing CSS variables while still emitting events | Use when you only consume JavaScript callbacks |
Module Snapshot
- Activation attribute:
string="spotlight" - CSS variables populated:
--spotlight-angle,--spotlight-angle-deg,--spotlight-distance - Event channel:
spotlight:update:<id>→{ angleDeg, distance } - Input source: leverages the shared cursor state; auto-disables on coarse pointers
- Deadzone logic: angle only updates once the cursor exits the configured deadzone
- Geometry reuse: inherits
CursorReactiveModulecentre tracking and hover activation
Basic Usage
import StringTune, { StringSpotlight } from '@fiddle-digital/string-tune';
const stringTune = StringTune.getInstance();
stringTune.use(StringSpotlight);
stringTune.start(60);
<article string="spotlight" string-id="feature-card" string-lerp="0.25" string-angle-threshold="0.35" class="feature-card">...</article>
.feature-card {
--dir: calc(var(--spotlight-angle, 0) * 1deg);
--falloff: clamp(0, 1, 1 - var(--spotlight-distance, 0) / 320);
box-shadow: calc(cos(var(--dir)) * 18px * var(--falloff)) calc(sin(var(--dir)) * 18px * var(--falloff)) 40px
rgba(0, 0, 0, 0.25 * var(--falloff));
}
How It Works
- Pointer sampling: inherits cursor deltas (
dx,dy,dist) fromCursorReactiveModule, measuring distance using cached centres for precision. - Angle handling: converts
atan2(dy, dx)to degrees relative to the element, honouring thedeadzonebefore the angle starts updating. - Distance control: optionally clamps distance via
string-dist-maxto stabilise effects; values are eased with the samelerpfactor as angle. - Threshold gating: updates only propagate when angle or distance shifts beyond their thresholds, reducing noise in CSS and events.
- CSS sync: writes three variables (
--spotlight-angle,--spotlight-angle-deg,--spotlight-distance) to the element and any mirrors; respectsstring-target-style-disable. - Event broadcast: emits
spotlight:update:<id>whenever either value crosses the change threshold, supplying rounded values.
Event Signal
| Channel pattern | Payload | Fired when | Use cases |
|---|---|---|---|
spotlight:update:<id> | { angleDeg: number; distance: number; } | Interpolated angle/dist exceed thresholds (or on forced refresh) | Aim lighting shaders, drive CSS gradients, record hover analytics |
stringTune.on('spotlight:update:feature-card', ({ angleDeg, distance }) => {
// angleDeg already normalised (-180..180); distance is in pixels
});
StringSpotlight turns cursor proximity into directional storytelling—dial the thresholds, craft your light cones in CSS, and let the module keep the motion smooth.