{"id":23657485,"url":"https://github.com/revueltai/movinwords","last_synced_at":"2025-09-01T08:32:53.906Z","repository":{"id":50217480,"uuid":"338303873","full_name":"revueltai/movinwords","owner":"revueltai","description":"Animate sentences, words, and letters in various creative ways.","archived":false,"fork":false,"pushed_at":"2024-12-22T19:02:47.000Z","size":459,"stargazers_count":22,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-12-27T15:09:42.897Z","etag":null,"topics":["animation","javascript","text","transitions","typescript","words"],"latest_commit_sha":null,"homepage":"https://movinwords.vercel.app/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/revueltai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-12T11:49:06.000Z","updated_at":"2024-12-26T21:00:55.000Z","dependencies_parsed_at":"2024-01-03T14:29:11.972Z","dependency_job_id":"df645c06-caf1-4419-b68a-019a3f64e59a","html_url":"https://github.com/revueltai/movinwords","commit_stats":{"total_commits":36,"total_committers":2,"mean_commits":18.0,"dds":0.05555555555555558,"last_synced_commit":"d5ed2d48fbf0a58fa203b754b2bb3cca0d263693"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revueltai%2Fmovinwords","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revueltai%2Fmovinwords/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revueltai%2Fmovinwords/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/revueltai%2Fmovinwords/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/revueltai","download_url":"https://codeload.github.com/revueltai/movinwords/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231680365,"owners_count":18410104,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","javascript","text","transitions","typescript","words"],"created_at":"2024-12-28T21:53:59.042Z","updated_at":"2025-09-01T08:32:53.884Z","avatar_url":"https://github.com/revueltai.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Movinwords Logo](https://a.storyblok.com/f/99692/378x134/92e66ed413/logo.gif)\n\n# Movinwords\nMovinwords is a versatile plugin for animating sentences, words, and letters in various creative ways.\n\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/revueltai/movinwords/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/movinwords)](https://img.shields.io/npm/v/movinwords)\n\n## Playgrounds\n\nExplore Movinwords capabilities in the [Playground](https://movinwords.vercel.app/).\n\nMovinwords is also available for your favorite Frameworks!\n\n[![Vue](https://a.storyblok.com/f/99692/80x80/38a9ffe002/vue.png)](https://stackblitz.com/edit/movinwords-vue)\n[![React](https://a.storyblok.com/f/99692/80x80/2162faf2ae/react.png)](https://stackblitz.com/edit/movinwords-react)\n[![Nuxt](https://a.storyblok.com/f/99692/80x80/1ee8d02e68/nuxt.png)](https://stackblitz.com/edit/movinwords-nuxt)\n[![Next](https://a.storyblok.com/f/99692/80x80/3d5e4cb32d/next.png)](https://stackblitz.com/edit/movinwords-next)\n[![Svelte](https://a.storyblok.com/f/99692/80x80/316e3ea903/svelte.png)](https://stackblitz.com/edit/movinwords-svelte)\n[![Angular](https://a.storyblok.com/f/99692/80x80/2a2726dabb/angular.png)](https://stackblitz.com/edit/movinwords-angular)\n\n## Installation\n\nInstall Movinwords using npm or yarn:\n\n```sh\nnpm install movinwords\n# npx movinwords\n# pnpm add movinwords\n# yarn add movinwords\n```\n\n## Basic Usage\n\n#### HTML\n```html\n\u003c!-- Static animated sentence --\u003e\n\u003ch1 class=\"my-sentence\"\u003eI am an animated sentence.\u003c/h1\u003e\n\u003c!-- \u003ch1 id=\"my-sentence\"\u003eI am an animated sentence.\u003c/h1\u003e --\u003e\n\n\u003c!-- Dynamically provided sentence --\u003e\n\u003ch1 class=\"my-dynamic-sentence\"\u003e\u003c/h1\u003e\n\u003c!-- \u003ch1 id=\"my-dynamic-sentence\"\u003e\u003c/h1\u003e --\u003e\n```\n\n### JavaScript \u0026 CSS\n\n#### Using a Framework or Bundler\n```javascript\nimport Movinwords from 'movinwords';\nimport 'movinwords/styles';\n\nconst staticSentence = new Movinwords({\n  el: '.my-sentence',\n});\n\nconst dynamicSentence = new Movinwords({\n  el: '.my-dynamic-sentence',\n  sentence: 'I am a dynamic sentence!',\n});\n```\n\n##### Using a CDN\n```html\n\u003clink rel=\"stylesheet\" href=\"https://unpkg.com/movinwords/dist/movinwords.css\"\u003e\n\u003cscript src=\"https://unpkg.com/movinwords/dist/movinwords.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n  (function () {\n    const sentence = new Movinwords({\n      el: '.my-sentence'\n    });\n\n    const injectedSentence = new Movinwords({\n      el: '.my-dynamic-sentence',\n      sentence: 'I am a dynamic sentence!'\n    });\n  })();\n\u003c/script\u003e\n```\n\n## Options\nCustomize Movinwords with various configuration options:\n\n| Option                  | Type      | Default                | Description                                                                                                                                         |\n|-------------------------|-----------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|\n| `el`                    | `string`  | `null`                 | **Required:** The element containing the sentence.                                                                                                  |\n| `sentence`              | `string`  | `''`                   | The sentence to animate dynamically.                                                                                                                |\n| `initialDelay`          | `number`  | `0`                    | The delay before animation starts, in milliseconds ([See Initial Delay](#initial-delay))                                                            |\n| `duration`              | `number`  | `1000`                 | The duration of the animation, in milliseconds.                                                                                                     |\n| `delay`                 | `number`  | `100`                  | The delay between word/letter animations, in milliseconds.                                                                                          |\n| `offset`                | `number`  | `20`                   | The offset for slide/reveal transitions ([See Offset](#offset)).                                                                                    |\n| `reverseTransition`     | `boolean` | `false`                | If true, reverses the animation transition ([See Reverse Transition](#reverse-transition)).                                                                                                        |\n| `reverseOrder`          | `boolean` | `false`                | If true, reverses the order of word/letter animations ([See Reverse Order](#reverse-order)).                                                                                             |\n| `animateLetters`        | `boolean` | `false`                | If true, animates individual letters ([See Animate Letters](#animate-letters)).                                                                                                              |\n| `autostart`             | `boolean` | `true`                 | If true, starts the animation on instance creation ([See Autostart](#autostart)).                                                                                                |\n| `transition`            | `MwTransition`  | `fadeIn`         | The transition effect to apply ([See Transitions](#transitions)).                                                                                                                    |\n| `pausableProps`         | `MwCSSProperties[]`  | `['opacity', 'transform']` | CSS properties to pause when animation is paused ([See Pause](#pause)).                                                                                                 |\n| `wordSpacing`           | `number`  | `null`                 | Custom spacing between words (in pixels) ([See Word Spacing](#word-spacing)).                                                   |\n| `letterSpacing`         | `number`  | `null`                 | Custom spacing between letters (in pixels) ([See Letter Spacing](#letter-spacing)).                                                 |\n| `highlight`                | `MwHighlightOptions`        | `{ classname: 'highlight', tag: 'strong', words: [] }` | Configuration to highlight specific words.                                                    |\n| `textAlignment`            | `MwTextAlignment`           | `initial`                      | The alignment of text inside the sentence (e.g., `left`, `center`, `right`).                    |\n| `events`                   | `MwEventListeners`          | `{}`                           | Callbacks for lifecycle events like `start`, `pause`, or `end`.                                 |\n| `eventsTransitionProperty` | `string`                    | `opacity`                      | The CSS property used to control transition-related events.                                      |\n| `scrambleLetters`          | `boolean`                   | `false`                        | Enables the scrambling or unscrambling of letters in the sentence ([See Scramble Letters](#scramble-letters)).  |\n| `scrambleMode`             | `MwScrambleMode`            | `unscramble`                   | The mode for scrambling letters (e.g., `scramble`, `unscramble`) ([See Scramble Letters](#scramble-letters)).  |\n| `scrambleChars`            | `string`                    | `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789` | The characters used during the scrambling process ([See Scramble Letters](#scramble-letters)). |\n| `scrambleFPS`              | `number`                    | `16`                           | The frames per second for the scrambling animation ([See Scramble Letters](#scramble-letters)). |\n| `intersectionStart`     | `boolean` | `false`            | Starts the animation when the element intersects the viewport ([See Viewport Intersection](#viewport-intersection)). |\n| `intersectionOptions`      | `MwIntersectionObserverProperties` | `{ root: null, threshold: 0, rootMargin: '0px' }` | Configuration for the viewport intersection behavior ([See Viewport Intersection](#viewport-intersection)). |\n\n\n## Methods\nMovinwords provides methods for additional control:\n\n| Method | Description |\n|--|--|\n| `start` | Starts the animation ([See Autostart](#autostart)).|\n| `pause` | Pauses the animation ([See Pause](#pause)).|\n| `resume` | Resumes the animation ([See Resume](#resume)).|\n| `destroy` | Destroys the instance and cleans up all associated resources ([See Destroy](#destroy)).|\n\n## Events\nMovinwords emits events at key points in its lifecycle.\nUse these events to implement custom behavior:\n\n| Event Name            | Description                                             |\n|-----------------------|---------------------------------------------------------|\n| `start`               | Triggered when the animation starts.                   |\n| `end`                 | Triggered when the animation ends.                     |\n| `pause`               | Triggered when the animation is paused.                |\n| `resume`              | Triggered when the animation is resumed.               |\n| `destroy`             | Triggered when the instance is destroyed.              |\n| `wordTransitionStart` | Triggered at the start of a word transition.            |\n| `wordTransitionEnd`   | Triggered at the end of a word transition.              |\n| `scrambleStart`            | Triggered when the letters scrambler starts.                                 |\n| `scrambleEnd`              | Triggered when the letters scrambler ends.                                   |\n| `letterScrambleStart`      | Triggered when a letter scrambling starts.                                   |\n| `letterScrambling`         | Triggered when a letter scrambles.                                           |\n| `letterScrambleEnd`        | Triggered when a letter scrambling ends.                                     |\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  events: {\n    start: (options) =\u003e {\n      console.log('Started!', options)\n    },\n    wordTransitionStart: (options) =\u003e {\n      console.log('Word Transition Started', options)\n    },\n    wordTransitionEnd: (options) =\u003e {\n      console.log('Word Transition Ended', options)\n    },\n    end: (options) =\u003e {\n      console.log('Ended!', options)\n    },\n    destroy: (options) =\u003e {\n      console.log('Instance destroyed!', options)\n    }\n  }\n})\n```\n\n#### Events and Transitions:\n`wordTransitionStart` and `wordTransitionEnd` use JavaScript's `transitionstart` and `transitionend` events under the hood to determine when they need to fire.\nThese events are triggered for each CSS transition property declared (e.g., if a CSS transition uses `opacity` and `transform`, the events will fire twice).\n\nTo avoid this issue, we have exposed the `eventsTransitionProperty` property.\nIt expects the CSS transition property name you want to focus on (e.g., `'filter'`) and excludes all other properties:\n\n```css\n.mw.slideInBottom .mw-l {\n  opacity: 0;\n  transition-property: opacity, transform;\n```\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  transition: 'slideInBottom',\n  events: { [YOUR EVENT CALLBACKS ] },\n  eventsTransitionProperty: 'opacity' // Movinwords will focus on the opacity prop and ignore the transform one.\n})\n```\n\n## Autostart\nBy default, Movinwords will start as soon as you create the instance.\n\nHowever, you can override this behavior and trigger the start action manually by passing `autostart: false` in the instance options and using the `start()` method:\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  autostart: false\n})\n\nsetTimeout(() =\u003e mw.start(), 2000) // Triggers start after 2 seconds.\n```\n\n## Pause\nTo pause an animation you can call the `pause()` method:\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  autostart: false\n})\n\nmw.start() // Triggers start\nsetTimeout(() =\u003e mw.pause(), 2000) // Triggers a pause after 2 seconds\n```\n\nInternally, Movinwords will pause the CSS properties listed in `pausableProps`.\nBy default, all transitions provided by Movinwords target the *opacity* and *transform* properties.\n\nIf you create custom [transitions](#transitions) that target other CSS properties, ensure to include them in `pausableProps`.\n\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  autostart: false,\n  transition: 'customTransition',\n  pausableProps: ['backgroundColor'] // Will pause the background-color property defined in 'customTransition' when pause() is triggered\n})\n\nmw.start()\nsetTimeout(() =\u003e mw.pause(), 2000)\n```\n\n## Resume\nTo resume (unpause) the animation, simply call the `resume()` method:\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  autostart: false\n})\n\nmw.start() // Triggers start\nsetTimeout(() =\u003e mw.pause(), 2000) // Triggers a pause after 2 seconds\nsetTimeout(() =\u003e mw.resume(), 4000) // Resumes the animation after 4 seconds\n```\n\n## Destroy\nTo destroy a Movinwords instance (including events, classes, and other resources), call the `destroy()` method:\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  autostart: false\n})\n\nmw.start() // Triggers start\nsetTimeout(() =\u003e mw.destroy(), 2000) // Triggers the destroy after 2 seconds\n```\n**Note:** After `destroy()` completes, each original sentence (or any injected ones) will be restored to their respective container elements.\n\n## Initial Delay\nYou can delay the start of a Movinwords instance by setting the `initialDelay` property.\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  initialDelay: 2000 // Delays the start of Movinwords by 2 seconds.\n})\n```\n\nThis is similar to doing:\n\n```js\nconst mw = new Movinwords({\n  el: '.my-sentence',\n  autostart: false\n})\n\nsetTimeout(() =\u003e mw.start(), 2000) // Delays the start of Movinwords by 2 seconds\n```\n\n\n## Transitions\nMovinwords comes with the following CSS transitions for use:\n\n| Name | Effect |\n|--|--|\n| `fadeIn` | Words fade in |\n| `slideInTop`    | Words slide+fade in from top to bottom |\n| `slideInBottom` | Words slide+fade in from bottom to top |\n| `slideInLeft`   | Words slide+fade in from left to right |\n| `slideInRight`  | Words slide+fade in from right to left |\n| `revealInTop`   | Words slide+fade in from top to bottom inside a hidden container |\n| `revealInBottom`   | Words slide+fade in from bottom to top inside a hidden container |\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  transition: 'slideInLeft' // Words will slide from the left\n})\n```\n\n## Offset\nYou can define an offset value for use with the `slide` and `reveal` animations.\nThis value determines how far the words should be offset from the baseline anchor point (0px).\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  transition: 'slideInLeft',\n  offset: 50 // Words will be offset by 50px from the start (0px) and slide in from left to right.\n\n})\n```\n\n## Reverse Transition\nYou can reverse the transition animations.\nThis instructs Movinwords to execute the reversed version of the transition you have defined.\n\n**Note:** This property may make transition names seem counterintuitive, as \"In\" transitions will behave like \"Out\" transitions.\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  transition: 'fadeIn',\n  reverseTransition: true // Transition \"fadeIn\" will behave like a \"fade out\" (from opacity 1, to opacity 0)\n})\n```\n\n## Reverse Order\nYou can reverse the order in which the words and/or letters appear or disappear.\nThis 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).\n\n### Reverse Words Order\n```html\n\u003ch2 class=\"my-sentence\"\u003eHello lovely world!\u003c/h2\u003e\n```\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  reverseOrder: true // \"world!\" will appear first, \"lovely\" second, \"Hello\" last (From right to left)\n})\n```\n\n### Reverse Letters Order\n```html\n\u003ch2 class=\"my-sentence\"\u003eHello lovely world!\u003c/h2\u003e\n```\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  reverseOrder: true, // \"!\" will appear first, \"d\" second, \"l\" third, etc (From right to left)\n  animateLetters: true // Enable letters animation\n})\n```\n\n## Word Spacing\nBy default, Movinwords calculates the space between words based on the sentence's font size.\nHowever, you can provide your own value to override this default behavior:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  wordSpacing: 50 // Will set a 50px space between each word\n})\n```\n\n## Letter Spacing\nYou can specify the space between each letter:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  letterSpacing: 50 // Will set a 50px space between each letter\n})\n```\n\n## Text Alignment\nYou can set the text alignment for each sentence:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  textAlignment: 'left' // Sentences will have their text left aligned\n})\n```\n\n## Highlight\nTo highlight words, pass a `highlight` object in the instance options:\n\n```html\n\u003ch1 class=\"my-sentence\"\u003eHello world! I am an animated sentence.\u003c/h1\u003e\n\n```\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  highlight: {\n    classname: 'highlight',\n    tag: 'strong',\n    words: ['world!', 'am']\n  }\n})\n```\n\n| Options    | Type    | Default    | Description                                                            |\n|------------|---------|------------|------------------------------------------------------------------------|\n| `classname` | `string` | `highlight` | Class name to append to the highlighted word tags                   |\n| `tag`      | `string` | `strong`   | HTML tag to wrap the highlighted word                                 |\n| `words`    | `array`  | `[]`       | Array containing the words to highlight                               |\n\n## Viewport Intersection\nYou can define whether you want to trigger Movinwords **only when the element is in the viewport**.\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  intersectionStart: true // Movinwords will start when the element enters the viewport\n})\n```\n\nMovinwords uses [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) behind the scenes.\nIf you wish to modify the intersection properties, you can provide `intersectionOptions` in the instance options:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  intersectionStart: true,\n  intersectionOptions: {\n    root: null,\n    threshold: 0,\n    rootMargin: '0px'\n  }\n})\n```\n\n## Animate Letters\nBy default, Movinwords animates the words in a sentence.\nIf you wish to animate each individual letter in a word instead, set `animateLetters` to `true`.\n\n```html\n\u003ch2 class=\"my-sentence\"\u003eHello lovely world!\u003c/h2\u003e\n```\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  transition: 'slideInBottom',\n  animateLetters: true // Each letter will slide in from the bottom\n})\n```\n\n## Scramble Letters\nYou can `scramble` or `unscramble` the letters in a sentence.\n\n```html\n\u003ch2 class=\"my-sentence\"\u003eHello lovely world!\u003c/h2\u003e\n```\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  scrambleLetters: true, // Enables the scrambler. By default each letter will be unscrambled from gibberish to the final letter\n})\n```\n\nYou can change the scrambler's mode to `scramble` the letters:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  scrambleLetters: true, // Enables the scrambler\n  scrambleMode: 'scramble', // Each letter will scrambled into gibberish\n})\n```\n\nSet additional scrambling options to achieve different results:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  scrambleLetters: true, // Enables the scrambler\n  scrambleChars: '123456789', // A custom set of characters to use for the scrambler\n  scrambleFPS: 30, // The scrambler's scrambling speed in FPS\n})\n```\n\nYou can also combine the scramble options with other Movinwords features for even cooler results:\n\n```js\nnew Movinwords({\n  el: '.my-sentence',\n  scrambleLetters: true,\n  reverseOrder: true, // The scramble will be done in the letter's opposite direction\n  animateLetters: true // The letters will have an animation\n})\n```\n\n---\n\n#### Like Movinwords, but you want to animate HTML blocks instead? \n## [Try Movinblocks!](https://github.com/revueltai/movinblocks)\nIt's another lightweight plugin I created, designed for animating divs, headers, footers, sections, buttons, and more in a seamless timeline sequence. \n\n[Give it a go!](https://github.com/revueltai/movinblocks)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frevueltai%2Fmovinwords","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frevueltai%2Fmovinwords","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frevueltai%2Fmovinwords/lists"}