Modules
StringSpotlight
Writes cursor-derived spotlight angle and distance variables for lighting effects.
StringSpotlight
StringSpotlight computes the pointer direction and distance relative to each target element and writes the result to two CSS variables. The module does not render a light effect on its own. You provide the visual treatment in CSS.
Public API
Attributes
| Attribute | Type | Default | Real runtime effect |
|---|---|---|---|
string-lerp | number | inherited lerp | Smooths how quickly spotlight direction and distance catch up to the pointer. |
string-angle-threshold | number | 0.2 | Minimal change before the angle output is rewritten and re-emitted. |
string-distance-threshold | number | 0.5 | Minimal change before the distance output is rewritten and re-emitted. |
string-deadzone | number | 4 | Small radius around the element center where angle changes are ignored unless a forced update happens. |
string-dist-max | number | 0 | Optional clamp for spotlight distance. 0 means no clamp. |
CSS Variables and DOM Output
The module writes these CSS variables on the source element and all mirrors:
--spotlight-angle--spotlight-distance
Both are plain numbers:
--spotlight-angleis degrees--spotlight-distanceis distance in pixels, but still emitted as a unitless number
Events
| Channel | Payload | Fired when |
|---|---|---|
spotlight:update:<id> | { angleDeg, distance } | Either spotlight output changes past the configured thresholds |
Mirror Behavior
Mirrors inherit the source element's spotlight variables. Events are emitted only for the source object ID.
Quick Example
HTML
<div class="features-grid">
<div
class="premium-card"
string="spotlight"
string-id="pro-plan"
string-lerp="0.15"
>
<div class="premium-card-inner">
<h3>Pro Tier</h3>
<p>Advanced modules and physics constraints for heavy data layers.</p>
</div>
</div>
</div>
CSS
.features-grid {
display: flex;
justify-content: center;
padding: 4rem;
}
.premium-card {
position: relative;
background: black;
border: 1px solid #333;
border-radius: 12px;
overflow: hidden;
width: 100%;
max-width: 320px;
}
.premium-card::before {
content: "";
position: absolute;
top: 50%;
left: 50%;
width: 400px;
height: 400px;
border-radius: 50%;
background: radial-gradient(circle, rgba(255,255,255,0.15), transparent 68%);
transform:
translate(-50%, -50%)
rotate(calc((var(--spotlight-angle, 0) + 90) * 1deg))
translateY(calc(var(--spotlight-distance, 0) * -1px));
pointer-events: none;
z-index: 0;
}
.premium-card-inner {
position: relative;
z-index: 1;
color: white;
padding: 2.5rem 2rem;
height: 100%;
}
.premium-card-inner h3 {
font-size: 1.5rem;
font-weight: bold;
margin-bottom: 0.5rem;
}
.premium-card-inner p {
color: #999;
line-height: 1.5;
}
Registration
TypeScript
import StringTune, { StringSpotlight } from '@fiddle-digital/string-tune';
const stringTune = StringTune.getInstance();
stringTune.use(StringSpotlight);
stringTune.start(60);
StringCursor is not required for StringSpotlight.
Detailed Behavior
- The current runtime does not write
--spotlight-angle-deg. Only--spotlight-angleand--spotlight-distanceare public output. - The module updates both on pointer movement and on scroll-driven center invalidation, so the spotlight stays aligned while the page moves.
- On coarse pointer devices the module disables itself.