Skip to content

添加图片页过渡效果 #51

Merged
merged 3 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## 1.2.4 (2023-03-16)


### 🐛 Bug Fixes

* **custom**: 修复网速过快导致图片快速切换的bug ([13f1f49](https://vlink.dev/EOEFANS/eoefans-web/commits/13f1f49))



## 1.2.3 (2023-03-07)


Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eoefans-web",
"version": "1.2.3",
"version": "1.2.4",
"type": "module",
"scripts": {
"dev": "vite --config ./config/vite.dev.config.ts",
Expand Down
39 changes: 34 additions & 5 deletions src/routers/photo/item/index.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,55 @@
import { PhotoRouterImageCardType } from "../phototype";
import { useState } from "react";
import { useEffect, useState, useMemo } from "react";
import ImgModals from "./modal";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
import { Link, styled } from "@mui/material";
import style from "./photo.module.less";
import { ImageBasic } from "@components/image";
import { Omit } from "@utils/index";
import CollectionsIcon from "@mui/icons-material/Collections";
import { getImageSize } from "@components/image/tool";

type CardType = {
data: PhotoRouterImageCardType;
};

const useLoading = (url: string) => {
const [isLoading, set] = useState<boolean>(true);
useMemo(async () => {
await getImageSize(url);
set(() => false);
}, [url]);
return isLoading;
};
export default function PhotoCard(props: CardType) {
const { images, dynamic_id, ...resPorps } = props.data;
const [open, set] = useState(false),
handlerChangeOpen = () => set((open) => !open);
const modalPorps = { open, images, onClose: handlerChangeOpen, dynamic_id };
const modalPorps = { open, images, onClose: handlerChangeOpen, dynamic_id },
url = `${images[0].src}@${250}w.webp`;
const isLoading = useLoading(url);
return (
<div className={style["card"]}>
<ImageBasic
url={`${images[0].src}@${250}w.webp`}
url={url}
{...Omit(images[0], "src")}
{...resPorps}
title={"图片栏"}
className={style["show-img"]}
onClick={handlerChangeOpen}
/>
>
<span
className={`absolute left-0 top-0 right-0 bottom-0 transition-all ${
isLoading ? "pointer-events-auto" : "pointer-events-none"
}`}
style={{
zIndex: 1,
transitionDuration: "400ms",
background: isLoading ? "hsla(0,0%,91.4%,.5)" : "transparent",
backdropFilter: !isLoading ? "blur(0)" : "blur(42.5px)",
WebkitBackdropFilter: !isLoading ? "blur(0)" : "blur(42.5px)",
}}
/>
</ImageBasic>
<ImgModals {...modalPorps} />
<DivJump>
<Link
Expand Down Expand Up @@ -65,6 +89,10 @@ const DivImgNum = styled("div")(({ theme }) => ({
columnGap: "2px",
pointerEvents: "none",
fontSize: "14px",
borderTopRightRadius: "8px",
[theme.breakpoints.down("sm")]: {
borderTopRightRadius: "4px",
},
}));

const DivJump = styled("div")(({ theme }) => ({
Expand All @@ -73,6 +101,7 @@ const DivJump = styled("div")(({ theme }) => ({
position: "absolute",
bottom: "0px",
width: "100%",

backgroundImage: `linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(90, 90,90, 0.8) 100%)`,
"&:hover": {
backgroundImage: `linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0,0, 0.8) 100%)`,
Expand Down
18 changes: 18 additions & 0 deletions src/routers/photo/item/loadingItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Skeleton from "@mui/material/Skeleton";
import React from "react";
import { PhotoMasonryLoadingItemType } from "../masonry";
type CardType = {
data: PhotoMasonryLoadingItemType;
};
export default function PhotoLoadingItem(props: CardType) {
return (
<Skeleton
variant='rounded'
animation='wave'
{...props.data}
sx={{
width: "100% !important",
}}
/>
);
}
72 changes: 53 additions & 19 deletions src/routers/photo/masonry.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { selectPhotoLoadingState } from "@store/loading";
import { Masonry as Masonic_masonry } from "masonic";
import { useState, useEffect } from "react";
import { useState, useEffect, useMemo } from "react";
import { useAppSelector, useAppDispatch } from "@store/hooks";

import Fade from "@mui/material/Fade";
import { changeLoading } from "@store/loading/index";
import { fetchPhotoHandler } from "./tools";
import { PhotoRouterImageCardType, PhotoRouterMasonryType } from "./phototype";
import PhotoCard from "./item";
import { useScreenSize } from "@components/proview/screenSize";
import message from "@components/message";
import styles from "./photo.module.less";
//todo props type change
export default function Masonry(props: PhotoRouterMasonryType) {
import PhotoLoadingItem from "./item/loadingItem";

const usePhotoMasonryData = (props: PhotoRouterMasonryType) => {
const [lists, setList] = useState<PhotoRouterImageCardType[]>([]);
const isLoading = useAppSelector(selectPhotoLoadingState),
dispatch = useAppDispatch(),
Expand Down Expand Up @@ -40,10 +41,10 @@ export default function Masonry(props: PhotoRouterMasonryType) {
width: img.img_width,
})),
};
if (data.length < 3) {
if (data.length < 9) {
message.info("没有更多图片了,尝试使用其他tag吧!");
}
if (index === data.length - 3) {
if (index === data.length - 9) {
return {
...itemRes,
observer: true,
Expand All @@ -61,23 +62,56 @@ export default function Masonry(props: PhotoRouterMasonryType) {
handerChangeLoading(true);
fetchHandler(1).then(() => handerChangeLoading(false));
}, [props]);
return { lists, isLoading };
};
export type PhotoMasonryLoadingItemType = Record<"width" | "height", number>;
export default function Masonry(props: PhotoRouterMasonryType) {
const { lists, isLoading } = usePhotoMasonryData(props);
const { sm, md } = useScreenSize(),
minCount = sm ? { columnCount: 2 } : {};
const loadingLists = useMemo(
() =>
Array.from({ length: 20 }, () => ({
width: 250,
height: Math.round(Math.random() * 300 + 100),
})),
[props]
);

return (
<div className={styles["container"]}>
{isLoading || (
<Masonic_masonry
items={lists}
maxColumnCount={5}
{...minCount}
columnGutter={md ? 5 : 10}
rowGutter={md ? 5 : 10}
columnWidth={200}
render={PhotoCard}
overscanBy={Infinity}
className={styles["container"]}
/>
)}
<Fade in={!isLoading} className={`${!isLoading ? "" : "hidden"}`}>
<div>
{!isLoading && (
<Masonic_masonry
items={lists}
maxColumnCount={5}
{...minCount}
columnGutter={md ? 5 : 10}
rowGutter={md ? 5 : 10}
columnWidth={200}
render={PhotoCard}
overscanBy={Infinity}
className={styles["container"]}
/>
)}
</div>
</Fade>
<Fade in={isLoading} className={`${isLoading ? "" : "hidden"}`}>
<div>
<Masonic_masonry
items={loadingLists}
maxColumnCount={5}
{...minCount}
columnGutter={md ? 5 : 10}
rowGutter={md ? 5 : 10}
columnWidth={200}
render={PhotoLoadingItem}
overscanBy={Infinity}
className={styles["container"]}
/>
</div>
</Fade>
</div>
);
}