├── LICENSE ├── README.md ├── Textion.png ├── dist └── textion.js ├── examples ├── data │ └── textionGIF.gif ├── index.html └── style.css ├── package.json └── src └── textion.js /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Yejun Kim 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | [![CodeFactor](https://www.codefactor.io/repository/github/unsignd/textion/badge)](https://www.codefactor.io/repository/github/unsignd/textion) 4 | 5 | 6 |
7 | 8 | # Textion 9 | Textion is a javascript module for text animation.
10 | It adds text animation without any affecting your code. 11 | 12 | 13 | 14 | ## Install 15 | ``` 16 | npm install textion 17 | ``` 18 | ``` 19 | yarn add textion 20 | ``` 21 | 22 | ## Usage 23 | Download js file in dist folder or using npm.
24 | And include it. 25 | 26 | ```html 27 | 28 | ``` 29 | To use Textion, add the class 'textion' to the text elements. 30 | ```html 31 |

32 | ``` 33 | Then add the options you want to use in the text elements' class list. 34 | 35 | ### Option List 36 | |Class Name|Default|Description| 37 | |-|-|-| 38 | |`timeout-{number}`|0|The latency before animation starts. (ms)| 39 | |`interval-{number}`|65|The interval of animation loop. (ms)| 40 | |`repeat-{number}`|2|The number of character changes.| 41 | |`lerpSpeed-{number}`|4 / `{timeout.number}`|The speed of opacity changing in lerp function| 42 | -------------------------------------------------------------------------------- /Textion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unsignd/Textion/83e367ade3be02341beea5570128164ee2439b68/Textion.png -------------------------------------------------------------------------------- /dist/textion.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * VERSION: 1.2.3 3 | * 4 | * @license Copyright (c) 2021, Yejun Kim. All rights reserved. 5 | **/ 6 | window.onload=()=>{let fadeList=document.getElementsByClassName('textion');let timeout=65;let repeat=2;let delay=0;let item,inner,speed;while(fadeList.length>0){speed=undefined;item=fadeList.item(0);inner=item.innerHTML;item.innerHTML='';for(let i=0;i<=5000;i++){if(item.classList.contains('interval-'+i))timeout=i;if(item.classList.contains('repeat-'+i))repeat=i;if(item.classList.contains('timeout-'+i))delay=i;if(item.classList.contains('lerpSpeed-'+i))speed=i}if(speed===undefined)speed=4/timeout;Anim(item,timeout,repeat,delay,inner,speed);item.classList.remove('textion')}};function Anim(obj,loopTimeout,repeatCount,loopDelay,innerText,lerpSpeed){const text=innerText;const lowerList=['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];const capitalList=['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];const numList=['0','1','2','3','4','5','6','7','8','9'];const spanText=document.createElement('span');let index=1;let count=0;let changeText;spanText.className='textion-span';setTimeout(()=>{spanText.style.setProperty('color',obj.style.color);changeText=setInterval(()=>{if(count===repeatCount||index===text.length){spanText.innerText=text[index-1]}else{if(numList.includes(text[index-1])){spanText.innerText=numList[Math.round(Math.random()*(numList.length-1))]}else if(capitalList.includes(text[index-1])){spanText.innerText=capitalList[Math.round(Math.random()*(capitalList.length-1))]}else{spanText.innerText=lowerList[Math.round(Math.random()*(lowerList.length-1))]}}count++;obj.appendChild(spanText);if(index===text.length+1){obj.innerHTML=text;clearInterval(changeText)}else if(count+1===repeatCount){count=0;index++;obj.innerHTML=text.substring(0,index-1);spanText.style.setProperty('opacity','0');opacityLerp(spanText,lerpSpeed)}},loopTimeout)},loopDelay)}function opacityLerp(obj,lerpSpeed){setTimeout(()=>{let changeOpacity=setInterval(()=>{if(parseFloat(obj.style.opacity)>=0.95){obj.style.setProperty('opacity','1');clearInterval(changeOpacity)}obj.style.setProperty('opacity',parseFloat(obj.style.opacity)+(1-parseFloat(obj.style.opacity))*lerpSpeed)},10)},10)} -------------------------------------------------------------------------------- /examples/data/textionGIF.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unsignd/Textion/83e367ade3be02341beea5570128164ee2439b68/examples/data/textionGIF.gif -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Textion 10 | 11 | 12 | 13 |

Textion

14 |

Textion is a javascript module for text typing animation

15 | 16 |

Text

17 |

Module

18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/style.css: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;700&display=swap'); 2 | 3 | body { 4 | overflow: hidden; 5 | } 6 | 7 | a, a:active, a:link, a:visited { 8 | position: absolute; 9 | top: 15px; 10 | right: 25px; 11 | 12 | color: #303847; 13 | font-size: 30px; 14 | text-decoration: none; 15 | } 16 | 17 | h1 { 18 | position: absolute; 19 | left: 50%; 20 | top: 35vmin; 21 | transform: translate(-50%, -35%); 22 | 23 | width: 100vw; 24 | 25 | font-family: 'Poppins', sans-serif; 26 | font-weight: 600; 27 | font-size: 75px; 28 | color: #303847; 29 | 30 | text-align: center; 31 | } 32 | 33 | @media screen and (max-width: 768px) { 34 | body { 35 | display: none; 36 | } 37 | } 38 | 39 | p { 40 | position: absolute; 41 | left: 50%; 42 | top: 50vmin; 43 | transform: translate(-50%, -50%); 44 | 45 | width: 100vw; 46 | 47 | font-family: 'Poppins', sans-serif; 48 | font-weight: 300; 49 | font-size: 30px; 50 | color: #303847; 51 | 52 | text-align: center; 53 | } 54 | 55 | #t1 { 56 | position: absolute; 57 | top: -50px; 58 | left: 50px; 59 | 60 | font-family: 'Poppins', sans-serif; 61 | font-weight: 600; 62 | font-size: 200px; 63 | color: #e0e4eb; 64 | 65 | text-align: left; 66 | } 67 | 68 | #t2 { 69 | position: absolute; 70 | bottom: -300px; 71 | right: 10px; 72 | 73 | font-family: 'Poppins', sans-serif; 74 | font-weight: 600; 75 | font-size: 300px; 76 | color: #e7ebf3; 77 | 78 | text-align: right; 79 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "textion", 3 | "version": "1.2.3", 4 | "description": "Textion is a javascript module for text animation.", 5 | "main": "dist/textion.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/unsignd/Textion.git" 12 | }, 13 | "keywords": [ 14 | "animation" 15 | ], 16 | "author": "Yejun Kim", 17 | "license": "MIT", 18 | "bugs": { 19 | "url": "https://github.com/unsignd/Textion/issues" 20 | }, 21 | "homepage": "https://github.com/unsignd/Textion#readme" 22 | } 23 | -------------------------------------------------------------------------------- /src/textion.js: -------------------------------------------------------------------------------- 1 | window.onload = () => { 2 | let fadeList = document.getElementsByClassName('textion'); 3 | let timeout = 65; 4 | let repeat = 2; 5 | let delay = 0; 6 | let item, inner, speed; 7 | 8 | while (fadeList.length > 0) { 9 | speed = undefined; 10 | 11 | item = fadeList.item(0); 12 | inner = item.innerHTML; 13 | item.innerHTML = ''; 14 | 15 | for (let i = 0; i <= 5000; i++) { 16 | if (item.classList.contains('interval-' + i)) 17 | timeout = i; 18 | 19 | if (item.classList.contains('repeat-' + i)) 20 | repeat = i; 21 | 22 | if (item.classList.contains('timeout-' + i)) 23 | delay = i; 24 | 25 | if (item.classList.contains('lerpSpeed-' + i)) 26 | speed = i; 27 | } 28 | 29 | if (speed === undefined) 30 | speed = 4 / timeout; 31 | 32 | Anim(item, timeout, repeat, delay, inner, speed); 33 | 34 | item.classList.remove('textion'); 35 | } 36 | }; 37 | 38 | function Anim(obj, loopTimeout, repeatCount, loopDelay, innerText, lerpSpeed) { 39 | const text = innerText; 40 | const lowerList = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']; 41 | const capitalList = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; 42 | const numList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; 43 | const spanText = document.createElement('span'); 44 | let index = 1; 45 | let count = 0; 46 | let changeText; 47 | 48 | spanText.className = 'textion-span'; 49 | 50 | setTimeout(() => { 51 | spanText.style.setProperty('color', obj.style.color); 52 | changeText = setInterval(() => { 53 | if (count === repeatCount || index === text.length) { 54 | spanText.innerText = text[index - 1]; 55 | } else { 56 | if (numList.includes(text[index - 1])) { 57 | spanText.innerText = numList[Math.round(Math.random() * (numList.length - 1))]; 58 | } else if (capitalList.includes(text[index - 1])) { 59 | spanText.innerText = capitalList[Math.round(Math.random() * (capitalList.length - 1))]; 60 | } else { 61 | spanText.innerText = lowerList[Math.round(Math.random() * (lowerList.length - 1))]; 62 | } 63 | } 64 | count++; 65 | obj.appendChild(spanText); 66 | if (index === text.length + 1) { 67 | obj.innerHTML = text; 68 | clearInterval(changeText); 69 | } else if (count + 1 === repeatCount) { 70 | count = 0; 71 | index++; 72 | obj.innerHTML = text.substring(0, index - 1); 73 | 74 | spanText.style.setProperty('opacity', '0'); 75 | opacityLerp(spanText, lerpSpeed); 76 | } 77 | }, loopTimeout); 78 | }, loopDelay); 79 | } 80 | 81 | function opacityLerp(obj, lerpSpeed) { 82 | setTimeout(() => { 83 | let changeOpacity = setInterval(() => { 84 | if (parseFloat(obj.style.opacity) >= 0.95) { 85 | obj.style.setProperty('opacity', '1'); 86 | clearInterval(changeOpacity); 87 | } 88 | obj.style.setProperty('opacity', parseFloat(obj.style.opacity) + (1 - parseFloat(obj.style.opacity)) * lerpSpeed); 89 | }, 10); 90 | }, 10); 91 | } 92 | --------------------------------------------------------------------------------