React 기본 사용법

React 환경에서 VRISM Viewer SDK를 4단계로 익혀보세요. 각 단계는 실제로 복사해서 사용할 수 있는 코드로 구성되어 있습니다.

1단계: 뷰어 띄우기

최소 설정으로 시작하기

가장 간단한 형태의 뷰어부터 시작해보겠습니다.

import { VrismViewer } from '@vrism/viewer-sdk';

function App() {
  return (
    <div style={{ width: '100%', height: '500px' }}>
      <VrismViewer
        token="your-token-here"
        contentId="your-content-id"
      />
    </div>
  );
}

이것만으로도 완전한 3D 뷰어가 동작합니다!

컨테이너 스타일링

뷰어의 크기와 위치를 조정할 수 있습니다:

<VrismViewer
  token="your-token-here"
  contentId="your-content-id"
  style={{
    width: '800px',
    height: '600px',
    border: '1px solid #ddd',
    borderRadius: '8px'
  }}
  className="my-viewer"
/>

2단계: 옵션 설정하기

UI 요소 제어

필요한 UI 요소만 선택적으로 표시할 수 있습니다:

<VrismViewer
  token="your-token-here"
  contentId="your-content-id"
  ui={{
    // 배경색 변경
    viewerBackgroundColor: '#f8f9fa',
    
    // UI 요소 끄고 켜기
    gestureGuide: true,           // 제스처 가이드 표시
    fullscreenButton: true,       // 전체화면 버튼 표시
    userGuide: false,             // 사용자 가이드 숨김
    
    // 로더 커스터마이징
    loader: {
      type: 'circle',             // 'circle' 또는 'bar'
      size: 'medium',             // 'small', 'medium', 'large'
      loaderFillColor: '#007bff', // 로더 색상
      loaderPlaceholderColor: '#e9ecef'
    }
  }}
/>

카메라 초기 설정

뷰어의 초기 카메라 위치와 동작을 설정할 수 있습니다:

<VrismViewer
  token="your-token-here"
  contentId="your-content-id"
  camera={{
    // 자동 회전 (음수: 반시계방향, 양수: 시계방향, 0: 정지)
    autoRotation: -2,
    
    // 사용자 조작 제어
    controls: {
      enableZoom: true,    // 줌 허용
      enablePan: true,     // 팬(이동) 허용  
      enableRotate: true   // 회전 허용
    },
    
    // 데스크톱 초기 위치
    desktop: {
      angle: { x: 0.2, y: 0.1 },  // 초기 각도
      zoom: 1.5,                   // 초기 줌
      limits: {
        angleUp: 1.5,              // 위쪽 각도 제한
        angleDown: -1.5,           // 아래쪽 각도 제한
        zoomMin: 0.5,              // 최소 줌
        zoomMax: 3.0               // 최대 줌
      }
    }
  }}
/>

스텝 기능 설정

제품의 여러 각도나 기능을 단계별로 보여줄 수 있습니다:

<VrismViewer
  token="your-token-here"
  contentId="your-content-id"
  ui={{
    step: {
      enabled: true,          // 스텝 기능 활성화
      stepControls: true,     // 이전/다음 버튼 표시
      stepDots: true,         // 스텝 도트 네비게이션 표시
      stepAnnotation: true,   // 3D 마커 표시
      items: [
        {
          id: 1,
          name: '전체 보기',
          order: 1,
          anchor: {
            desktop: {
              position: { x: 0, y: 0, z: 5 },
              target: { x: 0, y: 0, z: 0 }
            },
            mobile: {
              position: { x: 0, y: 0, z: 5 },
              target: { x: 0, y: 0, z: 0 }
            }
          },
        },
        {
          id: 2,
          name: '디테일 보기',
          order: 2,
          anchor: {
            desktop: {
              position: { x: 2, y: 1, z: 3 },
              target: { x: 0, y: 0, z: 0 }
            },
            mobile: {
              position: { x: 2, y: 1, z: 3 },
              target: { x: 0, y: 0, z: 0 }
            }
          },
          annotation: {
            marker: {
              position: { x: 1, y: 0.5, z: 0 }
            },
            content: {
              title: '디테일 보기',
              description: '제품의 세부 디테일을 살펴보세요'
            }
          }
        }
      ]
    }
  }}
/>

참고사항

  • 첫번째 step에는 Annotation 정보를 설정할 수 없습니다.
  • step 활성화시 기존 카메라 설정에서 step의 첫번째 anchor 값을 기준으로 뷰어의 카메라가 초기화됩니다.

Anchor, Annotation Marker 설정 방법

VrismViewer 에 등록한 ref 값을 통해 현재 카메라 정보 및 클릭지점의 위치 확인이 가능합니다. 해당 값을 anchor (각 step별 위치시키려는 카메라 위치)와 annotation marker position(step별로 주석을 달고자하는 제품의 특정 부분의 위치)로 적용하시면 됩니다.

자세한 사용 방법은 아래 3D 위치 선택 기능에서 확인하세요.

💡 팁: 마커는 끄고 스텝 기능만 사용하려면 stepAnnotation: false로 설정하세요.

3단계: 이벤트 처리하기

로딩 상태 처리

뷰어의 로딩 상태를 감지하고 처리할 수 있습니다:

import { useState } from 'react';

