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 {