ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • TIL-2024.03.14 - 3js - Interactive Card - 1. 카드 모형 만들기
    > Frontend/ThreeJS 2024. 3. 14. 15:37

     

     

     

    목표:

    1. Card Class
    2. Shape Geometry
    3. Extrude Geometry
    4. Orbit Controls 컨트롤 설정
    5. GSAP을 이용한 애니메이션 구현

     

     

    Card Class

     

    - card.js

    import * as THREE from "three";
    
    class Card {
        constructor({width, height, color}) {
            const shape = new THREE.Shape()
            const geometry = new THREE.ShapeGeometry(shape);
            const material = new THREE.MeshStandardMaterial({color, side: THREE.DoubleSide}); // 정면만 렌더링
    
            const mesh = new THREE.Mesh(geometry, material);
            console.log(1, this)
            console.log(2, mesh)
            this.mesh = mesh;
        }
    }
    
    export default Card;

     

    • Mesh는 Three.js에서 3D 객체를 나타내는 기본적인 요소로.  Geometry(기하)와 Material(재질)로 구성됨

    • Geometry(기하):
      - Mesh의 모양이나 구조를 정의.
      - 객체의 형태, 꼭짓점, 면 및 경계를 결정.
      - Geometry는 점, 선, 면 또는 이들의 조합으로 구성됩니다.

    • Material(재질):
      - Mesh가 어떻게 보일지를 결정.
      - 객체의 색상, 빛, 반사율 등을 제어.
      - 재질은 Mesh를 렌더링할 때 표면의 시각적 특성을 정의.

    -> MeshGeometryMaterial을 결합하여 실제로 화면에 그려지는 3D 객체를 형성

     

     

     

    - main.js

    import * as THREE from "three";
    import Card from "./card";
    import { OrbitControls } from "three/addons";
    import {GUI} from 'lil-gui'
    
    window.addEventListener("load", () => {
        init();
    });
    
    const init = () => {
        const gui = new GUI();
        const card = new Card({
            width: 10,
            height: 15.8,
            color: "#0077ff",
        });
    
    
    ... 생략 ...

     

    이와 같이, Class 로 만들어서, 다른 파일에서 Obj를 생성해서 사용.

     

     

     

    Shape Geometry

    import * as THREE from "three";
    
    class Card {
        constructor({width, height, radius, color}) {
            const shape = new THREE.Shape();
            const x = width / 2 - radius;
            const y = height / 2 - radius;
    
            // shape의 Geometry 를 카드 형태로 변경
            shape
                .absarc(x, y, radius, Math.PI / 2, 0, true) // 타원모형의 곡선에서 사용 > x , y , startAngle, endAngle, clockwise 를 인자로 받음
                .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 / 2, true)
                .absarc(-x, y, radius, Math.PI, Math.PI / 2, true);
    
            const geometry = new THREE.ShapeGeometry(shape);
            
            // shape의 material를 통해, 색깔 변경 및 뒷면 표시
            const material = new THREE.MeshStandardMaterial({color, side: THREE.DoubleSide}); // 기본값은 정면만 렌더링하므로, 양측 렌더링위해 변경
            
            
            // 값 합체
            const mesh = new THREE.Mesh(geometry, material);
    
            this.mesh = mesh;
        }
    }
    
    export default Card;

     

     

     

     

     

    Extrude Geometry

     

    - Shape Geometry 는 두께감이 없음

    - Extrude Geometry는 경로 모양에서 돌출된 형상 즉, 두께감이 있는 Geometry 

     

    const options = {
        depth: 0.01, // 두께감
        bbevelThickness: 0.1, // 경계
    };
    const geometry = new THREE.ExtrudeGeometry(shape, options);

     

     

     

     

    Orbit Controls 카메라 설정

     

    const controls = new OrbitControls(camera, renderer.domElement);
    controls.autoRotate = true; // 자동 회전
    controls.autoRotateSpeed = .75; // 회전 속도
    controls.enableDamping = true; // 감쇠 관성
    controls.enableZoom = false; // 줌 기능
    controls.minPolarAngle = Math.PI / 2 - Math.PI / 3; // 수직 궤도 얼마나 돌 수 있는지 하한 - 0 ~ Math.PI
    controls.maxPolarAngle = Math.PI / 2 + Math.PI / 3; // 수직 궤도 얼마나 돌 수 있는지 상한 - 0 ~ Math.PI
    

     

     

     

     

     

     

    gsap 라이브러리를 사용한 애니메이션 효과 

     

     

    참조: https://gsap.com/

     

     

     

    1. 설치

    yarn add gsap

     

    2. import

    import { gsap } from "gsap";
    
    ... 생략 ...

     

     

    3. gsap 사용

     

        /* gsap -1 mesh.rotation */
        const gsapOptions1 = {
            y: -Math.PI * 4,
            duration: 2,
            ease: "back.out(4)",
        };
        gsap.to(card.mesh.rotation, gsapOptions1);

     

     

     

    댓글

Designed by Tistory.