最近工作項目中有製作動畫效果的需求,查閱了一些網站之後,在一個名叫species-in-pieces的網站(species-in-pieces.com)看到了以下神奇的動畫效果:
用Chrome的開發者工具窺探一番之後,發現這個酷炫的動畫效果基本是純css實現的!其實現核心就是css3中加入的 clip-path 屬性。
clip-path 是css3中添加的新屬性(屬於CSS Shapes Module Level 1),直譯過來就是裁剪路徑,是已經被棄用的屬性 clip 的拓展。
通過路徑繪製區域,隱藏路徑包裹外的內容,顯示路徑包裹內的內容。
與 clip 的區別在於, clip 只能裁剪矩形區域,而 clip-path 可以裁剪出各種幾何圖形。
API:
{
clip-path: none;
clip-path: url(resources.svg#c1);
clip-path: fill-box;
clip-path: stroke-box;
clip-path: view-box;
clip-path: margin-box;
clip-path: border-box;
clip-path: padding-box;
clip-path: content-box;
clip-path: inset(100px 50px); //矩形
clip-path: circle(50px at 0 100px); //園形
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%); //多邊形
clip-path: padding-box circle(50px at 0 100px); //幾何框的參考框盒
clip-path: inherit;
clip-path: initial;
clip-path: unset;
}
例子:
//圓形
.shape{
background-color: #333;
width: 100px;
height: 100px;
clip-path: circle(50px at 50px 50px);
}
//三角形
.shape{
clip-path: polygon(10% 10%, 10% 50%, 50% 50%)
}
.shape {
clip-path: polygon(50% 0%, 80% 10%, 100% 35%, 100% 70%, 80% 90%, 50% 100%, 20% 90%, 0% 70%, 0% 35%, 20% 10%);
}
可以看出 clip-path 實現圖形裁剪的關鍵在於 polygon() ,這個裁剪路徑的使用與SVG中的path類似但不相同。
SVG中的path可以繪製繪製任何圖形,而 clip-path 只能用於繪製CSS的基本圖形。
除此之外, clip-path 有兩個需要了解的特點:
詳細的使用方法可以參考MDN web docs上的文檔
讓clip-path動起來 clip-path 能實現諸多動畫特效的原因,在於其支持 CSS transtion 與 CSS animation 。
通過簡單的設置 transtion 或 animation 關鍵幀,就能實現不同圖形狀態間的變換:
.shape-animate {
position: absolute;width: 200px;height: 200px;top: 50%;left: 50%;transform: translate(-50%, -50%);
background: red;
clip-path: polygon(50% 0%, 0% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%, 100% 100%);
//動畫參數
transition: .3s;
animation: shape-ani 5s linear infinite;
}
@keyframes shape-ani {
10% {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%);
}
20% {
clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%, 0% 50%);
}
30% {
background: green;
clip-path: polygon(100% 38%, 82% 100%, 82% 100%, 18% 100%, 0% 38%, 0% 38%, 0% 38%, 0% 38%, 50% 0%);
}
40% {
clip-path: polygon(100% 38%, 82% 100%, 82% 100%, 18% 100%, 0% 38%, 0% 38%, 0% 38%, 0% 38%, 50% 0%);
}
50% {
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 100% 75%, 50% 100%, 0% 75%, 0% 75%, 0% 25%, 0% 25%);
}
60% {
background: black;
clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 100% 75%, 50% 100%, 0% 75%, 0% 75%, 0% 25%, 0% 25%);
}
70% {
clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 25% 100%, 0% 60%, 10% 20%, 50% 0%);
}
80% {
clip-path: polygon(50% 0%, 90% 20%, 100% 60%, 75% 100%, 25% 100%, 25% 100%, 0% 60%, 10% 20%, 50% 0%);
}
}
不過 clip-path:animation 也有其局限:裁剪的多邊形必須具有相同的頂點數。
如果要實現不同頂點數圖形的轉換,比如三角形到矩形的動畫,可以將4個頂點中的2個重合或藏在其他路徑中,畫出三角形。
.shape {
//3頂點
clip-path: polygon(10% 10%, 10% 50%, 50% 50%);
//4頂點
clip-path: polygon(10% 10%, 10% 50%, 50% 50%, 30% 30%)
}
.shape:hover {
clip-path: polygon(10% 10%, 10% 50%, 50% 50%, 50% 10%)
}
回到species-in-pieces。
動圖中的各種小動物,全都是由30個形態不一的三角形拼接而成的,動物的切換並沒有改變三角形數量和圖形頂點數目。
其代碼是下面這樣:
<div class="wrap left-to-right">
<div class="shard-wrap">
<div class="shard"></div>
</div>
<div class="shard-wrap">
<div class="shard"></div>
</div>
.
.
.
<div class="shard-wrap">
<div class="shard"></div>
</div>
<div class="shard-wrap">
<div class="shard"></div>
</div>
</div>
對應的關鍵css:
.shard-wrap {
.crow .shard-wrap:nth-child(1) .shard {
-webkit-clip-path: polygon(20% 50%,25% 52.4%,11.5% 54.5%);
background-color: #2C323D
}
.crow .shard-wrap:nth-child(2) .shard {
-webkit-clip-path: polygon(14.7% 47.5%,35.2% 50.2%,25% 52.5%);
background-color: #63676F
}
.crow .shard-wrap:nth-child(3) .shard {
-webkit-clip-path: polygon(22.9% 44.5%,35.2% 50.2%,25% 48.9%);
background-color: #0F1622
}
.crow .shard-wrap:nth-child(29) .shard {
-webkit-clip-path: polygon(61.7% 44.7%,64.4% 44%,65.1% 36.2%);
background-color: #0f1622
}
.crow .shard-wrap:nth-child(30) .shard {
-webkit-clip-path: polygon(78.5% 21.5%,76.3% 23.7%,74.6% 22.5%);
background-color: #0f1622
}
我們可以發現,每一個 .shard-wrap>.shard 節點都是100%的寬高的盒子,圖形完全是通過 clip-path:polygon() 裁剪而來。
上例的crow烏鴉,所有的圖形描述都定義在css中,由 :nth-child 偽類選擇器來控制每一塊三角的形狀,通過 polygon() 傳入三角形的三個頂點參數,使用百分比單位來達成響應式定位。
在此基礎上通過父元素選擇器改變組成不同動物形態的三角形的坐標狀態,實現動畫效果。
兼容性目前 clip-path 的兼容性不是很好,基本只支持-webkit-內核的瀏覽器。不過作為css3官方屬性,將來的發展空間還是很大。
通過本文介紹,可以發現通過 clip-path 來實現動畫是非常簡單和易用的,
例如species-in-pieces的動畫實現就沒有非常複雜的技術問題,而是靠創意和美術功底進行精心的設計來實現。
我們也可以靈活使用這些工具完成自己想要的動畫效果。
感興趣的話可以多了解下官方文檔,多看看大牛們的動畫實現。
由於水平和經驗有限,如有紕漏或建議,歡迎留言。如果覺得不錯,歡迎關注海致星圖,謝謝你的閱讀。
參考文章:
species-in-pieces
(http://species-in-pieces.com/)
css-tricks || clip-path
(https://css-tricks.com/almanac/properties/c/clip-path/)
MDN web docs || clip-path
(https://developer.mozilla.org/zh-CN/docs/Web/CSS/clip-path)
使用clip-path製作簡單的動畫效果
(http://qcyoung.com/2015/11/18/使用clip-path製作簡單的動畫效果/)
CSS Shapes module level 1
(http://dev.w3.org/csswg/css-shapes/)