網(wǎng)站制作NEWS
Flutter 小技巧之不一樣的思路實(shí)現(xiàn)炫酷 3D 翻頁(yè)折疊動(dòng)畫(huà)
在Flutter動(dòng)畫(huà)實(shí)現(xiàn)中,有一個(gè)有趣的話題——如何制作一個(gè)3D折疊動(dòng)畫(huà)效果?許多人可能會(huì)首先想到使用Dart中的矩陣變換和Canvas來(lái)實(shí)現(xiàn)。
這種效果在當(dāng)前的小說(shuō)閱讀器場(chǎng)景中非常常見(jiàn),而類(lèi)似的翻頁(yè)效果通常是通過(guò)這種思路實(shí)現(xiàn)的。例如,我曾經(jīng)嘗試過(guò)的《炫酷的3D卡片和帥氣的360°展示效果》以及《用純代碼實(shí)現(xiàn)立體Dash和3D掘金Logo》都是利用矩陣變換實(shí)現(xiàn)的視覺(jué)3D效果。
然而,今天我要介紹一個(gè)名為riveo_page_curl的項(xiàng)目,它提供了一個(gè)與眾不同的實(shí)現(xiàn)方法,即通過(guò)自定義Fragment Shaders來(lái)實(shí)現(xiàn)動(dòng)畫(huà)。這種方式允許開(kāi)發(fā)者使用GLSL語(yǔ)言進(jìn)行編程,從而通過(guò)GPU渲染出更豐富的圖形效果。
在介紹這個(gè)項(xiàng)目之前,我們先來(lái)了解一下Fragment Shader。自Flutter 3.7版本開(kāi)始,就提供了Fragment Shader API。這個(gè)API允許開(kāi)發(fā)者直接介入到Flutter渲染管道的渲染流程中。
直接使用Fragment Shader而不是Dart矩陣變換的好處是,它可以減少CPU的耗時(shí)。通過(guò)圖形語(yǔ)言(GLSL)直接給GPU發(fā)送指令,性能上可以得到提升,并且實(shí)現(xiàn)起來(lái)更簡(jiǎn)潔。不過(guò),加載著色器可能會(huì)帶來(lái)一定的開(kāi)銷(xiāo),因此需要在運(yùn)行時(shí)將其編譯為特定于平臺(tái)的著色器。
在Flutter中使用Fragment Shader也有一些條件限制,例如需要引入特定的頭文件,以及只支持.frag格式的文件。
如果需要將已有的GLSL效果(如shadertoy上的代碼)搬運(yùn)到Flutter中,可能需要進(jìn)行一些代碼改造。以下是一段漸變動(dòng)畫(huà)的著色器示例,以及它在Flutter中的對(duì)應(yīng)代碼。
通過(guò)這些片段著色器,我們可以獲得極其豐富的渲染效果。在Flutter中,漸變動(dòng)畫(huà)的完整代碼可以在GitHub上的相應(yīng)倉(cāng)庫(kù)中找到。
riveo_page_curl項(xiàng)目中的折疊著色器包含了一些矩陣變換和三角函數(shù)計(jì)算。它的核心在于計(jì)算彎曲部分的弧度,并增加陰影投影以提高視覺(jué)效果。
在Dart層,除了ShaderBuilder之外,還可以通過(guò)flutter_shaders的AnimatedSampler來(lái)實(shí)現(xiàn)更簡(jiǎn)潔的shader、image和canvas的配合。
完整項(xiàng)目可以在GitHub上查看。相比在Dart層實(shí)現(xiàn)3D翻頁(yè)折疊,使用FragmentShader實(shí)現(xiàn)的代碼更加簡(jiǎn)潔,性能體驗(yàn)也更優(yōu)秀。此外,通過(guò)簡(jiǎn)單的移植適配,ShaderToy里的著色器代碼可以直接在Flutter中使用,這對(duì)于Flutter在游戲場(chǎng)景的實(shí)現(xiàn)非常有幫助。
最后,F(xiàn)lutter 3.10版本之后,F(xiàn)lutter Web也支持了fragment shaders,因此著色器在Flutter的實(shí)現(xiàn)已經(jīng)相對(duì)成熟。如果將之前通過(guò)Flutter實(shí)現(xiàn)的《霓虹燈文本的「故障」效果》的邏輯轉(zhuǎn)換成fragment shaders來(lái)完成,性能和代碼簡(jiǎn)潔程度也可能會(huì)有所提升。
多重隨機(jī)標(biāo)簽