Movinwords is a versatile plugin for animating sentences, words, and letters in various creative ways.
Explore Movinwords capabilities in the Playground.
Movinwords is also available for your favorite Frameworks!
Install Movinwords using npm or yarn:
npm install movinwords
# npx movinwords
# pnpm add movinwords
# yarn add movinwords
<!-- Static animated sentence -->
<h1 class="my-sentence">I am an animated sentence.</h1>
<!-- <h1 id="my-sentence">I am an animated sentence.</h1> -->
<!-- Dynamically provided sentence -->
<h1 class="my-dynamic-sentence"></h1>
<!-- <h1 id="my-dynamic-sentence"></h1> -->
import Movinwords from 'movinwords';
import 'movinwords/styles';
const staticSentence = new Movinwords({
el: '.my-sentence',
});
const dynamicSentence = new Movinwords({
el: '.my-dynamic-sentence',
sentence: 'I am a dynamic sentence!',
});
<link rel="stylesheet" href="https://unpkg.com/movinwords/dist/movinwords.css">
<script src="https://unpkg.com/movinwords/dist/movinwords.min.js"></script>
<script>
(function () {
const sentence = new Movinwords({
el: '.my-sentence'
});
const injectedSentence = new Movinwords({
el: '.my-dynamic-sentence',
sentence: 'I am a dynamic sentence!'
});
})();
</script>
Customize Movinwords with various configuration options:
Option | Type | Default | Description |
---|---|---|---|
el |
string |
null |
Required: The element containing the sentence. |
sentence |
string |
'' |
The sentence to animate dynamically. |
initialDelay |
number |
0 |
The delay before animation starts, in milliseconds (See Initial Delay) |
duration |
number |
1000 |
The duration of the animation, in milliseconds. |
delay |
number |
100 |
The delay between word/letter animations, in milliseconds. |
offset |
number |
20 |
The offset for slide/reveal transitions (See Offset). |
reverseTransition |
boolean |
false |
If true, reverses the animation transition (See Reverse Transition). |
reverseOrder |
boolean |
false |
If true, reverses the order of word/letter animations (See Reverse Order). |
animateLetters |
boolean |
false |
If true, animates individual letters (See Animate Letters). |
autostart |
boolean |
true |
If true, starts the animation on instance creation (See Autostart). |
transition |
MwTransition |
fadeIn |
The transition effect to apply (See Transitions). |
pausableProps |
MwCSSProperties[] |
['opacity', 'transform'] |
CSS properties to pause when animation is paused (See Pause). |
wordSpacing |
number |
null |
Custom spacing between words (in pixels) (See Word Spacing). |
letterSpacing |
number |
null |
Custom spacing between letters (in pixels) (See Letter Spacing). |
highlight |
MwHighlightOptions |
{ classname: 'highlight', tag: 'strong', words: [] } |
Configuration to highlight specific words. |
textAlignment |
MwTextAlignment |
initial |
The alignment of text inside the sentence (e.g., left , center , right ). |
events |
MwEventListeners |
{} |
Callbacks for lifecycle events like start , pause , or end . |
eventsTransitionProperty |
string |
opacity |
The CSS property used to control transition-related events. |
scrambleLetters |
boolean |
false |
Enables the scrambling or unscrambling of letters in the sentence (See Scramble Letters). |
scrambleMode |
MwScrambleMode |
unscramble |
The mode for scrambling letters (e.g., scramble , unscramble ) (See Scramble Letters). |
scrambleChars |
string |
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 |
The characters used during the scrambling process (See Scramble Letters). |
scrambleFPS |
number |
16 |
The frames per second for the scrambling animation (See Scramble Letters). |
intersectionStart |
boolean |
false |
Starts the animation when the element intersects the viewport (See Viewport Intersection). |
intersectionOptions |
MwIntersectionObserverProperties |
{ root: null, threshold: 0, rootMargin: '0px' } |
Configuration for the viewport intersection behavior (See Viewport Intersection). |
Movinwords provides methods for additional control:
Method | Description |
---|---|
start |
Starts the animation (See Autostart). |
pause |
Pauses the animation (See Pause). |
resume |
Resumes the animation (See Resume). |
destroy |
Destroys the instance and cleans up all associated resources (See Destroy). |
Movinwords emits events at key points in its lifecycle. Use these events to implement custom behavior:
Event Name | Description |
---|---|
start |
Triggered when the animation starts. |
end |
Triggered when the animation ends. |
pause |
Triggered when the animation is paused. |
resume |
Triggered when the animation is resumed. |
destroy |
Triggered when the instance is destroyed. |
wordTransitionStart |
Triggered at the start of a word transition. |
wordTransitionEnd |
Triggered at the end of a word transition. |
scrambleStart |
Triggered when the letters scrambler starts. |
scrambleEnd |
Triggered when the letters scrambler ends. |
letterScrambleStart |
Triggered when a letter scrambling starts. |
letterScrambling |
Triggered when a letter scrambles. |
letterScrambleEnd |
Triggered when a letter scrambling ends. |
const mw = new Movinwords({
el: '.my-sentence',
events: {
start: (options) => {
console.log('Started!', options)
},
wordTransitionStart: (options) => {
console.log('Word Transition Started', options)
},
wordTransitionEnd: (options) => {
console.log('Word Transition Ended', options)
},
end: (options) => {
console.log('Ended!', options)
},
destroy: (options) => {
console.log('Instance destroyed!', options)
}
}
})
wordTransitionStart
and wordTransitionEnd
use JavaScript's transitionstart
and transitionend
events under the hood to determine when they need to fire.
These events are triggered for each CSS transition property declared (e.g., if a CSS transition uses opacity
and transform
, the events will fire twice).
To avoid this issue, we have exposed the eventsTransitionProperty
property.
It expects the CSS transition property name you want to focus on (e.g., 'filter'
) and excludes all other properties:
.mw.slideInBottom .mw-l {
opacity: 0;
transition-property: opacity, transform;
const mw = new Movinwords({
el: '.my-sentence',
transition: 'slideInBottom',
events: { [YOUR EVENT CALLBACKS ] },
eventsTransitionProperty: 'opacity' // Movinwords will focus on the opacity prop and ignore the transform one.
})
By default, Movinwords will start as soon as you create the instance.
However, you can override this behavior and trigger the start action manually by passing autostart: false
in the instance options and using the start()
method:
const mw = new Movinwords({
el: '.my-sentence',
autostart: false
})
setTimeout(() => mw.start(), 2000) // Triggers start after 2 seconds.
To pause an animation you can call the pause()
method:
const mw = new Movinwords({
el: '.my-sentence',
autostart: false
})
mw.start() // Triggers start
setTimeout(() => mw.pause(), 2000) // Triggers a pause after 2 seconds
Internally, Movinwords will pause the CSS properties listed in pausableProps
.
By default, all transitions provided by Movinwords target the opacity and transform properties.
If you create custom transitions that target other CSS properties, ensure to include them in pausableProps
.
const mw = new Movinwords({
el: '.my-sentence',
autostart: false,
transition: 'customTransition',
pausableProps: ['backgroundColor'] // Will pause the background-color property defined in 'customTransition' when pause() is triggered
})
mw.start()
setTimeout(() => mw.pause(), 2000)
To resume (unpause) the animation, simply call the resume()
method:
const mw = new Movinwords({
el: '.my-sentence',
autostart: false
})
mw.start() // Triggers start
setTimeout(() => mw.pause(), 2000) // Triggers a pause after 2 seconds
setTimeout(() => mw.resume(), 4000) // Resumes the animation after 4 seconds
To destroy a Movinwords instance (including events, classes, and other resources), call the destroy()
method:
const mw = new Movinwords({
el: '.my-sentence',
autostart: false
})
mw.start() // Triggers start
setTimeout(() => mw.destroy(), 2000) // Triggers the destroy after 2 seconds
Note: After destroy()
completes, each original sentence (or any injected ones) will be restored to their respective container elements.
You can delay the start of a Movinwords instance by setting the initialDelay
property.
const mw = new Movinwords({
el: '.my-sentence',
initialDelay: 2000 // Delays the start of Movinwords by 2 seconds.
})
This is similar to doing:
const mw = new Movinwords({
el: '.my-sentence',
autostart: false
})
setTimeout(() => mw.start(), 2000) // Delays the start of Movinwords by 2 seconds
Movinwords comes with the following CSS transitions for use:
Name | Effect |
---|---|
fadeIn |
Words fade in |
slideInTop |
Words slide+fade in from top to bottom |
slideInBottom |
Words slide+fade in from bottom to top |
slideInLeft |
Words slide+fade in from left to right |
slideInRight |
Words slide+fade in from right to left |
revealInTop |
Words slide+fade in from top to bottom inside a hidden container |
revealInBottom |
Words slide+fade in from bottom to top inside a hidden container |
new Movinwords({
el: '.my-sentence',
transition: 'slideInLeft' // Words will slide from the left
})
You can define an offset value for use with the slide
and reveal
animations.
This value determines how far the words should be offset from the baseline anchor point (0px).
new Movinwords({
el: '.my-sentence',
transition: 'slideInLeft',
offset: 50 // Words will be offset by 50px from the start (0px) and slide in from left to right.
})
You can reverse the transition animations. This instructs Movinwords to execute the reversed version of the transition you have defined.
Note: This property may make transition names seem counterintuitive, as "In" transitions will behave like "Out" transitions.
new Movinwords({
el: '.my-sentence',
transition: 'fadeIn',
reverseTransition: true // Transition "fadeIn" will behave like a "fade out" (from opacity 1, to opacity 0)
})
You can reverse the order in which the words and/or letters appear or disappear. This will instruct Movinwords to transition the words and/or letters in the opposite order (e.g., the last word of the sentence will be the first to transition).
<h2 class="my-sentence">Hello lovely world!</h2>
new Movinwords({
el: '.my-sentence',
reverseOrder: true // "world!" will appear first, "lovely" second, "Hello" last (From right to left)
})
<h2 class="my-sentence">Hello lovely world!</h2>
new Movinwords({
el: '.my-sentence',
reverseOrder: true, // "!" will appear first, "d" second, "l" third, etc (From right to left)
animateLetters: true // Enable letters animation
})
By default, Movinwords calculates the space between words based on the sentence's font size. However, you can provide your own value to override this default behavior:
new Movinwords({
el: '.my-sentence',
wordSpacing: 50 // Will set a 50px space between each word
})
You can specify the space between each letter:
new Movinwords({
el: '.my-sentence',
letterSpacing: 50 // Will set a 50px space between each letter
})
You can set the text alignment for each sentence:
new Movinwords({
el: '.my-sentence',
textAlignment: 'left' // Sentences will have their text left aligned
})
To highlight words, pass a highlight
object in the instance options:
<h1 class="my-sentence">Hello world! I am an animated sentence.</h1>
new Movinwords({
el: '.my-sentence',
highlight: {
classname: 'highlight',
tag: 'strong',
words: ['world!', 'am']
}
})
Options | Type | Default | Description |
---|---|---|---|
classname |
string |
highlight |
Class name to append to the highlighted word tags |
tag |
string |
strong |
HTML tag to wrap the highlighted word |
words |
array |
[] |
Array containing the words to highlight |
You can define whether you want to trigger Movinwords only when the element is in the viewport.
new Movinwords({
el: '.my-sentence',
intersectionStart: true // Movinwords will start when the element enters the viewport
})
Movinwords uses IntersectionObserver behind the scenes.
If you wish to modify the intersection properties, you can provide intersectionOptions
in the instance options:
new Movinwords({
el: '.my-sentence',
intersectionStart: true,
intersectionOptions: {
root: null,
threshold: 0,
rootMargin: '0px'
}
})
By default, Movinwords animates the words in a sentence.
If you wish to animate each individual letter in a word instead, set animateLetters
to true
.
<h2 class="my-sentence">Hello lovely world!</h2>
new Movinwords({
el: '.my-sentence',
transition: 'slideInBottom',
animateLetters: true // Each letter will slide in from the bottom
})
You can scramble
or unscramble
the letters in a sentence.
<h2 class="my-sentence">Hello lovely world!</h2>
new Movinwords({
el: '.my-sentence',
scrambleLetters: true, // Enables the scrambler. By default each letter will be unscrambled from gibberish to the final letter
})
You can change the scrambler's mode to scramble
the letters:
new Movinwords({
el: '.my-sentence',
scrambleLetters: true, // Enables the scrambler
scrambleMode: 'scramble', // Each letter will scrambled into gibberish
})
Set additional scrambling options to achieve different results:
new Movinwords({
el: '.my-sentence',
scrambleLetters: true, // Enables the scrambler
scrambleChars: '123456789', // A custom set of characters to use for the scrambler
scrambleFPS: 30, // The scrambler's scrambling speed in FPS
})
You can also combine the scramble options with other Movinwords features for even cooler results:
new Movinwords({
el: '.my-sentence',
scrambleLetters: true,
reverseOrder: true, // The scramble will be done in the letter's opposite direction
animateLetters: true // The letters will have an animation
})
It's another lightweight plugin I created, designed for animating divs, headers, footers, sections, buttons, and more in a seamless timeline sequence.