如何在React应用中使用IntersectionObserver和Tailwind制作动画。

huangapple go评论69阅读模式
英文:

How to make animations works with IntersectionObserver in React app with Tailwind

问题

以下是您的代码的中文翻译:

import React from 'react';

const TestAnimation = () => {
    const observer = new IntersectionObserver((entries) => {
        entries.forEach((entry) => {
            if (entry.isIntersecting) {
                entry.target.classList.add('opacity-100');
            } else {
                entry.target.classList.remove('opacity-100');
            }
        });
    });

    const hiddenElements = document.querySelectorAll('.opacity-0');
    hiddenElements.forEach((el) => {
        observer.observe(el);
    });

    return (
        <div className='m-0 bg-slate-900 p-0 text-white'>
            <section className='grid min-h-screen place-items-center content-center opacity-0'>
                <h1>测试</h1>
            </section>
            <section className='grid min-h-screen place-items-center content-center opacity-0'>
                <h2>这是第一页</h2>
                <p>
                    Lorem ipsum dolor, sit amet consectetur adipisicing elit. Autem modi voluptatem est iste a commodi
                    nesciunt saepe quisquam id dignissimos odit, repellat asperiores laboriosam quibusdam expedita
                    itaque blanditiis eos pariatur.
                </p>
            </section>
            <section className='grid min-h-screen place-items-center content-center opacity-0'>
                <h2>这是第三页</h2>
                <p>
                    Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur veniam sint illo quas beatae,
                    eum omnis, deleniti error, eveniet praesentium fugiat quia quod? Maxime, placeat reiciendis ab
                    debitis exercitationem nemo. Laborum perspiciatis eum architecto laboriosam, necessitatibus
                    voluptatibus cupiditate accusantium corrupti placeat mollitia omnis tenetur! Incidunt fugiat
                    possimus quod, quidem itaque ducimus, perspiciatis eligendi, commodi voluptate cupiditate nihil
                    corrupti soluta maxime.
                </p>
            </section>
            <section className='grid min-h-screen place-items-center content-center opacity-0'>
                <h2>这是第四页</h2>
                <p className='text-center'>
                    Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos similique harum, officiis facere odit
                    adipisci maxime obcaecati placeat, quibusdam totam magni eaque? Dicta id commodi saepe dignissimos
                    quam unde eaque.
                </p>
            </section>
        </div>
    );
};

export default TestAnimation;

请注意,代码中的文本已翻译为中文,但HTML和CSS部分保持原样。希望这对您有所帮助!

英文:

I'm stuck. So what do I want from my app:

  1. to animate sections with left fading and opacity (0 to 1) when I scroll down or up.
  2. reuse this component later with different separate components.

What I have now:

  1. Js function that perfectly works with simple HTML and CSS.
  2. nothing from my 'want list'

Please help!
My code is next:

