• 日常搜索
  • 百度一下
  • Google
  • 在线工具
  • 搜转载

使用CSS3的透视属性创建3D感

使用CSS3的透视属性创建3D感  第1张你将要创建的内容

在本教程中,我们将使用 css3 透视属性创建一个交互式元素,以提供三维感。本教程还将教您如何使用 jquery 和鼠标事件来获取javascript中的元素位置以及如何操作 CSS 属性。

透视属性的 html 结构

我们需要一个父子关系才能使透视属性正常工作。让我们首先创建 HTML 结构,然后继续 CSS 样式。

<div id="mainWrapper">
  <div id="cardsWrapper">
    
    <div class="card">
      <div class="image first">
        <div class="screen"></div>
        <div class="text">
            <p>Mountain</p>
            <p>5 Days</p>
        </div>
      </div>
    </div>
    
    <div class="card">
      <div class="image second">
        <div class="screen"></div>
        <div class="text">
            <p>Island</p>
            <p>2 Days</p>
        </div>
      </div>
    </div>
    
  </div>  
</div>

在这里,我们将两个 card元素包装到一个 id 为 的 div 中 cardsWrapper此外,它 cardsWrapper被包装到另一个 div 中,以便能够轻松地操纵其在视口中的位置。

每个具有类 of 的元素card都有一个 image元素,该元素包含 screen和 text元素。结构暂时有点模糊,但我会在接下来的相关章节中解释每个元素的用法。

让我们使用以下 CSS 样式来定位我们的元素。

#mainWrapper{
  display: flex;
  justify-content: center;
  align-items: center;
  height: 350px;
}

#cardsWrapper{
  display: flex;
  justify-content: space-between;
  width: 700px;
}

.card{
  width: 300px;
  height: 175px;
  background-color: red;
}

.image{
  width: 100%;
  height: 100%;
  background-color: red;
}

使用透视属性

perspective属性是您必须在父 div 中设置的内容,其中包含您要使用透视感进行转换的 div。想象一下父 div 是您的世界,它具有您正在体验的特定视角值。

让我们将 perspective属性添加到我们的父 div,即card我们选择 card元素作为父元素,而不是 cardsWrapper,因为我们希望对每个卡片元素都有单独的透视效果。

调整 CSS card 如下。

.card{
  width: 300px;
  height: 175px;
  background-color: red;
  perspective: 500px;
}

现在尝试为 transform图像元素添加一个属性以查看透视效果。

.image{
  width: 100%;
  height: 100%;
  background-color: red;
  transform: rotateX(30deg);
}

使用CSS3的透视属性创建3D感  第2张

由于 image 是 的直接子代 card,因此受透视图的影响。但是,如果您尝试将 transform属性添加到 的任何子级 image,这将不起作用。

为了使这些子元素相对于它们的父 image 元素(本示例中的元素)进行转换,您应该 transform-style: preserve-3d在父元素上使用。

.image{
  width: 100%;
  height: 100%;
  transform-style: preserve-3d;
  transform: rotateX(30deg);
}

现在我们在透视属性中有足够的背景知识,并准备继续为其他元素设置样式。

不要忘记 transform: rotateX(30deg)从图像元素中删除 。

设计卡片样式

我们有一个image 元素,在它之上我们有一个名为 的元素 screen,然后是 text由于我们在这里使用透视,您可以将这些元素中的每一个视为单独的层。

现在我们将背景图像添加到我们的 imagediv 中,然后设置 screen和 text元素的样式。

让我们使用以下 CSS 样式为每个卡片对象添加背景图像。

.image.first{
  background-image: url("https://c1.staticflickr.com/1/343/31652757460_b2b5794a51_n.jpg");
}

.image.second{
  background-image: url("https://c2.staticflickr.com/2/1506/25121644830_2d768ef51a_n.jpg");
}

现在我们将为 screen元素设置样式。

由于我们希望 screen元素的大小与其父元素完全相同 image,因此我们使用 100% 的宽度和高度值以及带有 alpha 通道的灰黑色背景色。

导入部分是 transform: translateZ(30px) scale(0.940).

