Jadual Kandungan
摘要" >摘要
视差的问题分析
不好的方案:使用滚动事件
不好的方案:更新背景位置
CSS 3D
调整perspective的比例
为什么这种方案好用?
美中不足:Mobile Safari
固定定位的问题
花式bug和应对
结论
Rumah hujung hadapan web tutorial css 高性能的视差动画【译】

高性能的视差动画【译】

Apr 04, 2017 am 10:21 AM

高性能的视差动画


爱也好,恨也好,视差效果已经遍布web之上了。当你用的巧妙的时候,它可以给应用增加深度和隐喻效果。但问题在于实现一个高性能的视差效果是一个很有挑战的工作。在这篇文章里,我们将讨论如何构造一个高性能的视差效果,当然同样重要的是还得跨浏览器。

高性能的视差动画【译】

视差效果示意图

摘要

  • 不要使用滚动事件(scroll events)或者背景定位(background-position)来创建视差动画。

  • 使用 CSS 3D 变换来创建一个更准确的视差效果。

  • 对于iOS移动设备的Safari浏览器使用 position: sticky 来确保视差可以生效。

如果你想要一个开箱即用的方案,请访问 Parallax helper JS ,这里还有一个 demo演示。

视差的问题分析

在开始之前,我们先来看两个现有的常见的实现视差的方法,探讨为何它们不适合我们要追求的目标。

不好的方案:使用滚动事件

视差的关键需求是它应该是滚动耦合的:对于页面滚动的每一个位置变化,视差元素的位置也应被更新。这看上去很容易,现代浏览器的重要机制之一就是它们可以异步处理工作。尽管如此,在大多数浏览器中,滚动事件是被作为“尽量好”(best effort)的工作处理的,也就意味着:浏览器并不确保每一帧的滚动动画送达!

这个重要的信息告诉我们为什么要避免使用Javascript基于滚动事件去移动元素:Javascript并不能确保视差会和页面滚动保持同样的步调。。在一些老版本的Mobile Safari上,滚动事件甚至是在滚动完成后才触发的,这一点让基于Javascript的滚动效果无法实现。在较新的Mobile Safari版本中,滚动事件可以在动画过程中触发了,但是和Chrome一样,它是一个基于“尽量好”的原则的。所以当主线程忙于其他工作时,滚动事件不会立即触发,也就意味着视差效果的丢失。

不好的方案:更新背景位置

我们要避免的另一个场景是在每帧都进行绘制。很多方案试图采用改变 background-position 来提供视差效果, 但这会让浏览器在滚动时重绘受影响的部分,而这可能会是相当消耗资源的,这种影响会使动画卡顿。

如果我们想提供一个高质量的视差动画,我们想要的是一个可以当作加速的属性(这里我们指的是 transformopacity ),而这是不依赖于滚动事件的。

CSS 3D

Scott Kellum 和 Keith Clark 都已经在利用 CSS 3D 来实现视差效果领域做出了很重要的工作。他们采用的非常有效技术有:

  1. 建立一个容器元素,设置 <a href="http://www.php.cn/wiki/926.html" target="_blank">overflow-y</a>: scroll 使其可以滚动(同时可能需要 <a href="http://www.php.cn/wiki/924.html" target="_blank">overflow-x</a>: hidden)。

  2. 对于上面的元素, 我们会应用一个 perspective 值,然后设置 perspective-origin<a href="http://www.php.cn/wiki/904.html" target="_blank">top</a> left, 或者 0 0

  3. 对上面元素的子元素应用一个在 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);
}
Salin selepas log masuk

当然我们假定你的 HTML 是下面的样子:

<p class="container”>
  <p class="parallax-child”></p>
</p>
Salin selepas log masuk

调整perspective的比例

把子元素挤回来会要求它设置一个更小的相对于 perspective 的比例。你可以通过下列等式来计算需要的缩放比例: (perspective - distance) / perspective。由于我们希望视差元素看上去和我们一开始设定的一样大,所以它应该根据这样的等式进行放缩而不是保持不变。

拿上面的例子来说, 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>
Salin selepas log masuk

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

.parallax-container {
  transform-style: preserve-3d;
}
Salin selepas log masuk

对于 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);
}
Salin selepas log masuk

这样就为 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> )。这种方案背后的原理是它会导致过大的元素进入滚动区域的“负面”(一般是左上),而滚动区域永远不会让你看到“负面”区域。

