본문 바로가기
수업내용

20230713 Cube2/Poligon

by titlejjk 2023. 7. 13.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step04_Cube2.html</title>
    <style>
        .wrapper{
            perspective: 500px;
            perspective-origin: 50% 50%;
        }
        .cube{
            width: 400px;
            height: 400px;
            margin: 0 auto;
            transform-style: preserve-3d;
            transform-origin: 50% 50%;
            transform: translateZ(-200px);
            transition: transform 1s ease-out;
        }
        .cube > div{
            border: 1px solid red;
            position: absolute;
            top: 0;
            left: 0;
            width: 400px;
            height: 400px;
            background-color: antiquewhite;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 100px;
            font-weight: bold;
            opacity: 0.5;
        } 
        .cube > div:nth-child(1){
            transform: translateZ(200px);
        }
        .cube > div:nth-child(2){
            transform: rotateY(90deg) translateZ(200px);
        }
        .cube > div:nth-child(3){
            transform: rotateY(180deg) translateZ(200px);
        }
        .cube > div:nth-child(4){
            transform: rotateY(270deg) translateZ(200px);
        }
        .cube > div:nth-child(5){
            transform: rotateX(90deg) translateZ(200px);
        }
        .cube > div:nth-child(6){
            transform: rotateX(270deg) translateZ(200px);
        }
        .nav{
            display: flex;
            justify-content: center;
            margin: 50px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h3>3d cube 테스트</h3>
        <div class="wrapper">
            <div class="cube">
                <div>1</div>
                <div>2</div>
                <div>3</div>
                <div>4</div>
                <div>5</div>
                <div>6</div>    
            </div>
        </div>
        <div class="nav">
            <button id="leftBtn">&larr;</button>
            <button id="rightBtn">&rarr;</button>
        </div>
    </div>    
    <script>
        const rotateYt=0;
        document.querySelector("#leftBtn").addEventListener("click", (e)=>{
            document.querySelector(".cube").style.transform="translateZ(-200px) rotateY(-90deg)";

        });
        document.querySelector("#rightBtn").addEventListener("click", (e)=>{
            document.querySelector(".cube").style.transform="translateZ(-200px) rotateY(+90deg)";

        });
    </script>
</body>
</html>

 

위 코드에 문제점은 화살표를 눌렀을 때 딱 한번만 실행이 되고

반대쪽 화살표 버튼을 눌렀을 경우에 180도 돌아가는 문제점이 있다.

그 이유는

document.querySelector("#leftBtn").addEventListener("click", (e)=>{
            document.querySelector(".cube").style.transform="translateZ(-200px) rotateY(rotateYt-90deg)";

        });

이 코드 부분에서 rotateY의 설정된 값들이 절대 값이라서 + - 로 이동되는 것이 아니라 좌표값으로 지정되어 있기 때문에 좌표로 이동되는 개념이다.

 

이를 해결하기 위해 y축을 기준으로 회전하는 값을 저장할 변수를 선언하고 초기값0을 대입하여 작성해준다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step04_Cube2.html</title>
    <style>
        .wrapper{
            perspective: 500px;
            perspective-origin: 50% 50%;
        }
        .cube{
            width: 400px;
            height: 400px;
            margin: 0 auto;
            transform-style: preserve-3d;
            transform-origin: 50% 50%;
            transform: translateZ(-200px);
            transition: transform 1s ease-out;
        }
        .cube > div{
            border: 1px solid red;
            position: absolute;
            top: 0;
            left: 0;
            width: 400px;
            height: 400px;
            background-color: antiquewhite;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 100px;
            font-weight: bold;
            opacity: 0.5;
        } 
        .cube > div:nth-child(1){
            transform: translateZ(200px);
        }
        .cube > div:nth-child(2){
            transform: rotateY(90deg) translateZ(200px);
        }
        .cube > div:nth-child(3){
            transform: rotateY(180deg) translateZ(200px);
        }
        .cube > div:nth-child(4){
            transform: rotateY(270deg) translateZ(200px);
        }
        .cube > div:nth-child(5){
            transform: rotateX(90deg) translateZ(200px);
        }
        .cube > div:nth-child(6){
            transform: rotateX(270deg) translateZ(200px);
        }
        .nav{
            display: flex;
            justify-content: center;
            margin: 50px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h3>3d cube 테스트</h3>
        <div class="wrapper">
            <div class="cube">
                <div>1</div>
                <div>2</div>
                <div>3</div>
                <div>4</div>
                <div>5</div>
                <div>6</div>    
            </div>
        </div>
        <div class="nav">
            <button id="leftBtn">&larr;</button>
            <button id="rightBtn">&rarr;</button>
        </div>
    </div>    
    <script>

        //y축 기준으로 회전하는 값을 저장할 변수를 선언하고 초기값 0 대입
        let rY=0;
        
        document.querySelector("#leftBtn").addEventListener("click", (e)=>{
            rY -= 90;
            document.querySelector(".cube").style.transform="translateZ(-200px) rotateY("+rY+"deg)";

        });
        document.querySelector("#rightBtn").addEventListener("click", (e)=>{
            rY += 90;
            document.querySelector(".cube").style.transform=`translateZ(-200px) rotateY(${rY}deg)`;

        });
    </script>
</body>
</html>

 

위 코드에는 문제점이 있다. 만약 육각형에서 면이 더 늘어나게 된다면? 또 style에서 추가를 해주어야 할 것이다.

이를 javascript영역에서 반복문으로 해결해 보겠다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step04_Cube3.html</title>
    <style>
        .wrapper{
            perspective: 500px;
            perspective-origin: 50% 50%;
        }
        .cube{
            width: 400px;
            height: 400px;
            margin: 0 auto;
            transform-style: preserve-3d;
            transform-origin: 50% 50%;
            transform: translateZ(-200px);
            transition: transform 1s ease-out;
        }
        .cube > div{
            border: 1px solid red;
            position: absolute;
            top: 0;
            left: 0;
            width: 400px;
            height: 400px;
            background-color: antiquewhite;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 100px;
            font-weight: bold;
            opacity: 0.5;
        } 
        .nav{
            display: flex;
            justify-content: center;
            margin: 50px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h3>3d cube 테스트</h3>
        <div class="wrapper">
            <div class="cube">
            
            
            </div>
        </div>
        <div class="nav">
            <button id="leftBtn">&larr;</button>
            <button id="rightBtn">&rarr;</button>
        </div>
    </div>    
    <script>
        //div가 4개니까 반복문 4번 돌기
        for(let i = 0; i < 4; i++){
            //div를 만들어서
            const div=document.createElement("div");
            //innerText를 출력하고
            div.innerText=i+1;
            //.cube에 추가하기
            document.querySelector(".cube").append(div);
        }
        let div = document.createElement("div");
        //.cube안에 있는 모든 div의 참조값을 배열로 얻어내고
        const divs=document.querySelectorAll(".cube div");
        
        for(let i=0; i<divs.length; i++){
            var rotate=i*90;
            divs[i].style.transform="rotateY("+rotate+"deg) translateZ(200px)";
        }
        

        //y축 기준으로 회전하는 값을 저장할 변수를 선언하고 초기값 0 대입
        let rY=0;
        
        document.querySelector("#leftBtn").addEventListener("click", (e)=>{
            rY -= 90;
            document.querySelector(".cube").style.transform="translateZ(-200px) rotateY("+rY+"deg)";

        });
        document.querySelector("#rightBtn").addEventListener("click", (e)=>{
            rY += 90;
            document.querySelector(".cube").style.transform=`translateZ(-200px) rotateY(${rY}deg)`;

        });


    </script>
</body>
</html>

 

Poligon

 

다각 형의 회전값과 평행이동이 되어야 할 값을 구하는 방정식을 알아야하는데, 오래간만에 고등학교 때 배웠던 탄젠트에 대해서 찾아봐야했다..

 

아래 함수를 만들어주고 

n과 width에 들어갈 변수를 만들어주어서 사용해주면된다.

       //n 각형의 폭을 함수에 전달하면 div 를 배치할때 rotateY 값과 translateZ 가 Object 로 리턴되는 함수 
        function getAngleNtz(n, width) {
            var angle = Math.round(360 / n);
            var tz = Math.round((width / 2) / Math.tan((angle * Math.PI) / (2 * 180)));
            var obj = {
                angle: angle,
                tz: tz
            };
            return obj;
        }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Step04_Poligon.html</title>
    <style>
        .wrapper{
            perspective: 500px;
            perspective-origin: 50% 50%;
        }
        .poligon{
            width: 400px;
            height: 400px;
            margin: 0 auto;
            transform-style: preserve-3d;
            transform-origin: 50% 50%;
            transition: transform 1s ease-out;
        }
        .poligon > div{
            border: 1px solid red;
            position: absolute;
            top: 0;
            left: 0;
            width: 400px;
            height: 400px;
            background-color: antiquewhite;
            display: flex;
            justify-content: center;
            align-items: center;
            font-size: 100px;
            font-weight: bold;
            opacity: 0.5;
        } 
        .nav{
            display: flex;
            justify-content: center;
            margin: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h3>3d poligon 테스트</h3>
        <div class="wrapper">
            <div class="poligon">
                 
            </div>
        </div>
        <div class="nav">
            <button id="leftBtn">&larr;</button>
            <button id="rightBtn">&rarr;</button>
        </div>
    </div>
    <script>
        //n 각형의 폭을 함수에 전달하면 div 를 배치할때 rotateY 값과 translateZ 가 Object 로 리턴되는 함수 
        function getAngleNtz(n, width) {
            var angle = Math.round(360 / n);
            var tz = Math.round((width / 2) / Math.tan((angle * Math.PI) / (2 * 180)));
            var obj = {
                angle: angle,
                tz: tz
            };
            return obj;
        }

        //n각형
        const n=6;
        //div 의 width
        const width=400;
        // 6 각형 폭은 400px 인 경우 
        const obj=getAngleNtz(n, width);
        //배치하면서 회전시킬 각도
        const angle=obj.angle;
        //배치하면서 z 축 방향으로 평행이동 해야 하는 값
        const tz=obj.tz;


        // 만들어야 할 div 가 n 개 이기 때문에 반복문 n번 돌기
        for(let i=0; i<n; i++){
            //div 를 만들어서 
            const div=document.createElement("div");
            //innerText 를 출력하고 
            div.innerText=i+1;
            //.poligon 에 추가하기
            document.querySelector(".poligon").append(div);
        }
        
        document.querySelector(".poligon").style.transform="translateZ(-"+tz+"px)";

        // .poligon 안에 있는 모든 div 의 참조값을 배열로 얻어내기
        const divs=document.querySelectorAll(".poligon div");

        //반복문 돌면서 모든 div 에 transform 적용하기
        for(let i=0; i<divs.length; i++){
            let rotate = i*angle;
            divs[i].style.transform="rotateY("+rotate+"deg) translateZ("+tz+"px)";
        }

        // y 축 기준 회전하는 값을 저장할 변수 선언하고 초기값 0 대입
        let rY=0;

        document.querySelector("#leftBtn").addEventListener("click", ()=>{
            rY -= angle;
            document.querySelector(".poligon")
                .style.transform="translateZ(-"+tz+"px) rotateY("+rY+"deg)";
        });

        document.querySelector("#rightBtn").addEventListener("click", ()=>{
            rY += angle;
            document.querySelector(".poligon")
                .style.transform=`translateZ(-${tz}px) rotateY(${rY}deg)`;
        });
    </script>    
</body>
</html>

 

6각형을 만들어보았다.

 

'수업내용' 카테고리의 다른 글

20230718 AndroidStudio설치/실행  (0) 2023.07.18
Lombok 다운로드/설치/적용  (0) 2023.07.17
20230712 3dTransform.html  (0) 2023.07.12
20230711 SpringBoot Controller/JSP/MyBatis  (0) 2023.07.11
20230711 CSS3 Animate  (0) 2023.07.11

댓글