Maison  >  Article  >  interface Web  >  Utilisez intelligemment CSS pour réaliser l'effet de rotation 3D suivant la souris, rendant l'interaction plus vivante !

Utilisez intelligemment CSS pour réaliser l'effet de rotation 3D suivant la souris, rendant l'interaction plus vivante !

青灯夜游
青灯夜游avant
2022-09-06 10:34:322622parcourir

Cet article vous expliquera comment utiliser CSS pour obtenir un effet de rotation 3D intéressant avec le suivi de la souris, rendant l'interaction plus vivante. J'espère que cela sera utile à tout le monde !

Utilisez intelligemment CSS pour réaliser l'effet de rotation 3D suivant la souris, rendant l'interaction plus vivante !

Aujourd'hui, un groupe d'amis a posé une question sur la manière de mettre en œuvre l'effet d'interaction suivant la souris, comme indiqué ci-dessous :

Une brève analyse montre que cet effet d'interaction a principalement deux noyaux :

  • Avec l'aide de Sans la capacité de CSS 3D

  • La rotation des éléments doit être combinée avec le mouvement de la souris

Cet article décrira comment utiliser du CSS pur pour obtenir des effets interactifs similaires et utiliser JavaScript pour liez les événements de la souris pour restaurer rapidement l'effet ci-dessus. [Apprentissage recommandé : Tutoriel vidéo CSS]

CSS pur pour implémenter la rotation 3D des éléments

Comment obtenir un effet de rotation 3D similaire sans JavaScript, juste CSS ?

Une petite astuce appelée annulation de rotation positive et négative ou annulation de rotation positive et négative sera utilisée ici. Eh bien, le nom est très étrange, cela ressemble à un concept mathématique.

En animation, la rotation est un attribut très couramment utilisé

{
  transform: rotate(90deg);
}

Que se passera-t-il si nous ajoutons une rotation dans différentes directions à des éléments à différents niveaux ?

Prenons d'abord le scénario. Nous avons une telle couche de structure HTML :

<div>
    <div>
        <div>正负旋转相消3D动画</div>
    </div>
</div>

Le style est le suivant :

.content est notre contenu principal. Si l'élément parent .rotate effectue une rotation linéaire avant de 360° et que l'élément parent le plus à l'extérieur .reverseRotate effectue une rotation linéaire inverse de 360°, quel sera l'effet ? .content 内是我们的主要内容,好了,现在想象一下,如果父元素 .rotate 进行正向 linear 360° 旋转,最外层的父级元素 .reverseRotate 进行反向 linear 360° 旋转,效果会是啥样?

CSS 代码如下:

.rotate {
    animation: rotate 5s linear infinite;
}
.reverseRotate {
    animation: reverseRotate 5s linear infinite;
}
@keyframes rotate {
    100% {
        transform: rotate(360deg);
    }
}
@keyframes reverseRotate {
    100% {
        transform: rotate(-360deg);
    }
}

我们可以得到这样一种动画(注意,下图是 GIF 不是 PNG):

神奇!因为一正一反的旋转,且缓动函数一样,所以整个 .content 看上去依然是静止的!注意,这里整个 .content 静止的非常重要。

有读者看到这里就要骂人了,作者你个智障,静止了不就没动画了吗?哪来的动画技巧?

别急!虽然看上去是静止的,但是其实祖先两个元素都是在旋转的!这会看上去风平浪静的效果底下其实是暗流涌动。用开发者工具选取最外层祖先元素是这样的:

既然如此,我们继续思考,如果我在其中旋转的一个父元素上,添加一些别的动画会是什么效果?想想就很刺激。

首先,我们先给这几个元素添加 CSS 3D 转换:

div {
    transform-style: preserve-3d;
    perspective: 100px;
}

接着,尝试修改上面的旋转动画,在内层旋转上额外添加一个 rotateX:

@keyframes rotate {
    0% {
        transform: rotateX(0deg) rotateZ(0deg);
    }
    50% {
        transform: rotateX(40deg) rotateZ(180deg);
    }
    100% {
        transform: rotateX(0deg) rotateZ(360deg);
    }
}

效果如下:

Wow,这里需要好好理解一下。由于内容 .content 层是静止的但其实外层两个图层都在旋转,通过设置额外的 rotateX(40deg),相当于叠加多了一个动画,由于正反旋转抵消了,所有整个动画只能看到旋转的 rotateX(40deg)

