CSS와 JS에서 3D 크리퍼의 머리 애니메이션하기!

저는 현재 마인크래프트 유니버스를 기반으로 웹 애플리케이션을 코딩하고 있습니다.
dev.to의 첫 번째 기사(영광입니다)에서 라이브러리 없이 CSS와 바닐라 JS만 있는 3D 크리퍼의 머리로 이 멋진 애니메이션을 구축한 방법을 공유합니다.

이 자습서는 두 부분으로 나뉩니다.
  • 크리퍼 헤드 모델링
  • javascript로 모델 애니메이션 처리

  • 이 자습서에서는 및 를 사용합니다.

    3D 크리퍼 머리 모델링



    이 작업의 첫 번째 단계는 크리퍼의 머리를 모델링하는 것입니다. 내 경우에는 큐브를 모델링하는 것과 유사하게 매우 쉽습니다. 다음 두 자산을 사용했습니다.
  • 크리퍼의 얼굴, face.png
  • 그의 머리의 측면, side.png




  • 큐브의 각 측면은 img 태그로 표시되며 div 요소(여기서는 #creeper )에 중첩됩니다.

    <div id="creeper">
        <img src="face.png" class="side front" />
        <img src="side.png" class="side back" />
        <img src="side.png" class="side top" />
        <img src="side.png" class="side bottom" />
        <img src="side.png" class="side left" />
        <img src="side.png" class="side right" />
    </div>
    


    기본적으로 CSS에서는 X축과 Y축을 기준으로 2D 공간에 HTML 노드를 배치할 수 있습니다. 그래서 모든 것이 평평합니다.


    제 경우에는 웹 페이지에서 3D 개체를 모델링하고 싶습니다. 따라서 CSS의 기본 동작을 변경해야 합니다! 그렇게 하려면 요소를 3D 공간에 배치하고 싶다고 CSS에 표시하기만 하면 됩니다.

    :root {
        --size-creeper: 128px;
    }
    #creeper {
        width: var(--size-creeper);
        height: var(--size-creeper);
        /* the magic happens here */
        transform-style: preserve-3d;
    }
    
    


    이제 X, Y, Z축을 기준으로 #creeper의 모든 하위 요소를 정확하게 배치할 수 있습니다. 큐브의 윗면을 배치하는 예는 다음과 같습니다.

    .side {
        position: absolute;
        width: var(--size-creeper);
        height: var(--size-creeper);
    }
    .top { transform: rotateX(90deg) translateZ(calc(var(--size-creeper) / 2)); }
    


    다음 아이소메트릭 뷰는 개체가 3D 공간에 있는 방식과 회전, 변환 및 배율 조정 방법을 이해하는 데 도움이 될 수 있습니다.

    #creeper 요소에 애니메이션을 추가하여 모든 것이 올바르게 배치되었는지 확인합니다! 자세한 내용은 다음 코드를 참조하십시오.


    크리퍼 머리 애니메이션



    codepen.io에서 멋진 애니메이션을 찾을 수 있습니다. 내가 본 마지막 작품 중 하나는 https://codepen.io/jhojann/pen/weKBxV?page=3 입니다. 이 창작물에서 영감을 얻어 마우스의 위치에 따라 내 덩굴 머리를 애니메이션할 것입니다. 자바스크립트 코드를 작성해봅시다! 내 기능의 서명은 다음과 같습니다.

    const animate = (element, options = {}) => {
        ...
    }
    


  • element는 애니메이션을 적용하려는 HTML 요소입니다
  • .
  • options는 애니메이션의 매개변수를 변경하려는 경우에 유용합니다.

  • 이 함수를 코딩해봅시다. 가장 먼저 원하는 것은 내 크리퍼 헤드의 중심 원점의 정확한 위치입니다. 논문 값을 얻으려면 getBoundingClientRect#creeper를 사용합니다.

    const characterRect = element.getBoundingClientRect()
    const originX = elementRect.left + elementRect.width / 2
    const originY = elementRect.top + elementRect.height / 2
    


    좋습니다. 이제 머리의 정확한 원점을 얻었습니다. 다음 단계는 커서의 위치를 ​​X축과 Y축의 회전과 바인딩하는 것입니다. 커서가 정확히 원점에 위치할 때 X축과 Y축의 회전은 0deg와 같아야 한다고 가정합니다. 청취자에게는 다음과 같은 것이 있습니다.

    // define default params 
    options = Object.assign({}, { maxAngleX: 30, maxAngleY: 30 }, options)
    // Re-maps a number from one range to another.
    const map = (value, low1, high1, low2, high2) => low2 + (high2 - low2) * (value - low1) / (high1 - low1)
    const follow = e => {
      try {
        const width = document.body.clientWidth
        const height = document.body.clientHeight
        // Support of smartphone/tablet
        const clientX = e.clientX || e.touches[0].clientX
        const clientY = e.clientY || e.touches[0].clientY
        const decY = map(clientY - originY, -height / 2, height / 2 , -options.maxAngleY, options.maxAngleY)
        const decX = map(clientX - originX, -width / 2, width / 2 , -options.maxAngleX, options.maxAngleX)
        element.style.transform = `rotateX(${-decY}deg) rotateY(${decX}deg)`
      } catch(e) {}
    }
    


    이제 my 함수handle를 사용하여 마우스 및 터치 이벤트를 바인딩하겠습니다.

    document.body.addEventListener('mousemove', handle)
    document.body.addEventListener("touchmove", handle, false)
    


    마지막 단계는 페이지가 로드될 때 animate 함수를 호출하는 것입니다.

    document.addEventListener('DOMContentLoaded', _ => {
        followCursor(document.querySelector('#creeper'))
    })
    


    이것이 최종 결과입니다(애니메이션을 보려면 커서를 이동하십시오).



    이 기사를 즐겼기를 바랍니다. 나는 또한 어떤 개선이든 열린 마음입니다. 저는 디자이너가 아니라 코딩과 멋진 것을 만드는 것을 좋아하는 사람입니다!

    좋은 웹페이지 즐겨찾기