You are currently viewing 10 Animated Text Reveals – Elementor and GSAP Tutorial

10 Animated Text Reveals – Elementor and GSAP Tutorial

(This page includes affiliate links. If you click and purchase, I receive a small commission at no extra cost from you and that way you can support me. I only recommend tools that I have personally used and loved.)

Get Elementor Pro Today –

1 – Elementor Pro

Don’t want to make from scratch? Get the template instead 🙂

Introduction – Amazing Text Reveals made with Elementor and GSAP for your website

In this tutorial, we are learning to make animated text reveals for a good user experience. We have 10 text reveals, but once you watch the above video, you will learn to customize it which makes it more than 10 text reveal animations. You can simply add scrub:true or scrub:false to make the animation scroll-movement based. (Please refer video for detailed understanding)

IMPORTANT NOTE: Make sure to use single-heading code and CSS class to only single headings. And make sure to use heading/paragraph CSS class and code to only Heading and paragraph combos. If you accidently add extra heading class or paragraph class for the heading/paragraph combo, then you might break the code. So make sure, there is always a paragraph class for each heading class for the combo.

Pre-requisite – Initialize GSAP, GSAP scrollTrigger, SplitType

				
					<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.4/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.5/ScrollTrigger.min.js"></script>
<script src="https://unpkg.com/split-type"></script>
				
			

I am a Single Heading That Reveals From The Bottom

I am Heading That Reveals From The Bottom

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#1 – Fade in Y Animated GSAP Text Reveal

  1. dm-single-heading-1 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading1 is the CSS class for the heading and dm-paragraph1 is the CSS class for the paragraph.
				
					<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading1 = document.querySelectorAll('.dm-single-heading-1');

  animHeading1.forEach((headingElement1, index) => {
    let dmSplitHeading1 = new SplitType(headingElement1.querySelector('h2'), { types: 'words' });

    gsap.from(dmSplitHeading1.words, {
      scrollTrigger: {
        trigger: headingElement1,
        start: 'top 80%'
      },
      y: 30,
      opacity: 0,
      duration: 0.3,
      stagger: 0.1
    });
  });
});

</script>

				
			
				
					<script>

document.addEventListener('DOMContentLoaded', () => {    

let animHeadingPara1 = document.querySelectorAll('.dm-heading1')

  animHeadingPara1.forEach((headingElement1, index) => {
  let dmSplitHeading1 = new SplitType(headingElement1.querySelector('h2'), { types: 'words' });
  let dmSplitParagraph1 = new SplitType(document.querySelectorAll('.dm-paragraph1')[index].querySelector('p'), { types: 'lines' });

  let headingParaTimeline1 = gsap.timeline({
    scrollTrigger: {
      trigger: headingElement1,
      scroller: 'body',
      start: 'top 80%'
    }
  });

  headingParaTimeline1
    .from(dmSplitHeading1.words, {
      y: 30,
      opacity: 0,
      duration: 0.3,
      stagger: 0.1
    })
    .from(dmSplitParagraph1.lines, {
      y: 30,
      opacity: 0,
      duration: 0.3,
      stagger: 0.1
    }, "-=0.2"); // overlap the animations slightly for a smoother effect
});

});

</script>
				
			

I am a Single Heading That Reveals From The Left

I am Heading That Reveals From The Left

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#2 – Fade in X Animated GSAP Text Reveal

  1. dm-single-heading-2 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading2 is the CSS class for the heading and dm-paragraph2 is the CSS class for the paragraph.
				
					<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading2 = document.querySelectorAll('.dm-single-heading-2');

  animHeading2.forEach((headingElement2, index) => {
    let dmSplitHeading2 = new SplitType(headingElement2.querySelector('h2'), { types: 'words' });

    gsap.from(dmSplitHeading2.words, {
      scrollTrigger: {
        trigger: headingElement2,
        start: 'top 80%'
      },
      x: -30,
      opacity: 0,
      duration: 0.3,
      stagger: 0.1
    });
  });
});

</script>

				
			
				
					<script>

