一直以來,使用純 CSS 實現波浪效果都是十分困難的。javascript
由於實現波浪的曲線須要藉助貝塞爾曲線。css
而使用純 CSS 的方式,實現貝塞爾曲線,額,暫時是沒有很好的方法。html
固然,藉助其餘力量(SVG、CANVAS),是能夠很輕鬆的完成所謂的波浪效果的,先看看,非 CSS 方式實現的波浪效果。java
藉助 SVG ,是很容易畫出三次貝塞爾曲線的。git
看看效果:github
代碼以下:canvas
1
2
3
4
5
6
7
8
9
10
11
12
13
|
<
svg
width="200px" height="200px" version="1.1" xmlns="http://www.w3.org/2000/svg">
<
text
class="liquidFillGaugeText" text-anchor="middle" font-size="42px" transform="translate(100,120)" style="fill: #000">50.0%</
text
>
<!-- Wave -->
<
g
id="wave">
<
path
id="wave-2" fill="rgba(154, 205, 50, .8)" d="M 0 100 C 133.633 85.12 51.54 116.327 200 100 A 95 95 0 0 1 0 100 Z">
<
animate
dur="5s" repeatCount="indefinite" attributeName="d" attributeType="XML" values="M0 100 C90 28, 92 179, 200 100 A95 95 0 0 1 0 100 Z;
M0 100 C145 100, 41 100, 200 100 A95 95 0 0 1 0 100 Z;
M0 100 C90 28, 92 179, 200 100 A95 95 0 0 1 0 100 Z"></
animate
>
</
path
>
</
g
>
<
circle
cx="100" cy="100" r="80" stroke-width="10" stroke="white" fill="transparent"></
circle
>
<
circle
cx="100" cy="100" r="90" stroke-width="20" stroke="yellowgreen" fill="none" class="percentage-pie-svg"></
circle
>
</
svg
>
|
SCSSsvg
.css-live-wrap {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
畫出三次貝塞爾曲線的核心在於 <path id="wave-2" fill="rgba(154, 205, 50, .8)" d="M 0 100 C 133.633 85.12 51.54 116.327 200 100 A 95 95 0 0 1 0 100 Z">
這一段。感興趣的能夠自行去研究研究。學習
使用 canvas 實現波浪效果的原理與 SVG 同樣,都是利用路徑繪製出三次貝塞爾曲線並賦予動畫效果。動畫
使用 canvas 的話,代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
$(
function
() {
let
canvas = $(
"canvas"
);
let
ctx = canvas[0].getContext(
'2d'
);
let
radians = (Math.PI / 180) * 180;
let
startTime = Date.now();
let
time = 2000;
let
clockwise = 1;
let
cp1x, cp1y, cp2x, cp2y;
// 初始狀態
// ctx.bezierCurveTo(90, 28, 92, 179, 200, 100);
// 末尾狀態
// ctx.bezierCurveTo(145, 100, 41, 100, 200, 100);
requestAnimationFrame(
function
waveDraw() {
let
t = Math.min(1.0, (Date.now() - startTime) / time);
if
(clockwise) {
cp1x = 90 + (55 * t);
cp1y = 28 + (72 * t);
cp2x = 92 - (51 * t);
cp2y = 179 - (79 * t);
}
else
{
cp1x = 145 - (55 * t);
cp1y = 100 - (72 * t);
cp2x = 41 + (51 * t);
cp2y = 100 + (79 * t);
}
ctx.clearRect(0, 0, 200, 200);
ctx.beginPath();
ctx.moveTo(0, 100);
// 繪製三次貝塞爾曲線
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, 200, 100);
// 繪製圓弧
ctx.arc(100, 100, 100, 0, radians, 0);
ctx.fillStyle =
"rgba(154, 205, 50, .8)"
;
ctx.fill();
ctx.save();
if
( t == 1 ) {
startTime = Date.now();
clockwise = !clockwise;
}
requestAnimationFrame(waveDraw);
});
})
|
HTML
<canvas id="canvas" width="200" height="200"></canvas>
SCSS
html,
body {
height: 100%;
text-align: center;
}
#canvas {
box-sizing: content-box;
padding: 5px;
background-color: #fff;
border-radius: 100%;
position: relative;
top: 50%;
transform: translateY(-50%);
border: 10px solid rgba(154, 205, 50, .8);
}
主要是利用了動態繪製 ctx.bezierCurveTo()
三次貝塞爾曲線實現波浪的運動效果,感興趣的能夠自行研究。
好,接下來纔是本文的重點!使用純 CSS 的方式,實現波浪的效果。
是,咱們沒有辦法直接繪製出三次貝塞爾曲線,可是咱們能夠利用一些討巧的方法,模擬達到波浪運動時的效果,姑且把下面這種方法看做一種奇技淫巧。
原理十分簡單,咱們都知道,一個正方形,給它添加 border-radius: 50%
,將會獲得一個圓形。
border-radius
:用來設置邊框圓角,當使用一個半徑時肯定一個圓形。
好的,若是 border-radius
沒到 50%,可是接近 50% ,咱們會獲得一個這樣的圖形:
注意邊角,整個圖形給人的感受是有點圓,卻不是很圓。額,這不是廢話嗎
好的,那整這麼個圖形又有什麼用?還能變出波浪來不成?
沒錯!就是這麼神奇。:) 咱們讓上面這個圖形滾動起來(rotate) ,看看效果:
可能不少人看到這裏還沒懂旋轉起來的意圖,仔細盯着一邊看,是會有相似波浪的起伏效果的。
而咱們的目的,就是要藉助這個動態變換的起伏動畫,模擬製造出相似波浪的效果。
固然,這裏看到是全景實現圖,因此感受並不明顯,OK,讓咱們用一個個例子看看具體實現起來能達到什麼樣的效果。
咱們利用上面原理能夠作到的一種波浪運動背景效果圖:
後面漂浮的波浪效果,其實就是利用了上面的 border-radius: 45%
的橢圓形,只是放大了不少倍,視野以外的圖形都 overflow: hidden
,只留下了一條邊的視野,而且增長了一些相應的 transform
變換。
注意,這裏背景是藍色靜止的,運動是白色的橢圓形。
代碼也很簡單,SCSS 代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
body {
position
:
relative
;
align-items:
center
;
min-height
:
100
vh;
background-color
:
rgb
(
118
,
218
,
255
);
overflow
:
hidden
;
&:before, &:after {
content
:
""
;
position
:
absolute
;
left
:
50%
;
min-width
:
300
vw;
min-height
:
300
vw;
background-color
:
#fff
;
animation-name: rotate;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
&:before {
bottom
:
15
vh;
border-radius:
45%
;
animation-duration:
10
s;
}
&:after {
bottom
:
12
vh;
opacity: .
5
;
border-radius:
47%
;
animation-duration:
10
s;
}
}
@keyframes rotate {
0%
{
transform: translate(
-50%
,
0
) rotateZ(
0
deg);
}
50%
{
transform: translate(
-50%
,
-2%
) rotateZ(
180
deg);
}
100%
{
transform: translate(
-50%
,
0%
) rotateZ(
360
deg);
}
}
h2 {
position: relative;
|
爲了方便寫 DEMO,用到的長度單位是 VW 與 VH,不太瞭解這兩個單位的能夠戳這裏:vh、vw、vmin、vmax 知多少
HTML
<h2>Pure Css Wave</h2>
可能有部分同窗,還存在疑問,OK,那咱們把上面的效果縮小 10 倍,將視野以外的動畫也補齊,那麼其實生成波浪的原理是這樣的:
圖中的虛線框就是咱們實際的視野範圍。
值得注意的是,要看到,這裏咱們生成波浪,並非利用旋轉的橢圓自己,而是利用它去切割背景,產生波浪的效果。那爲何不直接使用旋轉的橢圓自己模擬波浪效果呢?由於
能夠點進去看看下面這個例子:
好,既然掌握了這種方法,下面咱們就使用純 CSS 實現上面最開始使用 SVG 或者 CANVAS 才能實現的波浪進度圖。
HTML 結構以下:
1
2
3
|
<
div
class="container">
<
div
class="wave"></
div
>
</
div
>
|
CSS 代碼以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
.container {
.wave {
position
:
relative
;
width
:
200px
;
height
:
200px
;
background-color
:
rgb
(
118
,
218
,
255
);
border-radius:
50%
;
&::before,
&::after{
content
:
""
;
position
:
absolute
;
width
:
400px
;
height
:
400px
;
top
:
0
;
left
:
50%
;
background-color
: rgba(
255
,
255
,
255
, .
4
);
border-radius:
45%
;
transform: translate(
-50%
,
-70%
) rotate(
0
);
animation: rotate
6
s linear infinite;
z-index
:
10
;
}
&::after {
border-radius:
47%
;
background-color
: rgba(
255
,
255
,
255
, .
9
);
transform: translate(
-50%
,
-70%
) rotate(
0
);
animation: rotate
10
s linear
-5
s infinite;
z-index
:
20
;
}
}
@keyframes rotate {
50%
{
transform: translate(
-50%
,
-73%
) rotate(
180
deg);
}
100%
{
transform: translate(
-50%
,
-70%
) rotate(
360
deg);
}
}
|
效果圖:
CodePen Demo -- Pure Css Wave Loading
雖然效果差了一點點,可是相較於要使用學習成本更高的 SVG 或者 CANVAS,這種純 CSS 方法無疑可以使用的場景更多,學習成本更低!
單純的讓一個 border-radius
接近 50 的橢圓形旋轉,動畫效果可能不是那麼好,咱們能夠適當的添加一些其餘變換因素,讓動畫效果看上去更真實:
border-radius
的值;
系列 CSS 文章彙總在個人 Github ,持續更新,歡迎點個 star 訂閱收藏。
好了,本文到此結束,但願對你有幫助 :)
若是還有什麼疑問或者建議,能夠多多交流,原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。
來源:http://www.cnblogs.com/coco1s/p/7197662.html