所以这里我们只是将 screenZ 轴上的元素平移 20px。这使它悬停在 image元素上。由于它是朝向我们的,由于透视规则,它的尺寸会更大。因此,我们将其缩小以匹配父元素的大小。如果您使用不同的平移值,则比例值会有所不同。同样,为父元素定义不同的高度和宽度大小将导致需要不同的缩放值。

.screen{
  background-color: rgba(0, 0, 0, 0.22);
  width: 100%;
  height: 100%;
  transform: translateZ(30px) scale(0.940);
}

为了了解这里发生了什么,只需将以 image下行添加到 CSS 规则中,围绕 X 和 Y 轴旋转您的元素:

transform: rotateX(30deg) rotateY(30deg)

现在本节的最后一部分是对 text元素进行样式设置,这非常简单。

我们基本上对元素使用相同的变换设置, text以使其与元素处于同一级别 screenCSS的其余部分只是简单的样式。您可以按照自己喜欢的方式对其进行调整。

.text{
  position: absolute;
  bottom: 25px;
  left: 30px;
  color: white;
  transform: translateZ(30px) scale(0.940);
}

.text p{
    cursor: default;
    padding: 0;
    margin: 0;
}

.text p:first-of-type{    font-size: 2em;
    margin-bottom: 5px;
}
.text p:last-of-type{
    font-size: 1em;
}

这是手动旋转的最终结果,看看效果。

使用CSS3的透视属性创建3D感  第3张

在继续之前,请从您的 CSS 中删除旋转规则,因为我们将根据光标位置自动控制旋转。

现在我们将编写一些 jQuery代码以使这些卡片具有交互性。

让我们开始吧!

添加与 jQuery 的交互

让我们从基本的 jQuery 代码开始。

(function($){

})(jQuery);

我们将在这个函数中编写所有内容。这将允许 jQuery 等到dom准备好。

由于我们有兴趣与我们的 card元素进行交互,因此我们需要选择它。

(function($){
    var card = $(".card");
})(jQuery);

下一步是在卡片元素上注册光标位置。为此,我们将使用内置 mousemove事件。

(function($){
    var card = $(".card");
    card.on('mousemove', function (e) {});
})(jQuery);

现在我们需要跟踪光标位置。获得正确的值有点棘手。

(function($){
    var card = $(".card");
    card.on('mousemove', function (e) {
        var x = e.clientX - $(this).offset().left + $(window).scrollLeft();
        var y = e.clientY - $(this).offset().top + $(window).scrollTop();
    });
})(jQuery);

在这里, e.clientX并 e.clientY返回视口内的光标位置。然而,由于每个 card对象都是相对于视口定位的,我们需要通过提取左侧和顶部偏移值来补偿这一点。

最后要考虑的也是最重要的事情是对窗口滚动的补偿。因此,由于您的光标位置是相对于您的视口注册的,但偏移值是固定的,因此当您滚动时,您的对象会根据您滚动的方向更靠近视口的顶部或左侧。 

结果,我们到视口顶部或左侧的相对距离会更小。然而,由于偏移值是固定的,我们需要对此进行补偿,这是通过 $(window).scrollLeft()and 来完成的$(window).scrollTop()因此,通过将这些值添加到相应的变量中,我们只是补偿了我们滚动的量。因此,当您将鼠标悬停在任何 card元素上时,您的 X 位置将介于 0 到卡片的宽度(定义为 300 像素)之间。同样,Y 位置的范围是从 0 到卡片的高度,即 175 像素。

下一步是将光标位置映射到一个新范围,这将是我们希望以度为单位应用的旋转量,这样当您的光标站在卡片元素的中间时,它看起来只是平坦的,但是当你移动到左/右或上/下时,你会得到一个旋转效果,就好像卡片跟随光标一样。

这是映射函数结果的快速说明。

使用CSS3的透视属性创建3D感  第4张

