StringTune/Docs

Modules

StringImpulse

Applies cursor-reactive tilt and spring-like movement to interactive elements.

Type
Built-in module
Status
Advanced
Scope
Element-level
Activation
string="impulse"

StringImpulse

StringImpulse turns cursor velocity into a spring simulation. It writes position and rotation values to CSS variables, while you stay in control of the final transform in your own styles.

Public API

Attributes

Position spring

AttributeTypeDefaultReal runtime effect
string-position-strengthnumber3Scales how much cursor velocity is injected into translation.
string-position-tensionnumber0.05Pull-back force toward the resting position.
string-position-frictionnumber0.15Per-frame damping for translation velocity.
string-position-max-velocitynumber10Translation velocity clamp.
string-position-update-thresholdnumber0.1Minimal visible delta before --push-x and --push-y are rewritten.
string-max-offsetnumber220Maximum translation offset in either direction.

Rotation spring

AttributeTypeDefaultReal runtime effect
string-rotation-strengthnumber0.75Scales torque generated from cursor movement around the object.
string-rotation-tensionnumber0.06Pull-back force toward 0deg.
string-rotation-frictionnumber0.18Per-frame damping for angular velocity.
string-rotation-max-angular-velocitynumber6Angular velocity clamp.
string-rotation-max-anglenumber18Maximum visible rotation in degrees.
string-rotation-update-thresholdnumber0.15Minimal visible delta before --push-rotation is rewritten.
string-rotation-originstringcenter centerChanges the torque pivot used by the simulation.

Shared control

AttributeTypeDefaultReal runtime effect
string-sleep-epsilonnumber0.01Snaps the simulation back to rest once motion becomes tiny enough.
string-continuous-pushbooleantrueWhen false, each hover pass injects only one push until the pointer leaves and re-enters.

CSS Variables and DOM Output

The module writes these CSS variables on the source element and all mirrors:

  • --push-x
  • --push-y
  • --push-rotation

These are plain numbers. Add units yourself in CSS:

  • translation usually consumes * 1px
  • rotation usually consumes * 1deg

Events

ChannelPayloadFired when
object:impulse:<id>:move{ x, y }Translation output changes past the configured threshold
object:impulse:<id>:rotate{ rotation }Rotation output changes past the configured threshold
object:impulse:<id>:side{ value }Pointer moves across the element; 0 is left edge and 1 is right edge

Mirror Behavior

Mirrors inherit the source element's impulse CSS variables. Events are emitted only by the source object's string-id.

Quick Example

HTML
<div class="news-grid">
  <article 
    class="news-card"
    string="impulse"
    string-id="breaking-news"
    string-position-strength="2.0"
    string-rotation-strength="1.5"
    string-max-offset="80"
  >
    <div class="news-content">
      <span class="news-date">March 21, 2026</span>
      <h2 class="news-title">Design Engineering at Scale</h2>
      <p>How modular effects pipelines transform the modern web.</p>
    </div>
  </article>
</div>
CSS
.news-grid {
  padding: 4rem;
  display: flex;
  justify-content: center;
}

.news-card {
  width: 100%;
  max-width: 400px;
  border: 1px solid black;
  padding: 2.5rem;
  background: white;
  color: black;
  cursor: default;
  transform:
    translate3d(
      calc(var(--push-x, 0) * 1px),
      calc(var(--push-y, 0) * 1px),
      0
    )
    rotate(calc(var(--push-rotation, 0) * 1deg));
  transform-origin: center center;
  will-change: transform;
}

.news-date {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #666;
  display: block;
  margin-bottom: 1rem;
}

.news-title {
  font-size: 1.5rem;
  font-weight: 700;
  margin-bottom: 0.5rem;
  line-height: 1.1;
}

.news-card p {
  font-size: 1rem;
  color: #333;
}

Registration

TypeScript
import StringTune, { StringImpulse } from '@fiddle-digital/string-tune';

const stringTune = StringTune.getInstance();
stringTune.use(StringImpulse);
stringTune.start(60);

StringCursor is not required for StringImpulse. The module reads shared pointer velocity from StringTune itself.

Detailed Behavior

  • StringImpulse never writes a transform style directly. The transform stays fully user-owned.
  • If you change string-rotation-origin, keep your CSS transform-origin in sync with the same point. Otherwise the visible rotation pivot and the simulated torque pivot will not match.
  • The module only injects pushes while the pointer is physically inside the element bounds.