实现随鼠标移动旋转的3D卡片

最近在做公司新产品的官网,偶然发现一个特别炫酷的卡片效果效果如下:

实现随鼠标移动旋转的3D卡片

自己研究了一下,尝试手动实现一个,以下是实现思路,码上掘金代码片段在最下方👇

第一步:先画一个带阴影的卡片

<div class="card">跟随鼠标移动的3D卡片</div>

第二步:添加css样式

.card {
  --rotateX: 0; // rotateX变量
  --rotateY: 0; // rotateY变量
  --scale3d: 1; // scale3d变量
  width: 200px;
  height: 300px;
  background-color: #007873;
  color: #fff;
  line-height: 300px;
  text-align: center;
  border-radius: 8px;
  transition: all 0.8s cubic-bezier(0.165, 0.84, 0.44, 1);
  box-shadow: 20px 10px 58px rgba(0, 0, 0, 0.3);
  transform-style: preserve-3d;
  transform: perspective(3000px) rotateY(var(--rotateX)) rotateX(var(--rotateY))
    scale3d(var(--scale3d), var(--scale3d), var(--scale3d));
}

transform-style: preserve-3d;CSS的一个属性,主要用于3D变换。

  • 默认值flat:元素不会在3D空间中呈现,而是被渲染为平面的,并且没有Z轴变换。
  • preserve-3d:元素会在3D空间中呈现,并保留其Z轴变换。具体细节详见MDN

transform

  • perspective透视定义了观察者与Z=0平面的距离,它影响元素看起来有多大以及它们如何随着距离变远而变小。具体细节详见MDN
  • rotateY元素绕纵轴(Y轴)旋转。rotateX元素绕横轴(X轴)旋转。scale3d元素3D缩放。

第三步:添加事件,处理元素旋转角度

function setElementRotate(element, rotateX, rotateY, scale3d) {
  element.style.setProperty("--rotateX", rotateX + "deg");
  element.style.setProperty("--rotateY", rotateY + "deg");
  element.style.setProperty("--scale3d", scale3d);
}

function rotateElement(event, element) {
  const x = event.clientX;
  // clientX 鼠标指针相对于当前窗口的水平坐标
  // offsetX 鼠标指针相对于目标元素边缘位置的水平坐标
  // 如果元素不在窗口左上角,建议使用 offsetX
  // event.offsetX
  const y = event.clientY;
  // event.offsetY

  const middleX = element.clientWidth / 2;
  const middleY = element.clientHeight / 2;

  const offsetX = ((x - middleX) / middleX) * 10;
  const offsetY = ((y - middleY) / middleY) * 10;

  setElementRotate(element, offsetX, -1 * offsetY, 1.04);
}

const initRotate = (element) => {
  element.addEventListener("mouseenter", function (e) {
    rotateElement(e, element);
  });
  element.addEventListener("mousemove", function (e) {
    rotateElement(e, element);
  });
  element.addEventListener("mouseleave", function () {
    setElementRotate(element, 0, 0, 1);
  });
};

initRotate(document.querySelector(".card"));


元素mouseenter mouseleave 事件触发rotateElement函数执行,rotateElement通过计算鼠标当前的位置,以及元素宽高的一半

其中旋转的逻辑主要在rotateElement函数中,以X轴为例:

  • -90deg代表元素沿着X轴向左旋转90度,从正面看上去就是一条直线,而需求是卡片能在一个较小的阈值能旋转。
  • 我们希望当鼠标在元素的最左侧的时候,得到的值是-1,鼠标在元素最右侧的时候,得到的值是1,鼠标在元素中间位置的时候得到的值是0,这样根据自身需求只需要再✖️一个阈值就可以。
  • 假设鼠标移动事件的event.clientXx,需要得到的值为y,元素宽度element.clientWidthcw,然后使用AI工具即得如下公式👇

实现随鼠标移动旋转的3D卡片

稍微简化一下就是目前代码中的逻辑,10为自定义的阈值,数值越大倾斜角越大

const middleX = element.clientWidth / 2; 
const middleY = element.clientHeight / 2; 
const offsetX = ((x - middleX) / middleX) * 10;
const offsetY = ((y - middleY) / middleY) * 10;

完结,撒花✿✿ヽ(°▽°)ノ✿,如有不妥请JYM指点🤗

原文链接:https://juejin.cn/post/7356240651040636943 作者:fe_jh

(0)
上一篇 2024年4月13日 下午4:28
下一篇 2024年4月13日 下午4:38

相关推荐

发表回复

登录后才能评论