近日在開發的頁面中,需要制作一個動態的圓形進度條,首先想到的是利用兩個矩形,寬等於直徑的一半,高等於直徑,兩個矩形利用浮動貼在一起,設置overflow:hidden屬性,作為盒子,內部有一個與其寬高相等的子盒子,左側的子盒子左上角和左下角以及右側子盒子的右上角和右下角利用border-radius:半徑,這樣兩個矩形便組成了一個完整的圓形。


我們讓左側的子盒子繞着右邊的中點旋轉180°,這樣左側的半圓就隱藏了,右側半圓同理。這個地方設置旋轉中心是用的transform-origin屬性,第一個值是X軸方向,第二個值是Y軸方向,可以用left,right,top,bottom,center這些詞,也可以用數值,數值的話是以圖形的左上角為原點。
然后我們給兩個半圓設置邊框,並且左邊的半圓的右邊框設置為none,右邊半圓的左邊框設置為none。此時一個完整的圓環就設置完畢了,然后通過動畫旋轉半圓,邊框從隱藏區域逐漸進入可視區域,我們看到的效果就是圓形進度條的加載過程。如下:

這個方法在PC端沒有太大問題,然而在移動端,由於瀏覽器的渲染等問題,旋轉過程中圓角消失,或是出現較大鋸齒導致邊框部分缺失。
這時我們就不用邊框來作進度條,而是給圓形一個背景色,再在上面覆蓋一個半徑稍小的圓形遮罩,這樣漏出一個圓環可以當作進度條,同樣可以實現以上功能。如下:


另外在這個動畫執行的過程中,我還發現有個元素的overflow:hidden樣式失效,后來在網上查閱了相關文章,發現overflow在visible以外其他值得時候,當transform發生時會重寫,因此我的旋轉動畫發生時,才會出現overflowhidden失效的情況。此時我們只需要給失效元素加上z-index:1的樣式,便解決了這個問題。


更於2017.8.14日
前幾天突然發現一個問題,上圖所示border-radius圓角溢出的問題在iPhone7機型上出現,而其他iPhone機型上又沒問題,並且兩台不同版本iPhone的IOS版本都是一樣的,這也讓我非常郁悶。通過測試,發現仍然是因為transform導致的元素溢出問題。后來通過CSS3一個新屬性“mask-img”順利解決了這個問題,起原理如下圖(此圖源自網絡)

background:url("color.png");
mask-img:url("mask.png");
此設置是先給元素設置背景圖片,再用mask.png的透明部分遮住背景圖,有顏色的部分反而是透明的,會顯露出元素的背景圖。於是我們制作 了一張圓形遮罩圖用來遮住圓角溢出部分,便解決了這個問題。此外mask-size屬性可以設置遮罩圖的尺寸,也非常方便。
更於2018.6.25
閱讀量挺高的,不過可能只有文字會比較抽象,那就貼一個示例代碼吧,為大家提供一個思路
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
html {
font-size:20px;
}
.centerBox {
width: 6.25rem;
height: 6.25rem;
border-radius: 50%;
position: absolute;
left: 6.25rem;
top: 1rem;
background: rgba(255, 255, 255, 0.4);
-webkit-box-sizing: content-box;
}
.leftBox,.rightBox{
width: 3.125rem;
height: 6.25rem;
overflow: hidden;
float: left;
}
.roundLeft{
width: 3.125rem;
height: 6.25rem;
border-radius: 3.125rem 0 0 3.125rem;
overflow: hidden;
transform: rotateZ(-180deg);
-webkit-transform-origin: right center;
background-color: red;
}
.roundRight {
width: 3.125rem;
height: 6.25rem;
border-radius: 0 3.125rem 3.125rem 0;
overflow: hidden;
transform: rotateZ(-160deg);
-webkit-transform-origin: left center;
background-color: red;
}
.roundMask {
width: 5.85rem;
height: 5.85rem;
background-color: #1E9BF9;
border-radius: 50%;
position: absolute;
top: 0.2rem;
left: 0.2rem;
overflow: hidden;
}
</style>
</head>
<body>
<div class="centerBox">
<div class="leftBox">
<div class="roundLeft"></div>
</div>
<div class="rightBox">
<div class="roundRight"></div>
</div>
<div class="roundMask">
</div>
</div>
</body>
</html>
