Skip to content

Commit

Permalink
增加图片加载过渡效果
Browse files Browse the repository at this point in the history
  • Loading branch information
master1lan committed Dec 27, 2022
1 parent 76b5047 commit a32d0e1
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 24 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
9 changes: 9 additions & 0 deletions pnpm-lock.yaml

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

5 changes: 2 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// import Masonry from "@components/masonry";
import Masonry from "@components/masonry";

import Image from "@components/image";

export default function App() {
// return <Masonry />;
const url = `https://images.pexels.com/photos/5702958/pexels-photo-5702958.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1`;

return (
<div>
<Image url={url} />
<Masonry />
</div>
);
}
49 changes: 35 additions & 14 deletions src/components/image/index.tsx
Original file line number Diff line number Diff line change
@@ -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<boolean>(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 <div>loading</div>;
}
return { loading, size };
}

export default function Image({ url }: ImageProps) {
const { loading, size } = useLoading(url);
return (
<div>
<img width={obj.width} height={obj.height} src={url} />
<img
width={180}
height={getResizeHeight(size, 180)}
src={loading ? fallbackUrl : url}
style={{
opacity: loading ? 0.09 : 1.0,
}}
alt=''
/>
</div>
);
}
20 changes: 18 additions & 2 deletions src/components/image/tool.ts
Original file line number Diff line number Diff line change
@@ -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<ImageSize> {
return new Promise((resolve, reject) => {
const image = new Image();
image.src = imageSrc;
Expand All @@ -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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";
10 changes: 6 additions & 4 deletions src/components/masonry/index.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div
style={{
display: "flex",
justifyContent: "center",
marginTop: "30px",
}}
>
<div className='feedContainer'>
Expand All @@ -18,6 +18,7 @@ export default function App() {
columnGutter={10}
maxColumnCount={5}
render={FakerCard}
overscanBy={Infinity}
/>
</div>
</div>
Expand All @@ -27,7 +28,8 @@ export default function App() {
function FakerCard({ data: { id, image, name } }) {
return (
<section key={id} className='element-item'>
<img src={image} alt='' loading='lazy' />
{/* <img src={image} alt='' loading='lazy' /> */}
<Image url={image} />
<div className='footer'>
<p>
<span>{name}</span>
Expand Down
4 changes: 3 additions & 1 deletion src/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down

0 comments on commit a32d0e1

Please sign in to comment.