tiefen_space_h5/components/ImagesMask/index.jsx

276 lines
9.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, {
useState,
useEffect,
useRef,
forwardRef,
useImperativeHandle,
} from "react";
import { Mask, Image } from "antd-mobile";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faAngleLeft,
faAngleRight,
faDownload,
} from "@fortawesome/free-solid-svg-icons";
import { createRoot } from "react-dom/client";
import { useRouter } from "next/navigation";
import baseRequest from "@/utils/baseRequest";
const root = createRoot(document?.getElementById("maskDomBox"));
function ImagesMask({}, ref) {
const [visible, setVisible] = useState(false);
const [images, setImages] = useState([]);
const [data, setData] = useState(null);
const scrollRef = useRef(null);
const defaultIndex = useRef(null);
const router = useRouter();
useEffect(() => {
root.render(
<div>
<ImagesMaskContaint
images={images}
visible={visible}
ref={scrollRef}
setVisible={setVisible}
setImages={setImages}
router={router}
data={data}
defaultIndex={defaultIndex.current}
/>
</div>
);
// root.render(<div>xxxx</div>);
}, [visible]);
useImperativeHandle(ref, () => ({
show: (arr, index, data) => {
defaultIndex.current = index;
setImages(arr);
setData(data);
setVisible((old) => {
// console.log(arr, index, old);
return !old;
});
// Mask.show
// const maskDomBox = document.getElementById("maskDomBox");
},
close: () => setVisible(false),
}));
return <></>;
}
const ImagesMaskContaint = forwardRef(
(
{ 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();
const directionX = useRef(0);
// const getDistance = (e) => {
// e.stopPropagation();
// const distance = ref.current.scrollLeft;
// setDistance(distance);
// };
useEffect(() => {
// setCurrentIndex(defaultIndex);
// test3(defaultIndex - 1, "left");
if (defaultIndex) {
test3(defaultIndex - 1, "left");
}
}, [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);
}
};
const test2 = (e) => {
if (active) {
let X = e.touches[0].clientX - initialX;
setDirection(
directionX.current > e.touches[0].clientX ? "left" : "right"
);
ref.current.style.transform = "translateX(" + X + "px)";
directionX.current = e.touches[0].clientX;
}
};
const test3 = (index, currentDirection) => {
setActive(false);
let cxOffset = window.innerWidth;
if (currentDirection == "left") {
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)`;
}
}
// setInitialX(currentX);
setInitialX(-cxOffset * (index + (currentDirection == "left" ? 1 : -1)));
if (currentDirection == "left" && index > images.length - 2) return;
setXOffset(-cxOffset * (index + (currentDirection == "left" ? 1 : -1)));
};
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();
});
}
return (
<div>
<Mask
visible={visible}
className="z-[1002] h-screen flex justify-center items-center"
onMaskClick={() => {
setVisible(false), setImages([]), setCurrentIndex(null);
// root.unmount();
}}
color="#000000d9"
>
<div className="relative">
{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>
)}
<div className="text-center mb-2 leading-[54px]">
{currentIndex + 1}/{images.length}
</div>
<div
className="flex justify-start items-center"
style={{ height: "calc(100vh - 174px)" }}
onClick={() => {
setVisible(false), setImages([]), setCurrentIndex(null);
// root.unmount();
}}
>
<div
ref={ref}
id="imagesScrollBox"
className="flex justify-center items-center transition-transform duration-300 h-full"
draggable={true}
onTouchStart={test1}
onTouchMove={test2}
onTouchEnd={() => test3(currentIndex, direction)}
>
{images.map((item, index) => {
return (
<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"
src={item.url}
style={{
filter: item.type == "hid" ? "blur(10px)" : "none",
}}
height={"100%"}
fit="contain"
placeholder={
<div className="w-full h-full min-h-96 bg-[#1d1d1d] rounded"></div>
}
/>
<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>
</div>
<div
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)",
visibility: images.length > 1 ? "visible" : "hidden",
}}
>
<div
className="w-12 h-full flex items-center justify-center rounded-full float-left pointer-events-auto"
onClick={() => {
test3(currentIndex, "right");
}}
>
<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={() => {
test3(currentIndex, "left");
}}
>
<FontAwesomeIcon icon={faAngleRight} size="xl" />
</div>
</div>
</div>
</Mask>
</div>
);
}
);
export default forwardRef(ImagesMask);