Advertisement
solielios

Text scramble animation ♡

Oct 11th, 2021 (edited)
3,679
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <div class="text"></div>
  2. <style>
  3.     @font-face {
  4.     font-family: winkle;
  5.     src: url(https://dl.dropbox.com/s/cmstfkwz0h96j8m/Winkle-Regular.otf);
  6. }
  7.  
  8. .text {
  9.     font-family: winkle;
  10.     font-weight 100;
  11.     font-size 28px;
  12.     color: gray;
  13. </style>
  14. <script>
  15. class TextScramble {
  16.     constructor(el) {
  17.         this.el = el
  18.         this.chars = '!<>-_\\/[]{}—=+*^?#________'
  19.         this.update = this.update.bind(this)
  20.     }
  21.     setText(newText) {
  22.         const oldText = this.el.innerText
  23.         const length = Math.max(oldText.length, newText.length)
  24.         const promise = new Promise((resolve) => this.resolve = resolve)
  25.         this.queue = []
  26.         for(let i = 0; i < length; i++) {
  27.             const from = oldText[i] || ''
  28.             const to = newText[i] || ''
  29.             const start = Math.floor(Math.random() * 40)
  30.             const end = start + Math.floor(Math.random() * 40)
  31.             this.queue.push({
  32.                 from, to, start, end
  33.             })
  34.         }
  35.         cancelAnimationFrame(this.frameRequest)
  36.         this.frame = 0
  37.         this.update()
  38.         return promise
  39.     }
  40.     update() {
  41.         let output = ''
  42.         let complete = 0
  43.         for(let i = 0, n = this.queue.length; i < n; i++) {
  44.             let {
  45.                 from, to, start, end, char
  46.             } = this.queue[i]
  47.             if(this.frame >= end) {
  48.                 complete++
  49.                 output += to
  50.             } else if(this.frame >= start) {
  51.                 if(!char || Math.random() < 0.28) {
  52.                     char = this.randomChar()
  53.                     this.queue[i].char = char
  54.                 }
  55.                 output += `<span class="dud">${char}</span>`
  56.             } else {
  57.                 output += from
  58.             }
  59.         }
  60.         this.el.innerHTML = output
  61.         if(complete === this.queue.length) {
  62.             this.resolve()
  63.         } else {
  64.             this.frameRequest = requestAnimationFrame(this.update)
  65.             this.frame++
  66.         }
  67.     }
  68.     randomChar() {
  69.         return this.chars[Math.floor(Math.random() * this.chars.length)]
  70.     }
  71. }
  72. // ——————————————————————————————————————————————————
  73. // Example
  74. // ——————————————————————————————————————————————————
  75. const phrases = ['According to all known laws of aviation', 'there is no way that a bee should be able to fly', 'Its wings are too small to get its fat little body off the ground', 'The bee, of course, flies anyways', 'Because bees dont care what humans think is impossible.', ]
  76. const el = document.querySelector('.text')
  77. const fx = new TextScramble(el)
  78. let counter = 0
  79. const next = () => {
  80.     fx.setText(phrases[counter]).then(() => {
  81.         setTimeout(next, 800)
  82.     })
  83.     counter = (counter + 1) % phrases.length
  84. }
  85. next()
  86. </script>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement