3D CSS 뒤집기 카드 만들기

얼마 전I wrote an article on 3d interactive CSS buttons.비슷한 기술을 사용하여 나는 3d 인터랙티브 (뒤집기 가능) CSS 사용자 카드를 설계하기로 결정했다.이것들도 은행 카드 사용자 인터페이스, 포커 사용자 인터페이스, 또는 단지 하나의 단체 페이지에 적용된다.시범은 아래에서 볼 수 있다!
The full code, as always, is Available on CodePen.


3d 뒤집기 카드(CSS 및 Javascript 포함)
마우스를 아래 카드에 걸거나(또는 휴대전화에서 카드의 어느 위치를 클릭하면) 전속력을 발휘할 수 있다.
이 효과를 얻기 위해서는 Javascript와 CSS에서 서로 다른 것들을 결합시켜야 한다.

  • 우선, 우리는 마우스 위치에 따라 카드의 각도를 조종할 수 있는 함수를 만들어야 한다.

  • 다음으로 카드의 맨 위에 '현광' 조명 효과가 추가된 위치를 확인하려면 이 함수를 사용해야 한다.

  • 그리고 카드의 뒷면과 앞면을 만들기 위해 대량의 CSS를 추가해야 합니다.

  • 마지막으로, 카드를 뒤집을 수 있도록 자바스크립트에 함수를 추가해야 합니다.

  • HTML 만들기
    HTML부터 시작하겠습니다.이것은 우리의 첫 번째 카드의 모습이다.카드마다 두 가지 주요 부분이 있는데 그것이 바로 inner-cardinner-card-backface이다.첫 번째는 카드의 앞면, 두 번째는 카드의 뒷면을 포함한다.
    카드의 어느 쪽이 보이는지 바꿀 수 있는 두 개의 단추가 있습니다. 뒤집기와 취소입니다.
        <div class="card blastoise">
            <span class="inner-card-backface"> <!-- back of the card -->
                <span class="image">
                    <span class="unflip">Unflip</span>
                </span>
            </span>
            <span class="inner-card"> <!-- front of the card -->
                <span class="flip">Flip</span> 
                <span class="glare"></span> <!-- to store the glare effect -->
            </span>
        </div>
    

    JS 만들기
    우리의 JS는 사용자가 카드에 있는 위치를 찾아내고 이를 하나의 각도로 전환시켜 CSS에 전달함으로써 카드에 대한 우리의 견해를 바꾸는 기본적인 일을 했다.이를 위해서는 사용자가 카드의 중심에서 얼마나 멀리 떨어져 있는지 알아야 한다.두 개의 축만 걱정할 수 있습니다. 사용자가 그 중 하나에 도달할 때, 우리는 중심에 비해 카드를 회전할 수 있습니다. 아래 그림과 같습니다.


    3d 뒤집기 가능 CSS 카드에 Javascript 적용 방법
    "마지막으로, 이를 위해""카드""요소를 적용하고 CSS를 업데이트하는 함수를 작성했습니다."
    let calculateAngle = function(e, item, parent) {
        let dropShadowColor = `rgba(0, 0, 0, 0.3)`
        if(parent.getAttribute('data-filter-color') !== null) {
            dropShadowColor = parent.getAttribute('data-filter-color');
        }
    
        parent.classList.add('animated');
        // Get the x position of the users mouse, relative to the button itself
        let x = Math.abs(item.getBoundingClientRect().x - e.clientX);
        // Get the y position relative to the button
        let y = Math.abs(item.getBoundingClientRect().y - e.clientY);
    
        // Calculate half the width and height
        let halfWidth  = item.getBoundingClientRect().width / 2;
        let halfHeight = item.getBoundingClientRect().height / 2;
    
        // Use this to create an angle. I have divided by 6 and 4 respectively so the effect looks good.
        // Changing these numbers will change the depth of the effect.
        let calcAngleX = (x - halfWidth) / 6;
        let calcAngleY = (y - halfHeight) / 14;
    
        let gX = (1 - (x / (halfWidth * 2))) * 100;
        let gY = (1 - (y / (halfHeight * 2))) * 100;
    
        // Add the glare at the reflection of where the user's mouse is hovering
        item.querySelector('.glare').style.background = `radial-gradient(circle at ${gX}% ${gY}%, rgb(199 198 243), transparent)`;
        // And set its container's perspective.
        parent.style.perspective = `${halfWidth * 6}px`
        item.style.perspective = `${halfWidth * 6}px`
    
        // Set the items transform CSS property
        item.style.transform = `rotateY(${calcAngleX}deg) rotateX(${-calcAngleY}deg) scale(1.04)`;
        parent.querySelector('.inner-card-backface').style.transform = `rotateY(${calcAngleX}deg) rotateX(${-calcAngleY}deg) scale(1.04) translateZ(-4px)`;
    
        if(parent.getAttribute('data-custom-perspective') !== null) {
            parent.style.perspective = `${parent.getAttribute('data-custom-perspective')}`
        }
    
        // Reapply this to the shadow, with different dividers
        let calcShadowX = (x - halfWidth) / 3;
        let calcShadowY = (y - halfHeight) / 6;
    
        // Add a filter shadow - this is more performant to animate than a regular box shadow.
        item.style.filter = `drop-shadow(${-calcShadowX}px ${-calcShadowY}px 15px ${dropShadowColor})`;
    }
    
    이 함수에는 다음과 같은 네 가지 기능이 있습니다.
  • 원소의 음영을 계산하여 3차원 공간에서 움직이는 것처럼 보인다.
  • 마우스 위치에 따라 카드의 각도를 계산합니다.
  • 뒷면의 위치를 계산하여 카드의 앞면과 동시 이동시킨다.
  • 눈부심 위치, 즉 사용자 마우스가 있는 위치의 반사를 계산합니다.
  • 우리가 지금 해야 할 일은 이 기능을 모든 마우스 이동 이벤트에 추가한 다음 사용자의 마우스가 요소를 떠날 때 매번 리셋하는 것이다.또한 카드를 "뒤집기"및 "풀기"에 사용할 수 있는 기능도 추가됩니다.
    document.querySelectorAll('.card').forEach(function(item) {
        // For flipping the card backwards and forwards
        if(item.querySelector('.flip') !== null) {
          item.querySelector('.flip').addEventListener('click', function() {
            item.classList.add('flipped');
          });
        }
    
        // For 'unflipping' the card.
        if(item.querySelector('.unflip') !== null) {
          item.querySelector('.unflip').addEventListener('click', function() {
            item.classList.remove('flipped');
          });
        }
    
        // For when the user's mouse 'enters' the card
        item.addEventListener('mouseenter', function(e) {
            calculateAngle(e, this.querySelector('.inner-card'), this);
        });
    
        // For when the users mouse moves on top of the card
        item.addEventListener('mousemove', function(e) {
            calculateAngle(e, this.querySelector('.inner-card'), this);
        });
    
        // For when the user's mouse leaves the card.
        item.addEventListener('mouseleave', function(e) {
            let dropShadowColor = `rgba(0, 0, 0, 0.3)`
            if(item.getAttribute('data-filter-color') !== null) {
                dropShadowColor = item.getAttribute('data-filter-color')
            }
            item.classList.remove('animated');
            item.querySelector('.inner-card').style.transform = `rotateY(0deg) rotateX(0deg) scale(1)`;
            item.querySelector('.inner-card-backface').style.transform = `rotateY(0deg) rotateX(0deg) scale(1.01) translateZ(-4px)`;
            item.querySelector('.inner-card').style.filter = `drop-shadow(0 10px 15px ${dropShadowColor})`;
        });
    });
    
    마우스 이벤트가 카드에 대한 것임을 알 수 있지만, 전환은 주로 발생합니다.내부 카드.그건 만약에카드가 변경됩니다. "정지 상자"가 변경됩니다.만약 이런 상황이 발생한다면 사용자는 카드에 멈추겠지만 각도가 크게 변할 것이다. 그들은 다시는 이렇게 하지 않아서 효과가 파괴되는 것 같다.카드에 정지 효과를 추가하면 고정된 정지 상자를 유지할 수 있으며 그림을 변환할 수 있습니다.이 고정 상자 안의 내부 카드.

    CSS 추가
    마지막으로 CSS를 추가할 수 있습니다.여기서 가장 기본적인 것은 우리가 카드 용기를 가지고 있다는 것이다.우리가 변환한 카드가 포함된 카드-.내부 카드.
    이렇게 하는 또 다른 장점은 사용자가'뒤집기'를 눌렀을 때 우리는 .card 자체를 뒤집을 수 있다는 것이다. 왜냐하면 우리는 부모 요소와 하위 요소를 유지하기 때문이다.이것은 우리가 계속 변환.inner-card,하고 뒤집을 수 있다는 것을 의미한다.동시에 카드를 제작하여 더욱 빈틈없는 효과를 낸다..inner-card-backface에 4픽셀을 뒤로 이동하는 행transform: rotateX(0) rotateY(0deg) scale(1) translateZ(-4px);을 추가합니다.이것은 멋진 3d 깊이 효과를 만들고 사용자가 멈출 때 정면과 뒷면이 충돌하지 않도록 합니다.우리는 또한 backface-visibility: visible; 우리에 추가할 것이다.이렇게 하면 우리의 정면과 뒷면이 모두 상호작용할 수 있다.
    마지막으로, 우리가 사용하기 때문이다.교실을 뒤집을 때 우리는 카드 뒷면의 내용을 풀어야 한다.만약 우리가 이렇게 하지 않는다면, 뒤의 텍스트는 뒤에서 앞으로 보일 것이다.그래서 우리는 .flip-inner-card라는 종류가 있는데 카드의 뒷면만 뒤집을 수 있고 텍스트는 더 이상 서로 등지고 있지 않다.
    .card {
        box-shadow: none;
        backface-visibility: visible;
        background: transparent;
        font-family: Inter,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Open Sans,Helvetica Neue,sans-serif;
        transform-style: preserve-3d;
        padding: 0;
        height: auto;
        margin: 0 2rem 0 0;
        width: 18rem;
        height: 25rem;
        float: left;
        transition: all 0.2s ease-out;
        border: none;
        letter-spacing: 1px;
    }
    .flip, .unflip {
        background: rgba(0,0,0,0.1);
        font-size: 1rem;
        position: absolute;
        top: 1rem;
        right: 1rem;
        padding: 0.5rem 0.75rem;
        border-radius: 100px;
        line-height: 1rem;
        cursor: pointer;
        transition: all 0.1s ease-out;
    }
    .unflip {
        top: auto;
        background: #2d2d62;
        bottom: 1rem;
    }
    .flip:hover {
      background: rgba(0,0,0,0.3);
    }
    .card .flip-inner-card {
        transform: rotateY(180deg);
        position: absolute;
        top: 0;
        padding: 2rem 1.5rem;
        box-sizing: border-box;
        left: 0;
        width: 100%;
        height: 100%;
    }
    .inner-card-backface {
        transform: rotateX(0) rotateY(0deg) scale(1) translateZ(-4px);
        border-radius: 14px;
        background: linear-gradient(45deg, #0b0b2a, #0b0b2a);
        position: absolute;
        top: 0;
        color: white;
        padding: 2rem;
        box-sizing: border-box;
        transition: all 0.15s ease-out;
        will-change: transform, filter;
        left: 0;
        width: 100%;
        height: 100%;
    }
    .card.flipped {
        transform: rotateY(180deg);
    }
    .card .flip-inner-card {
        transform: rotateY(180deg);
        position: absolute;
        top: 0;
        padding: 2rem 1.5rem;
        box-sizing: border-box;
        left: 0;
        width: 100%;
        height: 100%;
    }
    

    결론
    이 자습서에서는 3d CSS 뒤집기 카드를 만드는 방법에 대해 설명합니다.사용자가 정지할 때 각도를 표시하는 데 필요한 기능과 이런 3d카드를 만드는 데 필요한 CSS를 계산해 봤습니다.나는 네가 좋아하길 바란다. 너의 어떤 개인 항목에서도 마음대로 사용할 수 있기를 바란다. 다음은 몇 가지 유용한 링크이다.
  • All the code can be found on Codepen
  • Here is a similar effect, with buttons instead of cards
  • 좋은 웹페이지 즐겨찾기