tiefen_space_h5/components/ImagesMask/index.jsx

276 lines
9.2 KiB
React
Raw Normal View History

"use client";
import React, {
useState,
useEffect,
useRef,
forwardRef,
useImperativeHandle,
} from "react";
import { Mask, Image } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2024-08-15 20:29:15 +08:00
import {
faAngleLeft,
faAngleRight,
faDownload,
} from "@fortawesome/free-solid-svg-icons";
2024-08-07 18:08:33 +08:00
import { createRoot } from "react-dom/client";
2024-08-14 19:59:03 +08:00
import { useRouter } from "next/navigation";
import baseRequest from "@/utils/baseRequest";
2024-08-07 20:41:51 +08:00
const root = createRoot(document?.getElementById("maskDomBox"));
function ImagesMask({}, ref) {
const [visible, setVisible] = useState(false);
const [images, setImages] = useState([]);
2024-08-14 19:59:03 +08:00
const [data, setData] = useState(null);
const scrollRef = useRef(null);
2024-08-14 19:59:03 +08:00
const defaultIndex = useRef(null);
const router = useRouter();
2024-08-07 18:08:33 +08:00
useEffect(() => {
root.render(
<div>
<ImagesMaskContaint
images={images}
visible={visible}
ref={scrollRef}
setVisible={setVisible}
setImages={setImages}
2024-08-14 19:59:03 +08:00
router={router}
data={data}
defaultIndex={defaultIndex.current}
2024-08-07 18:08:33 +08:00
/>
</div>
);
// root.render(<div>xxxx</div>);
}, [visible]);
2024-08-14 19:59:03 +08:00
useImperativeHandle(ref, () => ({
2024-08-14 19:59:03 +08:00
show: (arr, index, data) => {
defaultIndex.current = index;
setImages(arr);
2024-08-14 19:59:03 +08:00
setData(data);
setVisible((old) => {
2024-08-15 20:29:15 +08:00
// console.log(arr, index, old);
2024-08-14 19:59:03 +08:00
return !old;
2024-08-07 18:08:33 +08:00
});
2024-08-14 19:59:03 +08:00
// Mask.show
// const maskDomBox = document.getElementById("maskDomBox");
},
close: () => setVisible(false),
}));
2024-08-07 18:08:33 +08:00
return <></>;
}
const ImagesMaskContaint = forwardRef(
2024-08-14 19:59:03 +08:00
(
{ visible, images, setVisible, setImages, router, data, defaultIndex = 0 },
ref
) => {
const [currentIndex, setCurrentIndex] = useState(0);
const [direction, setDirection] = useState("left");
const [initialX, setInitialX] = useState(0);
const [xOffset, setXOffset] = useState(0);
const [active, setActive] = useState(false);
const base = baseRequest();
2024-08-15 20:29:15 +08:00
const directionX = useRef(0);
// const getDistance = (e) => {
// e.stopPropagation();
// const distance = ref.current.scrollLeft;
// setDistance(distance);
// };
2024-08-14 19:59:03 +08:00
useEffect(() => {
2024-08-15 20:29:15 +08:00
// setCurrentIndex(defaultIndex);
// test3(defaultIndex - 1, "left");
if (defaultIndex) {
test3(defaultIndex - 1, "left");
}
2024-08-14 19:59:03 +08:00
}, [defaultIndex]);
useEffect(() => {
if (ref.current) {
ref.current.style.transform = `translateX(${
-window.innerWidth * currentIndex
}px)`;
}
}, [currentIndex]);
const test1 = (e) => {
setInitialX(e.touches[0].clientX - (!currentIndex ? 0 : xOffset));
if (e.touches.length === 1) {
// 单点触摸
setActive(true);
2024-08-07 18:08:33 +08:00
}
};
2024-08-14 19:59:03 +08:00
const test2 = (e) => {
if (active) {
2024-08-15 20:29:15 +08:00
let X = e.touches[0].clientX - initialX;
setDirection(
directionX.current > e.touches[0].clientX ? "left" : "right"
);
2024-08-14 19:59:03 +08:00
ref.current.style.transform = "translateX(" + X + "px)";
2024-08-15 20:29:15 +08:00
directionX.current = e.touches[0].clientX;
2024-08-14 19:59:03 +08:00
}
};
2024-08-15 20:29:15 +08:00
const test3 = (index, currentDirection) => {
2024-08-14 19:59:03 +08:00
setActive(false);
let cxOffset = window.innerWidth;
2024-08-15 20:29:15 +08:00
if (currentDirection == "left") {
2024-08-14 19:59:03 +08:00
if (index < images.length - 1) {
setCurrentIndex(index + 1);
} else {
ref.current.style.transform = `translateX(${-cxOffset * index}px)`;
}
} else {
if (index > 0) {
setCurrentIndex(index - 1);
} else {
ref.current.style.transform = `translateX(${-cxOffset * index}px)`;
}
}
2024-08-15 20:29:15 +08:00
// setInitialX(currentX);
setInitialX(-cxOffset * (index + (currentDirection == "left" ? 1 : -1)));
if (currentDirection == "left" && index > images.length - 2) return;
setXOffset(-cxOffset * (index + (currentDirection == "left" ? 1 : -1)));
2024-08-14 19:59:03 +08:00
};
2024-08-15 20:29:15 +08:00
function downloadImage(url) {
let randomNum = "";
for (let i = 0; i < 10; i++) {
randomNum += Math.floor(Math.random() * 10);
}
fetch(url)
.then((res) => res.blob())
.then((blob) => {
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = randomNum + ".jpg";
a.click();
});
}
2024-08-07 18:08:33 +08:00
return (
<div>
<Mask
2024-08-14 19:59:03 +08:00
visible={visible}
className="z-[1002] h-screen flex justify-center items-center"
onMaskClick={() => {
2024-08-15 20:29:15 +08:00
setVisible(false), setImages([]), setCurrentIndex(null);
2024-08-14 19:59:03 +08:00
// root.unmount();
}}
2024-08-15 20:29:15 +08:00
color="#000000d9"
2024-08-14 19:59:03 +08:00
>
<div className="relative">
2024-08-15 20:29:15 +08:00
{images[currentIndex]?.type != "hid" && (
<div
onClick={() => downloadImage(images[currentIndex]?.url)}
className="z-50 flex justify-center items-center w-[38px] h-[38px] bg-[#ffffff1a] text-[#fff] rounded-full absolute top-[12px] left-[12px]"
>
<FontAwesomeIcon icon={faDownload} size="xl" />
</div>
)}
2024-08-14 19:59:03 +08:00
<div className="text-center mb-2 leading-[54px]">
{currentIndex + 1}/{images.length}
</div>
2024-08-07 18:08:33 +08:00
<div
2024-08-14 19:59:03 +08:00
className="flex justify-start items-center"
style={{ height: "calc(100vh - 174px)" }}
2024-08-07 18:08:33 +08:00
onClick={() => {
2024-08-15 20:29:15 +08:00
setVisible(false), setImages([]), setCurrentIndex(null);
2024-08-14 19:59:03 +08:00
// root.unmount();
2024-08-07 18:08:33 +08:00
}}
>
2024-08-14 19:59:03 +08:00
<div
ref={ref}
id="imagesScrollBox"
2024-08-15 20:29:15 +08:00
className="flex justify-center items-center transition-transform duration-300 h-full"
2024-08-14 19:59:03 +08:00
draggable={true}
2024-08-15 20:29:15 +08:00
onTouchStart={test1}
onTouchMove={test2}
onTouchEnd={() => test3(currentIndex, direction)}
2024-08-14 19:59:03 +08:00
>
{images.map((item, index) => {
return (
2024-08-15 20:29:15 +08:00
<div
key={index}
className="flex-none w-screen relative h-full"
>
{/* <img
src={item.url}
className="h-full m-auto"
style={{
filter: item.type == "hid" ? "blur(10px)" : "none",
}}
/> */}
<Image
className="h-full m-auto"
2024-08-14 19:59:03 +08:00
src={item.url}
style={{
filter: item.type == "hid" ? "blur(10px)" : "none",
}}
2024-08-15 20:29:15 +08:00
height={"100%"}
fit="contain"
placeholder={
<div className="w-full h-full min-h-96 bg-[#1d1d1d] rounded"></div>
}
2024-08-14 19:59:03 +08:00
/>
2024-08-15 20:29:15 +08:00
2024-08-14 19:59:03 +08:00
<div className="absolute top-1/2 left-1/2 -ml-[100px] -mt-[14px]">
{item.type == "hid" && (
<div className="flex justify-center">
<div
className="rounded-full text-sm h-max w-max px-4 py-1 bg-primary"
onClick={() => {
router.push(
"/webView/" +
encodeURIComponent(
"/zone/pay/" +
data?.zid +
"/h5_zone_moment/" +
data?.id +
"?base=" +
encodeURIComponent(JSON.stringify(base))
)
);
}}
>
此内容暂未解锁立即解锁
</div>
</div>
)}
</div>
</div>
);
})}
</div>
2024-08-07 18:08:33 +08:00
</div>
<div
2024-08-14 19:59:03 +08:00
className="flex justify-between items-center w-screen absolute top-1/2 px-4 pointer-events-none"
style={{
marginTop: "calc(-50vh + 118px)",
height: "calc(100vh - 174px)",
2024-08-15 20:29:15 +08:00
visibility: images.length > 1 ? "visible" : "hidden",
2024-08-07 18:08:33 +08:00
}}
>
2024-08-14 19:59:03 +08:00
<div
className="w-12 h-full flex items-center justify-center rounded-full float-left pointer-events-auto"
onClick={() => {
2024-08-15 20:29:15 +08:00
test3(currentIndex, "right");
2024-08-14 19:59:03 +08:00
}}
>
<FontAwesomeIcon icon={faAngleLeft} size="xl" />
</div>
<div
className="w-12 h-full flex items-center justify-center rounded-full float-left pointer-events-auto"
onClick={() => {
2024-08-15 20:29:15 +08:00
test3(currentIndex, "left");
2024-08-14 19:59:03 +08:00
}}
>
<FontAwesomeIcon icon={faAngleRight} size="xl" />
</div>
2024-08-07 18:08:33 +08:00
</div>
</div>
2024-08-14 19:59:03 +08:00
</Mask>
</div>
2024-08-07 18:08:33 +08:00
);
}
);
export default forwardRef(ImagesMask);