01_ShapeGeometry 를 이용한 카드의 곡선표현
absarc 앱솔루트아크 메소드
border-radius 와 비슷한 개념
absarc 는 총 여섯개의 인자를 받을 수 있다.
radius인 border-radius 가 있는 직사각형을 표현하기 위해서 반시계 혹은 시계방향으로 회전한 만큼을 생각하면 된다.
startAngle, endAngle 은 각각 부채꼴 중심각의 시작, 끝 각도를 의미하며,
clockwise 는 시계방향으로 꺾을지, 반시계로 꺾을지 정하는 값을 받는다.
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2Fb7a4fc44-1547-475f-83a2-faab4432d448%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.02.52.png?table=block&id=2c5763f3-28e7-49d3-96ea-653968905994&cache=v2)
위 그림과 설명을 토대로 곡선이 있는 부드러운 카드를 만든다면
우측상단의 곡선
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F04cfe292-f6cb-4a1c-82f1-6dbfa351c5c0%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.10.37.png?table=block&id=aacbdb2e-50ca-4ac8-b8c8-e2d001f8ea92&cache=v2)
- 회전의 중심점 x,y 좌표를 구한다.
- 전체카드 width의 절반값에서 radius 를 뺀 값이 x 좌표가 된다.
- 전체카드 height 의 절반값에서 radius 를 뺀 값이 y 좌표가 된다.
const x = width / 2 - radius; const y = height / 2 - radius;
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F51cf2322-1f7c-4b87-aff1-9929c5cb6580%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.16.55.png?table=block&id=082c04bd-cfaf-438f-814d-f6889d5fbdd2&cache=v2)
- 회전각의 시작과 끝값을 정해준다.
- x 축 양의방향을 기준으로 90도에서 0도 방향으로, 시계방향으로 회전시킨다.
- 이때 각도가 아닌, 파이 형식으로 넣어줘야 하기 때문에 90도는 Math.PI 를 2로 나눈값이되고 0은 그냥 0 처리 한다.
shape.absarc(x, y, radius, Math.PI / 2, 0, true)
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F247222d5-e19b-41d4-a5f5-839dc1536fcf%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.17.56.png?table=block&id=60510ee5-e7b4-477d-97aa-9269de48bfa8&cache=v2)
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F5997da7c-a1a7-4bb6-a811-09d89380281d%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.23.33.png?table=block&id=fb513a8d-0a38-4185-b33d-15619810fde9&cache=v2)
- 첫번째 부채꼴이 끝나는 시점부터 그다음 부채꼴이 시작되는 지점까지의 직선길이를 구하려면 radius 의 길이를 뺀 나머지가 되어야 한다.
- 우측하단의 x 값은 방금 계산한 x 값에 radius 를 더한값이 되고, y 값은 방금 계산한 y값의 부호만 반대로 설정해주면 된다.
shape .absarc(x, y, radius, Math.PI / 2, 0, true) // 앱솔루트아크 메소드는 타워모양의 곡선을 그릴때 사용 가능 .lineTo(x + radius, -y);
- 길이를 구했으니 부채꼴의 중심점을 알아내어 x,y 좌표를 구해야 한다.
- 이전과 x 좌표는 똑같고, y 좌표는 부호만 반대로 하여 -y가 된다.
- 회전의 시작과 끝 각도는 0도에서 -90도인 시계방향으로 진행된다.
shape .absarc(x, y, radius, Math.PI / 2, 0, true) // 앱솔루트아크 메소드는 타워모양의 곡선을 그릴때 사용 가능 .lineTo(x + radius, -y) .absarc(x, -y, radius, 0, -Math.PI / 2, true);
이런식으로 나머지 부분도 계산한다면 다음과 같이 최종 코드가 작성된다.
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F44f4c20f-abee-49cb-9d63-68697770720d%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.29.07.png?table=block&id=9e109f3b-e6fc-4d3a-b022-db241bea0614&cache=v2)
//https://threejs.org/docs/?q=shape#api/en/geometries/ShapeGeometry const shape = new THREE.Shape(); shape .absarc(x, y, radius, Math.PI / 2, 0, true) // 앱솔루트아크 메소드는 타워모양의 곡선을 그릴때 사용 가능 .lineTo(x + radius, -y) .absarc(x, -y, radius, 0, -Math.PI / 2, true) .lineTo(-x, -(y + radius)) .absarc(-x, -y, radius, -Math.PI / 2, Math.PI, true) .lineTo(-(x + radius), y, radius, Math.PI, Math.PI / 2, true) .absarc(-x, y, radius, Math.PI, Math.PI / 2, true);
02_카드의 두께감 표현하기
ExtrudeGeometry
shapeGeometry 는 두께감을 표현하지 못하기 때문에 ExtrudeGeometry 를 대신 이용할 수 있다.
앞서 설정한 shape 인스턴스를 인자로 받을 수 있고 다양한 속성들을 두번째 인자로 설정할 수 있다.
const geometry = new THREE.ExtrudeGeometry(shape, { depth: 0.01, bevelThickness: 0.1, });
![ShapeGeometry](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2Fec8598ad-e7fc-4629-86ef-3f82e9177891%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.32.23.png?table=block&id=a8c2e300-e1fb-4dbc-9c27-e1cfc5cacb36&cache=v2)
![ExtrudeGeometry](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2Fe4e0c94b-9413-406f-91cb-f05454aea0ca%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.32.42.png?table=block&id=bf28b64b-c394-4ef5-997a-9574a61fb26c&cache=v2)
ExtrudeGeometry 를 사용했을때 최대로 확대해보면 여러개의 경계면이 있는것을 볼 수 있다.
이러한 경사진면의 두께를 더 부드럽게 표현하기 위해서 TextGeometry에서 다뤘던 bevel 옵션을 사용할 수 있다.
const geometry = new THREE.ExtrudeGeometry(shape, { depth: 0.01, bevelThickness: 0.1, });
![notion image](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F76c20bf1-0133-4674-b1f6-9783ab363c9f%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.36.02.png?table=block&id=5d208180-d173-49d6-947d-d26a96f41a33&cache=v2)
![bevelThickness 적용](https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F60501850-d7da-4308-8f3c-187df3aea321%2F776a65c5-e719-4d20-9570-a326a6ba35de%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2023-11-21_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.38.26.png?table=block&id=effaefcd-b6a6-4f71-9625-af14b1ff6e92&cache=v2)
03_카드 애니메이션 구현하기
gsap
import { gsap } from "gsap"; gsap.to(card.mesh.rotation, { y: -Math.PI * 4, //한바퀴 돌리려면 파이값으로 2이므로 두바퀴에 해당하는 4를 곱한다. duration: 2.5, ease: "back.out(2.5)", });