document.addEventListener('DOMContentLoaded', () => {    

  let animHeadingPara2 = document.querySelectorAll('.dm-heading2');

  animHeadingPara2.forEach((headingElement2, index) => {
    let dmSplitHeading2 = new SplitType(headingElement2.querySelector('h2'), { types: 'words' });
    let dmSplitParagraph2 = new SplitType(document.querySelectorAll('.dm-paragraph2')[index].querySelector('p'), { types: 'lines' });

    let headingParaTimeline2 = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement2,
        scroller: 'body',
        start: 'top 80%'
      }
    });

    headingParaTimeline2
      .from(dmSplitHeading2.words, {
        x: -30,
        opacity: 0,
        duration: 0.3,
        stagger: 0.1
      })
      .from(dmSplitParagraph2.lines, {
        x: -30,
        opacity: 0,
        duration: 0.3,
        stagger: 0.1
      }, "-=0.2"); // overlap the animations slightly for a smoother effect
  });

});
</script>

				
			

I am a Single Heading That Reveals by Clipping from Bottom

I am Heading That Reveals by Clipping from Bottom

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#3 – Clipping from Bottom – Animated GSAP Text Reveal

  1. dm-single-heading-3 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading3 is the CSS class for the heading and dm-paragraph3 is the CSS class for the paragraph.
  6. You can change clip-path values to change the direction of reveal
				
					<style>
    
    .dm-single-heading-3 .word {
        
        clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
        
    }
 
    
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading3 = document.querySelectorAll('.dm-single-heading-3');

  animHeading3.forEach((headingElement3, index) => {
    let dmSplitHeading3 = new SplitType(headingElement3.querySelector('h2'), { types: 'words' });

    gsap.from(dmSplitHeading3.words, {
      scrollTrigger: {
        trigger: headingElement3,
        start: 'top 80%'
      },
      clipPath: 'polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)',
      duration: 0.3,
      stagger: 0.1
    });
  });
});

</script>

				
			
				
					<style>
    
    .dm-heading3 .word {
        
         clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
        
    }
    
    .dm-paragraph3 .line {
        
        clip-path: polygon(0 0, 100% 0, 100% 100%, 0% 100%);
        
    }
    
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {    

  let animHeadingPara3 = document.querySelectorAll('.dm-heading3');

  animHeadingPara3.forEach((headingElement3, index) => {
    let dmSplitHeading3 = new SplitType(headingElement3.querySelector('h2'), { types: 'words' });
    let dmSplitParagraph3 = new SplitType(document.querySelectorAll('.dm-paragraph3')[index].querySelector('p'), { types: 'lines' });

    let headingParaTimeline3 = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement3,
        scroller: 'body',
        start: 'top 80%'
      }
    });

    headingParaTimeline3
      .from(dmSplitHeading3.words, {
        clipPath: 'polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)',
        opacity: 0,
        duration: 0.3,
        stagger: 0.1
      })
      .from(dmSplitParagraph3.lines, {
        clipPath: 'polygon(0% 100%, 100% 100%, 100% 100%, 0% 100%)',
        opacity: 0,
        duration: 0.3,
        stagger: 0.1
      }, "-=0.2"); // overlap the animations slightly for a smoother effect
  });

});

</script>

				
			

I am a Single Heading That Reveals by Clipping from Bottom

I am Heading That Reveals by Clipping from Bottom

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#4 – Text reveals from bottom with clipping – Animated GSAP Text Reveal

  1. dm-single-heading-4 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading4 is the CSS class for the heading and dm-paragraph4 is the CSS class for the paragraph
  6. You can change clip-path values to change the direction of reveal
				
					<style>

  .dm-single-heading-4 .line {
      
      overflow: hidden;
      
  }
  
  .dm-single-line-wrapper-4 {
      
      overflow: hidden;
  }
  
</style>

<script>
  document.addEventListener('DOMContentLoaded', () => {
    let animHeading4 = document.querySelectorAll('.dm-single-heading-4');

    animHeading4.forEach((headingElement4, index) => {
      let dmSplitHeading4 = new SplitType(headingElement4.querySelector('h2'), { types: 'lines, words' });
      
       const dmSingleHeadingLines4 = document.querySelectorAll('.dm-single-heading-4 .line');
       
    dmSingleHeadingLines4.forEach((lineElement) => {

    const dmWrapper = document.createElement('div');
    dmWrapper.classList.add('dm-single-line-wrapper-4');
    lineElement.parentNode.insertBefore(dmWrapper, lineElement);
    dmWrapper.appendChild(lineElement);
    
    });

      gsap.from(dmSplitHeading4.words, {
        scrollTrigger: {
          trigger: headingElement4,
          start: 'top 80%'
        },
        y:'120%',
        duration: 0.3,
        stagger: 0.1
      });
    });
  });
  
