整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          純CSS實現波浪效果

          純CSS實現波浪效果

          直以來,使用純 CSS 實現波浪效果都是十分困難的。

          因為實現波浪的曲線需要借助貝塞爾曲線。

          而使用純 CSS 的方式,實現貝塞爾曲線,額,暫時是沒有很好的方法。

          當然,借助其他力量(SVG、CANVAS),是可以很輕松的完成所謂的波浪效果的,先看看,非 CSS 方式實現的波浪效果。

          使用 SVG 實現波浪效果

          借助 SVG ,是很容易畫出三次貝塞爾曲線的。

          看看效果:

          代碼如下:

          <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>
          

          畫出三次貝塞爾曲線的核心在于這一段。感興趣的可以自行去研究研究。

          使用 canvas 實現波浪效果

          使用 canvas 實現波浪效果的原理與 SVG 一樣,都是利用路徑繪制出三次貝塞爾曲線并賦予動畫效果。

          使用 canvas 的話,代碼如下:

          $(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);
              });
          })
          

          主要是利用了動態繪制 ctx.bezierCurveTo() 三次貝塞爾曲線實現波浪的運動效果,感興趣的可以自行研究。

          純 CSS 實現波浪效果

          好,接下來才是本文的重點!使用純 CSS 的方式,實現波浪的效果。

          你 TM 在逗我?剛剛不是還說使用 CSS 無能為力嗎?

          是,我們沒有辦法直接繪制出三次貝塞爾曲線,但是我們可以利用一些討巧的方法,模擬達到波浪運動時的效果,姑且把下面這種方法看作一種奇技淫巧。

          原理

          原理十分簡單,我們都知道,一個正方形,給它添加 border-radius: 50%,將會得到一個圓形。

          border-radius:用來設置邊框圓角,當使用一個半徑時確定一個圓形。

          好的,如果 border-radius 沒到 50%,但是接近 50% ,我們會得到一個這樣的圖形:

          注意邊角,整個圖形給人的感覺是有點圓,卻不是很圓。額,這不是廢話嗎

          好的,那整這么個圖形又有什么用?還能變出波浪來不成?

          沒錯!就是這么神奇。:) 我們讓上面這個圖形滾動起來(rotate) ,看看效果:

          可能很多人看到這里還沒懂旋轉起來的意圖,仔細盯著一邊看,是會有類似波浪的起伏效果的。

          而我們的目的,就是要借助這個動態變換的起伏動畫,模擬制造出類似波浪的效果。

          實現

          當然,這里看到是全景實現圖,所以感覺并不明顯,OK,讓我們用一個個例子看看具體實現起來能達到什么樣的效果。

          我們利用上面原理可以做到的一種波浪運動背景效果圖:

          CodePen Demo -- Pure CSS Wave[1]

          后面漂浮的波浪效果,其實就是利用了上面的 border-radius: 45% 的橢圓形,只是放大了很多倍,視野之外的圖形都 overflow: hidden,只留下了一條邊的視野,并且增加了一些相應的 transform 變換。

          注意,這里背景是藍色靜止的,運動是白色的橢圓形。

          代碼也很簡單,SCSS 代碼如下:

          body {
              position: relative;
              align-items: center;
              min-height: 100vh;
              background-color: rgb(118, 218, 255);
              overflow: hidden;
           
              &:before, &:after {
                  content: "";
                  position: absolute;
                  left: 50%;
                  min-width: 300vw;
                  min-height: 300vw;
                  background-color: #fff;
                  animation-name: rotate;
                  animation-iteration-count: infinite;
                  animation-timing-function: linear;
              }
           
              &:before {
                  bottom: 15vh;
                  border-radius: 45%;
                  animation-duration: 10s;
              }
           
              &:after {
                  bottom: 12vh;
                  opacity: .5;
                  border-radius: 47%;
                  animation-duration: 10s;
              }
          }
           
          @keyframes rotate {
              0% {
                  transform: translate(-50%, 0) rotateZ(0deg);
              }
              50% {
                  transform: translate(-50%, -2%) rotateZ(180deg);
              }
              100% {
                  transform: translate(-50%, 0%) rotateZ(360deg);
              }
          }
          

          為了方便寫 DEMO,用到的長度單位是 VW 與 VH,不太了解這兩個單位的可以戳這里:vh、vw、vmin、vmax 知多少[2]

          可能有部分同學,還存在疑問,OK,那我們把上面的效果縮小 10 倍,將視野之外的動畫也補齊,那么其實生成波浪的原理是這樣的:

          圖中的虛線框就是我們實際的視野范圍。

          值得探討的點

          值得注意的是,要看到,這里我們生成波浪,并不是利用旋轉的橢圓本身,而是利用它去切割背景,產生波浪的效果。那為什么不直接使用旋轉的橢圓本身模擬波浪效果呢?因為中間高,兩邊低的效果不符合物理學原理,看上去十分別扭;

          可以點進去看看下面這個例子:

          CodePen Demo -- pure css wave[3]

          使用純 CSS 實現波浪進度圖

          好,既然掌握了這種方法,下面我們就使用純 CSS 實現上面最開始使用 SVG 或者 CANVAS 才能實現的波浪進度圖。

          HTML 結構如下:

          <div class="container">
              <div class="wave"></div>
          </div>
          
          .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 6s linear infinite;
                  z-index: 10;
              }
               
              &::after {
                  border-radius: 47%;
                  background-color: rgba(255, 255, 255, .9);
                  transform: translate(-50%, -70%) rotate(0);
                  animation: rotate 10s linear -5s infinite;
                  z-index: 20;
              }
          }
           
          @keyframes rotate {
              50% {
                  transform: translate(-50%, -73%) rotate(180deg);
              } 100% {
                  transform: translate(-50%, -70%) rotate(360deg);
              }
          }
          

          效果圖:

          CodePen Demo -- Pure Css Wave Loading[4]

          雖然效果差了一點點,但是相較于要使用學習成本更高的 SVG 或者 CANVAS,這種純 CSS 方法無疑可使用的場景更多,學習成本更低!

          純 CSS 的充電效果

          還能實現類似這樣的充電效果:

          一些小技巧

          單純的讓一個 border-radius 接近 50 的橢圓形旋轉,動畫效果可能不是那么好,我們可以適當的添加一些其他變換因素,讓動畫效果看上去更真實:

        1. 在動畫過程中,動態的改變 border-radius 的值;
        2. 在動畫過程中,利用 transform 對旋轉橢圓進行輕微的位移、變形;
        3. 上面也演示到了,多個橢圓同時轉動,賦予不同時長的動畫,并且添加輕微的透明度,讓整個效果更加逼真。
        4. 提起圖標,大家可能第一個會想到PS、美工等詞語,但很多小圖標現在根本都不需要再打開PS了。

          1、常見的括號( 前進或后退“>” )

          .arrow{
            width:12rpx;
            height:12rpx; 
            border-top:1px solid #999;
            border-right:1px solid #999;
            transform:rotate(-45deg); 
            position:absolute; 
            right:10px; 
          }


          2、常見的關閉按鈕( “X” ),這里需要用到一個偽類

          .close {
                  display: inline-block;
                  width: 30px;
                  height: 4px;
                  background: #333;
                  transform: rotate(45deg);
              }
          
              .close::after {
                  content: '';
                  display: block;
                  width: 30px;
                  height: 4px;
                  background: #333;
                  transform: rotate(-90deg);
              }


          3、常見的勾選( “√” )

          .check {
              position: relative;
              display: inline-block;
              width: 25px;
              height: 25px;
              background: #333;
              border-radius: 25px;
          }
          .check::after {
              content: "";
              position: absolute;
              left: 5px;
              top: 8px;
              width: 50%;
              height: 25%;
              border: 2px solid #fff;
              border-radius: 1px;
              border-top: none;
              border-right: none;
              background: transparent;
              transform: rotate(-45deg);
          }


          4、常見的加號( “+” ),同樣需要利用偽類

          .add {
            width: 100px;
            height: 100px;
            color: #ccc;
            transition: color .25s;
            position: relative;
          }
          
           .add::before{
            content: '';
            position: absolute;
            left: 50%;
            top: 50%;
            width: 80px;
            margin-left: -40px;
            margin-top: -5px;
            border-top: 10px solid;
          }
          
          .add::after {
           content: '';
           position: absolute;
           left: 50%;
           top: 50%;
           height: 80px;
           margin-left: -5px;
           margin-top: -40px;
           border-left: 10px solid;
          }


          5、常見的波浪線( “~” ),同樣需要利用偽類

          .info::before {
          content: '';
          position: absolute;
          top: 30px;
          width: 100%;
          height: 0.25em;
          
          background:
           linear-gradient(
          135deg, 
           transparent, 
           transparent 45%, 
           #008000, 
           transparent 55%, 
           transparent 100%
           ),
          linear-gradient(
           45deg, 
           transparent, 
           transparent 45%, 
            #008000, 
           transparent 55%, 
           transparent 100%
          );
          background-size: 0.5em 0.5em;
          background-repeat: repeat-x, repeat-x;
          }


          5、常見的三角形

          .triangle-up {
          width: 0;
          height: 0;
          border-left: 50px solid transparent;
          border-right: 50px solid transparent;
          border-bottom: 100px solid red;
          }


          6、常見的扇形

          .sector {
          width: 0;
          height: 0;
          border-left: 50px solid transparent;
          border-right: 50px solid transparent;
          border-top: 100px solid #f00;
          border-radius: 50%;
          }


          7、仿微信對話框

          .alertDialog {
          /* 對話框:一個圓角矩形和一個小三角形 */
          width: 150px;
          height: 100px;
          background: #f00;
          border-radius: 10px;
          position: relative;
          }
          .alertDialog:before {
          content: "";
          width: 0;
          height: 0;
          position: absolute;
          left: -20px;
          top: 40px;
          border-top: 10px solid transparent;
          border-bottom: 10px solid transparent;
          border-right: 20px solid #f00;
          }


          8、鉆石圖標

          .diamond {
          /* 鉆石:梯形和三角形組成 */
          width: 50px;
          height: 0;
          position: relative;
          border-bottom: 25px solid #f00;
          border-left: 25px solid transparent;
          border-right: 25px solid transparent;
          }
          .diamond:before {
          content: "";
          width: 0;
          height: 0;
          position: absolute;
          border-left: 50px solid transparent;
          border-right: 50px solid transparent;
          border-top: 70px solid #f00;
          left: -25px;
          top: 25px;
          }


          9、五角星圖標

          .starFive {
           width: 0;
           height: 0;
           position: relative;
           border-left: 80px solid transparent;
           border-right: 80px solid transparent;
           border-bottom: 60px solid #f00;
           transform: rotate(35deg);
          }
          .starFive:before {
           content: "";
           position: absolute;
           width: 0;
           height: 0;
           border-left: 80px solid transparent;
           border-right: 80px solid transparent;
           border-bottom: 60px solid #f00;
           transform: rotate(-70deg);
           top: 3px;
           left: -80px;
          }
          .starFive:after {
           content: "";
           position: absolute;
           width: 0;
           height: 0;
           border-bottom: 60px solid #f00;
           border-right: 20px solid transparent;
           border-left: 20px solid transparent;
           transform: rotate(-35deg);
                  top: -40px;
                  left: -49px;
          }


          喜歡的可以加個關注,不定期發布更多CSS相關文章

          1)背景樣式屬性,用于定義 HTML 元素的背景色、背景圖片,同時還可以進行背景定位、背景圖片重復、背景圖片固定。

          • background-color
          • background-image
          • background-size
          • background-position
          • background-repeat

          background-color 屬性可以給指定標簽元素設置背景色。

          舉個例子! 我們給 body 元素設置一個背景顏色:

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>Document</title>
              <style>
                body {
                  background-color: yellowgreen;
                }
              </style>
            </head>
            <body></body>
          </html>

          background-image 屬性可以把圖像插入背景。background-size 屬性可以給背景圖設置大小。

          舉個例子! 我們給 body 元素設置一個背景圖像。

          wget https://labfile.oss.aliyuncs.com/courses/3773/moon.jpg
          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>Document</title>
              <style>
                body {
                  background-image: url("moon.jpg");
                  background-size: 300px 300px;
                }
              </style>
            </head>
            <body></body>
          </html>


          通過 background-position 屬性,可以改變圖像在背景中的位置。

          background-position 屬性,設置屬性值為居中:

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>Document</title>
              <style>
                body {
                  background-image: url("moon.jpg");
                  background-size: 300px 300px;
                  background-position: center;
                }
              </style>
            </head>
            <body></body>
          </html>


          background-repeat 屬性是用來設置背景圖像是否平鋪。

          下表列出了 background-repeat 屬性的一些可取值以及每個可取值的含義。

          可 取 值

          描 述

          repeat

          背景圖像將在垂直方向和水平方向重復(默認值)

          repeat-x

          背景圖像將在水平方向重復

          repeat-y

          背景圖像將在垂直方向重復

          no-repeat

          背景圖像將僅顯示一次

          我們規定應該從父元素繼承 background-repeat 屬性的設置。

          background-repeat 屬性并設置值為不平鋪:

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>Document</title>
              <style>
                body {
                  background-image: url("moon.jpg");
                  background-size: 300px 300px;
                  background-position: center;
                  background-repeat: no-repeat;
                }
              </style>
            </head>
            <body></body>
          </html>


          (2)文本相關的屬性

          • line-height 屬性
          • text-indent 屬性
          • text-align 屬性
          • letter-spacing 屬性
          • text-decoration 屬性
          • white-space 屬性
          • line-break 屬性

          文本屬性用于定義文本的樣式,通過文本屬性,可以改變文本的顏色、字間距、對齊方式、文本修飾和文本縮進等。常用文本屬性如下表所示:

          屬 性

          可 取 值

          描 述

          line-height

          normal、number、length、%

          設置行高

          text-indent

          length、%

          設置文本縮進

          text-align

          left、right、center、justify、start、end

          設置對齊方式

          letter-spacing

          normal、length

          設置字符間距

          text-decoration

          line、color、style、thickness

          設置文本修飾

          white-space

          normal、pre、nowrap、pre-wrap、pre-line、break-spaces

          規定如何處理空白

          line-break

          auto、loose、normal、strict、anywhere、unset

          處理如何斷開帶有標點符號的文本的行

          line-height 用于設置多行元素的空間量,可取值具體說明如下:

          • normal:取決于用戶端。
          • number:數字乘以元素的字體大小。
          • length:指定長度用于計算高度。
          • %:計算值是給定的百分比值乘以元素計算出的字體大小。

          例子,

          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8" />
              <meta name="viewport" content="width=device-width, initial-scale=1.0" />
              <title>line-height 的使用</title>
              <style>
                div {
                  width: 300px;
                  height: 400px;
                  border: 1px solid;
                  font-size: 15px;
                  display: inline-block;
                  vertical-align: top;
                }
                .div1 {
                  line-height: 2; /*15 * 2*/
                }
                .div2 {
                  line-height: 30%; /*15 * 30% */
                }
              </style>
            </head>
            <body>
              <div class="div1">
                <p>“海水呀,你說的是什么?”</p>
                <p>“是永恒的疑問?!?lt;/p>
                <p>“天空呀,你回答的話是什么?”</p>
                <p>“是永恒的沉默?!?lt;/p>
              </div>
              <div class="div2">
                <p>“海水呀,你說的是什么?”</p>
                <p>“是永恒的疑問。”</p>
                <p>“天空呀,你回答的話是什么?”</p>
                <p>“是永恒的沉默?!?lt;/p>
              </div>
            </body>
          </html>
          

          顯示為,


          主站蜘蛛池模板: 成人影片一区免费观看| 色欲综合一区二区三区| 无码人妻精品一区二区蜜桃 | 国产精品毛片一区二区 | 国产激情一区二区三区四区| 日本一道一区二区免费看| 亚洲熟妇av一区二区三区下载| 色老头在线一区二区三区 | 好吊妞视频一区二区| 极品少妇一区二区三区四区| 日本精品啪啪一区二区三区| 精品亚洲一区二区三区在线播放| 国产亚洲3p无码一区二区| 久久久精品人妻一区亚美研究所| 无码精品黑人一区二区三区 | 精品国产一区二区三区无码| 一色一伦一区二区三区| 福利一区二区在线| 免费一区二区三区| 国产微拍精品一区二区| 大伊香蕉精品一区视频在线| 麻豆高清免费国产一区| 一区二区三区免费高清视频| 91久久精品一区二区| 一区五十路在线中出| 精品亚洲综合在线第一区| 亚洲av无码一区二区三区四区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 日韩精品乱码AV一区二区| 日韩精品一区在线| 国产人妖视频一区二区| 国模无码视频一区| 一区二区三区精品| 国产MD视频一区二区三区| 一区二区三区福利视频免费观看| 国产一区二区三区免费在线观看| 一区二区三区四区视频| 国产韩国精品一区二区三区| 欧美激情国产精品视频一区二区| 精品亚洲一区二区| 亚洲国模精品一区|