目錄
(scroll events)或背景定位(background-position " >事件(scroll events)或背景定位(background-position
perspective
为什么这种方案好用?
美中不足:Mobile Safari
固定定位的问题
花式bug和应对
结论
首頁 web前端 css教學 高性能的視差動畫【譯】

高性能的視差動畫【譯】

Apr 04, 2017 am 10:21 AM

高效能的視差動畫


##也好,恨也好,視差效果已經遍布web之上了。 。示意圖

摘要高性能的視差動畫【譯】

不要使用滾動

事件(scroll events)或背景定位(background-position

)來創建視差動畫。的Safari瀏覽器使用
    position: sticky
  • 來確保視差可以生效。 #JS

    ,這裡還有一個demo演示。為何它們不適合我們要追求的目標。 ,視差元素的位置也應被更新。被當作「盡量好」(best effort)的工作處理的,也就意味著:瀏覽器並不確保每一幀的滾動動畫送達!告訴我們為什麼要避免

    使用Javascript
  • 基於滾動事件去移動元素:
  • Javascript並不能確保視差會和頁面滾動保持相同的步調。滾動事件甚至是在滾動完成後才觸發的,這一點讓基於Javascript的滾動效果無法實現。 #ome一樣,它是一個基於「盡量好」的原則的。

    不好的方案:更新背景位置
  • 我們要避免的另一個場景是在每個畫面都進行繪製。許多方案試圖採用改變

    background-position 來提供視差效果, 但這會讓瀏覽器在滾動時重繪受影響的部分,而這可能會是相當消耗資源的,這種影響會使動畫卡頓。

    如果我們想提供一個高品質的視差動畫,我們想要的是一個可以當作加速的
  • 屬性
(這裡我們指的是

transformopacity

),而這是不依賴滾動事件的。

CSS 3D

Scott Kellum 和 Keith Clark 都已經在利用 CSS 3D 來實現視差效果領域做出了很重要的工作。他們採用的非常有效技術有:

建立一個容器元素,設定overflow-y: scroll

使其可以捲動(同時可能需要

overflow-x: hidden)。

對於上面的元素, 我們會套用一個

perspective

值,然後設定

perspective-origin

top

left, 或0 0

對上面元素的子元素套用 Z 軸的變換,然後把它們還原回來以實現視差效果,而不會影響它們在螢幕上的大小。

這種方案的CSS 看起來是下面的樣子:
    .container {
      width: 100%;
      height: 100%;
      overflow-x: hidden;
      overflow-y: scroll;
      perspective: 1px;
      perspective-origin: 0 0;
    }
    
    .parallax-child {
      transform-origin: 0 0;
      transform: translateZ(-2px) scale(3);
    }
    登入後複製
  1. 當然我們假定你的HTML 是下面的樣子:

    <p class="container”>
      <p class="parallax-child”></p>
    </p>
    登入後複製
    調整perspective的比例<a href="http://www.php.cn/wiki/926.html" target="_blank"></a>把子元素擠回來會要求它設定一個更小的相對於perspective 的比例。你可以透過下列等式來計算所需的縮放比例: <a href="http://www.php.cn/wiki/924.html" target="_blank"></a>(perspective - distance) / perspective。由於我們希望視差元素看起來和我們一開始設定的一樣大,所以它應該根據這樣的等式進行放縮而不是保持不變。
  2. 拿上面的例子来说, perspective1px, 而 parallax-child 在 Z 轴方向是 -2px,这就意味着元素需要被放大3倍,你可以看到我们在 scale 中写入了 3 这个值。

    对于任何没有应用 translateZ 的内容,你可以用 0 替代,也就是缩放比为 (perspective - 0) / perspective,结果为 1 ,即既不放大也不缩小。真的是非常方便。

    为什么这种方案好用?

    弄清楚为什么这种方案好用是非常重要的,因为我们很快就要使用这个知识了。滚动其实本质是一种变换,这是它为什么可以被加速的原因。滚动很大程度上使用GPU参与了图层的变换。一个常见的滚动(没有应用任何 perspective )是这样的:滚动这种情况下是以 1:1 的方式在对待滚动的元素和它的子元素。换人话说,如果你向下滚动一个元素 <a href="http://www.php.cn/code/4221.html" target="_blank">300</a>px,那么它的子元素向上变换了同样的数量: 300px

    但是,如果对这个滚动元素应用 perspective 值会把这个过程“搞乱”:这个值改变了滚动变换的理想路线。现在如果一个 300px 的滚动可能把子元素移动了 150px,当然这取决于你给 perspectivetranslateZ 设置什么值。如果一个 translateZ 设置为0的子元素,它的滚动会一切如常 ( 1:1 ),但是一个被推向 Z 轴向( translateZ 不为 0 )的子元素将以不同的比例滚动!因此出现了视差效果。另外非常重要的一点是:这个过程本身就是浏览器内部的滚动机制的一部分,因此没有必要监听滚动事件或者改变背景位置。

    美中不足:Mobile Safari

    每种效果都有一些约束,对于变换( transform )来讲,对子元素的 3D 效果的保持就是这样。如果在应用 perspective 的元素和它的“视差”子元素的结构之中有其它元素的存在,那么 3D 的效果会被“拍扁”,也就是说效果将不复存在。

    <p class="container”>
      <p class="parallax-container”>
        <p class="parallax-child”></p>
      </p>
    </p>
    登入後複製

    在上面的HTML中 .parallax-container 是一个新添加的元素,而它会"抹平" perspective,从而导致效果丢失。通常情况下,解决方案还是比较符合直觉的:给这个元素添加 transform-style: preserve-3d 以便让它可以把 3D 效果应用到更深层的节点去。

    .parallax-container {
      transform-style: preserve-3d;
    }
    登入後複製

    对于 Mobile Safari 来说,事情变的有点麻烦。对容器元素应用  overflow-y : 技术上这是没问题的,但是这会让滚动元素的移动过于凶猛。解决方案是加上一个  -webkit-overflow-scrolling: touch ,但这个设置会导致 perspective 被抹平,因此我们会得不到任何视差效果。

    从一个发展的角度看,这可能算不上什么问题(因为只在旧版本的 Mobile Safari 出现),即使我们无法在每一个浏览器中展现视差效果,但一个应用的功能还是好用的,但我们最好找出一个方案。

    position:sticky 来拯救

    事实上,我们可以从 position: sticky 中得到一些帮助,这个设置允许元素固定在 <a href="http://www.php.cn/css/css-rwd-viewport.html" target="_blank">viewport</a> 的顶部或者固定在一个滚动元素的父元素。这个属性的文档,就如同任何其它文档一样,又臭又长,但是还是可以找到一些有用信息:

    一个固定的“盒子”非常像一个相对定位的盒子,但是位移是通过引用最近的可滚动的祖先来计算的,或者根据 viewport 来计算,如果找不到这样一个祖先的话 -- CSS Positioned Layout Module Level 3

    第一眼看上去好像帮助不大,但一个关键点在句中说到如何计算元素的固定位置的那部分:“位移是通过引用最近的可滚动的祖先来计算的”。换句话说,移动固定元素的距离(为了让它看起来是固定在某个元素或者 viewport 上)是在应用其它任何变换之前进行计算的,而不是之后。这就意味着,和我们刚才说的滚动的那个例子很像,如果位移计算的结果是 300px,那么我们就有了一个新的机会去使用 perspective (或者其它任何变换)来在这个 300px 应用到固定元素之前去改变它。

    通过给视差元素设置 position: -webkit-sticky,我们可以有效的“翻转”那个由于 -webkit-overflow-scrolling: touch 而产生的“抹平”效果。这样就确保了视差元素引用最近的可滚动的祖先元素,这里就是 .container 。然后,和上文讲的类似,给 .parallax-container 设置一个 perspective 值,这样就改变了计算的滚动位移,创建出了视差效果。

    <p class="container”>
      <p class="parallax-container”>
        <p class="parallax-child”></p>
      </p>
    </p>
    
    .container {
      overflow-y: scroll;
      -webkit-overflow-scrolling: touch;
    }
    
    .parallax-container {
      perspective: 1px;
    }
    
    .parallax-child {
      position: -webkit-sticky;
      top: 0px;
      transform: translate(-2px) scale(3);
    }
    登入後複製

    这样就为 Mobile Safari 恢复了视差效果,真是一个不错的结果。

    固定定位的问题

    和之前的方案确实还有一个明显区别, position: sticky 改变了视差的机制。固定定位试图固定某个元素在滚动容器顶端,而非固定元素不是。这就意味着固定定位产生的视差和非固定产生的色差是相反的:

  • 使用 position: sticky: 元素离 z=0 越近,它移动的越少

  • 不使用 position: sticky: 元素离 z=0 越近,它移动的越多

如果你还是感到有些抽象的话,可以看一下Robert Flack的这个demo,这个demo展示了在固定定位和非固定定位的条件下,元素是如何有不同的表现的。要看到这个效果的话,你需要 Chrome Canary (写作本文是,版本为56) 或者 Safari 。

高性能的視差動畫【譯】

position: sticky 对视差的影响

花式bug和应对

如同任何事情一样,还是有很多的坑需要填。

  • 固定定位的支持是不一致的:当前在 Chrome 中对于这个特性还在开发中,Edge 则完全缺失,FireFox则有绘制的bug。在这种情况下,我们应该增加一点代码来在需要时(这里就是 Mobile Safari )才添加 position: sticky

  • 该效果在 Edge 中完全没有作用。Edge试图在OS级别处理滚动,通常情况下这是个好事。但在这个例子中,这种机制会使得我们无法在滚动时去应用 perspective。为了修复这个问题,我们可以为父元素 设置 `translateZ(0px)``。

  • 页面内容太大了:在决定页面内容有多大时,很多浏览器负责放缩,但很遗憾 Chrome 和 Safari 不负责。所以假如有一个放大 3 倍的变换应用到某个元素时,你可能会看到滚动条出现了,而且一旦出现后,即使之后你恢复了 1:1 的比例,滚动条也不会消失。有一个方法可以避免这种情况:那就是从右下角进行放缩( transform-origin: <a href="http://www.php.cn/wiki/906.html" target="_blank">bottom</a> <a href="http://www.php.cn/wiki/905.html" target="_blank">right</a> )。这种方案背后的原理是它会导致过大的元素进入滚动区域的“负面”(一般是左上),而滚动区域永远不会让你看到“负面”区域。

结论

视差动画如果经过的周全的设计考虑后会是一个非常有趣的效果。而且现在你应该可以了解到我们是可以实现一个高性能的、滚动耦合的、跨浏览器的方案。由于这里面需要一点点数学计算和一些模板化的操作,所以我们封装了一个工具类和例子。

欢迎试用,并提出您的宝贵意见。

以上是高性能的視差動畫【譯】的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱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.能量晶體解釋及其做什麼(黃色晶體)
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

PHP和WebSocket: 建立高效能的即時應用程式 PHP和WebSocket: 建立高效能的即時應用程式 Dec 17, 2023 pm 12:58 PM

PHP和WebSocket:建立高效能的即時應用程式隨著網路的發展和用戶需求的提升,即時應用程式變得越來越普遍。而傳統的HTTP協定在處理即時資料時會有一些限制,例如需要頻繁的輪詢或長輪詢方式來取得最新的資料。為了解決這個問題,WebSocket應運而生。 WebSocket是一種先進的通訊協議,它提供了雙向通訊的能力,允許瀏覽器和伺服器之間即時發送和接

如何使用Swoole實現高效能的HTTP反向代理伺服器 如何使用Swoole實現高效能的HTTP反向代理伺服器 Nov 07, 2023 am 08:18 AM

如何使用Swoole實現高效能的HTTP反向代理伺服器Swoole是一款基於PHP語言的高效能、非同步、並發的網路通訊框架。它提供了一系列的網路功能,可以用來實作HTTP伺服器、WebSocket伺服器等。在本文中,我們將介紹如何使用Swoole來實作一個高效能的HTTP反向代理伺服器,並提供具體的程式碼範例。環境配置首先,我們需要在伺服器上安裝Swoole擴展

C++高效能程式設計技巧:優化程式碼以應對大規模資料處理 C++高效能程式設計技巧:優化程式碼以應對大規模資料處理 Nov 27, 2023 am 08:29 AM

C++是一種高效能的程式語言,可以為開發人員提供靈活性和可擴充性。尤其在大規模資料處理場景下,C++的高效率和快速運算速度是非常重要的。本文將介紹一些最佳化C++程式碼的技巧,以因應大規模資料處理需求。使用STL容器取代傳統數組在C++程式設計中,數組是常用的資料結構之一。但是,在大規模資料處理中,使用STL容器,如vector,deque,list和set等,可以更

使用Go語言開發實現高效能的語音辨識應用 使用Go語言開發實現高效能的語音辨識應用 Nov 20, 2023 am 08:11 AM

隨著科技的不斷發展,語音辨識技術也得到了長足的進步與應用。語音辨識應用廣泛運用在語音助理、智慧音箱、虛擬實境等領域,為人們提供了更便利和智慧的互動方式。而如何實現高效能的語音辨識應用,則成為了一個值得探討的問題。近年來,Go語言作為一種高效能的程式語言,在語音辨識應用的開發中備受矚目。 Go語言具備並發性高、編寫簡潔、執行速度快等特點,非常適合用於建構高效能

使用Go語言開發實現高效能的人臉辨識應用 使用Go語言開發實現高效能的人臉辨識應用 Nov 20, 2023 am 09:48 AM

使用Go語言開發實現高效能的人臉辨識應用摘要:人臉辨識技術是一個在當今網路時代非常流行的應用領域。本文介紹了使用Go語言開發高效能人臉辨識應用的步驟和流程。透過使用Go語言的並發、高效能和簡單易用的特點,開發人員可以更便捷地建立高效能的人臉辨識應用。引言:在當今的資訊化社會,人臉辨識技術被廣泛應用於安全監控、人臉支付、人臉解鎖等領域。隨著網路的快速發

Java開發:如何使用Netty進行高效能網路編程 Java開發:如何使用Netty進行高效能網路編程 Sep 20, 2023 pm 02:09 PM

Java開發:如何使用Netty進行高效能網路程式設計摘要:Netty是一個高效能、非同步事件驅動的網路程式框架,能夠簡化網路應用程式的開發過程。本文將介紹Netty的主要特點以及如何使用Netty進行高性能網路程式設計。同時,我們也會提供一些具體的Java程式碼範例,幫助讀者更能理解和應用Netty。一、Netty簡介Netty是一個基於JavaNIO的網路程式框

高效能資料庫搜尋演算法的Java實作思路 高效能資料庫搜尋演算法的Java實作思路 Sep 18, 2023 pm 01:39 PM

高效能資料庫搜尋演算法的Java實現想法摘要:隨著網際網路和大數據時代的到來,資料庫的儲存和搜尋效能對於資料處理的效率至關重要。本文將介紹一種高效能資料庫搜尋演算法的Java實作思路,並提供具體的程式碼範例。引言資料庫搜尋是對於大規模資料集合中的快速查詢的關鍵操作之一。傳統的資料庫搜尋演算法存在搜尋效率低的問題,無法滿足大數據時代的需求。因此,高效能資料庫搜尋演算法的

Docker和Spring Boot的技術實踐:快速建立高效能的應用服務 Docker和Spring Boot的技術實踐:快速建立高效能的應用服務 Oct 21, 2023 am 08:18 AM

Docker和SpringBoot的技術實踐:快速建立高效能的應用服務引言:在當今的資訊時代,網路應用的開發和部署變得越來越重要。隨著雲端運算和虛擬化技術的快速發展,Docker作為一個輕量級的容器技術,受到了廣泛關注和應用。而SpringBoot作為快速開發和部署Java應用的框架,也得到了廣泛認可。本文將探討如何結合Docker和SpringB

See all articles