</script>

				
			
				
					<style>

  .dm-heading4 .line {
      
   overflow: hidden;
   
  }
  
  .dm-line-wrapper-4 {
      
      overflow: hidden;
  }

  .dm-paragraph4 .line {
      
    overflow: hidden;
    
  }
  
</style>

<script>

  document.addEventListener('DOMContentLoaded', () => {    

    let animHeadingPara4 = document.querySelectorAll('.dm-heading4');

    animHeadingPara4.forEach((headingElement4, index) => {
      
      //Split Heading and Paragraph into lines,words, chars
      let dmSplitHeading4 = new SplitType(headingElement4.querySelector('h2'), { types: 'lines, words' });
      
      let dmSplitParagraph4 = new SplitType(document.querySelectorAll('.dm-paragraph4')[index].querySelector('p'), { types: 'lines' });

      let headingParaTimeline4 = gsap.timeline({
        scrollTrigger: {
          trigger: headingElement4,
          scroller: 'body',
          start: 'top 80%'
        }
      });
      
    const dmParagraphLines4 = document.querySelectorAll('.dm-paragraph4 .line');
    const dmHeadinglines4 = document.querySelectorAll('.dm-heading4 .line');
    
    dmParagraphLines4.forEach((lineElement) => {
    
    const dmWrapper = document.createElement('div');
    dmWrapper.classList.add('dm-line-wrapper-4');
    lineElement.parentNode.insertBefore(dmWrapper, lineElement);
    dmWrapper.appendChild(lineElement);
    
    });
    
    dmHeadinglines4.forEach((lineElement) => {

    const dmWrapper = document.createElement('div');
    dmWrapper.classList.add('dm-line-wrapper-4');
    lineElement.parentNode.insertBefore(dmWrapper, lineElement);
    dmWrapper.appendChild(lineElement);
    
    });

      headingParaTimeline4
        .from(dmSplitHeading4.words, {
          y:'120%',
          opacity: 0,
          duration: 0.3,
          stagger: 0.1
        })
        .from(dmSplitParagraph4.lines, {
           y:'120%',
          opacity: 0,
          duration: 0.3,
          stagger: 0.1 //Remove Stagger if you want to reveal by line
        }, "-=0.2"); // overlap the animations slightly for a smoother effect
    });

  });
  
</script>

				
			

I am a Single Heading That Reveals by Color from Left

I am Heading That Reveals by Color from Left

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#5 – Text reveals by Clipping Color from left – Animated GSAP Text Reveal

  1. dm-single-heading-5 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading5 is the CSS class for the heading and dm-paragraph5 is the CSS class for the paragraph
  6. You can change clip-path inset values to change the direction of reveal
  7. Change background value to your desired color. 
  8. Change “1s” in both line 14 and line 31 to same values and your desired values. This controls the duration of reveal. For Heading/Paragraph Combo, make sure to change for all 3 values.
  9. Simply change delay to your desired value. 0.1 = 100ms difference between each reveal.
				
					<style>

    .dm-single-heading-5 .dm-line-5 {
        
        overflow: hidden;
        position: relative;
        clip-path: inset(0 100% 0 0);
        transition: none !important;
        width: fit-content !important;
    }
    
    .dm-line-5.animate {
        
        animation: dm-clip-text 1s forwards;
        
    }
   
    
    .dmRevealAnim1:after {
        
        transition: none !important;
        content: '';
        position: absolute;
        left: 0;
        top:0;
        height: 100%;
        width: 100%;
        z-index: 5;
        background-color: red; /*Reveal Color*/
		pointer-events: none;
		animation: dm-bg-reveal 1s forwards;
    }
    
    @keyframes dm-bg-reveal {
	
	0% {
	    
	    clip-path: inset(0 100% 0 0);
	    
	}
	
	50% {
	    
	    clip-path: inset(0 0% 0 0);
	    
	}
	
	100% {
	    
	    
	    clip-path: inset(0 0% 0 100%);
	    
	}
}


