StringTune/Docs

Modules

StringAnchor

Sets transform-origin style metadata from declarative anchor attributes.

Type
Built-in module
Status
Stable
Scope
Element-level
Activation
string="anchor"

StringAnchor

StringAnchor is a small element module that sets transform-origin from one declarative attribute. It does not animate anything by itself. Its only job is to define the pivot point that your own CSS transforms, keyframes, or other modules will use.

Public API

Attributes

AttributeTypeDefaultReal runtime effect
string-anchortuple stringmodule setting anchor, default center centerSplit into two tuple parts, each part is passed through originParser.process(), then written as inline transform-origin on the element.

Accepted values are two-part origin strings such as:

  • top left
  • left center
  • center center
  • 30% 70%
  • right bottom

The parser also accepts single values and random(...) expressions because each axis is passed through originParser.

Examples:

  • string-anchor="center"
  • string-anchor="top left"
  • string-anchor="random(left,right) bottom"

Because the tuple is split by whitespace first, keep random(...) options without spaces.

CSS Variables and DOM Output

StringAnchor does not write CSS variables and does not emit classes.

Its public output is one inline style:

  • element.style.transformOrigin = "<x> <y>"

Events

This module has no public event contract.

Mirror Behavior

If another element uses string-copy-from="<source-id>", the same computed transform-origin is written to the mirror element too.

Quick Example

HTML
<div class="anchor-demo">
  <div class="anchor-card">
    <div class="anchor-stage">
      <div string="anchor" string-anchor="top left" class="anchor-box">
        <span class="anchor-box__label">top left</span>
      </div>
      <span class="anchor-dot anchor-dot--top-left"></span>
    </div>
  </div>

  <div class="anchor-card">
    <div class="anchor-stage">
      <div string="anchor" string-anchor="center center" class="anchor-box">
        <span class="anchor-box__label">center center</span>
      </div>
      <span class="anchor-dot anchor-dot--center"></span>
    </div>
  </div>

  <div class="anchor-card">
    <div class="anchor-stage">
      <div string="anchor" string-anchor="bottom right" class="anchor-box">
        <span class="anchor-box__label">bottom right</span>
      </div>
      <span class="anchor-dot anchor-dot--bottom-right"></span>
    </div>
  </div>
</div>
CSS
.anchor-demo {
  min-height: 100vh;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px;
  padding: 24px;
}

.anchor-card {
  display: grid;
  place-items: center;
}

.anchor-stage {
  position: relative;
  width: 220px;
  height: 220px;
  border: 1px solid black;
  overflow: hidden;
}

.anchor-box {
  position: absolute;
  inset: 30px;
  display: grid;
  place-items: center;
  border: 2px solid black;
  background: white;
  animation: anchor-spin 3s linear infinite;
}

.anchor-box__label {
  font-size: 12px;
  text-transform: uppercase;
}

.anchor-dot {
  position: absolute;
  width: 8px;
  height: 8px;
  background: black;
  border-radius: 9999px;
}

.anchor-dot--top-left {
  top: 30px;
  left: 30px;
}

.anchor-dot--center {
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.anchor-dot--bottom-right {
  right: 30px;
  bottom: 30px;
}

@keyframes anchor-spin {
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
}

The animation is plain CSS. StringAnchor only changes the pivot that animation rotates around.

Registration

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

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

You can also provide a default fallback:

TypeScript
stringTune.use(StringAnchor, {
  anchor: 'center center',
});

Detailed Behavior

  • The module activates on elements with string="anchor".
  • It maps the anchor property as a tuple, so runtime input is read from string-anchor.
  • Each axis is processed through originParser.process(). In practice this mostly means resolving random(...) and handling empty values, not converting keywords into percentages.
  • The write happens in onObjectConnected(), so this module is connection-time only. It does not update every frame, on scroll, or on mouse move.
  • Because the write is applied directly to style.transformOrigin, the module composes well with CSS keyframes, StringImpulse, and any transform-based animation you already have.
  • The module does not remove or manage transform itself. It only defines the pivot for transforms coming from elsewhere.
  • The module also does not restore a previous transform-origin value on disconnect. It is a one-way inline style write.