import React from &#39;react&#39;;
const TestAnimation = () =&gt; {
const observer = new IntersectionObserver((entries) =&gt; {
entries.forEach((entry) =&gt; {
if (entry.isIntersecting) {
entry.target.classList.add(&#39;.opacity-100&#39;);
} else {
entry.target.classList.remove(&#39;.opacity-100&#39;);
}
});
});
const hiddenElements = document.querySelectorAll(&#39;.opacity-0&#39;);
hiddenElements.forEach((el) =&gt; {
observer.observe(el);
});
return (
&lt;div className=&#39;m-0 bg-slate-900 p-0 text-white&#39;&gt;
&lt;section className=&#39;grid min-h-screen place-items-center content-center opacity-0&#39;&gt;
&lt;h1&gt;Test&lt;/h1&gt;
&lt;/section&gt;
&lt;section className=&#39;grid min-h-screen place-items-center content-center opacity-0&#39;&gt;
&lt;h2&gt;This is first page&lt;/h2&gt;
&lt;p&gt;
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Autem modi voluptatem est iste a commodi
nesciunt saepe quisquam id dignissimos odit, repellat asperiores laboriosam quibusdam expedita
itaque blanditiis eos pariatur.
&lt;/p&gt;
&lt;/section&gt;
&lt;section className=&#39;grid min-h-screen place-items-center content-center opacity-0&#39;&gt;
&lt;h2&gt;This is third page&lt;/h2&gt;
&lt;p&gt;
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consectetur veniam sint illo quas beatae,
eum omnis, deleniti error, eveniet praesentium fugiat quia quod? Maxime, placeat reiciendis ab
debitis exercitationem nemo. Laborum perspiciatis eum architecto laboriosam, necessitatibus
voluptatibus cupiditate accusantium corrupti placeat mollitia omnis tenetur! Incidunt fugiat
possimus quod, quidem itaque ducimus, perspiciatis eligendi, commodi voluptate cupiditate nihil
corrupti soluta maxime.
&lt;/p&gt;
&lt;/section&gt;
&lt;section className=&#39;grid min-h-screen place-items-center content-center opacity-0&#39;&gt;
&lt;h2&gt;this is Fourth page&lt;/h2&gt;
&lt;p className=&#39;text-center&#39;&gt;
Lorem ipsum dolor sit amet consectetur adipisicing elit. Quos similique harum, officiis facere odit
adipisci maxime obcaecati placeat, quibusdam totam magni eaque? Dicta id commodi saepe dignissimos
quam unde eaque.
&lt;/p&gt;
&lt;/section&gt;
&lt;/div&gt;
);
};
export default TestAnimation;

答案1

得分: 2

你应该将交叉观察器的初始化移到useEffect钩子中。

以下是我以前使用过的Observer组件的示例:

export default function Observer({ children, sectionRef, callback }) {
  function onObserver(entries) {
    const entry = entries[0];
    console.log(entry);
    if (entry.isIntersecting) {
      callback(sectionRef.current.id);
      console.log("进入元素:", entry.target.id);
    } else {
      console.log("离开元素:", entry.target.id);
    }
  }

  useEffect(() => {
    const refCopy = sectionRef;

    let options = {
      root: null,
      rootMargin: "0% 0% -5% 0%",
      threshold: [0.5],
    };

    let observer = new IntersectionObserver(onObserver, options);

    if (refCopy.current) {
      observer.observe(refCopy.current);
    }
    return () => {
      if (refCopy.current) {
        observer.unobserve(refCopy.current);
      }
    };
  }, [sectionRef]);

  return <div id="observation">{children}</div>;
}

以下是如何使用它的示例:

export default function Education({ children, handleInView }) {
  const sectionRef = useRef(null);

  return (
    <Observer sectionRef={sectionRef} callback={handleInView}>
      <section
        ref={sectionRef}
        id="education"
        className="education"
        data-scroll-section
        data-scroll
        data-scroll-class="purpleColor"
      >
        <Pencils />
        <div className="details">
          <div className="side-by-side">
            <div className="title" data-scroll data-scroll-speed={2}>
              <span>Fullstack</span>
              <span> Software </span>
              <span>Engineer</span>
            </div>
          </div>
        </div>
      </section>
    </Observer>
  );
}
英文:

You should move the initiation of the intersection observer into a useEffect hook.

Here is an example of an Observer component I've used in the past:

export default function Observer({ children, sectionRef, callback }) {
function onObserver(entries) {
const entry = entries[0];
console.log(entry);
if (entry.isIntersecting) {
callback(sectionRef.current.id);
console.log(&quot;element in:&quot;, entry.target.id);
} else {
console.log(&quot;element left:&quot;, entry.target.id);
}
}
useEffect(() =&gt; {
const refCopy = sectionRef;
let options = {
root: null,
rootMargin: &quot;0% 0% -5% 0%&quot;,
threshold: [0.5],
};
let observer = new IntersectionObserver(onObserver, options);
if (refCopy.current) {
observer.observe(refCopy.current);
}
return () =&gt; {
if (refCopy.current) {
observer.unobserve(refCopy.current);
}
};
}, [sectionRef]);
return &lt;div id=&quot;observation&quot;&gt;{children}&lt;/div&gt;;
}

And here is how to use it:

export default function Education({ children, handleInView }) {
const sectionRef = useRef(null);
return (
&lt;Observer sectionRef={sectionRef} callback={handleInView}&gt;
&lt;section
ref={sectionRef}
id=&quot;education&quot;
className=&quot;education&quot;
data-scroll-section
data-scroll
data-scroll-class=&quot;purpleColor&quot;
&gt;
&lt;Pencils /&gt;
&lt;div className=&quot;details&quot;&gt;
&lt;div className=&quot;side-by-side&quot;&gt;
&lt;div className=&quot;title&quot; data-scroll data-scroll-speed={2}&gt;
&lt;span&gt;Fullstack&lt;/span&gt;
&lt;span&gt; Software &lt;/span&gt;
&lt;span&gt;Engineer&lt;/span&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/section&gt;
&lt;/Observer&gt;
);
}

huangapple
  • 本文由 发表于 2023年2月8日 20:03:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/75385545.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定