@keyframes dm-clip-text {
	from {
		clip-path: inset(0 100% 0 0);
	}
	to {
		clip-path: inset(0 0 0 0);
	}
}

   
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading5 = document.querySelectorAll('.dm-single-heading-5');

  animHeading5.forEach((headingElement5, index) => {
    let dmSplitHeading5 = new SplitType(headingElement5.querySelector('h2'), { types: 'lines', lineClass: 'dm-line-5' });
    
    const dmSingleHeadingLines5 = document.querySelectorAll('.dm-single-heading-5 .dm-line-5');

    dmSingleHeading5timeline = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement5,
        start: 'top 80%'
      }
    });
   
   dmSplitHeading5.lines.forEach((line, i) => {
       dmSingleHeading5timeline.to(line, {
           onStart: () => {
               line.classList.add('animate', 'dmRevealAnim1');
            },
            delay: 0.1   //Add delay here
       }); 
});
});
});


</script>

				
			
				
					<style>

  .dm-heading5 .line {
      
   overflow: hidden;
   position: relative;
    clip-path: inset(0 100% 0 0);
    transition: none !important;
    width: fit-content !important;
  }
  
   .dm-heading5 .line.animate {
        
        animation: dm-clip-text 1s forwards;
        
    }

  .dm-paragraph5 .line {
      
    overflow: hidden;
    position: relative;
    clip-path: inset(0 100% 0 0);
    transition: none !important;
    
  }
  
  .dm-paragraph5 .line.animate {
      
    animation: dm-clip-text 1s forwards;
    
  }
  
   .dmRevealAnim1hp:after {
        
        transition: none !important;
        content: '';
        position: absolute;
        left: 0;
        top:0;
        height: 100%;
        width: 100%;
        z-index: 5;
        background-color: red; /*Reveal Color*/
		pointer-events: none;
		animation: dm-bg-reveal-hp 1s forwards;
    }
  
  @keyframes dm-bg-reveal-hp {
	
	0% {
	    
	    clip-path: inset(0 100% 0 0);
	    
	}
	
	50% {
	    
	    clip-path: inset(0 0% 0 0);
	    
	}
	
	100% {
	    
	    
	    clip-path: inset(0 0% 0 100%);
	    
	}
}


@keyframes dm-clip-text-hp {
	from {
		clip-path: inset(0 100% 0 0);
	}
	to {
		clip-path: inset(0 0 0 0);
	}
}
  
</style>

<script>

 document.addEventListener('DOMContentLoaded', () => {    

  let animHeadingPara5 = document.querySelectorAll('.dm-heading5');

  animHeadingPara5.forEach((headingElement5, index) => {
    let dmSplitHeading5 = new SplitType(headingElement5.querySelector('h2'), { types: 'words, lines' });
    let dmSplitParagraph5 = new SplitType(document.querySelectorAll('.dm-paragraph5')[index].querySelector('p'), { types: 'lines' });

    let headingParaTimeline5 = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement5,
        scroller: 'body',
        start: 'top 80%'
      }
    });

   // Adding class for heading lines
      dmSplitHeading5.lines.forEach((line, i) => {
        headingParaTimeline5.to(line, {
          onStart: () => {
            line.classList.add('animate', 'dmRevealAnim1hp');
          } ,
          delay: 0.1 // addDelay here
        });
      });

      // Adding class for paragraph lines
      dmSplitParagraph5.lines.forEach((line, i) => {
        headingParaTimeline5.to(line, {
          onStart: () => {
            line.classList.add('animate', 'dmRevealAnim1hp');
          },
          delay: 0.1 // add Delay here
        });
      });
  });

});

</script>

				
			

I am a Single Heading That Reveals by Color from Bottom

I am Heading That Reveals by Color from Bottom

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char. 

#6 – Text reveals by Clipping Color from Bottom – Animated GSAP Text Reveal

  1. dm-single-heading-6 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading6 is the CSS class for the heading and dm-paragraph6 is the CSS class for the paragraph
  6. You can change clip-path inset values to change the direction of reveal
  7. Change background value to your desired color. 
  8. Change “1s” in both line 15 and line 31 to same values and your desired values. This controls the duration of reveal. For Heading/Paragraph, make sure to change for all 3 values.
  9. Simply change delay to your desired value. 0.1 = 100ms difference between each reveal.
				
					<style>

   .dm-single-heading-6 .dm-line-6 {
       
  overflow: hidden;
  position: relative;
  clip-path: inset(100% 0% 0 0);
  transition: none !important;
  width: fit-content !important;
  
}

