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.
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. - On viewports
<= 1024px, the runtime switches to a mobile branch that emits0and writestranslate3d(0, 0px, 0).