류림스 공간

[항해99 58일차] 2022.05.02 TIL (모달창 띄우기) 본문

TIL/2022 TIL

[항해99 58일차] 2022.05.02 TIL (모달창 띄우기)

ryurim 2022. 5. 3. 01:45
반응형

 

흐ㄱ...소스 코드를 뒤지고, 구글에 검색하며 리액트로 모달창을 구현해보았다 !!!!!!!!

이미지 수정 버튼 있는 JS

 

import React,{useState} from 'react';
import {Button,Grid,Image,Text} from '../../elements/index';
import {ProfileModal} from './index';
import styled from 'styled-components';

const MyProfile = () => {

    const [isOpen,setIsOpen] =useState(false);
    const openModalHandler=()=>{
        setIsOpen(!isOpen);
    };
    return (
        <React.Fragment>
            <Grid>
                <Grid width="100%" margin="40px 0" height="180px" 
                position="relative" display="flex" flexDirection="column" alignItems="start" justifyContent="center"
                >
                    <Grid width="100%" display="flex" justifyContent="center"  position="relative">
                        <Image type="circle" size="112"/>
                        <Button is_edit position="absolute" top="80px" right="35%" _onClick={openModalHandler}/>
                    </Grid>
                    <Grid width="100%" display="flex" padding="12px 0" justifyContent="center">
                        <Text  size="1.250rem" cursor="pointer">오싹이님</Text>
                    </Grid>
                    <Grid width="100%" display="flex" justifyContent="center">
                        <Text  size="0.85rem" cursor="pointer">alskldskf123@naver.com</Text>
                    </Grid>
                </Grid>
                    {isOpen ? 
                    (<>
                    <ModalBackdrop onClick={openModalHandler}>
                        
                        
                    </ModalBackdrop>
                    <ProfileModal isOpen={isOpen} setIsOpen={setIsOpen}/>
                    </>
                    )
                    : null}
            </Grid>
           
           
            
        </React.Fragment>
    );
};
const ModalBackdrop = styled.div`
  width: 100%;
  height: 100%;
  position: absolute;
  top:0;
  left:0;
  display: flex;
  z-index:2;
  justify-content: center;
  align-items: center;
  background: rgba(0, 0, 0, 0.7);
`;

export default MyProfile;

 

isOpen 이 트루값 일때만, 모달창을 보여주게 하고, 
모달창 컴포넌트에 isOpen 그리고 setIsOpen을 주입했다 !!

 

모달창 js

 

import React,{useState,useRef} from 'react';
import styled from 'styled-components';
import {Button,Grid,Image} from '../../elements/index';
import defaultImg from '../../static/images/default.svg'
//heic 이미지 파일을 jpeg로 변환하는 라이브러리
import heic2any from "heic2any";
// 이미지 압축 라이브러리
import imageCompression from "browser-image-compression";

const ProfileModal = (props) => {

    const {isOpen,setIsOpen}=props;
    const ModalClose=()=>{
        setIsOpen(!isOpen)
    }

    const fileInput = useRef();

    const [image, setImage] = useState(null);
    const [preview, setPreview] = useState(null);
    const [isWarning, setIsWarning] = useState(false);

    const selectFile = async (e) => {
        const reader = new FileReader();
        let file;
        // 이미지 resize 옵션 설정 (최대 width을 400px로 지정)
        const options = {
          maxSizeMB: 2,
          maxWidthOrHeight: 200,
        };
        if (
          fileInput.current.files[0].name.split(".")[1] === "gif" ||
          fileInput.current.files[0].name.split(".")[1] === "GIF" ||
          fileInput.current.files[0].name.split(".")[1] === "heic" ||
          fileInput.current.files[0].name.split(".")[1] === "HEIC"
        ) {
          file = fileInput.current.files[0];
        } else {
          file = await imageCompression(fileInput.current.files[0], options);
        }
        const maxSize = 20 * 1024 * 1024; // 파일 용량 제한 (20MB)
        if (file.size > maxSize) {
          setIsWarning(true);
        } else {
          setIsWarning(false);
          if (file.name.split(".")[1] === "heic" || file.name.split(".")[1] === "HEIC") {
            let blob = fileInput.current.files[0];
            // blob에다가 변환 시키고 싶은 file값을 value로 놓는다.
            // toType에다가는 heic를 변환시키고싶은 이미지 타입을 넣는다.
            heic2any({ blob: blob, toType: "image/jpeg" })
              .then(function (resultBlob) {
                //file에 새로운 파일 데이터를 씌웁니다.
                file = new File([resultBlob], file.name.split(".")[0] + ".jpg", {
                  type: "image/jpeg",
                  lastModified: new Date().getTime(),
                });
                reader.readAsDataURL(file);
                reader.onloadend = () => {
                  setPreview(reader.result);
                };
                if (file) {
                  setImage(file);
                }
              })
              .catch(function (err) {
                console.log("이미지 변환 오류", err);
              });
          }
          reader.readAsDataURL(file); //파일 내용 읽어오기
          // onloadend: 읽기가 끝나면 발생하는 이벤트 핸들러
          reader.onloadend = () => {
            // reader.result는 파일의 컨텐츠(내용물)입니다!
            setPreview(reader.result);
          };
          if (file) {
            setImage(file);
          }
        }
      };
    return (
        <React.Fragment>
            {isOpen ?
            (<Outter>
                <Grid width="100%" height="500px" margin="16px" bg="#fff" position="relative">
                <Button is_close position="absolute" right="8px" top="8px" _onClick={ModalClose}/>
               <Grid display="flex" flexDirection="column" alignItems="center" >
                    
                        <Grid width="200px" height="200px" margin="50px 0">
                        <Image
                            className="edit"
                            shape="rectangle"
                            size="90"
                            radius="30px"
                            src={preview ? preview : 
                                // userInfo.profileUrl ? userInfo.profileUrl :
                                 defaultImg}
                        ></Image>
                                                    
                        </Grid>
                
                    
                    <Grid width="200px" height="200px" display="flex" flexDirection="column" alignItems="start" >
                        
                        <Label htmlFor="file_input" className="upload-box">
                          <Grid>사진업로드</Grid>
                        </Label>
                        <Button width="200px" height="24px" 
                        padding="none" margin="10px 0"
                         fontSize="1.25rem" backgroundColor="none">사진제거</Button>
                        <Button width="200px" margin="none" padding="none" height="24px" fontSize="1.25rem" backgroundColor="none">저장하기</Button>
                    </Grid>
                    <input type="file" id="file_input" ref={fileInput} onChange={selectFile} style={{display:"none"}} />
                </Grid>
            </Grid>
            </Outter>
            ) 
            :null

            }
        </React.Fragment>
    );
};
const Outter=styled.div`

  width:90%;
  position: absolute;
  top:50%;
  left:0;
  transform: translate(0, -50%) ;
  z-index:4;

`
const Label=styled.label`
 width:200px;
 text-align:center;
 font-size:1.250rem;
 font-weight:bold;

`;
export default ProfileModal;

조금 길지만 @@@

이렇게 모달창을 완성시켰다..!@@@@!!!

 

728x90
반응형
Comments