.dm-line-6.animate {
    
  animation: dm-clip-text-2 1s forwards;
  
}

.dmRevealAnim2:after {
    
  transition: none !important;
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  z-index: 5;
  background-color: red; /*Reveal Color*/
  pointer-events: none;
  animation: dm-bg-reveal-2 1s forwards;
  
}

@keyframes dm-bg-reveal-2 {
    
  0% {
    clip-path: inset(100% 0% 0% 0%);
  }
  50% {
    clip-path: inset(0% 0% 0% 0%);
  }
  100% {
    clip-path: inset(0% 0% 100% 0%);
  }
  
}

@keyframes dm-clip-text-2 {
    
  from {
    clip-path: inset(100% 0% 0% 0%);
  }
  to {
    clip-path: inset(0% 0% 0% 0%);
  }
  
}

   
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading6 = document.querySelectorAll('.dm-single-heading-6');

  animHeading6.forEach((headingElement6, index) => {
    let dmSplitHeading6 = new SplitType(headingElement6.querySelector('h2'), { types: 'lines', lineClass: 'dm-line-6' });
    
    const dmSingleHeadingLines6 = document.querySelectorAll('.dm-single-heading-6 .dm-line-6');

    dmSingleHeading6timeline = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement6,
        start: 'top 80%'
      }
    });
   
    dmSplitHeading6.lines.forEach((line, i) => {
      dmSingleHeading6timeline.to(line, {
        onStart: () => {
          line.classList.add('animate', 'dmRevealAnim2');
        },
        delay: 0.1 //Add Delay Here
      });
    });
  });
});


</script>

				
			
				
					<style>

  .dm-heading6 .line {
  overflow: hidden;
  position: relative;
  clip-path: inset(100% 0% 0 0);
  transition: none !important;
  width: fit-content !important;
}

.dm-heading6 .line.animate {
  animation: dm-clip-text-hp-2 1s forwards;
}

.dm-paragraph6 .line {
  overflow: hidden;
  position: relative;
  clip-path: inset(0 100% 0 0);
  transition: none !important;
}

.dm-paragraph6 .line.animate {
  animation: dm-clip-text-hp-2 1s forwards;
}

.dmRevealAnim2hp:after {
  transition: none !important;
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 100%;
  z-index: 5;
  background-color: red; /*Reveal Color*/
  pointer-events: none;
  animation: dm-bg-reveal-hp-2 1s forwards;
}

@keyframes dm-bg-reveal-hp-2 {
  0% {
    clip-path: inset(100% 0% 0 0);
  }
  50% {
    clip-path: inset(0 0% 0 0);
  }
  100% {
    clip-path: inset(0 0% 100% 0%);
  }
}

@keyframes dm-clip-text-hp-2 {
  from {
    clip-path: inset(100% 0% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

  
</style>

<script>

 document.addEventListener('DOMContentLoaded', () => {
  let animHeadingPara6 = document.querySelectorAll('.dm-heading6');

  animHeadingPara6.forEach((headingElement6, index) => {
    let dmSplitHeading6 = new SplitType(headingElement6.querySelector('h2'), { types: 'words, lines' });
    let dmSplitParagraph6 = new SplitType(document.querySelectorAll('.dm-paragraph6')[index].querySelector('p'), { types: 'lines' });

    let headingParaTimeline6 = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement6,
        scroller: 'body',
        start: 'top 80%'
      }
    });

    // Adding class for heading lines
    dmSplitHeading6.lines.forEach((line, i) => {
      headingParaTimeline6.to(line, {
        onStart: () => {
          line.classList.add('animate', 'dmRevealAnim2hp');
        },
        delay: 0.1 //Add Delay Here
      });
    });

    // Adding class for paragraph lines
    dmSplitParagraph6.lines.forEach((line, i) => {
      headingParaTimeline6.to(line, {
        onStart: () => {
          line.classList.add('animate', 'dmRevealAnim2hp');
        },
        delay: 0.1 //Add Delay Here
      });
    });
  });
});


