Skip to content

Commit

Permalink
Merge pull request #89 from space-401/feat/imageEdit
Browse files Browse the repository at this point in the history
[FE] createย ํŽ˜์ด์ง€ ๋ฐ˜์‘ํ˜• ์ž‘์—…
  • Loading branch information
ooherin authored Sep 28, 2023
2 parents b5320de + 2c1120b commit f546380
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 78 deletions.
7 changes: 4 additions & 3 deletions client/src/components/Create/ImageEditModal/Cropper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,19 @@ type PropsType = {
image: string;
index: number;
myRef: any;
width: number;
};

const ImageCropper = ({ image, myRef }: PropsType) => {
const ImageCropper = ({ image, myRef, width }: PropsType) => {
return (
<div style={{ position: 'relative' }}>
<Cropper
ref={myRef}
aspectRatio={1}
src={image}
viewMode={1}
width={740}
height={740}
width={width}
height={width}
background={false}
responsive
autoCropArea={1}
Expand Down
39 changes: 23 additions & 16 deletions client/src/components/Create/ImageEditModal/ImageEditModal.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import S from '@components/Create/ImageEditModal/style';
import ImageCropper from '@components/Create/ImageEditModal/Cropper';
import { useEffect, useRef } from 'react';
import { useRef } from 'react';
import { usePhotoModalStore } from '@/store/modal';
import { ReactCropperElement } from 'react-cropper';
import { dataURLtoFile } from '@/utils/fileConvertor';
import { Box, Modal } from '@mui/material';
import { ImageArrType } from '@/types/image.type';

type ModalType = {
imageArr: ImageArrType;
setImageArr: React.Dispatch<React.SetStateAction<ImageArrType>>;
};

const ImgEditModal = ({ imageArr, setImageArr }: ModalType) => {
const cropperRef1 = useRef<ReactCropperElement>(null);

const myRefs = [cropperRef1];
const sliderRef = useRef<any>();
const { ModalClose, isOpen } = usePhotoModalStore();
Expand All @@ -24,25 +24,26 @@ const ImgEditModal = ({ imageArr, setImageArr }: ModalType) => {
const newImage = cropperRef.current?.cropper
.getCroppedCanvas()
.toDataURL();

console.log(imageArr);
setImageArr((prev) => ({ ...prev, cropImages: [newImage] }));
const filename = `SpaceImg`;
const convertedImg = dataURLtoFile(newImage, filename);

convertedImg &&
setImageArr((prev) => ({ ...prev, convertedImages: [convertedImg] }));
console.log(imageArr);
ModalClose();
}
};

//ํฌ๋กญํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋ชจ๋‘ ์ €์žฅํ•จ.
const onSaveAllEditImg = (e: any) => {
e.preventDefault();

//๊ธฐ์กด์— ํฌ๋กญํ•œ ์ด๋ฏธ์ง€๊ฐ€ ์กด์žฌํ•˜๋ฉด ์—†์• ์คŒ
if (imageArr.cropImages.length > 0) {
setImageArr((prev) => ({ ...prev, cropImages: [] }));
setImageArr((prev) => ({ ...prev, cropImages: [], convertedImages: [] }));
}
getCropData(cropperRef1);
//๊ธฐ์กด์— ํฌ๋กญํ•œ ์ด๋ฏธ์ง€๊ฐ€ ์กด์žฌํ•˜๋ฉด ์—†์• ์คŒ
};

//๋ชจ๋‹ฌ ์ทจ์†Œ
Expand All @@ -51,9 +52,14 @@ const ImgEditModal = ({ imageArr, setImageArr }: ModalType) => {
setImageArr((prev) => ({ ...prev, images: [] }));
};

useEffect(() => {
console.log(imageArr.images);
}, [imageArr]);
//ํ˜„์žฌ ํ™”๋ฉด ํฌ๊ธฐ
const screenWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;

const cropperWidth = Math.floor(screenWidth / 2) + 20;

return (
<Modal
open={isOpen}
Expand All @@ -66,7 +72,7 @@ const ImgEditModal = ({ imageArr, setImageArr }: ModalType) => {
}}
>
<Box tabIndex={-1}>
<S.Form>
<S.Form width={cropperWidth}>
<S.Header>
<button onClick={onClickCancelModal}>์ทจ์†Œ</button>
<button
Expand All @@ -86,21 +92,22 @@ const ImgEditModal = ({ imageArr, setImageArr }: ModalType) => {
<div
style={{
position: 'relative',
height: '760px',
width: '760px',
height: cropperWidth,
width: cropperWidth,
overflow: 'hidden',
}}
>
<div
style={{ display: 'flex', position: 'absolute', left: 10 }}
style={{ display: 'flex', position: 'absolute', left: 0 }}
ref={sliderRef}
>
{imageArr.images.length && (
<ImageCropper
key={1}
width={cropperWidth}
key={0}
image={imageArr.images[0].img}
index={1}
myRef={myRefs[1]}
index={0}
myRef={myRefs[0]}
/>
)}
</div>
Expand Down
60 changes: 44 additions & 16 deletions client/src/components/Create/ImageEditModal/ImagesEditModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ const ImagesEditModal = ({
const [currentX, setCurrentX] = useState<number>(0);
const imageNum = imageArr.images.length;

//ํ˜„์žฌ ํ™”๋ฉด ํฌ๊ธฐ
const screenWidth =
window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;

const cropperWidth = Math.floor(screenWidth / 2) + 20;

//ํ•˜๋‚˜์˜ ์ด๋ฏธ์ง€๋ฅผ ํฌ๋กญํ•ด์„œ ์ €์žฅํ•จ.
const getCropData = (cropperRef: any, index: number) => {
if (typeof cropperRef.current?.cropper !== 'undefined') {
Expand All @@ -71,7 +79,6 @@ const ImagesEditModal = ({
const filename = `${index}postImg`;
const convertedImg = dataURLtoFile(newImage, filename);
convertedImg &&
// setConvertedImages((prev: File[]) => [...prev, convertedImg]);
setImageArr((prev) => ({
...prev,
convertedImages: [...prev.convertedImages, convertedImg],
Expand All @@ -83,8 +90,12 @@ const ImagesEditModal = ({
e.preventDefault();

//๊ธฐ์กด์— ํฌ๋กญํ•œ ์ด๋ฏธ์ง€๊ฐ€ ์กด์žฌํ•˜๋ฉด ์—†์• ์คŒ
if (imageArr.cropImages.length > 0) {
setImageArr((prev: ImageArrType) => ({ ...prev, cropImages: [] }));
if (imageArr.convertedImages.length > 0) {
setImageArr((prev: ImageArrType) => ({
...prev,
cropImages: [],
convertedImages: [],
}));
}
myRefs.map((ref, index) => {
getCropData(ref, index);
Expand All @@ -95,22 +106,22 @@ const ImagesEditModal = ({
//์™ผ์ชฝ ์ด๋ฏธ์ง€ ๋ณด๊ธฐ
const onClickMoveLeft = () => {
if (currentIdx > 0) {
const newPosition = currentX + 760;
const newPosition = currentX + cropperWidth;
setCurrentX(newPosition);
sliderRef.current.style.transform = `translateX(${newPosition}px)`;
setCurrentIdx((currentIdx) => currentIdx - 1);
} else {
const newPosition = -760 * (imageNum - 1);
setCurrentX(newPosition);
sliderRef.current.style.transform = `translateX(${newPosition}px)`;
const newPosition = cropperWidth * (imageNum - 1);
setCurrentX(-newPosition);
sliderRef.current.style.transform = `translateX(-${newPosition}px)`;
setCurrentIdx(imageArr.images.length - 1);
}
};

//์˜ค๋ฅธ์ชฝ ์ด๋ฏธ์ง€ ๋ณด๊ธฐ
const onClickMoveRight = () => {
if (currentIdx < imageNum - 1) {
const newPosition = currentX - 760;
const newPosition = currentX - cropperWidth;
setCurrentX(newPosition);
sliderRef.current.style.transform = `translateX(${newPosition}px)`;
setCurrentIdx((currentIdx) => currentIdx + 1);
Expand All @@ -125,14 +136,16 @@ const ImagesEditModal = ({
//์ทจ์†Œ
const onClickCancelModal = () => {
ModalClose();
setImageArr((prev: ImageArrType) => ({ ...prev, images: [] }));
// setImageArr((prev: ImageArrType) => ({ ...prev, images: [] }));
};

//์„ ํƒํ•œ ์ด๋ฏธ์ง€๋ฅผ ๋ณด๊ธฐ
const onClickCurrentImg = (idx: number) => {
setCurrentIdx(idx);
const newPosition = idx * 760;
sliderRef.current.style.transform = `translateX(-${newPosition}px)`;
const newPosition = -(idx * cropperWidth);
sliderRef.current.style.transform = `translateX(${newPosition}px)`;
setCurrentX(newPosition);
console.log('ํ˜„์žฌx์ถ•', newPosition);
};

return (
Expand All @@ -159,13 +172,14 @@ const ImagesEditModal = ({
onClickCurrentImg={onClickCurrentImg}
/>
)}
<S.Form>
<S.Form width={cropperWidth}>
<PrevBtn
style={{
position: 'absolute',
top: '50%',
left: '30px',
zIndex: 10000,
cursor: 'pointer',
}}
onClick={onClickMoveLeft}
/>
Expand All @@ -175,6 +189,7 @@ const ImagesEditModal = ({
top: '50%',
right: '30px',
zIndex: 1000,
cursor: 'pointer',
}}
onClick={onClickMoveRight}
/>
Expand All @@ -197,20 +212,33 @@ const ImagesEditModal = ({
<div
style={{
position: 'relative',
height: '760px',
width: '760px',
height: cropperWidth,
width: cropperWidth,
overflow: 'hidden',
padding: 10,
}}
>
<div
style={{ display: 'flex', position: 'absolute', left: 0 }}
style={{
display: 'flex',
position: 'absolute',
gap: 20,
}}
ref={sliderRef}
>
{imageArr.images.map(
(image: { id: number; img: string }, index: number) => {
return (
<div style={{ margin: '10px' }}>
<div
style={{
height: cropperWidth - 20,
width: cropperWidth - 20,
display: 'flex',
alignItems: 'center',
}}
>
<ImageCropper
width={cropperWidth - 20}
key={index}
image={image.img}
index={index}
Expand Down
12 changes: 2 additions & 10 deletions client/src/components/Create/ImageEditModal/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,21 @@ const Wrapper = styled.div`
z-index: ${({ theme }) => theme.Z_INDEX['LEVEL-4']};
`;

const Form = styled.form`
const Form = styled.form<{ width: number }>`
${flexCenter}
flex-direction: column;
${flexCenter}
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 760px;
width: ${({ width }) => width};
border-radius: 8px;
background: ${({ theme }) => theme.COLOR['gray-6']};
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.25);
border-radius: 15px;
`;

const CropperWrapper = styled.div`
width: 760px;
height: 760px;
background-color: black;
position: relative;
`;

const Header = styled.div`
height: 4rem;
width: 100%;
Expand Down Expand Up @@ -114,7 +107,6 @@ const S = {
Header,
Footer,
SizeController,
CropperWrapper,
MultiViewWrapper,
SmallPhotoBox,
PhotoContainer,
Expand Down
11 changes: 8 additions & 3 deletions client/src/components/Create/ImgSlider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ const ImgSlider = ({ images, onClickImgEditModal }: SliderProps) => {
<div style={{ width: '348px', height: '348px', position: 'relative' }}>
<LeftIcon
className="prevBtn"
style={{ position: 'absolute', top: '50%', zIndex: 100, left: '10px' }}
style={{
position: 'absolute',
top: '50%',
zIndex: 100,
left: '10px',
cursor: 'pointer',
}}
/>
<RightIcon
className="nextBtn"
Expand All @@ -26,6 +32,7 @@ const ImgSlider = ({ images, onClickImgEditModal }: SliderProps) => {
top: '50%',
zIndex: 100,
right: '10px',
cursor: 'pointer',
}}
/>
<Swiper
Expand All @@ -36,8 +43,6 @@ const ImgSlider = ({ images, onClickImgEditModal }: SliderProps) => {
prevEl: '.prevBtn',
}}
pagination={{ clickable: true }}
// onSwiper={(swiper) => console.log(swiper)}
// onSlideChange={() => console.log('slide change')}
loop={true}
>
{images.map((img) => {
Expand Down
20 changes: 14 additions & 6 deletions client/src/components/common/Calender/Calender.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,18 @@ import { ReactComponent as UpIcon } from '@/assets/svg/chevron/chevron_up.svg';

//๋ฉ”์ธ์ผ ๋•Œ๋Š” ๊ฒ€์ƒ‰๊ธฐ๋Šฅ
type CalenderPropsType = {
width: number;
isMain: boolean;
height: number;
borderRadius: number;
setPostData?: React.Dispatch<React.SetStateAction<PostType>>;
isMain: boolean;
};

const Calender = ({ isMain, setPostData }: CalenderPropsType) => {
const Calender = ({
setPostData,
height,
borderRadius,
isMain,
}: CalenderPropsType) => {
const [startDate, setStartDate] = useState(null);
const [endDate, setEndDate] = useState(null);
const [isDropdownOpen, setIsDropdownOpen] = useState([false, false]);
Expand Down Expand Up @@ -72,6 +78,9 @@ const Calender = ({ isMain, setPostData }: CalenderPropsType) => {
<div className="custom-react-datepicker__wrapper">
<label>
<MStyledDatePicker
isMain={isMain}
borderRadius={borderRadius}
height={height}
dateFormat="yyyy.MM.dd"
showYearDropdown
scrollableYearDropdown
Expand Down Expand Up @@ -219,12 +228,11 @@ const Calender = ({ isMain, setPostData }: CalenderPropsType) => {
export default Calender;

const MStyledDatePicker = styled(DatePicker)`
height: ${({ isMain }) =>
isMain ? '50px' : '60px'}; /* ์กฐ๊ฑด์— ๋”ฐ๋ผ height ์„ค์ • */
height: ${({ height }) => height}px; /* ์กฐ๊ฑด์— ๋”ฐ๋ผ height ์„ค์ • */
background-color: ${({ theme }) => theme.COLOR['gray-5']};
color: ${({ theme }) => theme.COLOR.white};
font-size: ${({ theme }) => theme.TEXT_SIZE['text-18']};
border-radius: ${({ isMain }) => (isMain ? '5px' : '10px')};
border-radius: ${({ borderRadius }) => borderRadius}px;
width: 322px !important;
display: flex;
padding-left: 2.6rem;
Expand Down
Loading

0 comments on commit f546380

Please sign in to comment.