结论

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

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

Atas ialah kandungan terperinci 高性能的视差动画【译】. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
4 minggu yang lalu By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Cara Membuka Segala -galanya Di Myrise
1 bulan yang lalu By 尊渡假赌尊渡假赌尊渡假赌

Alat panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Cara menggunakan Swoole untuk melaksanakan pelayan proksi terbalik HTTP berprestasi tinggi Cara menggunakan Swoole untuk melaksanakan pelayan proksi terbalik HTTP berprestasi tinggi Nov 07, 2023 am 08:18 AM

Cara menggunakan Swoole untuk melaksanakan pelayan proksi terbalik HTTP berprestasi tinggi Swoole ialah rangka kerja komunikasi rangkaian berprestasi tinggi, tak segerak dan serentak berdasarkan bahasa PHP. Ia menyediakan satu siri fungsi rangkaian dan boleh digunakan untuk melaksanakan pelayan HTTP, pelayan WebSocket, dsb. Dalam artikel ini, kami akan memperkenalkan cara menggunakan Swoole untuk melaksanakan pelayan proksi terbalik HTTP berprestasi tinggi dan memberikan contoh kod khusus. Konfigurasi persekitaran Pertama, kita perlu memasang sambungan Swoole pada pelayan

PHP dan WebSocket: Membina aplikasi masa nyata berprestasi tinggi PHP dan WebSocket: Membina aplikasi masa nyata berprestasi tinggi Dec 17, 2023 pm 12:58 PM

PHP dan WebSocket: Membina aplikasi masa nyata berprestasi tinggi Apabila Internet berkembang dan keperluan pengguna meningkat, aplikasi masa nyata menjadi semakin biasa. Protokol HTTP tradisional mempunyai beberapa had semasa memproses data masa nyata, seperti keperluan untuk mengundi yang kerap atau mengundi panjang untuk mendapatkan data terkini. Untuk menyelesaikan masalah ini, WebSocket wujud. WebSocket ialah protokol komunikasi lanjutan yang menyediakan keupayaan komunikasi dua hala, membenarkan penghantaran dan penerimaan masa nyata antara penyemak imbas dan pelayan.

Petua Pengaturcaraan Berprestasi Tinggi C++: Mengoptimumkan Kod untuk Pemprosesan Data Berskala Besar Petua Pengaturcaraan Berprestasi Tinggi C++: Mengoptimumkan Kod untuk Pemprosesan Data Berskala Besar Nov 27, 2023 am 08:29 AM

C++ ialah bahasa pengaturcaraan berprestasi tinggi yang menyediakan pembangun dengan fleksibiliti dan skalabiliti. Terutamanya dalam senario pemprosesan data berskala besar, kecekapan dan kelajuan pengkomputeran pantas C++ adalah sangat penting. Artikel ini akan memperkenalkan beberapa teknik untuk mengoptimumkan kod C++ untuk menampung keperluan pemprosesan data berskala besar. Menggunakan bekas STL dan bukannya tatasusunan tradisional Dalam pengaturcaraan C++, tatasusunan ialah salah satu struktur data yang biasa digunakan. Walau bagaimanapun, dalam pemprosesan data berskala besar, menggunakan bekas STL, seperti vektor, deque, senarai dan set, dsb., boleh menjadi lebih

Gunakan bahasa Go untuk membangun dan melaksanakan aplikasi pengecaman pertuturan berprestasi tinggi Gunakan bahasa Go untuk membangun dan melaksanakan aplikasi pengecaman pertuturan berprestasi tinggi Nov 20, 2023 am 08:11 AM

Dengan perkembangan berterusan sains dan teknologi, teknologi pengecaman pertuturan juga telah mencapai kemajuan dan aplikasi yang besar. Aplikasi pengecaman pertuturan digunakan secara meluas dalam pembantu suara, pembesar suara pintar, realiti maya dan bidang lain, memberikan orang ramai cara interaksi yang lebih mudah dan bijak. Cara melaksanakan aplikasi pengecaman pertuturan berprestasi tinggi telah menjadi persoalan yang patut diterokai. Dalam beberapa tahun kebelakangan ini, bahasa Go, sebagai bahasa pengaturcaraan berprestasi tinggi, telah menarik banyak perhatian dalam pembangunan aplikasi pengecaman pertuturan. Bahasa Go mempunyai ciri-ciri konkurensi yang tinggi, penulisan ringkas, dan kelajuan pelaksanaan yang pantas Ia sangat sesuai untuk membina prestasi tinggi

