tiefen_space_h5/components/UploadImgs/index.js

201 lines
6.1 KiB
JavaScript
Raw Normal View History

2024-10-22 17:24:02 +08:00
"use client";
import React, { useEffect, useState } from "react";
import { DotLoading, Image, Toast, ImageViewer, Modal } from "antd-mobile";
2024-07-16 20:20:12 +08:00
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
2024-10-22 17:24:02 +08:00
import { faAdd, faClose, faPlay } from "@fortawesome/free-solid-svg-icons";
export default function UploadImgs({
assets,
getImgs,
accept = "image/png, image/jpeg, image/jpg",
existImages = [],
type = 1,
videoSrc = null,
getVideoCover,
}) {
2024-07-02 23:08:38 +08:00
const maxCount = 6;
2024-07-16 20:20:12 +08:00
const [loading, setLoading] = useState(false);
2024-10-30 21:42:23 +08:00
const [filesUrls, setFilesUrls] = useState([]);
2024-10-22 17:24:02 +08:00
const [videoUrl, setVideoUrl] = useState(null);
const [frameImage, setFrameImage] = useState({ src: null, h: 0, w: 0 });
useEffect(() => {
if (existImages.length > 0) {
setFilesUrls(existImages.map((it) => it.url));
}
if (videoSrc) {
setVideoUrl(videoSrc);
}
2024-10-24 21:28:49 +08:00
}, [existImages]);
2024-10-22 17:24:02 +08:00
useEffect(() => {
getVideoCover && getVideoCover(frameImage);
}, [frameImage]);
2024-07-16 20:20:12 +08:00
const handleUploadImage = async (e) => {
let file = e.target.files[0];
if (!file) return;
2024-10-22 17:24:02 +08:00
var videoUrl = URL.createObjectURL(file);
var videoObj = document.createElement("video");
const eles = Array.from(e.target.files);
if (type == 1) {
2024-10-30 21:42:23 +08:00
const newFils = eles.map((it) => URL.createObjectURL(it));
setFilesUrls((old) => [...old, ...newFils]);
2024-10-22 17:24:02 +08:00
} else {
videoObj.onloadedmetadata = function (evt) {
URL.revokeObjectURL(videoUrl);
const target = evt.target;
setFrameImage({
src: videoUrl,
w: target.videoWidth,
h: target.videoHeight,
});
setLoading(true);
// let newFilesUrls = [...filesUrls];
2024-07-17 16:58:27 +08:00
2024-10-22 17:24:02 +08:00
if (type == 2) {
if (typeof window == "undefined") return;
// newFiles = [...assets, file];
// setFileList(newAssets);
creatVideoCanvas(file);
setVideoUrl(URL.createObjectURL(file));
}
// setFileList(newFiles);
setLoading(false);
};
2024-07-02 23:08:38 +08:00
2024-10-22 17:24:02 +08:00
videoObj.src = videoUrl;
videoObj.load();
}
getImgs([...assets, ...eles]);
2024-07-16 20:20:12 +08:00
};
const handleRemoveItem = (index) => {
2024-10-22 17:24:02 +08:00
let newArr = [...filesUrls];
let newAssets = [...assets];
2024-07-16 20:20:12 +08:00
newArr.splice(index, 1);
2024-10-22 17:24:02 +08:00
newAssets.splice(index, 1);
setFilesUrls(newArr);
getImgs(newAssets);
2024-07-16 20:20:12 +08:00
};
const showPhotos = (images, index) => {
2024-10-22 17:24:02 +08:00
const file = images[0];
const urls = type == 2 ? [frameImage.src] : images;
if (type == 1) {
ImageViewer.Multi.show({
images: urls,
defaultIndex: index,
});
} else {
Modal.show({
content: (
<video autoPlay>
<source src={videoUrl} />
</video>
),
closeOnMaskClick: true,
bodyStyle: {
background: "none",
maxHeight: "100vh",
},
});
}
};
const creatVideoCanvas = (file) => {
if (typeof window == "undefined") return;
2024-11-04 14:55:23 +08:00
const videoD = document.getElementById("video_upload");
2024-10-22 17:24:02 +08:00
const url = URL.createObjectURL(file);
videoD.src = url;
videoD.addEventListener("loadeddata", function () {
videoD.pause();
2024-11-04 14:55:23 +08:00
videoD.currentTime = 1;
});
videoD.addEventListener("seeked", function () {
2024-10-22 17:24:02 +08:00
const canvas = document.createElement("canvas");
canvas.width = videoD.videoWidth;
canvas.height = videoD.videoHeight;
canvas
.getContext("2d")
.drawImage(videoD, 0, 0, canvas.width, canvas.height);
2024-11-04 14:55:23 +08:00
const canvasImg = canvas.toDataURL("image/png");
2024-10-22 17:24:02 +08:00
setFrameImage((old) => ({ ...old, src: canvasImg }));
setFilesUrls([canvasImg]);
// 释放URL对象
URL.revokeObjectURL(url);
2024-07-16 20:20:12 +08:00
});
};
2024-07-02 23:08:38 +08:00
return (
2024-07-17 20:30:33 +08:00
<div>
<div className="grid grid-cols-4 gap-1">
2024-10-22 17:24:02 +08:00
{filesUrls.map((item, index) => {
2024-07-17 20:30:33 +08:00
return (
<div key={index} className="rounded relative">
2024-10-22 17:24:02 +08:00
<div
onClick={() => showPhotos(filesUrls, index)}
style={{ height: "calc(25vw - 0.75rem)" }}
>
<Image
src={item}
width="100%"
height="100%"
className="rounded"
fit="cover"
/>
</div>
2024-07-17 20:30:33 +08:00
<div
2024-11-05 14:54:48 +08:00
className="h-6 w-6 bg-[#33333380] absolute top-0 right-0 flex justify-center items-center rounded-bl"
2024-07-17 20:30:33 +08:00
onClick={() => handleRemoveItem(index)}
>
2024-11-04 15:48:31 +08:00
<FontAwesomeIcon icon={faClose} size="xl" />
2024-07-17 20:30:33 +08:00
</div>
2024-10-22 17:24:02 +08:00
{type == 2 && (
<div
2024-11-04 15:48:31 +08:00
className="absolute top-1/2 left-1/2 flex justify-center items-center -mt-2 -ml-1"
2024-10-22 17:24:02 +08:00
onClick={() => showPhotos(filesUrls)}
>
2024-11-04 15:48:31 +08:00
<FontAwesomeIcon icon={faPlay} size="xl" />
2024-10-22 17:24:02 +08:00
</div>
)}
2024-07-16 20:20:12 +08:00
</div>
2024-07-17 20:30:33 +08:00
);
})}
{loading && (
<div className="rounded border-[#ffffff80] text-[#ffffff80] flex flex-col justify-center items-center">
<DotLoading />
<p>上传中</p>
2024-07-16 20:20:12 +08:00
</div>
2024-07-17 20:30:33 +08:00
)}
2024-10-22 17:24:02 +08:00
{type == 2 && filesUrls.length > 0 ? null : (
<>
<label htmlFor="uploadAvatarBtn">
<div
className="border-2 border-[#ffffff80] text-[#ffffff80] rounded border-dashed w-full h-full flex justify-center items-center"
style={{ minHeight: "calc(25vw - 0.75rem)" }}
>
<div style={{ maxWidth: "24px" }}>
<FontAwesomeIcon icon={faAdd} size="2xl" />
</div>
</div>
</label>
<input
type="file"
2024-11-04 14:55:23 +08:00
multiple={type == 1}
2024-10-22 17:24:02 +08:00
id="uploadAvatarBtn"
style={{ display: "none" }}
// accept="image/png, image/jpeg, video/*"
accept={accept}
// capture="camera"
onChange={handleUploadImage}
/>
</>
)}
2024-07-17 20:30:33 +08:00
</div>
2024-07-24 13:53:12 +08:00
<div className="hidden">
2024-11-04 14:55:23 +08:00
<video id="video_upload" controls autoPlay name="media">
2024-10-22 17:24:02 +08:00
<source />
2024-07-17 16:58:27 +08:00
您的浏览器不支持 Video 标签
</video>
</div>
2024-07-16 20:20:12 +08:00
</div>
2024-07-02 23:08:38 +08:00
);
}