function map(x, in_min, in_max, out_min, out_max)
{
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

在这个函数中, in_min和 in_max参数分别是输入值的最小值和最大值,分别对应 card元素的宽度和高度。 out_min是输入将被映射的最小值和 out_max最大值。

让我们将这个地图函数与我们的 X 和 Y 光标位置一起使用。

(function($){
    var card = $(".card");
    card.on('mousemove', function (e) {
        var x = e.clientX - $(this).offset().left + $(window).scrollLeft();
        var y = e.clientY - $(this).offset().top + $(window).scrollTop();
        
        var rY = map(x, 0, $(this).width(), -17, 17);
        var rX = map(y, 0, $(this).height(), -17, 17);
    });
    
    function map(x, in_min, in_max, out_min, out_max)
    {
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
})(jQuery);

现在我们的映射值是 rXand  rY

下一步是 image通过使用映射值作为旋转值来为元素设置 CSS 规则。

(function($){
    var card = $(".card");
    card.on('mousemove', function (e) {
        var x = e.clientX - $(this).offset().left + $(window).scrollLeft();
        var y = e.clientY - $(this).offset().top + $(window).scrollTop();
        
        var rY = map(x, 0, $(this).width(), -17, 17);
        var rX = map(y, 0, $(this).height(), -17, 17);
    
        $(this).children(".image").css("transform", "rotateY(" + rY + "deg)" + " " + "rotateX(" + -rX + "deg)");
    });
        
    function map(x, in_min, in_max, out_min, out_max)
    {
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
})(jQuery);

这里我们选择了 card名为 的元素的子元素 image,然后设置 CSS 规则来分别绕 X 和 Y 轴旋转这个元素 rX和 rY度数。

使用CSS3的透视属性创建3D感  第5张

您将意识到卡片元素在各自的视角中跟随光标。但是,当光标离开卡片元素时,它们会保持其方向。此外,他们会对光标在卡片元素上的存在做出突然的反应。所以我们还需要处理鼠标进入和离开卡片元素的那些情况。

为了处理这些问题,我们需要使用 mouseenter和 mouseleave事件。

当鼠标进入 card元素的区域时,我们给元素添加一个过渡 CSS 规则 image这将使 image元素的“凝视”平滑过渡。

card.on('mouseenter', function () {
    $(this).children(".image").css({
            transition: "all " + 0.05 + "s" + " linear"
    });
});

同样,我们需要处理 mouseleave事件。

在这里,我还添加了另一个具有不同时序的过渡 CSS 规则,当鼠标离开 card元素时,它可以更平滑地过渡到初始位置。 

我还添加了变换 CSS 规则以重置 card元素的旋转。

card.on('mouseleave', function () {
    $(this).children(".image").css({
        transition: "all " + 0.2 + "s" + " linear"
    });

    $(this).children(".image").css("transform", "rotateY(" + 0 + "deg)" + " " + "rotateX(" + 0 + "deg)");
});

所以我们最终的 jQuery 代码如下所示:

(function($){
    var card = $(".card");
    card.on('mousemove', function (e) {
        var x = e.clientX - $(this).offset().left + $(window).scrollLeft();
        var y = e.clientY - $(this).offset().top + $(window).scrollTop();
        
        var rY = map(x, 0, $(this).width(), -17, 17);
        var rX = map(y, 0, $(this).height(), -17, 17);
    
        $(this).children(".image").css("transform", "rotateY(" + rY + "deg)" + " " + "rotateX(" + -rX + "deg)");
    });
    
    card.on('mouseenter', function () {
        $(this).children(".image").css({
            transition: "all " + 0.05 + "s" + " linear",
        });
    });

    card.on('mouseleave', function () {
        $(this).children(".image").css({
            transition: "all " + 0.2 + "s" + " linear",
        });

        $(this).children(".image").css("transform", "rotateY(" + 0 + "deg)" + " " + "rotateX(" + 0 + "deg)");
    });
        
    function map(x, in_min, in_max, out_min, out_max)
    {
        return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
    }
})(jQuery);

这是最终结果。我还在元素上使用了不同的无衬线字体 text以使其看起来更好。

使用CSS3的透视属性创建3D感  第6张

结论

在本教程中,我们学习了如何使用透视属性和所需的 HTML 结构使其正常工作。此外,我们还介绍了如何在鼠标悬停在特定 HTML 元素上时注册鼠标光标位置。

最重要的是,我们通过使用 jQuery 向 HTML 元素添加 CSS 规则来使用 mousemove、 mouseenter和 mouseleave事件来引入交互性。


文章目录
  • 透视属性的 html 结构
  • 使用透视属性
  • 设计卡片样式
  • 添加与 jQuery 的交互
  • 结论