Skip to content

Commit

Permalink
feat: get bounding client rect
Browse files Browse the repository at this point in the history
  • Loading branch information
wkylin committed Dec 9, 2024
1 parent 4ee0b89 commit a4d577f
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 11 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@types/react-test-renderer": "^18.3.0",
"@types/resize-observer-browser": "^0.1.11",
"@types/three": "^0.170.0",
"@types/user-agents": "^1.0.4",
"@typescript-eslint/eslint-plugin": "^8.16.0",
Expand Down Expand Up @@ -307,6 +308,7 @@
"remark-gfm": "^4.0.0",
"remark-math": "^6.0.0",
"remove-markdown": "^0.5.5",
"resize-observer-polyfill": "^1.5.1",
"sanitize.css": "^13.0.0",
"screenfull": "^6.0.2",
"sse": "github:mpetazzoni/sse.js",
Expand Down
4 changes: 2 additions & 2 deletions src/components/container/masonryContainer/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import useMasonry from '@hooks/useMasonry'

Check failure on line 1 in src/components/container/masonryContainer/index.jsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package

const Masonry = () => {
const MyMasonry = () => {
const masonryContainer = useMasonry()
return (
<div
Expand Down Expand Up @@ -29,4 +29,4 @@ const Masonry = () => {
)
}

export default Masonry
export default MyMasonry
4 changes: 2 additions & 2 deletions src/components/hooks/useMasonry/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useEffect, useState, useRef } from 'react'
import { useEffect, useLayoutEffect, useState, useRef } from 'react'

Check failure on line 1 in src/components/hooks/useMasonry/index.tsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package

const useMasonry = () => {
const masonryContainer = useRef<HTMLDivElement | null>(null)
const [items, setItems] = useState<ChildNode[]>([])

useEffect(() => {
useLayoutEffect(() => {
if (masonryContainer.current) {
const masonryItem = Array.from(masonryContainer.current.children)
setItems(masonryItem)
Expand Down
60 changes: 60 additions & 0 deletions src/components/hooks/useRect/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { useCallback, useLayoutEffect, useRef, useState } from "react";

Check failure on line 1 in src/components/hooks/useRect/index.tsx

View workflow job for this annotation

GitHub Actions / Qodana for JS

ESLint

ESLint: Install the 'eslint' package

import ResizeObserver from 'resize-observer-polyfill'

type RectResult = {
bottom: number;
height: number;
left: number;
right: number;
top: number;
width: number;
} | null;

const getRect = (element: HTMLElement | null): RectResult | null => {
if (!element) return null;
return element.getBoundingClientRect();
};

const useRect = (): [
RectResult,
React.MutableRefObject<HTMLDivElement | null>
] => {
const ref = useRef<HTMLDivElement | null>(null);
const current = ref.current || null;
const [rect, setRect] = useState(getRect(current));

const handleResize = useCallback(() => {
if (!ref.current) return;

// Update client rect
setRect(getRect(ref.current));
}, [ref]);

useLayoutEffect(() => {
const element = ref.current;
if (!element) return;

handleResize();
if (typeof ResizeObserver === "function") {
let resizeObserver: ResizeObserver | null = new ResizeObserver(() =>
handleResize()
);
resizeObserver.observe(element);

return () => {
if (!resizeObserver) return;
resizeObserver.disconnect();
resizeObserver = null;
};
}
// set resize listener
window.addEventListener("resize", handleResize);
// remove resize listener
return () => window.removeEventListener("resize", handleResize);
}, [handleResize]);

return [rect, ref];
};

export default useRect
23 changes: 16 additions & 7 deletions src/pages/home/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import AnimateOnScreen from '@stateless/AnimateOnScreen'
import AnimateRipple from '@stateless/AnimateRipple'
import AnimateWave from '@stateless/AnimateWave'
import MeshGradientBackground from '@stateless/MeshGradientBackground'
import useRect from '@hooks/useRect'
import TagCloud from '@stateless/TagCloud'
// import SlideLinear from '@stateless/SlideLinear'
// import Masonry from '@container/masonryContainer'
Expand Down Expand Up @@ -165,7 +166,9 @@ const Home = () => {
})
}

const { scrollDir, scrollPosition } = useDetectScroll({target: document.getElementById('container')})
// const { scrollDir, scrollPosition } = useDetectScroll({target: document.getElementById('container')})

const [barRect, barRef] = useRect()

return (
<FixTabPanel>
Expand All @@ -192,12 +195,12 @@ const Home = () => {
<section style={{ display: 'flex', alignItems: 'center', marginTop: 10, marginBottom: 40 }}>
<Atom /> <Merge /> <GitMerge /> <GitPullRequestArrow />
</section>
<section style={{ marginBottom: 40, fontSize: 16 }}>
{/* <section style={{ marginBottom: 40, fontSize: 16 }}>
<h2>Scroll direction: {`${scrollDir}`}</h2>
<p>
Scroll position - Top: {scrollPosition.top}, Bottom: {scrollPosition.bottom}
</p>
</section>
</section> */}
<section style={{ marginBottom: 40, fontSize: 16 }}>
<h3>
React Animate On Scroll.
Expand Down Expand Up @@ -274,11 +277,14 @@ const Home = () => {
<section></section>
</SpotlightCard>
</section>
<section className={styles.box} style={{ marginBottom: 40, width: 360, height: 200, position: 'relative', backgroundColor: 'rgba(0, 0,0, 0.9)', borderRadius:8 }}>
<section className={styles.dotMask}>
我的中国心
<section className={styles.box} style={{ marginBottom: 10, width: 360, height: 200, position: 'relative', backgroundColor: 'rgba(0, 0,0, 0.9)', borderRadius:8 }}>
<section className={styles.dotMask} ref={barRef}>
dot mask
</section>
</section>
<section style={{ marginBottom: 40, fontSize: 18 }}>
<section>RectResult.</section>
width: {parseInt(barRect?.width)} height: {parseInt(barRect?.height)} top: {parseInt(barRect?.top)} bottom: {parseInt(barRect?.bottom)} right: {parseInt(barRect?.right)} left: {parseInt(barRect?.left)}</section>
<section style={{ marginBottom: 40, height: 200, width: 360, overflow: 'hidden' }}>
<MeshGradientBackground />
</section>
Expand Down Expand Up @@ -373,6 +379,10 @@ const Home = () => {
<LazyLoadImage src="https://picsum.photos/id/6/300/100" alt="Strawberries" />
<LazyLoadImage src="https://picsum.photos/id/7/300/150" alt="Strawberries" />
<LazyLoadImage src="https://picsum.photos/id/8/300/200" alt="Strawberries" />
<LazyLoadImage src="https://picsum.photos/id/1/300/100" alt="Strawberries" />
<LazyLoadImage src="https://picsum.photos/id/2/300/200" alt="Strawberries" />
<LazyLoadImage src="https://picsum.photos/id/3/300/150" alt="Strawberries" />
<LazyLoadImage src="https://picsum.photos/id/4/300/150" alt="Strawberries" />
</Masonry>
</ResponsiveMasonry>
</section>
Expand All @@ -389,7 +399,6 @@ const Home = () => {
<div style={{ width: 200, height: 40, lineHeight: '40px', textAlign: 'center', background: '#aaa', margin: '0 10px', borderRadius: 4 }}>Vue</div>
</Marquee>
</section>

</FixTabPanel>
)
}
Expand Down

0 comments on commit a4d577f

Please sign in to comment.