搜尋
首頁web前端css教學巧用CSS實現滑鼠跟隨 3D 旋轉效果,讓互動更加生動!

這篇文章跟大家介紹如何使用CSS實現有趣的滑鼠跟隨 3D 旋轉效果,讓互動更加生動,希望對大家有幫助!

巧用CSS實現滑鼠跟隨 3D 旋轉效果,讓互動更加生動!

今天,群組朋友問了這樣一個問題,如下所示的滑鼠跟隨互動效果,如何實現:

#簡單分析一下,這個交互效果主要有兩個核心:

  • 借助了CSS 3D 的能力

  • 元素的旋轉需求和滑鼠的移動相結合

本文,就將講述如何使用純CSS 實現類似的互動效果,以及,借助JavaScript 綁定滑鼠事件,快速還原上述效果。 【推薦學習:css影片教學

純CSS 實作元素的3D 旋轉

如果不借助JavaScript,僅僅只是CSS,如何實現類似的3D 旋轉效果呢?

這裡會運用到一個名為正反旋轉相消或是正負旋轉相消的小技巧。嗯,名字取的很奇怪,好像數學概念一樣。

在動畫中,旋轉是非常常用的屬性,

{
  transform: rotate(90deg);
}

如果我們給不同的層級的元素,添加不同方向的旋轉,會發生什麼?

先假設場景,我們有這樣的一層HTML 結構:

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

樣式如下:

##.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) 這個動畫,產生了上述的效果。

這樣,在沒有 JavaScript 介入的情況下,我們就模擬了題圖所示的 3D 效果。當然,僅僅是這樣,與使用者的連動是不夠的,如果一定要結合滑鼠移動,我們就需要 JavaScript 的一些輔助了。

借助Javascript 實現滑鼠跟隨3D 旋轉動效

我們的目標是實現這樣一個動畫效果:

這裡,我們其實有兩個核心元素:

  • 滑鼠活動區域

  • 旋轉物件本身

#滑鼠在

滑鼠活動區域內的移動,會影響旋轉物件本身的3D 旋轉,而旋轉的方向其實可以被分解為X 軸方向與Y 軸方向。

我們來看一下,假設我們的 HTML 結構如下:

    <div></div>
得到這樣一個圖形:

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

巧用CSS實現滑鼠跟隨 3D 旋轉效果,讓互動更加生動!

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

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

效果如下:

巧用CSS實現滑鼠跟隨 3D 旋轉效果,讓互動更加生動!

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

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

以上是巧用CSS實現滑鼠跟隨 3D 旋轉效果,讓互動更加生動!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除
利用CSS怎么创建渐变色边框?5种方法分享利用CSS怎么创建渐变色边框?5种方法分享Oct 13, 2021 am 10:19 AM

利用CSS怎么创建渐变色边框?下面本篇文章给大家分享CSS实现渐变色边框的5种方法,希望对大家有所帮助!

css ul标签怎么去掉圆点css ul标签怎么去掉圆点Apr 25, 2022 pm 05:55 PM

在css中,可用list-style-type属性来去掉ul的圆点标记,语法为“ul{list-style-type:none}”;list-style-type属性可设置列表项标记的类型,当值为“none”可不定义标记,也可去除已有标记。

css与xml的区别是什么css与xml的区别是什么Apr 24, 2022 am 11:21 AM

区别是:css是层叠样式表单,是将样式信息与网页内容分离的一种标记语言,主要用来设计网页的样式,还可以对网页各元素进行格式化;xml是可扩展标记语言,是一种数据存储语言,用于使用简单的标记描述数据,将文档分成许多部件并对这些部件加以标识。

css3怎么实现鼠标隐藏效果css3怎么实现鼠标隐藏效果Apr 27, 2022 pm 05:20 PM

在css中,可以利用cursor属性实现鼠标隐藏效果,该属性用于定义鼠标指针放在一个元素边界范围内时所用的光标形状,当属性值设置为none时,就可以实现鼠标隐藏效果,语法为“元素{cursor:none}”。

css怎么实现英文小写转为大写css怎么实现英文小写转为大写Apr 25, 2022 pm 06:35 PM

转换方法:1、给英文元素添加“text-transform: uppercase;”样式,可将所有的英文字母都变成大写;2、给英文元素添加“text-transform:capitalize;”样式,可将英文文本中每个单词的首字母变为大写。

rtl在css是什么意思rtl在css是什么意思Apr 24, 2022 am 11:07 AM

在css中,rtl是“right-to-left”的缩写,是从右往左的意思,指的是内联内容从右往左依次排布,是direction属性的一个属性值;该属性规定了文本的方向和书写方向,语法为“元素{direction:rtl}”。

css怎么设置i不是斜体css怎么设置i不是斜体Apr 20, 2022 am 10:36 AM

在css中,可以利用“font-style”属性设置i元素不是斜体样式,该属性用于指定文本的字体样式,当属性值设置为“normal”时,会显示元素的标准字体样式,语法为“i元素{font-style:normal}”。

怎么设置rotate在css3的旋转中心点怎么设置rotate在css3的旋转中心点Apr 24, 2022 am 10:50 AM

在css3中,可以用“transform-origin”属性设置rotate的旋转中心点,该属性可更改转换元素的位置,第一个参数设置x轴的旋转位置,第二个参数设置y轴旋转位置,语法为“transform-origin:x轴位置 y轴位置”。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。