自定义图片滚动组件
This commit is contained in:
parent
d976b642ff
commit
f442b82354
|
@ -101,20 +101,26 @@ footer{
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
.scrollbarBoxX {
|
||||||
|
/* IE 10+ */
|
||||||
|
overflow-y: hidden;
|
||||||
|
overflow-x: auto;
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
}
|
||||||
|
|
||||||
.scrollbarBox::-webkit-scrollbar {
|
.scrollbarBoxX::-webkit-scrollbar, .scrollbarBox::-webkit-scrollbar {
|
||||||
/* display:none; */
|
/* display:none; */
|
||||||
width: 6px;
|
width: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollbarBox::-webkit-scrollbar-thumb {
|
.scrollbarBoxX::-webkit-scrollbar-thumb,.scrollbarBox::-webkit-scrollbar-thumb {
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
-webkit-box-shadow: inset 0 0 5px rgba(138, 138, 138, 0.2);
|
-webkit-box-shadow: inset 0 0 5px rgba(138, 138, 138, 0.2);
|
||||||
background: nb-theme(background-basic-color-4);
|
background: nb-theme(background-basic-color-4);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.scrollbarBox::-webkit-scrollbar-track {
|
.scrollbarBoxX::-webkit-scrollbar-track,.scrollbarBox::-webkit-scrollbar-track {
|
||||||
-webkit-box-shadow: inset 0 0 5px rgba(138, 138, 138, 0.2);
|
-webkit-box-shadow: inset 0 0 5px rgba(138, 138, 138, 0.2);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: nb-theme(background-basic-color-2);
|
background: nb-theme(background-basic-color-2);
|
||||||
|
|
|
@ -72,10 +72,7 @@ export default function RootLayout({ children }) {
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
{/* <!-- 用来定义顶部状态栏的形式默认是default为白色 black为黑色 black-translucent为灰色半透明(会占据屏幕的约20px,不同的设备可能会有差异)--> */}
|
{/* <!-- 用来定义顶部状态栏的形式默认是default为白色 black为黑色 black-translucent为灰色半透明(会占据屏幕的约20px,不同的设备可能会有差异)--> */}
|
||||||
{/* <!-- 在定义了apple-mobile-web-app-capable的前提下,设置状态栏的属性值apple-mobile-web-app-status-bar-style才有效; --> */}
|
{/* <!-- 在定义了apple-mobile-web-app-capable的前提下,设置状态栏的属性值apple-mobile-web-app-status-bar-style才有效; --> */}
|
||||||
<meta
|
<meta name="apple-mobile-web-app-status-bar-style" content="#ffffff" />
|
||||||
name="apple-mobile-web-app-status-bar-style"
|
|
||||||
content="#ffffff"
|
|
||||||
/>
|
|
||||||
{/* <!-- apple-touch-startup-image用来配置启动动画 --> */}
|
{/* <!-- apple-touch-startup-image用来配置启动动画 --> */}
|
||||||
{/* <!-- 这里要注意,这里图片的尺寸要和设备的静态图片显示尺寸完全对应,差一个像素都会导致启动动画无法显示 --> */}
|
{/* <!-- 这里要注意,这里图片的尺寸要和设备的静态图片显示尺寸完全对应,差一个像素都会导致启动动画无法显示 --> */}
|
||||||
{/* <!-- 下面列举了iPhone的所有尺寸(ps:为了方便大家就全部贴出来了!!) --> */}
|
{/* <!-- 下面列举了iPhone的所有尺寸(ps:为了方便大家就全部贴出来了!!) --> */}
|
||||||
|
@ -191,9 +188,16 @@ export default function RootLayout({ children }) {
|
||||||
</head>
|
</head>
|
||||||
<body className={`${inter.className} h-full`}>
|
<body className={`${inter.className} h-full`}>
|
||||||
<main className={`w-full bg-deepBg h-full`}>
|
<main className={`w-full bg-deepBg h-full`}>
|
||||||
{withAuth(<Provider store={store}>{children}</Provider>)}
|
|
||||||
{/* <Provider store={store}>{children}</Provider> */}
|
|
||||||
<div id="maskDomBox"></div>
|
<div id="maskDomBox"></div>
|
||||||
|
{withAuth(
|
||||||
|
<Provider store={store}>
|
||||||
|
<div>
|
||||||
|
{children}
|
||||||
|
{/* <ImagesMask ref={imagesMaskRef} /> */}
|
||||||
|
</div>
|
||||||
|
</Provider>
|
||||||
|
)}
|
||||||
|
{/* <Provider store={store}>{children}</Provider> */}
|
||||||
</main>
|
</main>
|
||||||
<footer className="fixed left-0 w-screen bg-black">
|
<footer className="fixed left-0 w-screen bg-black">
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -10,12 +10,32 @@ import React, {
|
||||||
import { Mask, Image } from "antd-mobile";
|
import { Mask, Image } from "antd-mobile";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { faAngleLeft, faAngleRight } from "@fortawesome/free-solid-svg-icons";
|
import { faAngleLeft, faAngleRight } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { createRoot } from "react-dom/client";
|
||||||
|
|
||||||
|
const maskDomBox = window ? document?.getElementById("maskDomBox") : null;
|
||||||
|
console.log(maskDomBox);
|
||||||
|
const root = createRoot(maskDomBox);
|
||||||
function ImagesMask({}, ref) {
|
function ImagesMask({}, ref) {
|
||||||
const [currentIndex, setCurrentIndex] = useState(0);
|
const [currentIndex, setCurrentIndex] = useState(0);
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const [images, setImages] = useState([]);
|
const [images, setImages] = useState([]);
|
||||||
const [distance, setDistance] = useState(0);
|
|
||||||
const scrollRef = useRef(null);
|
const scrollRef = useRef(null);
|
||||||
|
useEffect(() => {
|
||||||
|
root.render(
|
||||||
|
<div>
|
||||||
|
<ImagesMaskContaint
|
||||||
|
images={images}
|
||||||
|
visible={visible}
|
||||||
|
currentIndex={currentIndex}
|
||||||
|
ref={scrollRef}
|
||||||
|
setCurrentIndex={setCurrentIndex}
|
||||||
|
setVisible={setVisible}
|
||||||
|
setImages={setImages}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
// root.render(<div>xxxx</div>);
|
||||||
|
}, [visible]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (scrollRef.current) {
|
if (scrollRef.current) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -27,15 +47,26 @@ function ImagesMask({}, ref) {
|
||||||
show: (arr, index) => {
|
show: (arr, index) => {
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
setImages(arr);
|
setImages(arr);
|
||||||
setVisible(true);
|
setVisible(old=>{
|
||||||
|
console.log(arr, index,old)
|
||||||
|
return !old
|
||||||
|
});
|
||||||
|
|
||||||
// Mask.show
|
// Mask.show
|
||||||
// const maskDomBox = document.getElementById("maskDomBox");
|
// const maskDomBox = document.getElementById("maskDomBox");
|
||||||
},
|
},
|
||||||
close: () => setVisible(false),
|
close: () => setVisible(false),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ImagesMaskContaint = forwardRef(
|
||||||
|
({ visible, images, currentIndex,setCurrentIndex,setVisible,setImages }, ref) => {
|
||||||
|
const [distance, setDistance] = useState(0);
|
||||||
const getDistance = (e) => {
|
const getDistance = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
const distance = scrollRef.current.scrollLeft;
|
const distance = ref.current.scrollLeft;
|
||||||
setDistance(distance);
|
setDistance(distance);
|
||||||
};
|
};
|
||||||
const handleMoveImages = (e, index) => {
|
const handleMoveImages = (e, index) => {
|
||||||
|
@ -45,37 +76,24 @@ function ImagesMask({}, ref) {
|
||||||
distance > window.innerWidth * currentIndex &&
|
distance > window.innerWidth * currentIndex &&
|
||||||
distance < window.innerWidth + window.innerWidth * currentIndex
|
distance < window.innerWidth + window.innerWidth * currentIndex
|
||||||
) {
|
) {
|
||||||
setCurrentIndex(Math.ceil(distance/414))
|
setCurrentIndex(Math.ceil(distance / 414));
|
||||||
} else if (distance < window.innerWidth * currentIndex) {
|
} else if (distance < window.innerWidth * currentIndex) {
|
||||||
setCurrentIndex(Math.ceil(distance/414)-1)
|
setCurrentIndex(Math.ceil(distance / 414) - 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
|
<div>
|
||||||
<Mask
|
<Mask
|
||||||
visible={visible}
|
visible={visible}
|
||||||
className="z-[99] h-screen flex justify-center items-center"
|
className="z-[1002] h-screen flex justify-center items-center"
|
||||||
>
|
>
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<div className="text-center mb-2">
|
<div className="text-center mb-2">
|
||||||
{currentIndex + 1}/{images.length}
|
{currentIndex + 1}/{images.length}
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div ref={ref} id="imagesScrollBox" className="flex overflow-auto scrollbarBoxX">
|
||||||
ref={scrollRef}
|
|
||||||
id="imagesScrollBox"
|
|
||||||
className="flex overflow-auto"
|
|
||||||
>
|
|
||||||
{images.map((item, index) => {
|
{images.map((item, index) => {
|
||||||
return (
|
return (
|
||||||
// <Image
|
|
||||||
// key={index}
|
|
||||||
// fit="cover"
|
|
||||||
// className="mr-3"
|
|
||||||
// // src={process.env.NEXT_PUBLIC_WEB_ASSETS_URL+"/icons/nodata.png"}
|
|
||||||
// src={item}
|
|
||||||
// placeholder=""
|
|
||||||
// width="100vw"
|
|
||||||
// // height="90vh"
|
|
||||||
// />
|
|
||||||
<img
|
<img
|
||||||
key={index}
|
key={index}
|
||||||
src={item}
|
src={item}
|
||||||
|
@ -111,7 +129,9 @@ function ImagesMask({}, ref) {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Mask>
|
</Mask>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
|
||||||
export default forwardRef(ImagesMask);
|
export default forwardRef(ImagesMask);
|
||||||
|
|
|
@ -7,8 +7,8 @@ import { faAngleUp, faClose } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import baseRequest from "@/utils/baseRequest";
|
import baseRequest from "@/utils/baseRequest";
|
||||||
import Player from "next-video/player";
|
import Player from "next-video/player";
|
||||||
// import ImagesMask from "@/components/ImagesMask";
|
import ImagesMask from "@/components/ImagesMask";
|
||||||
// import Viewer from 'react-viewer';
|
|
||||||
export default function Photos({
|
export default function Photos({
|
||||||
isUnlocked,
|
isUnlocked,
|
||||||
mediaVisibleRange,
|
mediaVisibleRange,
|
||||||
|
@ -23,9 +23,10 @@ export default function Photos({
|
||||||
const [visible, setVisible] = useState(false);
|
const [visible, setVisible] = useState(false);
|
||||||
const currentIndex = useRef();
|
const currentIndex = useRef();
|
||||||
const swiper = useRef(null);
|
const swiper = useRef(null);
|
||||||
// const imagesMaskRef = useRef(null);
|
const imagesMaskRef = useRef(null);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const base = baseRequest();
|
const base = baseRequest();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (media) {
|
if (media) {
|
||||||
let imgArr = media.images.map((item) => ({
|
let imgArr = media.images.map((item) => ({
|
||||||
|
@ -74,88 +75,92 @@ export default function Photos({
|
||||||
// }, 400);
|
// }, 400);
|
||||||
|
|
||||||
// 添加左右切换按钮
|
// 添加左右切换按钮
|
||||||
const btns = document.createElement("div");
|
// const btns = document.createElement("div");
|
||||||
btns.className = "imagesBtnsControllers";
|
// btns.className = "imagesBtnsControllers";
|
||||||
const btnL = document.createElement("div");
|
// const btnL = document.createElement("div");
|
||||||
btnL.className = "imagesBtnsControllerLeft";
|
// btnL.className = "imagesBtnsControllerLeft";
|
||||||
btnL.addEventListener("click", () => {
|
// btnL.addEventListener("click", () => {
|
||||||
if (currentIndex.current > 0) {
|
// if (currentIndex.current > 0) {
|
||||||
currentIndex.current = currentIndex.current - 1;
|
// currentIndex.current = currentIndex.current - 1;
|
||||||
handleShowImages(currentIndex.current, photos, btns);
|
// handleShowImages(currentIndex.current, photos, btns,interval);
|
||||||
if (!currentIndex.current) {
|
// if (!currentIndex.current) {
|
||||||
btnL.style.opacity = 0.5;
|
// btnL.style.opacity = 0.5;
|
||||||
btnR.style.opacity = 1;
|
// btnR.style.opacity = 1;
|
||||||
} else {
|
// } else {
|
||||||
btnR.style.opacity = 1;
|
// btnR.style.opacity = 1;
|
||||||
btnL.style.opacity = 1;
|
// btnL.style.opacity = 1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
const btnR = document.createElement("div");
|
// const btnR = document.createElement("div");
|
||||||
btnR.className = "imagesBtnsControllerRight";
|
// btnR.className = "imagesBtnsControllerRight";
|
||||||
btnR.addEventListener("click", () => {
|
// btnR.addEventListener("click", () => {
|
||||||
if (currentIndex.current < currentPhotos.length - 1) {
|
// if (currentIndex.current < currentPhotos.length - 1) {
|
||||||
currentIndex.current = currentIndex.current + 1;
|
// currentIndex.current = currentIndex.current + 1;
|
||||||
handleShowImages(currentIndex.current, photos, btns);
|
// handleShowImages(currentIndex.current, photos, btns,interval);
|
||||||
if (currentIndex.current == currentPhotos.length - 1) {
|
// if (currentIndex.current == currentPhotos.length - 1) {
|
||||||
btnR.style.opacity = 0.5;
|
// btnR.style.opacity = 0.5;
|
||||||
btnL.style.opacity = 1;
|
// btnL.style.opacity = 1;
|
||||||
} else {
|
// } else {
|
||||||
btnR.style.opacity = 1;
|
// btnR.style.opacity = 1;
|
||||||
btnL.style.opacity = 1;
|
// btnL.style.opacity = 1;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
btns.append(btnL, btnR);
|
// btns.append(btnL, btnR);
|
||||||
handleShowImages(index, photos, btns);
|
// handleShowImages(index, photos, btns,interval);
|
||||||
|
|
||||||
// setVisible(true)
|
// setVisible(true)
|
||||||
// imagesMaskRef.current.show(photos.map((item) => item?.url),index)
|
console.log(imagesMaskRef.current);
|
||||||
|
imagesMaskRef.current.show(
|
||||||
|
photos.map((item) => item?.url),
|
||||||
|
index
|
||||||
|
);
|
||||||
};
|
};
|
||||||
const handleShowImages = (index, photos, btns) => {
|
// const handleShowImages = (index, photos, btns) => {
|
||||||
const mediaDom = document.createElement("div");
|
// const mediaDom = document.createElement("div");
|
||||||
mediaDom.style.width = "100vw";
|
// mediaDom.style.width = "100vw";
|
||||||
document.body.appendChild(mediaDom);
|
// document.body.appendChild(mediaDom);
|
||||||
mediaDom.className = `${
|
// mediaDom.className = `${
|
||||||
photos[index]?.type == "hid" ? "mediaDom photos-body" : "mediaDom"
|
// photos[index]?.type == "hid" ? "mediaDom photos-body" : "mediaDom"
|
||||||
}`;
|
// }`;
|
||||||
mediaDom.appendChild(btns);
|
// mediaDom.appendChild(btns);
|
||||||
ImageViewer.clear();
|
// ImageViewer.clear();
|
||||||
ImageViewer.Multi.show({
|
// ImageViewer.Multi.show({
|
||||||
images: photos.map((item) => item?.url),
|
// images: photos.map((item) => item?.url),
|
||||||
defaultIndex: index,
|
// defaultIndex: index,
|
||||||
renderFooter: (image, index) => {
|
// renderFooter: (image, index) => {
|
||||||
return renderFooter(photos[index]?.type == "hid", mediaDom);
|
// return renderFooter(photos[index]?.type == "hid", mediaDom);
|
||||||
},
|
// },
|
||||||
|
|
||||||
getContainer: mediaDom,
|
// getContainer: mediaDom,
|
||||||
onIndexChange: (index) => {
|
// onIndexChange: (index) => {
|
||||||
currentIndex.current = index;
|
// currentIndex.current = index;
|
||||||
mediaDom.className = `${
|
// mediaDom.className = `${
|
||||||
photos[index]?.type == "hid" ? "mediaDom photos-body" : "mediaDom"
|
// photos[index]?.type == "hid" ? "mediaDom photos-body" : "mediaDom"
|
||||||
}`;
|
// }`;
|
||||||
const leftBtn = document.getElementsByClassName("imagesBtnsControllerLeft")[0]
|
// const leftBtn = document.getElementsByClassName("imagesBtnsControllerLeft")[0]
|
||||||
const rightBtn = document.getElementsByClassName("imagesBtnsControllerRight")[0]
|
// const rightBtn = document.getElementsByClassName("imagesBtnsControllerRight")[0]
|
||||||
if(leftBtn && rightBtn){
|
// if(leftBtn && rightBtn){
|
||||||
if(!index){
|
// if(!index){
|
||||||
leftBtn.style.opacity=0.5
|
// leftBtn.style.opacity=0.5
|
||||||
rightBtn.style.opacity=1
|
// rightBtn.style.opacity=1
|
||||||
}else if(index==currentPhotos.length-1){
|
// }else if(index==currentPhotos.length-1){
|
||||||
leftBtn.style.opacity=1
|
// leftBtn.style.opacity=1
|
||||||
rightBtn.style.opacity=0.5
|
// rightBtn.style.opacity=0.5
|
||||||
}else{
|
// }else{
|
||||||
leftBtn.style.opacity=1
|
// leftBtn.style.opacity=1
|
||||||
rightBtn.style.opacity=1
|
// rightBtn.style.opacity=1
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
afterClose: () => {
|
// afterClose: () => {
|
||||||
mediaDom.remove();
|
// mediaDom.remove();
|
||||||
// clearInterval(interval);
|
// // clearInterval(interval);
|
||||||
},
|
// },
|
||||||
classNames: { body: "photos-bodyBox" },
|
// classNames: { body: "photos-bodyBox" },
|
||||||
});
|
// });
|
||||||
};
|
// };
|
||||||
const handleShowVideo = (video) => {
|
const handleShowVideo = (video) => {
|
||||||
Dialog.className = "videoMask";
|
Dialog.className = "videoMask";
|
||||||
Dialog.show({
|
Dialog.show({
|
||||||
|
@ -354,7 +359,7 @@ export default function Photos({
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
{/* <ImagesMask ref={imagesMaskRef}/> */}
|
<ImagesMask ref={imagesMaskRef} />
|
||||||
{/* <Viewer
|
{/* <Viewer
|
||||||
visible={visible}
|
visible={visible}
|
||||||
onClose={() => { setVisible(false); } }
|
onClose={() => { setVisible(false); } }
|
||||||
|
|
Loading…
Reference in New Issue