<!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">←</button>
<button id="rightBtn">→</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">←</button>
<button id="rightBtn">→</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">←</button>
<button id="rightBtn">→</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">←</button>
<button id="rightBtn">→</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 |
댓글