在
之前的文章《教你怎麼使用shell腳本實現伺服器快速設定(附程式碼)》中,跟大家介紹怎麼使用shell腳本實作伺服器快速設定。以下這篇文章跟大家介紹如何用CSS實作簡單骨骼動畫,我們一起看看怎麼做。
某天設計師來找我說,「這個心願牌傻傻地掛在那邊不好看,加個動效唄,就左右擺動一下就行,很簡單的!”,我一想,行呀,提升用戶視覺體驗,開搞。
十分鐘後,不對呀,這個左右擺動好假,不像現實中風吹的效果。
註:此處加快了動畫的速度和擺動的幅度。
.animate-1 { animation: swing1 1s ease-in-out infinite; transform: rotate(-5deg); transform-origin: top center; } @keyframes swing1 { 0% { transform: rotate(-5deg); } 50% { transform: rotate(5deg);} 100% { transform: rotate(-5deg);} }
冷靜思考,為啥這個擺動會沒有靈魂。於是拿起工卡開始擺動,看看現實中的擺動效果是咋樣的,最後豁然開朗:原來現實中的心願牌(和工卡同理)在受力的時候,並不會整體擺動,而是會根據節點位置分成幾個部分有關聯地擺動,這其實是個簡單的骨骼動畫!那到底怎麼去實現呢?
這裡將以這個心願牌擺動動畫為例,和大家一起研究如何使用css來實現。
2.1 分離元素
要讓動畫元素分開移動,首先需要分割元素。拆分的依據是上面提到的節點,也就是骨頭動畫中所謂的關節。例如這張心願牌就有兩個關節,分別在牌的上面和牌的下面,於是我們能拆分出3個動畫元素:
2.2拼接元素
<div> <!--元素1--> <div class="item-1"></div> <!--元素2--> <div class="item-2"></div> <!--元素3--> <div class="item-3"></div> </div>
這裡看似簡單,但是如果對骨骼動畫不了解的話,會掉到坑里,上面就是錯誤的示範。為了加深大家的理解,特地挖了一個坑
2.3 添加動效
在上面的基礎上,我們就可以為每一部分加上不同幅度和方向的擺動效啦。
<div class="animate-2"> <!--元素1--> <div class="item-1"></div> <!--元素2--> <div class="item-2"></div> <!--元素3--> <div class="item-3"></div> </div>
.animate-2 .item-1 { /* 设置margin是为了定位,使其部分重叠在一起 */ margin-bottom: -8px; margin-left: 18px; position: relative; z-index: 1; animation: swing2-1 1s ease-in-out infinite; transform: rotate(-3deg); transform-origin: top center; } .animate-2 .item-2 { animation: swing2-2 1s ease-in-out infinite; transform: rotate(5deg); transform-origin: top center; } .animate-2 .item-3 { margin-top: -5px; margin-left: 17.5px; position: relative; animation: swing2-3 1s ease-in-out infinite; transform: rotate(-5deg); transform-origin: top center; } @keyframes swing2-1 { 0% { transform: rotate(-3deg); } 50% { transform: rotate(3deg);} 100% { transform: rotate(-3deg);} } @keyframes swing2-2 { 0% { transform: rotate(5deg); } 50% { transform: rotate(-5deg);} 100% { transform: rotate(5deg);} } @keyframes swing2-3 { 0% { transform: rotate(-5deg); } 50% { transform: rotate(5deg);} 100% { transform: rotate(-5deg);} }
大功告成?來看看效果吧
我的天,這是啥啊! ! !看起來擺動確實要比整體擺動真實,不同元素有不同的擺動幅度和方向。但是錯位了呀。
再繼續冷靜思考,問題出在,骨骼動畫的每一個子動畫都是有關聯的,而我們上面設計的每一個動畫都是獨立的。舉個例子,頂部的紅繩擺動時,會牽引住下面的牌子,導致下面牌子位置改變。下面的牌子在位置改變的同時,播放自己擺動的動畫,這才是骨骼動畫!
2.4 填坑- 從js實現骨骼動畫來理解其原理
源碼在這裡,因為在油管,為了避免某些同學沒能科學上網看不到,所以以下面的跑步動作為例,先來說明一下js實作過程
https://github.com/bit101/CodingMath/tree/master/episode44
#根據大腿的初始狀態,當前旋轉速度,計算大腿下一幀的位置;
#根據當前大腿的位置和小腿當前的速度,計算小腿下一幀的位置;
...無限迴圈...
從這裡可以看出,小腿的位置是依賴大腿的位置的,這就不會出現我們上面的錯位狀況。所以說穿了,骨骼動畫的特性就是:
關鍵元素帶著子元素一起運動,子元素在此基礎上自己運動。
那麼js實作中是先計算大腿位置,再由大腿位置計算小腿位置來實現聯結的,而css該怎麼實現呢?
2.5 純css實作
回顧最關鍵的地方:關鍵元素帶著子元素一起運動,子元素在此基礎上自己運動。 ,要實現關鍵元素和子元素一起運動,在css裡面,只要關鍵元素包裹子元素即可! ,這就是css實現骨骼動畫的基石。
<div class="animate-3"> <!--运动模块1--> <div class="s-1"> <div class="item-1"></div> <!--运动模块2--> <div class="s-2"> <div class="item-2"></div> <!--运动模块3--> <div class="s-3"> <div class="item-3"></div> </div> </div> </div> </div>
.animate-3 .s-1 { animation: swing3-1 1s ease-in-out infinite; transform: rotate(-3deg); transform-origin: top center; } .animate-3 .s-2 { animation: swing3-2 1s ease-in-out infinite; transform: rotate(-5deg); transform-origin: top center; } .animate-3 .s-3 { animation: swing3-3 1s ease-in-out infinite; transform: rotate(-5deg); transform-origin: top center; } @keyframes swing3-1 { 0% { transform: rotate(-3deg); } 50% { transform: rotate(3deg);} 100% { transform: rotate(-3deg);} } @keyframes swing3-2 { 0% { transform: rotate(5deg); } 50% { transform: rotate(-5deg);} 100% { transform: rotate(5deg);} } @keyframes swing3-3 { 0% { transform: rotate(-5deg); } 50% { transform: rotate(5deg);} 100% { transform: rotate(-5deg);} }
这次终于大功告成了。这里有三个元素,更多元素也是同理的,不断嵌套即可。
细心的同学会发现上面实现的骨骼动画看着也别扭,归根结底是各个元素摆动的方向和幅度没有调节好,这里附上调整完的效果,用心感受:
.animate-4 .s-1 { animation: swing4-1 5s ease-in-out infinite; transform: rotate(-2deg); transform-origin: top center; } .animate-4 .s-2 { animation: swing4-2 8s ease-in-out infinite; transform: rotate3d(0, 1, 0, 20deg); transform-origin: top center; } .animate-4 .s-3 { animation: swing4-3 8s ease-in-out infinite; transform: rotate(3deg); transform-origin: top center; } @keyframes swing4-1 { 0% { transform: rotate(-2deg); } 50% { transform: rotate(2deg);} 100% { transform: rotate(-2deg);} } @keyframes swing4-2 { 0% { transform: rotate3d(0, 1, 0, 20deg); } 50% { transform: rotate3d(0, 1, 0, -20deg);} 100% { transform: rotate3d(0, 1, 0, 20deg);} } @keyframes swing4-3 { 0% { transform: rotate(3deg); } 50% { transform: rotate(-3deg);} 100% { transform: rotate(3deg);} }
纯CSS确实能实现骨骼动画,但仅限于简单的场景。在复杂场景中,例如前端游戏里面的骨骼动画,涉及到的节点比较多,用CSS虽然能实现,但效率不高,所以社区有很多从设计工具直接导出可用的骨骼动画信息,再用js来加载运行的方案,大家感兴趣可以Google一下。
本文主要通过简单的案例来加深大家对骨骼动画的原理性的认识,至于最后大家用CSS还是用JS来实现,就是“杀鸡要不要用牛刀”的问题了。
个人认为,只要屠龙刀在手,用不用已经不重要了。加油,希望大家能在各个方向找到自己的屠龙刀。
推荐学习:CSS视频教程
以上是新手篇:如何用CSS實作簡單骨骼動畫(程式碼分享)的詳細內容。更多資訊請關注PHP中文網其他相關文章!