</script>

				
			

I am a Single Heading That Reveals by rotating on X from left

I am Heading That Reveals rotating on X from left

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#7 – Slanted Text Reveal – Animated GSAP Text Reveal

  1. dm-single-heading-7 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading7 is the CSS class for the heading and dm-paragraph7 is the CSS class for the paragraph
				
					<style>

    .dm-single-heading-7 .word {
        
        transition: none !important;
        transform-origin: bottom left;
        perspective: 2000px;
        
    
    }
   
    
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading7 = document.querySelectorAll('.dm-single-heading-7');

  animHeading7.forEach((headingElement7, index) => {
    let dmSplitHeading7 = new SplitType(headingElement7.querySelector('h2'), { types: 'words' });

    gsap.from(dmSplitHeading7.words, {
        
      scrollTrigger: {
          
        trigger: headingElement7,
        start: 'top 80%'
        
      },
      
      x:-100,
      opacity:0,
      transform:'skew(-50deg)',
      rotateX: 90,
      duration: 0.5,
      stagger: 0.1
      
    });
  });
});

</script>

				
			
				
					<style>

    .dm-heading7 .word {
        
         transition: none !important;
        transform-origin: bottom left;
        perspective: 2000px;
    }

    .dm-paragraph7 .line {
        
         transition: none !important;
        transform-origin: bottom left;
        perspective: 2000px;
    }
    
</style>


<script>

document.addEventListener('DOMContentLoaded', () => {    
    let animHeadingPara7 = document.querySelectorAll('.dm-heading7');

    animHeadingPara7.forEach((headingElement7, index) => {
        let dmSplitHeading7 = new SplitType(headingElement7.querySelector('h2'), { types: 'words' });
        let dmSplitParagraph7 = new SplitType(document.querySelectorAll('.dm-paragraph7')[index].querySelector('p'), { types: 'lines' });

        let headingParaTimeline7 = gsap.timeline({
            scrollTrigger: {
                trigger: headingElement7,
                scroller: 'body',
                start: 'top 80%'
            }
        });

        headingParaTimeline7
            .from(dmSplitHeading7.words, {
                
            x:-100,
            opacity:0,
            transform:'skew(-50deg)',
            rotateX: 90,
            duration: 0.5,
            stagger: 0.1
            
            })
            .from(dmSplitParagraph7.lines, {
                
                 x:-100,
                 opacity:0,
                 transform:'skew(-50deg)',
                 rotateX: 90,
                 duration: 0.5,
                 stagger: 0.1
            }, "-=0.2"); // overlap the animations slightly for a smoother effect
    });
});

</script>
				
			

I am a Single Heading That Increase opacity as you scroll

I am a Heading That Increase opacity as you scroll

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#8 – Opacity Reveal – Animated GSAP Text Reveal

  1. dm-single-heading-8 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading8 is the CSS class for the heading and dm-paragraph8 is the CSS class for the paragraph
  6. opacity 0.1 is the default opacity value.
  7. opacity: 1 is the final opacity value.
  8. You can also add extra CSS properties to animate.
  9. SCRUB is set to true, so the animation is based on amount of scroll. Make it false to run it automatically without scroll based movement.
				
					<style>

    .dm-single-heading-8 .word {
        
        transition: none !important;
        opacity: 0.1;
       
    }
    
</style>