Le code CSS est le suivant :

    <div></div>
On peut obtenir une telle animation (notez que l'image ci-dessous est un GIF, pas un PNG) :

Incroyable ! Parce que l'un tourne vers l'avant et l'autre vers l'arrière, et que la fonction d'accélération est la même, l'ensemble du .content semble toujours stationnaire ! Notez qu'il est très important que l'intégralité du .content soit statique ici.

Certains lecteurs sont sur le point de jurer en voyant ça. Auteur, vous êtes une personne attardée, n'y aura-t-il pas d'animation ? Où avez-vous acquis vos compétences en animation ?

Ne vous inquiétez pas ! Bien qu'ils semblent stationnaires, les deux éléments ancêtres tournent en réalité ! Cela peut sembler être un effet de calme, mais il s’agit en réalité d’un courant sous-jacent. L'utilisation des outils de développement pour sélectionner l'élément ancêtre le plus externe ressemble à ceci :

    Dans ce cas, continuons à y réfléchir, quel sera l'effet si j'ajoute d'autres animations à un élément parent qui pivote ? C’est excitant d’y penser.
  • Tout d'abord, ajoutons une transformation CSS 3D à ces éléments :

    body {
        width: 100vw;
        height: 100vh;
        transform-style: preserve-3d;
        perspective: 500px;
    }
    
    div {
        width: 200px;
        height: 200px;
        background: #000;
        transform-style: preserve-3d;
    }
  • Ensuite, essayez de modifier l'animation de rotation ci-dessus et d'ajouter un rotateX supplémentaire à la rotation interne :
  • div {
         transform: rotateX(15deg) rotateY(30deg);
    }

    L'effet est le suivant :

Wow, cela doit être compris attentivement. Étant donné que la couche de contenu .content est statique mais que les deux couches externes tournent réellement, en définissant un rotateX(40deg) supplémentaire, cela équivaut à superposer une animation supplémentaire, puisque. les rotations avant et arrière sont décalées, toute l'animation entière ne peut voir que l'animation rotateX(40deg) pivotée, qui produit l'effet ci-dessus. De cette façon, sans intervention de JavaScript, nous simulons l'effet 3D présenté dans l'image du titre. Bien entendu, cela ne suffit pas à lui seul pour établir un lien avec l'utilisateur. Si cela doit être combiné avec le mouvement de la souris, nous aurons besoin de l'aide de JavaScript.

Utilisez Javascript pour réaliser l'effet de rotation 3D de la souris

Notre objectif est d'obtenir un tel effet d'animation :

🎜Ici, nous avons en fait deux éléments principaux :🎜🎜🎜🎜Zone d'activité de la souris🎜🎜🎜 🎜L'objet rotatif lui-même🎜🎜🎜🎜Le mouvement de la souris dans la 🎜zone d'activité de la souris🎜 affectera la rotation 3D de 🎜l'objet rotatif lui-même🎜, et la direction de rotation peut en fait être décomposée dans la direction de l'axe X et la direction de l’axe Y. 🎜🎜Jetons un coup d'oeil, en supposant que notre structure HTML est la suivante : 🎜
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");

mouseOverContainer.onmousemove = function(e) {
  let box = element.getBoundingClientRect();
  let calcY = e.clientX - box.x - (box.width / 2);
    
  element.style.transform  = "rotateY(" + calcY + "deg) ";
}
🎜Obtenez un tel graphique : 🎜🎜🎜🎜

这里,body 的范围就是整个鼠标可活动区域,也是我们添加鼠标的 mousemove 事件的宿主 target,而 #element 就是需要跟随鼠标一起转动的旋转物体本身。

因为整个效果是需要基于 CSS 3D 的,我们首先加上简单的 CSS 3D 效果:

body {
    width: 100vw;
    height: 100vh;
    transform-style: preserve-3d;
    perspective: 500px;
}

div {
    width: 200px;
    height: 200px;
    background: #000;
    transform-style: preserve-3d;
}

效果如下:

没有什么不一样。这是因为还没有添加任何的 3D 变换,我们给元素添加 X、Y 两个方向的 rotate() 试一下(注意,这里默认的旋转圆心即是元素中心):

div {
     transform: rotateX(15deg) rotateY(30deg);
}

效果如下,是有那么点意思了:

好,接下来,我们的目标就是通过结合 mouseover 事件,让元素动起来。

控制 X 方向的移动

当然,为了更加容易理解,我们把动画拆分为 X、Y 两个方向上的移动。首先看 X 方向上的移动:

Utilisez intelligemment CSS pour réaliser leffet de rotation 3D suivant la souris, rendant linteraction plus vivante !

这里,我们需要以元素的中心为界:

  • 当鼠标在中心右侧连续移动,元素绕 Y 轴移动,并且值从 0 开始,越来越大,范围为(0, +∞)deg

  • 反之,当鼠标在中心左侧连续移动,元素绕 Y 轴移动,并且值从 0 开始,越来越小,范围为(-∞, 0)deg

这样,我们可以得到这样一个公式:

rotateY = (鼠标 x 坐标 - 元素左上角 x 坐标 - 元素宽度的一半)deg

通过绑定 onmousemove 事件,我们尝试一下:

const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");

mouseOverContainer.onmousemove = function(e) {
  let box = element.getBoundingClientRect();
  let calcY = e.clientX - box.x - (box.width / 2);
    
  element.style.transform  = "rotateY(" + calcY + "deg) ";
}

效果如下:

Utilisez intelligemment CSS pour réaliser leffet de rotation 3D suivant la souris, rendant linteraction plus vivante !

好吧,旋转的太夸张了,因此,我们需要加一个倍数进行控制:

const multiple = 20;
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");

mouseOverContainer.onmousemove = function(e) {
  let box = element.getBoundingClientRect();
  let calcY = (e.clientX - box.x - (box.width / 2)) / multiple;
    
  element.style.transform  = "rotateY(" + calcY + "deg) ";
}

通过一个倍数约束后,效果好了不少:

控制 Y 方向的移动

同理,我们利用上述的方式,同样可以控制 Y 方向上的移动:

const multiple = 20;
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");

mouseOverContainer.onmousemove = function(e) {
  let box = element.getBoundingClientRect();
  let calcX = (e.clientY - box.y - (box.height / 2)) / multiple;
    
  element.style.transform  = "rotateX(" + calcX + "deg) ";
};

效果如下:

当然,在这里,我们会发现方向是元素运动的方向是反的,所以需要做一下取反处理,修改下 calcX 的值,乘以一个 -1 即可:

let calcX = (e.clientY - box.y - (box.height / 2)) / multiple * -1;

结合 X、Y 方向的移动

OK,到这里,我们只需要把上述的结果合并一下即可,同时,上面我们使用的是 onmousemove 触发每一次动画移动。现代 Web 动画中,我们更倾向于使用 requestAnimationFrame 去优化我们的动画,确保每一帧渲染一次动画即可。

完整的改造后的代码如下:

const multiple = 20;
const mouseOverContainer = document.getElementsByTagName("body")[0];
const element = document.getElementById("element");

function transformElement(x, y) {
  let box = element.getBoundingClientRect();
  let calcX = -(y - box.y - (box.height / 2)) / multiple;
  let calcY = (x - box.x - (box.width / 2)) / multiple;
  
  element.style.transform  = "rotateX("+ calcX +"deg) "
                        + "rotateY("+ calcY +"deg)";
}

mouseOverContainer.addEventListener('mousemove', (e) => {
  window.requestAnimationFrame(function(){
    transformElement(e.clientX, e.clientY);
  });
});

至此,我们就能简单的实现题图所示的鼠标跟随 3D 旋转动效:

设置平滑出入

现在,还有最后一个问题,就是当我们的鼠标离开活动区域时,元素的 transform 将停留在最后一帧,正确的表现应该是复原到原状。因此,我们还需要添加一些事件监听做到元素的平滑复位。

通过一个 mouseleave 事件配合元素的 transition 即可。

div {
    // 与上述保持一致...
    transition: all .1s;
}
mouseOverContainer.addEventListener('mouseleave', (e) => {
  window.requestAnimationFrame(function(){
    element.style.transform = "rotateX(0) rotateY(0)";
  });
});

至此,我们就可以完美的实现平滑出入,整体效果最终如下:

完整的代码,你可以戳这里:CodePen Demo -- CSS 3D Rotate With Mouse Move

(学习视频分享:web前端

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer