【问题标题】:CSS Transform Rotate 3D - Hover on each corner of a cardCSS Transform Rotate 3D - 悬停在卡片的每个角落
【发布时间】:2020-02-09 06:20:22
【问题描述】:

我正在尝试使用 css 3d 旋转来模拟当鼠标悬停在卡片上时按下卡片分为 4 个象限。左上、右上、左下、右下。我让左上/右上可以工作,但无论我尝试什么组合,我都无法让底部效果与顶部一样工作。知道如何让左下角/右下角看起来正确,就像它们被向下推一样,顶角看起来正确吗?另外,如果有更好的方法在 css/js 中完全做到这一点,请告诉我,我只是第一次搞乱这些 css 转换。

我添加了阴影来尝试帮助“推销”底部被推入而顶部弹出但看起来仍然错误的效果。可能只是我,某事的诡计。

function ThzhotspotPosition(evt, el, percent) {
  var left = el.offset().left;
  var top = el.offset().top;
  if (percent) {
    x = (evt.pageX - left) / el.outerWidth() * 100;
    y = (evt.pageY - top) / el.outerHeight() * 100;
  } else {
    x = (evt.pageX - left);
    y = (evt.pageY - top);
  }

  return {
    x: Math.round(x),
    y: Math.round(y)
  };
}

$(".card").mousemove(function(e) {
  var hp = ThzhotspotPosition(e, $(this), true); // true = percent | false or no attr = px

  if (hp.x >= 50 && hp.y >= 50) {
    $(this).removeClass(function(index, className) {
      return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
    }).addClass("roll-BR");
  } else if (hp.x >= 50 && hp.y < 50) {
    $(this).removeClass(function(index, className) {
      return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
    }).addClass("roll-TR");
  } else if (hp.x < 50 && hp.y >= 50) {
    $(this).removeClass(function(index, className) {
      return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
    }).addClass("roll-BL");
  } else {
    $(this).removeClass(function(index, className) {
      return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
    }).addClass("roll-TL");
  }

  $('#debug').text(hp.x + '%x' + ' ' + hp.y + '%y');
});


$(".card").hover(
  function(e) {
    //$( this ).addClass( "roll-left" );

  },
  function() {
    $(this).removeClass(function(index, className) {
      return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
    });
  }
);
.card {
    width: 100px;
    height: 150px;
    background: red;
    position: relative;
    transition: transform 1s;
    transform-style: preserve-3d;
}

.card.roll-TL {
    transform: rotate3d(1, -1, 0, 20deg);
    -webkit-box-shadow: 5px 5px 13px 2px rgba(0,0,0,0.41); 
    box-shadow: 5px 5px 13px 2px rgba(0,0,0,0.41);
    
}
.card.roll-TR {
    transform: rotate3d(-1, -1, 0, -20deg);
    -webkit-box-shadow: -5px 5px 13px 2px rgba(0,0,0,0.41); 
    box-shadow: -5px 5px 13px 2px rgba(0,0,0,0.41);
}

.card.roll-BL {
    transform: rotate3d(-1, -1, 0, 20deg);
    -webkit-box-shadow: 5px -5px 13px 2px rgba(0,0,0,0.41); 
    box-shadow: 5px -5px 13px 2px rgba(0,0,0,0.41);
}

.card.roll-BR {
    transform: rotate3d(1, -1, 0, -20deg);
    -webkit-box-shadow: -5px -5px 13px 2px rgba(0,0,0,0.41); 
    box-shadow: -5px -5px 13px 2px rgba(0,0,0,0.41);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="card">Testing</div>
<div id="debug"></div>

【问题讨论】:

    标签: javascript jquery html css css-transforms


    【解决方案1】:

    我假设你的 js 代码是正确的(因为我在运行它时没有发现问题)并且只是调整了一些 css。

    function ThzhotspotPosition(evt, el, percent) {
      var left = el.offset().left;
      var top = el.offset().top;
      if (percent) {
        x = (evt.pageX - left) / el.outerWidth() * 100;
        y = (evt.pageY - top) / el.outerHeight() * 100;
      } else {
        x = (evt.pageX - left);
        y = (evt.pageY - top);
      }
    
      return {
        x: Math.round(x),
        y: Math.round(y)
      };
    }
    
    $(".card").mousemove(function(e) {
      var hp = ThzhotspotPosition(e, $(this), true); // true = percent | false or no attr = px
    
      if (hp.x >= 50 && hp.y >= 50) {
        $(this).removeClass(function(index, className) {
          return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
        }).addClass("roll-BR");
      } else if (hp.x >= 50 && hp.y < 50) {
        $(this).removeClass(function(index, className) {
          return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
        }).addClass("roll-TR");
      } else if (hp.x < 50 && hp.y >= 50) {
        $(this).removeClass(function(index, className) {
          return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
        }).addClass("roll-BL");
      } else {
        $(this).removeClass(function(index, className) {
          return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
        }).addClass("roll-TL");
      }
    
      $('#debug').text(hp.x + '%x' + ' ' + hp.y + '%y');
    });
    
    
    $(".card").hover(
      function(e) {
        //$( this ).addClass( "roll-left" );
    
      },
      function() {
        $(this).removeClass(function(index, className) {
          return (className.match(/(^|\s)roll-\S+/g) || []).join(' ');
        });
      }
    );
    .card {
      width: 200px;
      height: 280px;
      background: red;
      position: relative;
      transition: transform 1s;
      transform-style: preserve-3d;
    }
    
    /*the backside*/
    .card:after{
      content:'';
      position:absolute;
      left:0;top:0;right:0;bottom:0;
      background: gray;
      transform: translateZ(-10px);
    }
    
    .card.roll-TL {
      transform: rotate3d(1, -1, 0, 20deg);
    }
    
    .card.roll-TR {
      transform: rotate3d(-1, -1, 0, -20deg);
    }
    
    .card.roll-BL {
      transform: rotate3d(-1, -1, 0, 20deg);
    }
    
    .card.roll-BR {
      transform: rotate3d(1, -1, 0, -20deg);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="card">Testing</div>
    <div id="debug"></div>

    【讨论】:

    • 当我运行你的时,它看起来仍然像底部被抬起并且顶部被向下推而不是相反。
    • @Danny 应该是正确的。只是因为没有影子,你无法分辨。
    • 我想知道这是否只是一个视觉透视的东西。当您将纯色块替换为扑克牌时,它会更加明显,它只是在顶部“看起来”正确而在底部看起来是错误的。您知道是否可以投射阴影或做任何有助于使其在底部的视觉上看起来正确的事情?
    • 我编辑了 OP 并添加了一个根据位置变化的阴影,看看是否有帮助,但它仍然看起来不正常。可能只是我自己,它在技术上是正确的,只是在进行眼花缭乱。
    • @Danny 我尝试添加一个背面(使用伪元素,但您也可以使用真实元素,如果需要,您可以添加所有 6 面),我认为现在看起来更好。
    猜你喜欢
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 2013-08-18
    • 2013-05-12
    • 2021-08-31
    • 1970-01-01
    相关资源
    最近更新 更多