<script>
document.addEventListener('DOMContentLoaded', () => {
  let animHeading8 = document.querySelectorAll('.dm-single-heading-8'); 

  animHeading8.forEach((headingElement8, index) => {  
    let dmSplitHeading8 = new SplitType(headingElement8.querySelector('h2'), { types: 'words' }); 

    gsap.to(dmSplitHeading8.words, {
        
      scrollTrigger: {
          
        trigger: headingElement8,
        start: '50% 80%',
        end:'50% 30%',
        markers: false,
        scrub:true
        
      },
      
      opacity: 1,
      duration: 0.5,
      stagger: 0.1
      
    });
  });
});
</script>

				
			
				
					<style>
    
    .dm-heading8 .word, .dm-paragraph8 .word {
        
        opacity: 0.1;
        
        
    }
    
    
    
    
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {    

  let animHeadingPara8 = document.querySelectorAll('.dm-heading8');

  animHeadingPara8.forEach((headingElement8, index) => {
    let dmSplitHeading8 = new SplitType(headingElement8.querySelector('h2'), { types: 'words' });
    let dmSplitParagraph8 = new SplitType(document.querySelectorAll('.dm-paragraph8')[index].querySelector('p'), { types: 'words' });

    let headingParaTimeline8 = gsap.timeline({
      scrollTrigger: {
          
        trigger: headingElement8,
        start: '50% 80%',
        end:'50% 30%',
        markers: false,
        scrub:true
        
      }
    });

    headingParaTimeline8
      .to(dmSplitHeading8.words, {
        
        opacity: 1,
        duration: 0.5,
        stagger: 0.1
      })
      .to(dmSplitParagraph8.words, {
        
        opacity: 1,
        duration: 0.5,
        stagger: 0.1
      }, "-=0.2");
  });

});

</script>

				
			

I am a Single Heading That changes color as you scroll

I am a Heading That changes color as you scroll

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#9 – Color Reveal – Animated GSAP Text Reveal

  1. dm-single-heading-9 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading9 is the CSS class for the heading and dm-paragraph9 is the CSS class for the paragraph
  6. color:blue is the default color.
  7. color:’red’ is the final color.
  8. You can also add extra CSS properties to animate.
  9. SCRUB is set to true, so the animation is based on amount of scroll. Make it false to run it automatically without scroll based movement.
				
					<style>

    .dm-single-heading-9 .word {
        
        color:blue;
        transition: none !important;
        opacity: 0.1;
       
    }
    
</style>

<script>
document.addEventListener('DOMContentLoaded', () => {
  let animHeading9 = document.querySelectorAll('.dm-single-heading-9'); 

  animHeading9.forEach((headingElement9, index) => {  
    let dmSplitHeading9 = new SplitType(headingElement9.querySelector('h2'), { types: 'words' }); 

    gsap.to(dmSplitHeading9.words, {
        
      scrollTrigger: {
          
        trigger: headingElement9,
        start: '50% 80%',
        end: '50% 30%',
        markers: false,
        scrub: true
        
      },
      
      color:'red',
      opacity: 1,
      duration: 0.5,
      stagger: 0.1
      
    });
  });
});
</script>

				
			
				
					<style>

    .dm-heading9 .word, .dm-paragraph9 .word {
        
        color:blue;
        opacity: 0.1;
    }
    
</style>

<script>

document.addEventListener('DOMContentLoaded', () => {    

  let animHeadingPara9 = document.querySelectorAll('.dm-heading9');

  animHeadingPara9.forEach((headingElement9, index) => {
    let dmSplitHeading9 = new SplitType(headingElement9.querySelector('h2'), { types: 'words' });
    let dmSplitParagraph9 = new SplitType(document.querySelectorAll('.dm-paragraph9')[index].querySelector('p'), { types: 'words' });

    let headingParaTimeline9 = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement9,
        start: '50% 80%',
        end: '50% 30%',
        markers: false,
        scrub: true
      }
    });

    headingParaTimeline9
      .to(dmSplitHeading9.words, {
        
        color:'red',
        opacity: 1,
        duration: 0.5,
        stagger: 0.1
      })
      .to(dmSplitParagraph9.words, {
          
        color:'red',
        opacity: 1,
        duration: 0.5,
        stagger: 0.1
      }, "-=0.2");
  });

});

</script>

				
			

I am a Single Heading That reveals by scramble words

I am a Heading That Reveals by Scramble words

I am a paragraph that only starts revealing when full heading above has been revealed. Heading and I can be revealed line by line, word by word or char by char.