Gunakan bahasa Go untuk membangunkan aplikasi pengecaman muka berprestasi tinggi Gunakan bahasa Go untuk membangunkan aplikasi pengecaman muka berprestasi tinggi Nov 20, 2023 am 09:48 AM

Gunakan bahasa Go untuk membangunkan aplikasi pengecaman muka berprestasi tinggi Abstrak: Teknologi pengecaman muka ialah bidang aplikasi yang sangat popular dalam era Internet hari ini. Artikel ini memperkenalkan langkah dan proses untuk membangunkan aplikasi pengecaman muka berprestasi tinggi menggunakan bahasa Go. Dengan menggunakan ciri serentak, prestasi tinggi dan kemudahan penggunaan bahasa Go, pembangun boleh membina aplikasi pengecaman muka berprestasi tinggi dengan lebih mudah. Pengenalan: Dalam masyarakat maklumat hari ini, teknologi pengecaman muka digunakan secara meluas dalam pemantauan keselamatan, pembayaran muka, buka kunci muka dan bidang lain. Dengan perkembangan pesat Internet

Pembangunan Java: Cara menggunakan Netty untuk pengaturcaraan rangkaian berprestasi tinggi Pembangunan Java: Cara menggunakan Netty untuk pengaturcaraan rangkaian berprestasi tinggi Sep 20, 2023 pm 02:09 PM

Pembangunan Java: Cara menggunakan Netty untuk pengaturcaraan rangkaian berprestasi tinggi Ringkasan: Netty ialah rangka kerja pengaturcaraan rangkaian dipacu peristiwa berprestasi tinggi yang memudahkan proses pembangunan aplikasi rangkaian. Artikel ini akan memperkenalkan ciri utama Netty dan cara menggunakan Netty untuk pengaturcaraan rangkaian berprestasi tinggi. Pada masa yang sama, kami juga akan menyediakan beberapa contoh kod Java khusus untuk membantu pembaca memahami dan menggunakan Netty dengan lebih baik. 1. Pengenalan kepada Netty Netty ialah kotak pengaturcaraan rangkaian berasaskan JavaNIO

Amalan teknikal Docker dan Spring Boot: membina perkhidmatan aplikasi berprestasi tinggi dengan cepat Amalan teknikal Docker dan Spring Boot: membina perkhidmatan aplikasi berprestasi tinggi dengan cepat Oct 21, 2023 am 08:18 AM

Amalan teknikal Docker dan SpringBoot: membina perkhidmatan aplikasi berprestasi tinggi dengan cepat Pengenalan: Dalam era maklumat hari ini, pembangunan dan penggunaan aplikasi Internet telah menjadi semakin penting. Dengan perkembangan pesat teknologi pengkomputeran awan dan virtualisasi, Docker, sebagai teknologi kontena ringan, telah mendapat perhatian dan aplikasi yang meluas. SpringBoot juga telah diiktiraf secara meluas sebagai rangka kerja untuk pembangunan pesat dan penggunaan aplikasi Java. Artikel ini akan meneroka cara menggabungkan Docker dan SpringB

Idea pelaksanaan Java untuk algoritma carian pangkalan data berprestasi tinggi Idea pelaksanaan Java untuk algoritma carian pangkalan data berprestasi tinggi Sep 18, 2023 pm 01:39 PM

Ringkasan idea pelaksanaan Java untuk algoritma carian pangkalan data berprestasi tinggi: Dengan kemunculan Internet dan era data besar, prestasi penyimpanan dan carian pangkalan data adalah penting untuk kecekapan pemprosesan data. Artikel ini akan memperkenalkan idea pelaksanaan Java untuk algoritma carian pangkalan data berprestasi tinggi dan menyediakan contoh kod khusus. Pengenalan Carian pangkalan data ialah salah satu operasi utama untuk pertanyaan pantas dalam pengumpulan data berskala besar. Algoritma carian pangkalan data tradisional mempunyai masalah kecekapan carian yang rendah dan tidak dapat memenuhi keperluan era data besar. Oleh itu, algoritma carian pangkalan data berprestasi tinggi adalah

See all articles