├── package.json ├── production.min.js ├── main.min.js ├── browserUnpkg.js ├── main.js └── README.md /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@murtuzaalisurti/wavy", 3 | "version": "1.3.1", 4 | "description": "A package to generate animated wavy text!", 5 | "main": "main.min.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/murtuzaalisurti/wavy.git" 12 | }, 13 | "keywords": [ 14 | "package", 15 | "text animation", 16 | "wavy text", 17 | "javascript" 18 | ], 19 | "author": "Murtuzaali Surti", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/murtuzaalisurti/wavy/issues" 23 | }, 24 | "homepage": "https://github.com/murtuzaalisurti/wavy#readme" 25 | } 26 | -------------------------------------------------------------------------------- /production.min.js: -------------------------------------------------------------------------------- 1 | function wavy(n,t,e){const a={color:"black",fontSize:"1rem",fontFamily:"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif",transform:"scale(1.5)"};function o(n){return void 0!==e&&0!==Object.keys(e).length&&void 0!==e[n]?e[n]:a[n]}n.style=` \n width: -webkit-fit-content;\n width: -moz-fit-content;\n width: fit-content; \n -webkit-transform: ${o("transform")};\n transform: ${o("transform")};\n font-family: ${o("fontFamily")};\n font-size: ${o("fontSize")};\n `;const r=t.words;let i=1,s=r.map((n=>n.split(""))).map((n=>n.map((n=>" "===n?" ":`${n}`)).join(""))),l=n;l.innerHTML=s[0],function t(){l.childNodes.forEach((n=>{n.style=`\n display: inline-block;\n opacity: 0;\n transform: translateY(10px);\n color: ${o("color")};\n `}));let e=n.childNodes;for(let n=0;n{e.forEach((n=>{n.style="opacity: 0;"}));for(let n=0;nt.split(""))).map((t=>t.map((t=>" "===t?" ":`${t}`)).join(""))),l=t;l.innerHTML=s[0],function n(){l.childNodes.forEach((t=>{t.style=`\n display: inline-block;\n opacity: 0;\n transform: translateY(10px);\n color: ${a("color")};\n `}));let e=t.childNodes;for(let t=0;t{e.forEach((t=>{t.style="opacity: 0;"}));for(let t=0;t skill.split("")); 29 | 30 | let array_of_final_html_string = array_of_skills_splitted.map(a_skill => a_skill.map(letter => letter === " " ? ` ` : `${letter}`).join("")); 31 | 32 | let text_string = element; 33 | 34 | text_string.innerHTML = array_of_final_html_string[0]; 35 | 36 | function text_animate() { 37 | text_string.childNodes.forEach((child) => { 38 | child.style = ` 39 | display: inline-block; 40 | opacity: 0; 41 | transform: translateY(10px); 42 | color: ${setOptions('color')}; 43 | `; 44 | }) 45 | 46 | let spans = element.childNodes; // document.querySelectorAll(".class span"); 47 | 48 | for (let i = 0; i < spans.length; i++) { 49 | let word_length = spans.length; 50 | let zoom_in = text_string.animate([ 51 | { 52 | transform: `${setOptions('transform')}` // default = `scale(${Number(1.5)})` 53 | }, 54 | { 55 | transform: `scale(${Number(1)})` 56 | } 57 | ], { 58 | delay: `${Number((word_length/3)*100)}`, 59 | duration: 400, 60 | iterations: 1, 61 | easing: `ease-in-out`, 62 | fill: `both` 63 | }); 64 | let animation = spans[i].animate([ 65 | { 66 | opacity: 0, 67 | transform: `translateY(${Number(10)}px)` 68 | }, 69 | { 70 | opacity: 1, 71 | transform: `translateY(${Number(0)}px)` 72 | } 73 | ], { 74 | delay: ((i + 2) / 2) * 100, 75 | duration: (i + 0.1) * 10, 76 | easing: `ease-out`, 77 | iterations: 1, 78 | fill: `forwards` 79 | }) 80 | 81 | if (i == (spans.length - 1)) { 82 | setTimeout(() => { 83 | spans.forEach((span) => { 84 | span.style = `opacity: 0;`; 85 | }) 86 | 87 | for(let k = 0; k < skills_name.length; k++){ 88 | if(iteration == (k+1)){ 89 | text_string.innerHTML = array_of_final_html_string[k]; 90 | break; 91 | } 92 | } 93 | 94 | text_animate(); 95 | }, 2000) 96 | } 97 | } 98 | if(iteration == skills_name.length){ 99 | iteration = 1; 100 | } else { 101 | iteration++; 102 | } 103 | } 104 | 105 | text_animate(); 106 | } 107 | 108 | /* --use-- 109 | 110 | wavy( 111 | document.querySelector(".description"), 112 | {words: ["Accenture", "Instagram", "Wordle", "Ginger"]}, 113 | {color: 'green', fontSize: '2rem', fontFamily: 'Poppins, sans-serif', transform: 'scale(1.8)'} 114 | ); 115 | 116 | */ -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | exports.wavy = function wavy(element, words, options) { 2 | 3 | const defaults = { 4 | color: 'black', 5 | fontSize: '1rem', 6 | fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif", 7 | transform: 'scale(1.5)' 8 | } 9 | 10 | function setOptions(type){ 11 | return (options !== undefined) ? ((Object.keys(options).length !== 0) ? (options[type] !== undefined ? options[type] : defaults[type]) : defaults[type]) : defaults[type]; 12 | } 13 | 14 | element.style = ` 15 | width: -webkit-fit-content; 16 | width: -moz-fit-content; 17 | width: fit-content; 18 | -webkit-transform: ${setOptions('transform')}; 19 | transform: ${setOptions('transform')}; 20 | font-family: ${setOptions('fontFamily')}; 21 | font-size: ${setOptions('fontSize')}; 22 | `; 23 | 24 | const skills_name = words.words; 25 | 26 | let iteration = 1; 27 | 28 | let array_of_skills_splitted = skills_name.map(skill => skill.split("")); 29 | 30 | let array_of_final_html_string = array_of_skills_splitted.map(a_skill => a_skill.map(letter => letter === " " ? ` ` : `${letter}`).join("")); 31 | 32 | let text_string = element; 33 | 34 | text_string.innerHTML = array_of_final_html_string[0]; 35 | 36 | function text_animate() { 37 | text_string.childNodes.forEach((child) => { 38 | child.style = ` 39 | display: inline-block; 40 | opacity: 0; 41 | transform: translateY(10px); 42 | color: ${setOptions('color')}; 43 | `; 44 | }) 45 | 46 | let spans = element.childNodes; // document.querySelectorAll(".class span"); 47 | 48 | for (let i = 0; i < spans.length; i++) { 49 | let word_length = spans.length; 50 | let zoom_in = text_string.animate([ 51 | { 52 | transform: `${setOptions('transform')}` // default = `scale(${Number(1.5)})` 53 | }, 54 | { 55 | transform: `scale(${Number(1)})` 56 | } 57 | ], { 58 | delay: `${Number((word_length/3)*100)}`, 59 | duration: 400, 60 | iterations: 1, 61 | easing: `ease-in-out`, 62 | fill: `both` 63 | }); 64 | let animation = spans[i].animate([ 65 | { 66 | opacity: 0, 67 | transform: `translateY(${Number(10)}px)` 68 | }, 69 | { 70 | opacity: 1, 71 | transform: `translateY(${Number(0)}px)` 72 | } 73 | ], { 74 | delay: ((i + 2) / 2) * 100, 75 | duration: (i + 0.1) * 10, 76 | easing: `ease-out`, 77 | iterations: 1, 78 | fill: `forwards` 79 | }) 80 | 81 | if (i == (spans.length - 1)) { 82 | setTimeout(() => { 83 | spans.forEach((span) => { 84 | span.style = `opacity: 0;`; 85 | }) 86 | 87 | for(let k = 0; k < skills_name.length; k++){ 88 | if(iteration == (k+1)){ 89 | text_string.innerHTML = array_of_final_html_string[k]; 90 | break; 91 | } 92 | } 93 | 94 | text_animate(); 95 | }, 2000) 96 | } 97 | } 98 | if(iteration == skills_name.length){ 99 | iteration = 1; 100 | } else { 101 | iteration++; 102 | } 103 | } 104 | 105 | text_animate(); 106 | } 107 | 108 | /* --use-- 109 | 110 | wavy( 111 | document.querySelector(".description"), 112 | {words: ["Accenture", "Instagram", "Wordle", "Ginger"]}, 113 | {color: 'green', fontSize: '2rem', fontFamily: 'Poppins, sans-serif', transform: 'scale(1.8)'} 114 | ); 115 | 116 | */ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wavy Text Animation Library 2 | 3 | A JavaScript Library which allows you to animate infinite words in an infinite loop in a modern wavy way! 4 | 5 | [![download badge](https://badgen.net/npm/dt/@murtuzaalisurti/wavy/?color=blue&icon=npm&labelColor=black&scale=1.1)](https://www.npmjs.com/package/@murtuzaalisurti/wavy) 6 | [![github release](https://badgen.net/github/release/murtuzaalisurti/wavy/?labelColor=black&color=green&scale=1.1&icon=github)](https://github.com/murtuzaalisurti/wavy/releases) 7 | [![Featured on Openbase](https://badges.openbase.com/js/featured/@murtuzaalisurti/wavy.svg?token=1kjnfJTvqtnXHprCgwkJyjFVymPGFCcbEXlIltpZktE=)](https://openbase.com/js/@murtuzaalisurti/wavy?utm_source=embedded&utm_medium=badge&utm_campaign=rate-badge) 8 | 9 | ![image](https://i.imgur.com/SLcvTrS.gif) 10 | 11 | ## Options 12 | 13 | - [JS library for Browser](#for-browsers---usage) 14 | - [NPM package](#npm-package---usage) 15 | 16 | --- 17 | 18 | ## NPM package - Usage 19 | 20 | ### - Install the package 21 | 22 | ```bash 23 | npm i @murtuzaalisurti/wavy 24 | ``` 25 | 26 | ### - Import the package 27 | 28 | ```js 29 | const { wavy } = require('@murtuzaalisurti/wavy'); 30 | ``` 31 | 32 | OR 33 | 34 | ```js 35 | import { wavy } from '@murtuzaalisurti/wavy'; 36 | ``` 37 | 38 | ### - Invoke the function 39 | 40 | - Invoke the below function with the required arguments as shown below in your javascript file! Let's understand **these arguments** which are passed to the function! 41 | 42 | ```js 43 | 44 | wavy( 45 | html_element, // example : document.querySelector('.text') 46 | { 47 | words: ["word-1", "word-2", "word-n"] 48 | }, 49 | { 50 | color: 'font-color', // hsl, rgb, hex, rgba, css standard values 51 | fontSize: 'font-size', // any valid unit 52 | fontFamily: 'font-family', // any valid font family 53 | transform: 'scale(x)' // example : scale(1.5) 54 | } 55 | ); 56 | 57 | ``` 58 | 59 | - The **first argument** you should pass is an html element in which you want to place the words! It's like a wrapper element! 60 | 61 | - Example for first argument: 62 | 63 | ```js 64 | 65 | wavy(document.querySelector(".text"), second_argument, third_argument); 66 | 67 | ``` 68 | 69 | - The **second argument** you should pass is an object with a property of `words` set to a value of an `array` containing as many words as you want to display. There is no word limit. These words will be animated in an infinite loop! 70 | 71 | - Example for second argument: 72 | 73 | ```js 74 | 75 | wavy(document.querySelector(".text"), {words: ["Wavy", "Text", "Animation", "Library", "JavaScript"]}, third_argument); 76 | 77 | ``` 78 | 79 | - The **third argument** you should pass is an object with some options to set the color, fontSize, fontFamily and scale properties of the `text`. Here are all the properties that you can modify: 80 | 81 | ```js 82 | //these are default values 83 | 84 | { 85 | color: 'black', // you can also use rgb, hsl, rgba, hex 86 | fontSize: '1rem', 87 | fontFamily: 'sans-serif', 88 | transform: scale(1.5) 89 | } 90 | 91 | ``` 92 | 93 | - Example for third argument: 94 | 95 | ```js 96 | 97 | wavy( 98 | document.querySelector(".text"), 99 | { 100 | words: ["Wavy", "Text", "Animation", "Library", "JavaScript"] 101 | }, 102 | { 103 | color: 'green', 104 | fontSize: '2rem', 105 | fontFamily: 'Poppins, sans-serif', 106 | transform: 'scale(1.8)' 107 | } 108 | ); 109 | 110 | ``` 111 | 112 | > *NOTE: The first two arguments are mandatory! 113 | 114 | --- 115 | 116 | ## For Browsers - Usage 117 | 118 | > For `npm package`, please follow the instructions mentioned [here](#npm-package---usage). 119 | 120 | ### - Fetch the library from CDN 121 | 122 | In order to use it, insert the following ` 128 | 129 | ``` 130 | 131 | > NOTE :- In order to fetch the latest version of the library, perform a hard reload (CTRL + SHIFT + R) in your browser to bypass the file stored in disk cache. If you don't do this, your browser will load an older version of the library from disk cache! 132 | 133 | OR 134 | 135 | ```html 136 | 137 | 138 | 139 | 140 | ``` 141 | 142 | --- 143 | 144 | ### - Invoke function 145 | 146 | - Invoke the below function with the required arguments as shown below in your javascript file! Let's understand **these arguments** which are passed to the function! 147 | 148 | ```js 149 | 150 | wavy( 151 | html_element, // example : document.querySelector('.text') 152 | { 153 | words: ["word-1", "word-2", "word-n"] 154 | }, 155 | { 156 | color: 'font-color', // hsl, rgb, hex, rgba, css standard values 157 | fontSize: 'font-size', // any valid unit 158 | fontFamily: 'font-family', // any valid font family 159 | transform: 'scale(x)' // example : scale(1.5) 160 | } 161 | ); 162 | 163 | ``` 164 | 165 | - The **first argument** you should pass is an html element in which you want to place the words! It's like a wrapper element! 166 | 167 | - Example for first argument: 168 | 169 | ```js 170 | 171 | wavy(document.querySelector(".text"), second_argument, third_argument); 172 | 173 | ``` 174 | 175 | - The **second argument** you should pass is an object with a property of `words` set to a value of an `array` containing as many words as you want to display. There is no word limit. These words will be animated in an infinite loop! 176 | 177 | - Example for second argument: 178 | 179 | ```js 180 | 181 | wavy(document.querySelector(".text"), {words: ["Wavy", "Text", "Animation", "Library", "JavaScript"]}, third_argument); 182 | 183 | ``` 184 | 185 | - The **third argument** you should pass is an object with some options to set the color, fontSize, fontFamily and scale properties of the `text`. Here are all the properties that you can modify: 186 | 187 | ```js 188 | //these are default values 189 | 190 | { 191 | color: 'black', // you can also use rgb, hsl, rgba, hex 192 | fontSize: '1rem', 193 | fontFamily: 'sans-serif', 194 | transform: scale(1.5) 195 | } 196 | 197 | ``` 198 | 199 | - Example for third argument: 200 | 201 | ```js 202 | 203 | wavy( 204 | document.querySelector(".text"), 205 | { 206 | words: ["Wavy", "Text", "Animation", "Library", "JavaScript"] 207 | }, 208 | { 209 | color: 'green', 210 | fontSize: '2rem', 211 | fontFamily: 'Poppins, sans-serif', 212 | transform: 'scale(1.8)' 213 | } 214 | ); 215 | 216 | ``` 217 | 218 | > **NOTE: The first two arguments are mandatory!** 219 | 220 | --- 221 | 222 | ### Demo 223 | 224 | > Try it on [CodePen](https://codepen.io/seekertruth/pen/ExmGJjE)! 225 | --------------------------------------------------------------------------------