We’ve invited the creators of StringTune to give us a deeper look into their powerful animation library. Originally built as an internal tool at Fiddle.Digital Design Agency, it’s grown into a flexible system for handling smooth scrolling, animation hooks, and performance-friendly effects—all without bloated dependencies.
In their case study, they shared how it all started—now, they’re here to show what it is and what you can build with it.
What is StringTune?
StringTune is a modular JavaScript library designed for the convenient and fast application of commonly used animations and animation hooks in web development. It offers a flexible system that allows you to combine, customize, or create your own effects without limitations.
It includes several prebuilt modules:
- StringTune
- StringLoading
- StringFPSTracker
- StringPositionTracker
- StringResponsive
- StringScrollbar
- StringLazy
- StringVideoAutoplay
- StringAnchor
- StringParallax
- StringProgress
- StringLerp
- StringLerpTracker
- StringDelayLerpTracker
- StringGlide
- StringCursor
- StringMagnetic
- StringSplit
StringTune isn’t just a collection of predefined effects—it’s a flexible framework that allows you to create custom modules that work just as efficiently as the built-in ones. Whether you need fine-tuned control over animations or want to build entirely new interactions, StringTune provides the tools to integrate them smoothly into your project.
Why it exists
StringTune is an alternative to popular libraries, but unlike them, it addresses all the challenges we encounter in daily web development. By consolidating everything in one place, we’ve improved efficiency, reduced file size, and eliminated unnecessary computations.
It acts as a centralized system that connects and manages everything happening on a web page from a single hub—Tune.
Read more in our Case Study to learn why we created StringTune and how it came to be.
What it can do
Let’s go through the modules currently available and explain what they do:
- StringTune – The core module that enables scroll events, creates hooks, and adds smooth scrolling (which can be disabled if needed). All the modules below are built on top of Tune.
- StringLoading – Determines when the page has finished loading to trigger animations. (manual hook)
- StringFPSTracker – Measures FPS in real-time for performance analysis. (for development stage)
- StringPositionTracker – Tracks the scroll position and movement direction of the page. (for development stage)
- StringResponsive – Adjusts element behavior based on screen size.
- StringScrollbar – Creates custom scrollbars with flexible styling and behavior settings.
- StringLazy – Delays image loading to reduce page load burden.
- StringVideoAutoplay – Automatically plays videos without user interaction.
- StringAnchor – Defines anchor points for element transformations.
- StringParallax – Adds a simple parallax effect with minimal setup.
- StringProgress – Determines an element’s position in the viewport to trigger animations.
- StringLerp, StringLerpTracker, StringDelayLerpTracker – Controls animation speeds using scroll values.
- StringGlide – Adds inertia effects to elements when scrolling.
- StringCursor – Creates a custom cursor that reacts to interactions.
- StringMagnetic – Adds a magnetic effect, pulling elements toward the cursor.
- StringSplit – Splits text into words, characters, or lines.
And now, it’s time for Vlad, our lead engineer, to dive deeper into how it all works.
Tech Features
StringTune is more than just an animation library. It is built as a flexible ecosystem that allows seamless animation integration without compromising performance or control. The core idea is declarative management through HTML and CSS, eliminating the need to write JavaScript for standard effects.
Modular Architecture
StringTune is built on a modular system where each component functions independently but integrates within a shared environment. This allows for:
- Easy activation and deactivation of features without modifying the core library.
- Independent modules that can be extended as needed.
- All modules sharing a common event-handling system.
- Global data accessibility, ensuring seamless synchronization.
Declarative Approach (HTML & CSS-Based)
One of StringTune’s standout features is its ability to control animations declaratively, without writing JavaScript. You define behaviors using HTML attributes and manage them through CSS variables, allowing real-time updates.
For example, adding an animation is as simple as:
<div class="element" string="progress"></div>
The animation is then controlled via CSS:
.element {
transform: translateX(calc(var(--progress) * 20px));
}
This approach gives full flexibility without requiring additional JavaScript logic.
Minimal Impact on Performance
StringTune is optimized for high performance, ensuring animations remain smooth while reducing browser workload. Key optimizations include:
- Updating only necessary parameters instead of recalculating entire styles.
- Reducing layout shifts and repaints to maintain a high FPS.
- Enabling modules only when required, avoiding unnecessary computations.
- Adapting dynamically based on device performance to ensure smooth rendering.
Integration Flexibility
StringTune is framework-agnostic, meaning it can be used in any development environment with ease:
- HTML + CSS: Simply include the library and use attributes.
- Nuxt / Vue / React / Angular: Easily integrates since it has no global dependencies.
- Flexible Configuration: Control behavior via environment variables or API.
Basic Use Cases
Most of the modules are showcased on the demo page: See the Live Demo.
For more details, check the official documentation.
Advanced Example – Creating Your Own Module in StringTune
In this example, we’ll create a custom module for StringTune that changes an element’s color during scrolling, smoothly transitioning between two shades.
Integrate StringTune
<script src="https://unpkg.com/@fiddle-digital/string-tune@0.0.61/dist/index.js"></script>
Creating Your Own Class and Inheriting from StringProgress
To integrate our module into the StringTune system, we create the StringColorChange
class and inherit it from StringProgress
. This allows access to the scroll tracking mechanism and interaction with elements.
class StringColorChange extends StringTune.StringProgress {
...
}
Defining the HTML Key for the Module
To allow StringTune to determine which elements to connect to the module, we need to set a unique HTML key (htmlKey
). In this case, we use “color-change,” meaning all elements with the attribute string="color-change"
will be processed by this module.
constructor(visitor) {
super(visitor);
this.htmlKey = "color-change";
}
Object Initialization and Color Storage
When the module is connected to an element, we want to store the initial and final colors to avoid reading them each time during scrolling. To do this, we use the initObject()
method, which is called during the element initialization.
initObject(globalId, object, el, attributes) {
super.initObject(globalId, object, el, attributes);
const startColor = this.attribute.process(el, "string-start-color", 10);
const endColor = this.attribute.process(el, "string-end-color", 10);
const startColorValues = this.parseColor(startColor);
const endColorValues = this.parseColor(endColor);
object.setProperty("start-color", startColorValues);
object.setProperty("end-color", endColorValues);
}
Helper Methods for Working with Colors
These methods are not part of StringTune, but they will help us in our work.
- hexToRgb(hex) – converts a color from HEX to RGB format.
- interpolateColor(start, end, progress) – calculates the intermediate color between two given colors using the progress value.
parseColor(color) {
if (color.startsWith("#")) {
return this.hexToRgba(color);
} else if (color.startsWith("rgb")) {
return this.rgbToArray(color);
}
return [0, 0, 0, 1];
}
hexToRgba(hex) {
let r = 0, g = 0, b = 0, a = 1;
if (hex.length === 4) {
r = parseInt(hex[1] + hex[1], 16);
g = parseInt(hex[2] + hex[2], 16);
b = parseInt(hex[3] + hex[3], 16);
} else if (hex.length === 7) {
r = parseInt(hex.substring(1, 3), 16);
g = parseInt(hex.substring(3, 5), 16);
b = parseInt(hex.substring(5, 7), 16);
}
return [r, g, b, a];
}
rgbToArray(rgb) {
const match = rgb.match(/\d+(\.\d+)?/g);
return match ? match.map(Number) : [0, 0, 0, 1];
}
interpolateColor(start, end, progress) {
const r = Math.round(start[0] + (end[0] - start[0]) * progress);
const g = Math.round(start[1] + (end[1] - start[1]) * progress);
const b = Math.round(start[2] + (end[2] - start[2]) * progress);
const a = (start[3] + (end[3] - start[3]) * progress).toFixed(2);
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
Applying the Scroll-Based Color Transition
Here’s where the magic happens; the color changes during scrolling.
The onScroll()
method is called every time the user scrolls the page. It retrieves the scroll progress value, calculates the intermediate color, and changes the element’s background.
onScroll(data) {
super.onScroll(data);
this.objects.forEach((object) => {
const progress = object.getProperty('progress');
if (progress !== undefined) {
const startColor = object.getProperty('start-color');
const endColor = object.getProperty('end-color');
if (startColor && endColor) {
const interpolatedColor = this.interpolateColor(startColor, endColor, progress);
object.el.style.backgroundColor = interpolatedColor;
}
}
});
}
Registering the Module in StringTune
Now we connect our module to StringTune.
Then, we need to register our module with StringTune so that the library can use it.
const stringTune = StringTune.StringTune.getInstance();
stringTune.use(StringColorChange);
stringTune.start(0);
HTML Example
<body>
<div style="height: 100vh; display: flex; align-items: center; justify-content: center;">
<h1>Scroll down</h1>
</div>
<div style="height: 100vh; display: flex; align-items: center; justify-content: center;"
string="color-change" string-start-color="#ff0000" string-end-color="rgba(0,255,0,0.5)">
</div>
<div style="height: 100vh; display: flex; align-items: center; justify-content: center;">
<h1>Footer</h1>
</div>
</body>
Project Source Code
Check out the source code on GitHub.
Live Demo
Real Live Usage
At Fiddle.Digital Design Agency, we used StringTune to develop a custom module for Xe.Works, bridging two worlds: 2D and 3D.
Our module dynamically integrates scroll values, mouse position, and DOM element positions, automatically transferring this data into a 3D environment. The motion curve of the WebGL element is synchronized with these inputs, ensuring seamless interaction within Three.js.
Conclusion
StringTune is not a simple animation library—it’s a professional tool designed for developers who need efficient calculations and hooks. Instead of offering predefined effects, it provides a robust foundation for building custom animation solutions.
From here, it’s all about your creativity. We, for one, make full use of ours.
Credits
Fiddle.Digital Design Agency