Modules
StringParallax
Transforms scroll progress into parallax travel and emits a numeric object event.
StringParallax
StringParallax uses the same internal timeline math as StringProgress, but its public output is different. Instead of publishing a progress variable, it computes a vertical translation and writes it directly to transform.
Public API
Attributes
| Attribute | Type | Default | Real runtime effect |
|---|---|---|---|
string-parallax | number | 0.2 | Sets movement strength. The runtime stores the absolute value as strength and keeps the sign as direction. |
string-parallax-bias | number | 0.0 | Redistributes movement before and after the midpoint of the travel. |
string-enter-el | string | top | Shared timeline start geometry inherited from StringProgress. |
string-enter-vp | string | bottom | Shared timeline start geometry inherited from StringProgress. |
string-exit-el | string | bottom | Shared timeline end geometry inherited from StringProgress. |
string-exit-vp | string | top | Shared timeline end geometry inherited from StringProgress. |
CSS Variables and DOM Output
The module writes:
- inline
transform: translate3d(0, <value>px, 0)
It also emits the current translation as a number.
The current runtime does not publish a parallax CSS variable, and it does not publish object:progress:<id> for parallax elements.
Events
| Channel | Payload | Fired when |
|---|---|---|
object:parallax:<id> | number | The current parallax translation is recomputed |
stringTune.on('object:parallax:hero-layer', (offset) => {
console.log(offset);
});
Mirror Behavior
If a mirror is linked with string-copy-from, the same transform string is applied to the mirror element too.
Quick Example
<section class="hero">Scroll down</section>
<section class="parallax-frame">
<div string="parallax" string-id="hero-layer" string-parallax="0.3" class="parallax-layer">
<div class="parallax-inner"></div>
</div>
<div class="parallax-center">
<div class="parallax-label">Offset <span id="parallax-value">0</span>px</div>
</div>
</section>
<section class="hero">Scroll up</section>
.hero,
.parallax-frame {
min-height: 100vh;
}
.hero {
display: grid;
place-items: center;
}
.parallax-frame {
position: relative;
overflow: hidden;
border-top: 1px solid black;
border-bottom: 1px solid black;
}
.parallax-layer {
position: absolute;
inset: -25% 0;
}
.parallax-inner {
position: absolute;
inset: 0;
border-top: 1px solid black;
border-bottom: 1px solid black;
background: repeating-linear-gradient(
180deg,
white 0,
white 18px,
black 18px,
black 19px
);
}
.parallax-center {
position: relative;
z-index: 1;
min-height: 100vh;
display: grid;
place-items: center;
}
Wrap the moving layer if you need any additional transform of your own. StringParallax owns the element's transform property.
Registration
import StringTune, { StringParallax } from '@fiddle-digital/string-tune';
const stringTune = StringTune.getInstance();
stringTune.use(StringParallax);
stringTune.start(60);
You do not need to register StringProgress separately. StringParallax already extends it internally.
Mode scope
StringParallax is scoped to smooth mode by default. On mobile — where the default scroll mode is default — objects with string="parallax" are automatically disconnected and produce no output.
To activate StringParallax in all scroll modes, use the bracket override:
<div string="parallax[]" string-id="hero-layer" string-parallax="0.3"></div>
See Scroll Modes for the full bracket syntax reference.
Detailed Behavior
StringParallaxcomputes progress internally, but it does not expose that progress as public CSS or public progress events.- During initialization, the module overwrites
offset-topandoffset-bottomwithabs(string-parallax) * viewportHeight. In the current runtime, manual parallax offsets are therefore not a reliable public control surface. - When the scroll mode changes away from
smooth, the object disconnects and all managed styles are cleared.