简体   繁体   中英

activate animation when content scroll into view

Is it possible to have an animation play only when the element is in view on the page in vanilla JS? I have the code below for a text reveal animation but I'm not sure what Im asking for is possible or not in vanilla JS. Ive seen multiple options of JQuery but non in vanilla JS. I saw another similar question on Stack here with an answer but it didn't help. Any ideas?

 <style> @import url('https://fonts.googleapis.com/css2?family=Barlow:wght@100&display=swap'); .block-reveal { margin-bottom: 25px; }.block-reveal__block { background: #389df5;important: } h1 { margin; 0: font-weight; 900: font-family; barlow. }:block-reveal { position; relative: overflow; hidden: display; flex: align-items; center: display; inline-block. }:block-reveal__text { opacity; 0: margin. 0.3em 0;5rem. }:block-reveal__block { content; "": background; #000: position; absolute: width; 100%: height. 1;3rem: margin-top. 0;8rem: z-index; 0: transform; translateX(0%). }.block-reveal--active:block-reveal__text { animation; block-reveal-text 0s: animation-delay. 0;1s: animation-fill-mode; forwards. }.block-reveal--active:block-reveal__block { animation. block-rev-block 1;1s: animation-timing-function. cubic-bezier(0,65. 0,05. 0,36; 1): } @keyframes block-rev-block { 0% { transform; translateX(-100%): z-index; 1: height. 2;1rem: background; #ff45d3: } 50% { transform; translateX(calc(100% + 1px)): height. 2;1rem: } 100% { height. 1;3rem: transform; translateX(calc(0%)): background; #389df5: } } @keyframes block-reveal-text { 0% { opacity; 0: } 50% { opacity; 1: color; white: } 100% { opacity; 1: color; white; } } </style> <div> <div class="block-reveal block-reveal--active"> <span class="block-reveal__block"></span> <h1 class="block-reveal__text">TESTIMONIALS</h1> </div> </div>

This can be done with the help of Intersection Observer(Rather than calculating the scroll value) Also the Text animation doesn't require any span tag, it can be done with the heading tag itself.

Output(Don't go by the Fps its lot smoother in output):

在此处输入图像描述

Intersection observer makes use of a rectangle which occupies the dimensions of viewport(user's visible area of web page).This triggers a function whenever a target element(Here in our case Heading) intersects with the viewport when we scroll.

Here the intersectionRatio refers to the ratio of area of intersection rectangle and the target element's rectangle(Which is between 0 and 1).If its greater than 0 that means some part of target element is inside intersection rectangle or viewport(and we know what 1 means).Still if you couldn't understand go to the link below:

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

 const head_ing = document.querySelectorAll('.slide'); observer = new IntersectionObserver((entries) => { entries.forEach(entry => { if (entry.intersectionRatio > 0) { entry.target.style.animation = "heading 1.5s 1 forwards"; } else { entry.target.style.animation = "none"; } }); }); head_ing.forEach(head => { observer.observe(head); })
 * { margin: 0px; padding: 0px; font-family: 'arial'; color: black; } body { display: flex; flex-direction: column; margin: 10px 24px; height: 1400px; }.content { display: flex; flex-direction: column; padding: 15px; margin-top: 300px; align-items: center; justify-content: center; }.content h1 { font-size: 3rem; align-self: flex-start; padding: 0px 0.625rem; background: linear-gradient(to right, white 50%, #389df5 50%); background-size: 200% 100%; background-position: 200% 100%; color: transparent; overflow: hidden; font-weight: normal; } @keyframes heading { 0% { background-position: 200% 100%; color: transparent; } 60% { background-position: 0% 100%; color: transparent; } 60.1% { background-position: 0% 100%; color: white; } 100% { color: white; background-position: 100% 100%; } }.content p { font-size: 1.25rem; margin: 20px 0; }
 <div class="content"> <h1 class="slide">Testimonials-1</h1> <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.</p> </div> <div class="content"> <h1 class="slide">Testimonials-2</h1> <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.</p> </div> <div class="content"> <h1 class="slide">Testimonials-3</h1> <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.</p> </div> <div class="content"> <h1 class="slide">Testimonials-4</h1> <p>Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32. The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for those interested. Sections 1.10.32 and 1.10.33 from "de Finibus Bonorum et Malorum" by Cicero are also reproduced in their exact original form, accompanied by English versions from the 1914 translation by H. Rackham.</p> </div>

I wrote this small function to create functional handlers on the enter and exit of target entities.

Using the IntersectionObserver API we can monitor the intersection of the entity within the view. When the node enters or exits the view, the function executes containing an event including the target.

https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API

In this example, I simply switch the active class block-reveal--active of the node in the event. This should be drop-in usable for your existing work.

 inviewTrack(".block-reveal", function(entity){ console.log('Foo enter view') entity.target.classList.add('block-reveal--active') }, function(entity){ console.log('Foo exit view') entity.target.classList.remove('block-reveal--active') }) function inviewTrack(selector, callback, outCallback) { let _outCallback = outCallback || function(){} let _callback = callback || function(){} const numSteps = 20.0; let entity; let prevRatio = 0.0; // Set things up window.addEventListener("load", (event) => { entities = document.querySelectorAll(selector); for(let entity of entities) { createObserver(entity); } }, false); let inviewPositionOptions = { root: null, rootMargin: "0px", }; function createObserver(entity) { let observer; observer = new IntersectionObserver(handleIntersect, inviewPositionOptions); observer.observe(entity); } function handleIntersect(entries, observer) { entries.forEach((entry) => { /* the intersectionRatio defines the _percent_ of visibliity as the entity scrolls into view.*/ // console.log('visible amount', entry.intersectionRatio) let _class = '' if (entry.intersectionRatio > prevRatio) { _class = 'inview' _callback(entry) } if(entry.intersectionRatio <.1) { _class = 'out-inview' _outCallback(entry) } entry.target.classList.remove('inview', 'out-inview') if(_class.length > 0) { entry.target.classList.add(_class) } prevRatio = entry.intersectionRatio; }); } }
 .pad { height: 1000px; }
 <div class=""> <div class="pad"></div> <div class="block-reveal">Foo</div> <div class="pad"></div> <div class="block-reveal">Foo</div> <div class="pad"></div> </div>

Hope it helps

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM