From a32d0e11bdbbcc5c11836e07cf358e638ebb54bd Mon Sep 17 00:00:00 2001 From: master1lan <278457198@qq.com> Date: Tue, 27 Dec 2022 20:19:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E7=89=87=E5=8A=A0?= =?UTF-8?q?=E8=BD=BD=E8=BF=87=E6=B8=A1=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + pnpm-lock.yaml | 9 ++++++ src/App.tsx | 5 ++-- src/components/image/index.tsx | 49 +++++++++++++++++++++++--------- src/components/image/tool.ts | 20 +++++++++++-- src/components/masonry/index.tsx | 10 ++++--- src/index.less | 4 ++- 7 files changed, 74 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 691adfd..4a444f7 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@types/node": "^18.11.18", "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", + "@types/react-lazy-load-image-component": "^1.5.2", "@vitejs/plugin-react-swc": "^3.0.0", "less": "^4.1.3", "typescript": "^4.9.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3cfeba6..3d39aaf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,6 +6,7 @@ specifiers: '@types/node': ^18.11.18 '@types/react': ^18.0.26 '@types/react-dom': ^18.0.9 + '@types/react-lazy-load-image-component': ^1.5.2 '@vitejs/plugin-react-swc': ^3.0.0 imagesloaded: ^5.0.0 less: ^4.1.3 @@ -31,6 +32,7 @@ devDependencies: '@types/node': 18.11.18 '@types/react': 18.0.26 '@types/react-dom': 18.0.10 + '@types/react-lazy-load-image-component': 1.5.2 '@vitejs/plugin-react-swc': 3.0.1_vite@4.0.3 less: 4.1.3 typescript: 4.9.4 @@ -468,6 +470,13 @@ packages: '@types/react': 18.0.26 dev: true + /@types/react-lazy-load-image-component/1.5.2: + resolution: {integrity: sha512-4NLJsMJVrMv18FuMIkUUBVj/PH9A+BvLKrZC75EWiEFn1IsMrZHgL1tVKw5QBfoa0Qjz6SkWIzEvwcyZ8PgnIg==} + dependencies: + '@types/react': 18.0.26 + csstype: 3.1.1 + dev: true + /@types/react/18.0.26: resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} dependencies: diff --git a/src/App.tsx b/src/App.tsx index 311feb2..b0db684 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,14 +1,13 @@ -// import Masonry from "@components/masonry"; +import Masonry from "@components/masonry"; import Image from "@components/image"; - export default function App() { // return ; const url = `https://images.pexels.com/photos/5702958/pexels-photo-5702958.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1`; return (
- +
); } diff --git a/src/components/image/index.tsx b/src/components/image/index.tsx index 2e95812..394a762 100644 --- a/src/components/image/index.tsx +++ b/src/components/image/index.tsx @@ -1,23 +1,44 @@ -import { useEffect, useState } from "react"; -import { getImageSize } from "./tool"; -export default function Image({ url }) { +import { useMemo } from "react"; +import { useEffect, useState, memo } from "react"; +import { getImageSize, getResizeHeight, fallbackUrl } from "./tool"; + +type ImageProps = { + url: string; +}; + +function useLoading(url: string) { const [loading, setLoading] = useState(true); - const [obj, setObj] = useState({}); - useEffect(() => { - getImageSize(url).then((data) => { - setLoading(() => false); - setObj(() => ({ - width: data.width, - height: data.height, + const [size, setSize] = useState<{ width: number; height: number }>({ + width: 0, + height: 0, + }); + useMemo(() => { + getImageSize(url).then(({ width, height }) => { + setTimeout(() => { + setLoading(() => false); + }, 500); + setSize(() => ({ + width: width, + height: height, })); }); }, [url]); - if (loading) { - return
loading
; - } + return { loading, size }; +} + +export default function Image({ url }: ImageProps) { + const { loading, size } = useLoading(url); return (
- +
); } diff --git a/src/components/image/tool.ts b/src/components/image/tool.ts index e6382d1..4a9abd6 100644 --- a/src/components/image/tool.ts +++ b/src/components/image/tool.ts @@ -1,9 +1,12 @@ import { Once } from "@utils/index"; -import { resolve } from "path"; +type ImageSize = { + width: number; + height: number; +}; /** * image组件的工具库 */ -export function getImageSize(imageSrc: string) { +export function getImageSize(imageSrc: string): Promise { return new Promise((resolve, reject) => { const image = new Image(); image.src = imageSrc; @@ -20,3 +23,16 @@ export function getImageSize(imageSrc: string) { }); }); } + +export function getResizeHeight(imageSizeObj: ImageSize, realwidth: number) { + const res = 100 + Math.ceil(Math.random() * 100); + if (imageSizeObj.width < 1 || imageSizeObj.height < 1) { + return res; + } + const realheight = + imageSizeObj.height / Math.floor(imageSizeObj.width / realwidth); + return isNaN(realheight) ? res : realheight; +} + +export const fallbackUrl = + "data:image/png;base64,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"; diff --git a/src/components/masonry/index.tsx b/src/components/masonry/index.tsx index a854f2d..08c6770 100644 --- a/src/components/masonry/index.tsx +++ b/src/components/masonry/index.tsx @@ -1,13 +1,13 @@ import { Masonry } from "masonic"; +import Image from "@components/image"; import { useFakerImages } from "@utils/faker/index"; export default function App() { - const lists = useFakerImages(100); + const lists = useFakerImages(20); return (
@@ -18,6 +18,7 @@ export default function App() { columnGutter={10} maxColumnCount={5} render={FakerCard} + overscanBy={Infinity} />
@@ -27,7 +28,8 @@ export default function App() { function FakerCard({ data: { id, image, name } }) { return (
- + {/* */} +

{name} diff --git a/src/index.less b/src/index.less index c75ad64..04ab005 100644 --- a/src/index.less +++ b/src/index.less @@ -5,11 +5,11 @@ } .feedContainer { + margin: 0 auto; max-width: 1200px; display: flex; align-items: flex-start; position: relative; - transition: width .5s; width: 100%; .element-item { @@ -21,6 +21,8 @@ border-radius: 8px; outline: 0.5px solid rgba(0, 0, 0, .05); object-fit: cover; + transition: opacity .5s; + -webkit-transition: opacity .5s; } .footer {