function ViewerWithLoading() {
  const [isLoading, setIsLoading] = useState(true);
  const [loadingProgress, setLoadingProgress] = useState(0);

  return (
    <div>
      {isLoading && (
        <div>로딩 중... {loadingProgress}%</div>
      )}
      
      <VrismViewer
        token="your-token-here"
        contentId="your-content-id"
        // 로딩 진행률 업데이트
        onLoadUpdate={(percentage) => {
          setLoadingProgress(percentage || 0);
        }}
        // 뷰어 완전히 준비 완료
        onLoadScene={() => {
          console.log('뷰어 사용 준비 완료');
          setIsLoading(false);
        }}
      />
    </div>
  );
}

스텝 변경 감지

사용자가 스텝을 변경했을 때를 감지할 수 있습니다:

function ViewerWithSteps() {
  const [currentStep, setCurrentStep] = useState(0);
  
  return (
    <div>
      <div>현재 스텝: {currentStep + 1}</div>
      
      <VrismViewer
        token="your-token-here"
        contentId="your-content-id"
        ui={{ step: { enabled: true } }}
        onStepChange={(options) => {
          console.log('스텝 변경:', options.step, options.direction);
          setCurrentStep(options.step || 0);
        }}
      />
    </div>
  );
}

에러 처리

뷰어에서 발생할 수 있는 에러를 처리할 수 있습니다:

function ViewerWithErrorHandling() {
  const [error, setError] = useState(null);
  
  if (error) {
    return <div>에러가 발생했습니다: {error.message}</div>;
  }
  
  return (
    <VrismViewer
      token="your-token-here"
      contentId="your-content-id"
      onError={(error) => {
        console.error('뷰어 에러:', error);
        setError(error);
      }}
    />
  );
}

4단계: 뷰어 제어하기

ref를 통한 뷰어 제어

뷰어를 프로그래밍 방식으로 제어할 수 있습니다:

import { useRef } from 'react';

function ControlledViewer() {
  const viewerRef = useRef(null);
  
  const handleControls = () => {
    // 현재 설정 확인
    const config = viewerRef.current?.getConfig();
    console.log('현재 설정:', config);
    
    // 카메라 위치 확인
    const position = viewerRef.current?.getCameraPosition();
    console.log('카메라 위치:', position);
  };
  
  const handleStepControl = () => {
    // 특정 스텝으로 이동
    viewerRef.current?.setStep(2);
  };
  
  const handleUIControl = () => {
    // 제스처 가이드 끄기
    viewerRef.current?.setGestureGuideShow(false);
    
    // 전체화면 열기
    viewerRef.current?.setFullscreenOpen(true);
  };
  
  return (
    <div>
      <div style={{ marginBottom: '10px' }}>
        <button onClick={handleControls}>설정 확인</button>
        <button onClick={handleStepControl}>2번 스텝으로</button>
        <button onClick={handleUIControl}>UI 제어</button>
      </div>
      
      <VrismViewer
        ref={viewerRef}
        token="your-token-here"
        contentId="your-content-id"
        ui={{ step: { enabled: true } }}
      />
    </div>
  );
}

3D 위치 선택 기능

사용자가 3D 모델에서 위치를 선택할 수 있게 할 수 있습니다:

function InteractiveViewer() {
  const viewerRef = useRef(null);
  
  const handlePickPosition = async () => {
    console.log('3D 모델에서 원하는 위치를 클릭하세요');
    
    const position = await viewerRef.current?.getClickedPosition();
    if (position) {
      console.log('선택된 위치:', position);
    }
  };
  
  return (
    <div>
      <button onClick={handlePickPosition}>
        3D 위치 선택하기
      </button>
      
      <VrismViewer
        ref={viewerRef}
        token="your-token-here"
        contentId="your-content-id"
        ui={{
          step: {
            enabled: true,  // getClickedPosition 사용을 위해 필수
            items: [        // 1개 이상 필수
              {
                id: 1,
                name: '전체 보기',
                order: 1,
                anchor: {
                  desktop: {
                    position: { x: 0, y: 0, z: 5 },
                    target: { x: 0, y: 0, z: 0 }
                  }
                }
              }
            ]
          }
        }}
      />
    </div>
  );
}

동적 설정 변경

뷰어를 리로드하여 설정을 동적으로 변경할 수 있습니다:

function DynamicViewer() {
  const viewerRef = useRef(null);
  const [backgroundColor, setBackgroundColor] = useState('#ffffff');
  
  const changeBackground = async (color) => {
    setBackgroundColor(color);
    
    // 뷰어 리로드로 설정 변경
    await viewerRef.current?.reload({
      ui: { viewerBackgroundColor: color }
    });
  };
  
  return (
    <div>
      <div style={{ marginBottom: '10px' }}>
        <button onClick={() => changeBackground('#ffffff')}>
          흰색 배경
        </button>
        <button onClick={() => changeBackground('#000000')}>
          검은색 배경
        </button>
        <button onClick={() => changeBackground('#f8f9fa')}>
          회색 배경
        </button>
      </div>
      
      <VrismViewer
        ref={viewerRef}
        token="your-token-here"
        contentId="your-content-id"
        ui={{ viewerBackgroundColor: backgroundColor }}
      />
    </div>
  );
}

🎯 다음 단계

React 기본 사용법을 익혔다면: