diff --git a/public/images/apple-music-icon.svg b/public/images/apple-music-icon.svg new file mode 100644 index 0000000..a118677 --- /dev/null +++ b/public/images/apple-music-icon.svg @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/src/pages/tools/music.tsx b/src/pages/tools/music.tsx new file mode 100644 index 0000000..cff5cb0 --- /dev/null +++ b/src/pages/tools/music.tsx @@ -0,0 +1,285 @@ +import { + Button, + Switch, + Drawer, + DrawerBody, + DrawerFooter, + DrawerHeader, + DrawerOverlay, + DrawerContent, + DrawerCloseButton, + useDisclosure, +} from '@chakra-ui/react' +import Cropper, { ReactCropperElement } from "react-cropper"; +import HighText from "../../components/HighText"; +import { useOutletContext } from "react-router-dom"; +import { ChangeEvent, RefObject, useState, useRef } from "react"; +import BaseCard from "../../components/BaseCard"; + +import "cropperjs/dist/cropper.css"; + +export default function Rseg() { + const cropperRef1 = useRef(null) + const cropperRef2 = useRef(null) + const { isOpen: isOpen1, onOpen: onOpen1, onClose: onClose1 } = useDisclosure() + const { isOpen: isOpen2, onOpen: onOpen2, onClose: onClose2 } = useDisclosure() + + const [highLight, ref]:[highLight: boolean, ref: RefObject] = useOutletContext(); + + const [image1, setImage1] = useState(''); + const [image2, setImage2] = useState(''); + const [image1Size, setImage1Size] = useState(0); + const [image2Size, setImage2Size] = useState(0); + const [image1Crop, setImage1Crop] = useState(''); + const [image2Crop, setImage2Crop] = useState(''); + const [bleedingLine, setBleedingLine] = useState(false); + const [isSmall, setIsSmall] = useState(false); + const [tw, setTw] = useState(false); + + const handleImage1Change = (e: ChangeEvent) => { + const file = e.target.files && e.target.files[0]; + setImage1Size(file?.size||0) + if (file) { + const reader = new FileReader(); + + reader.onloadend = () => { + setImage1(reader.result as string); + }; + + reader.readAsDataURL(file); + } + onOpen1() + } + const handleImage2Change = (e: ChangeEvent) => { + const file = e.target.files && e.target.files[0]; + setImage2Size(file?.size||0) + if (file) { + const reader = new FileReader(); + + reader.onloadend = () => { + setImage2(reader.result as string); + }; + + reader.readAsDataURL(file); + } + onOpen2() + } + + const getCropData1 = () => { + if (typeof cropperRef1.current?.cropper !== "undefined") { + setImage1Crop(cropperRef1.current?.cropper.getCroppedCanvas().toDataURL()); + } + } + const getCropData2 = () => { + if (typeof cropperRef2.current?.cropper !== "undefined") { + setImage2Crop(cropperRef2.current?.cropper.getCroppedCanvas().toDataURL()); + } + } + + function formatBytes(bytes: number, decimals = 2) { + if (bytes === 0) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i]; + } + + return ( +
+ + + + + 裁剪图片 + + + + + + + {/* */} + + + + + + + + + 裁剪图片 + + + + + + + {/* */} + + + + +
+ + +
+
+ {image1Size+image2Size>=5120000? +
文件较大({formatBytes(image1Size+image2Size)}) 导出可能需要 1-3分钟
:'' + } +
+
+ + + + + + + + + + + +
3mm 出血线(印刷需打开) + {setBleedingLine(v.target.checked)}} /> +
修复模式(图像缺失需打开) + {setIsSmall(v.target.checked)}} /> +
+ +
+
85*54mm(大陆)
+ {setTw(v.target.checked)}} /> +
90*54mm(中国台湾)
+
+
+ +
+
+ + + + + + + + + + + + + + + + +
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+ {image1Crop? +
: +
+ 请上传图片 +
+ } + {image2Crop? +
: +
+ 请上传图片 +
+ } +
+
+
+
+ +
+
+
+ +
+
+
+
+
+ ) +} diff --git a/src/utils/router.ts b/src/utils/router.ts index c43d8a0..34e0912 100644 --- a/src/utils/router.ts +++ b/src/utils/router.ts @@ -11,6 +11,13 @@ const hot = ['#FEE2E2','#DC2626'] const list = { done: [ + { + name: ['Apple Music', '播放器 透卡/小卡'], + logo: '/images/apple-music-icon.svg', + url: '/tools/music', + tag: '还没做好', + tag_color: ['#dcfce7','#16a34a'] + }, { name: ['星巴克', '咖啡标签'], logo: '/images/starbucks.png',