상호작용을 더욱 생생하게 만들어보세요! 마우스를 따라가는 3D 회전 효과를 얻기 위해 CSS를 기발하게 사용

青灯夜游
풀어 주다: 2023-01-18 21:06:04
앞으로
1598명이 탐색했습니다.

이 기사에서는 CSS를 사용하여 마우스를 따라가는 흥미로운 3D 회전 효과를 구현하고 상호 작용을 더욱 생생하게 만드는 방법을 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.

상호작용을 더욱 생생하게 만들어보세요! 마우스를 따라가는 3D 회전 효과를 얻기 위해 CSS를 기발하게 사용

오늘 친구 그룹이 아래와 같이 마우스 팔로우 상호작용 효과를 구현하는 방법에 대해 질문했습니다.

간단한 분석에 따르면 이 상호작용 효과는 주로 두 개의 코어로 구성됩니다.

  • With CSS 3D 기능이 없는 경우

  • 요소의 회전은 마우스의 움직임과 결합되어야 합니다

이 문서에서는 순수 CSS를 사용하여 유사한 대화형 효과를 얻는 방법과 JavaScript를 사용하여 다음을 수행하는 방법을 설명합니다. 위의 효과를 빠르게 복원하려면 마우스 이벤트를 바인딩하세요. [추천 학습: css 비디오 튜토리얼]

요소의 3D 회전을 구현하는 순수 CSS

JavaScript 없이 CSS만으로 유사한 3D 회전 효과를 얻는 방법은 무엇입니까?

여기에서는 양 및 음의 회전 취소 또는 양 및 음의 회전 취소라는 작은 트릭이 사용됩니다. 글쎄요, 이름이 참 이상하네요. 마치 수학적 개념처럼 보이네요.

애니메이션에서 회전은 매우 일반적으로 사용되는 속성입니다.

{
  transform: rotate(90deg);
}
로그인 후 복사

서로 다른 레벨의 요소에 서로 다른 방향으로 회전을 추가하면 어떻게 될까요?

먼저 다음과 같은 HTML 구조 레이어가 있다고 가정합니다.

<div>
    <div>
        <div>正负旋转相消3D动画</div>
    </div>
</div>
로그인 후 복사

스타일은 다음과 같습니다.

.content가 주요 콘텐츠입니다. 상위 요소 .rotate가 정방향 선형 360° 회전을 수행하고 가장 바깥쪽 상위 요소 .reverseRotate가 역방향 선형 360° 회전을 수행하는 경우 효과는 어떻게 될까요? .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)

CSS 코드는 다음과 같습니다:

    <div></div>
로그인 후 복사
그러한 애니메이션을 얻을 수 있습니다(아래 그림은 PNG가 아니라 GIF입니다):

놀라워요! 하나는 앞으로 회전하고 다른 하나는 역방향으로 회전하고 이징 기능이 동일하기 때문에 전체 .content는 여전히 정지된 것처럼 보입니다! 여기에서는 전체 .content가 정적이라는 것이 매우 중요합니다.

이거 보면 욕할 것 같은 작가님, 멈추면 애니메이션이 안 나오는 거 아닌가요? 애니메이션 기술은 어디서 얻었나요?

걱정하지 마세요! 정지해 있는 것처럼 보이지만 조상의 두 요소는 실제로 회전하고 있습니다! 이는 차분한 효과처럼 보일 수 있지만 그 밑에는 실제로 저류가 있습니다. 개발자 도구를 사용하여 가장 바깥쪽 조상 요소를 선택하는 방법은 다음과 같습니다.

    이런 경우, 회전하는 부모 요소에 다른 애니메이션을 추가하면 어떤 효과가 있을지 계속 생각해 볼까요? 생각만 해도 신난다.
  • 먼저 다음 요소에 CSS 3D 변환을 추가해 보겠습니다.

    body {
        width: 100vw;
        height: 100vh;
        transform-style: preserve-3d;
        perspective: 500px;
    }
    
    div {
        width: 200px;
        height: 200px;
        background: #000;
        transform-style: preserve-3d;
    }
    로그인 후 복사
    로그인 후 복사
  • 그런 다음 위의 회전 애니메이션을 수정하고 내부 회전에 추가rotateX를 추가해 보세요.
  • div {
         transform: rotateX(15deg) rotateY(30deg);
    }
    로그인 후 복사
    로그인 후 복사

    효과는 다음과 같습니다.

와우, 이건 주의 깊게 이해해야 합니다. 콘텐츠 .content 레이어는 정적이지만 두 개의 외부 레이어가 실제로 회전하므로 추가 rotateX(40deg)를 설정하면 추가 애니메이션을 겹쳐놓는 것과 같습니다. 정방향 및 역방향 회전이 오프셋되어 전체 애니메이션에서 위의 효과를 생성하는 회전된 rotateX(40deg) 애니메이션만 볼 수 있습니다. 이런 방식으로 JavaScript 개입 없이 제목 그림에 표시된 3D 효과를 시뮬레이션합니다. 물론 이것만으로는 사용자와 연결하기에는 충분하지 않습니다. 마우스 움직임과 결합되어야 한다면 JavaScript의 도움이 필요합니다.

Javascript를 사용하여 3D 회전 효과에 따른 마우스 구현

우리의 목표는 이러한 애니메이션 효과를 달성하는 것입니다.

🎜여기에는 실제로 두 가지 핵심 요소가 있습니다.🎜🎜🎜🎜마우스 활동 영역🎜🎜🎜 🎜회전하는 개체 자체🎜🎜🎜🎜🎜마우스 활동 영역🎜 내에서 마우스의 움직임은 🎜회전하는 개체 자체🎜의 3차원 회전에 영향을 미치며, 회전 방향은 실제로 X축 방향으로 분해되어 Y축 방향. 🎜🎜HTML 구조가 다음과 같다고 가정하고 살펴보겠습니다. 🎜
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) ";
}
로그인 후 복사
로그인 후 복사
🎜다음과 같은 그래픽 가져오기: 🎜🎜🎜🎜

这里,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 方向上的移动:

상호작용을 더욱 생생하게 만들어보세요! 마우스를 따라가는 3D 회전 효과를 얻기 위해 CSS를 기발하게 사용

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

  • 当鼠标在中心右侧连续移动,元素绕 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) ";
}
로그인 후 복사
로그인 후 복사

效果如下:

상호작용을 더욱 생생하게 만들어보세요! 마우스를 따라가는 3D 회전 효과를 얻기 위해 CSS를 기발하게 사용

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

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前端

위 내용은 상호작용을 더욱 생생하게 만들어보세요! 마우스를 따라가는 3D 회전 효과를 얻기 위해 CSS를 기발하게 사용의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
css
원천:cnblogs.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!