65 lines
1.6 KiB
TypeScript
65 lines
1.6 KiB
TypeScript
import React, { useEffect, useRef } from "react";
|
|
import styles from "../index.less";
|
|
|
|
interface OwnProps {
|
|
item: any;
|
|
ob: any;
|
|
map: any;
|
|
}
|
|
|
|
type Props = OwnProps;
|
|
const SLIDE_FADE_DISTANCE = 50;
|
|
const SLIDE_FADE_DURATION = 1000;
|
|
|
|
const isBelowViewport = (el: HTMLDivElement) => {
|
|
const rect = el.getBoundingClientRect();
|
|
return rect.top - SLIDE_FADE_DISTANCE > window.innerHeight;
|
|
};
|
|
const slideInItem: React.FC<Props> = (props) => {
|
|
const { item, ob, map } = props;
|
|
const itemRef = useRef<HTMLDivElement>(null);
|
|
|
|
useEffect(() => {
|
|
if (itemRef.current && ob) {
|
|
if (!isBelowViewport(itemRef.current)) {
|
|
return;
|
|
}
|
|
const animation = itemRef.current.animate(
|
|
[
|
|
{
|
|
transform: `translateY(${SLIDE_FADE_DISTANCE}px)`,
|
|
opacity: 0.1
|
|
},
|
|
{
|
|
transform: `translateY(0)`,
|
|
opacity: 1
|
|
}
|
|
],
|
|
{
|
|
duration: SLIDE_FADE_DURATION,
|
|
easing: "ease-in-out",
|
|
fill: "forwards" // 当动画完成后,保留最后一个关键帧的样式
|
|
}
|
|
);
|
|
animation.pause();
|
|
map.set(itemRef.current, animation);
|
|
ob.observe(itemRef.current);
|
|
}
|
|
|
|
return () => {
|
|
ob.unobserve(itemRef.current);
|
|
};
|
|
}, [itemRef.current]);
|
|
|
|
return (
|
|
<div className={styles.block} ref={itemRef} style={{ backgroundColor: item.bg }}>
|
|
<h3>The most popular component library</h3>
|
|
|
|
<h5>for Tailwind CSS</h5>
|
|
<p>daisyUI adds component class names to Tailwind CSS so you can make beautiful websites faster than ever.</p>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default slideInItem;
|