#10 – Scramble Text Reveal – Animated GSAP Text Reveal with baffle JS library

  1. dm-single-heading-10 – add this CSS class to the single headings you want to animate
  2. h2 is the HTML tag, make sure to change it to appropriate one
  3. types: ‘words’ – we are splitting the text into words
  4. types: ‘lines’ – we are splitting the text into lines
  5. For heading and paragraph combo, dm-heading10 is the CSS class for the heading and dm-paragraph10 is the CSS class for the paragraph.
  6. Change characters to your desired letters/characters that need to be shown randomized before revealing your final text.
  7. speed:50, change 50 to your desired value for the speed of scramble characters.
  8. change duration value from 0.1 to your desired value to change the amount of time it requires to go from scramble text to final text.
				
					<script src="https://cdnjs.cloudflare.com/ajax/libs/baffle.js/0.2.0/baffle.min.js" integrity="sha512-haSDSYvV1BDJYCDs52GczvTcLl3hpw8SK7isG5arkvNdHKBOcOqvl/vjO0qKNtQdZLznXA408zT0tzIamWJgrw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<style>
    
    .dm-single-heading-10 .word {
        
        opacity: 0;
        
    }
    
    
</style>


<script>

document.addEventListener('DOMContentLoaded', () => {
  let animHeading10 = document.querySelectorAll('.dm-single-heading-10');

  animHeading10.forEach((headingElement10) => {
    let headingText = headingElement10.querySelector('h2');

    // Initialize SplitType for splitting the text into words
    let dmSplitHeading10 = new SplitType(headingText, { types: 'words' });

    const revealTL = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement10,
        start: 'top 80%',
        once: true, // Ensures the animation only happens once
      },
    });

    // Initialize a Baffle.js instance for each word
    dmSplitHeading10.words.forEach((word, index) => {
      let baffleInstance = baffle(word, {
        characters: '!/|~#.^+*$#%nwf',
        speed: 50,
      });

      // Start the obfuscation immediately
      baffleInstance.start();

      // Use GSAP to reveal each word
      revealTL.to(word, {
          
        opacity: 1, // Optional, animates opacity or other properties
        duration:0.1, //Duration of text-reveal
        onStart: () => {
          baffleInstance.reveal(100, { easing: 'linear', delay: 0 });
        }
        
      });
    });
  });
});

</script>

				
			
				
					<script src="https://cdnjs.cloudflare.com/ajax/libs/baffle.js/0.2.0/baffle.min.js" integrity="sha512-haSDSYvV1BDJYCDs52GczvTcLl3hpw8SK7isG5arkvNdHKBOcOqvl/vjO0qKNtQdZLznXA408zT0tzIamWJgrw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<style>
    
    .dm-heading10 .word, .dm-paragraph10 .word {
        
        opacity: 0;
        
    }
    
    
    
</style>


<script>

document.addEventListener('DOMContentLoaded', () => {    

  let animHeadingPara10 = document.querySelectorAll('.dm-heading10');

  animHeadingPara10.forEach((headingElement10, index) => {
    // Split heading and paragraph into words using SplitType
    let dmSplitHeading10 = new SplitType(headingElement10.querySelector('h2'), { types: 'words' });
    let dmSplitParagraph10 = new SplitType(document.querySelectorAll('.dm-paragraph10')[index].querySelector('p'), { types: 'words' });

    // Create GSAP timeline
    let headingParaTimeline10 = gsap.timeline({
      scrollTrigger: {
        trigger: headingElement10,
        start: 'top 80%',
       
      }
    });

    // Process each word in the heading
    dmSplitHeading10.words.forEach((word) => {
      let baffleInstance = baffle(word, {
        characters: '!/|~#.^+*$#%nwf', // Custom characters for obfuscation
        speed: 50,
      });

      // Start Baffle.js obfuscation
      baffleInstance.start();

      // Use GSAP to reveal the word
      headingParaTimeline10.to(word, {
        opacity: 1,
        duration: 0.1,
        onStart: () => {
          baffleInstance.reveal(100, { easing: 'linear', delay: 0 });
        },
        stagger: 0.1,
      });
    });

    // Process each word in the paragraph
    dmSplitParagraph10.words.forEach((word) => {
      let baffleInstance = baffle(word, {
        characters: '!/|~#.^+*$#%nwf', // Custom characters for obfuscation
        speed: 50,
      });

      // Start Baffle.js obfuscation
      baffleInstance.start();

      // Use GSAP to reveal the word
      headingParaTimeline10.to(word, {
        opacity: 1,
        duration: 0.1,
        onStart: () => {
          baffleInstance.reveal(100, { easing: 'linear', delay: 0 });
        },
        stagger: 0.1,
      }); // Stagger this to overlap with the previous animation
    });
  });

});


</script>

				
			

Leave a Reply