成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

聊聊怎么利用CSS實現波浪進度條效果

本篇文章給大家分享CSS 高階技巧,介紹一下如何使用CSS實現波浪進度條效果,希望對大家有所幫助!

聊聊怎么利用CSS實現波浪進度條效果

本文是 CSS Houdini 之 CSS Painting API 系列第三篇。

  • 現代 CSS 之高階圖片漸隱消失術
  • 現代 CSS 高階技巧,像 Canvas 一樣自由繪圖構建樣式!

在上兩篇中,我們詳細介紹了 CSS Painting API 是如何一步一步,實現自定義圖案甚至實現動畫效果的!

在這一篇中,我們將繼續探索,嘗試使用 CSS Painting API,去實現一些過往純 CSS 無法實現的效果。【推薦學習:css視頻教程】

CSS Painting API

再簡單快速的過一下,什么是 CSS Painting API。

CSS Painting API 是 CSS Houdini 的一部分。而 Houdini 是一組底層 API,它們公開了 CSS 引擎的各個部分,從而使開發人員能夠通過加入瀏覽器渲染引擎的樣式和布局過程來擴展 CSS。Houdini 是一組 API,它們使開發人員可以直接訪問 CSS 對象模型 (CSSOM),使開發人員可以編寫瀏覽器可以解析為 CSS 的代碼,從而創建新的 CSS 功能,而無需等待它們在瀏覽器中本地實現。

CSS Paint API 目前的版本是 CSS Painting API Level 1。它也被稱為 CSS Custom Paint 或者 Houdini's Paint Worklet。

我們可以把它理解為 JS In CSS,利用 JavaScript Canvas 畫布的強大能力,實現過往 CSS 無法實現的功能。

利用 CSS Painting API 實現波浪效果

CSS 實現波浪效果,一直是 CSS 的一個難點之一。在過往,雖然我們有很多方式利用 Hack 出一些波浪效果,我在之前的多篇文章中有反復提及過:

  • 純 CSS 實現波浪效果!
  • 一種巧妙的使用 CSS 制作波浪效果的思路
  • 圓角大殺器,使用濾鏡構建圓角及波浪效果!

是的,大部分時候,我們都是利用一些奇技淫巧實現波浪效果,像是這樣:

聊聊怎么利用CSS實現波浪進度條效果

如今,有了 CSS Painting API,我們已經可以繪制真實的波浪效果了。看看代碼:

<div></div>  <script> if (CSS.paintWorklet) {                   CSS.paintWorklet.addModule('/CSSHoudini.js'); } </script>
登錄后復制

div {     position: relative;     width: 300px;     height: 300px;     background: paint(waveDraw);     border-radius: 50%;     border: 2px solid rgba(255, 0, 0, 0.5); }
登錄后復制

我們定義了一個 waveDraw 方法,接下來,就通過利用 registerPaint 來實現這個方法即可。

// 文件名為 CSSHoudini.js registerPaint(     "waveDraw",     class {         static get inputProperties() {             return [];         }         paint(ctx, size, properties) {             const { width, height } = size;             const initY = height * 0.5;             ctx.beginPath();             for (let i = 0; i <= width; i++) {                 ctx.lineTo(i, initY + Math.sin((i) / 20) * 10);             }             ctx.lineTo(width, height);             ctx.lineTo(0, height);             ctx.lineTo(0, initY);             ctx.closePath();              ctx.fillStyle = 'rgba(255, 0, 0, 0.9)';             ctx.fill();         }     } );
登錄后復制

這樣,我們就得到了這樣一個波浪效果:

聊聊怎么利用CSS實現波浪進度條效果

上面的代碼其實很好理解,簡單解釋一下,我們核心就是利用路徑繪制,基于 Math.sin() 三角函數,繪制了一段 sin(x) 三角函數的圖形。

  • 整個圖形從 ctx.beginPath() 開始,第一個點是 ctx.lineTo(0, initY + Math.sin((i) / 20) * 10),不過 Math.sin(0) = 0,所以等于 ctx.lineTo(0, initY)

  • initY 在這的作用是控制從什么高度開始繪制波浪圖形,我們這里的取值是 initY = height * 0.5,也就是定義成了圖形的中間位置

  • 利用 for (let i = 0; i <= width; i++) 循環,配合 ctx.lineTo(i, initY + Math.sin((i) / 20) * 10),也就是在每一個 x 軸上的點,都繪制一個點

  • 隨后三個在循環體外的 ctx.lineTo 的作用是讓整個圖形形成一個閉環

  • 最后 ctx.closePath() 完成整個路徑,ctx.fill() 進行上色

如果不 ctx.fill() 上色,利用 ctx.stroke() 繪制邊框,也是可以的,其實我們得到是這樣一個圖形:

聊聊怎么利用CSS實現波浪進度條效果

上圖是同時去掉了 CSS 代碼里面的 border-radius: 50%,方便大家理解。

當然,上面的圖形,有個很大的問題,沒法動起來,所以,我們需要借助一個 CSS @Property 自定義變量,讓它擁有一些動畫效果。

我們需要改造一下代碼,首先,添加一個 CSS @Property 自定義變量:

@property --animation-tick {   syntax: '<number>';   inherits: false;   initial-value: 1000; } div {   // ... 代碼與上述保持一致   animation: move 20s infinite linear;   --animation-tick: 1000; } @keyframes move {     100% {         --animation-tick: 0;     } }
登錄后復制

我們添加了一個 --animation-tick 變量,并且利用 CSS 動畫,讓它從 1000 減至 0。

下一步,利用這個不斷在變化的 CSS 自定義變量,我們在 waveDraw 方法中,把它利用上:

// 文件名為 CSSHoudini.js registerPaint(     "waveDraw",     class {         static get inputProperties() {             return ["--animation-tick"];         }         paint(ctx, size, properties) {             let tick = Number(properties.get("--animation-tick"));             const { width, height } = size;             const initY = height * 0.5;             ctx.beginPath();             for (let i = 0; i <= width; i++) {                 ctx.lineTo(i, initY + Math.sin((i + tick) / 20) * 10);             }             ctx.lineTo(width, height);             ctx.lineTo(0, height);             ctx.lineTo(0, initY);             ctx.closePath();              ctx.fillStyle = 'rgba(255, 0, 0, 0.9)';             ctx.fill();         }     } );
登錄后復制

仔細看,和上述的代碼變化不大,核心在于,利用三角函數繪制圖形的時候,我們把這個變量加入進去。

從原來的 ctx.lineTo(i, initY + Math.sin((i) / 20) * 10),變成了 ctx.lineTo(i, initY + Math.sin((i + tick) / 20) * 10)

這樣,在這個不斷變化的變量的作用下,我們的波浪圖形就能運動起來了:

聊聊怎么利用CSS實現波浪進度條效果

CodePen Demo — CSS Houdini Wave

雖然能動了,但是總是感覺還少了些什么。如果我們把這個波浪效果應用與進度條之類的效果上,我們可以需要可以快速定義波浪的振幅、每個波峰之間的間距、效果的顏色、百分比等等。

因此,我們需要再通過一個 CSS 變量,讓它成為一個實際可用的封裝良好的波浪進度條。我們再簡單改造一下:

@property --animation-tick {   syntax: '<number>';   inherits: false;   initial-value: 1000; } @property --height {   syntax: '<number>';   inherits: false;   initial-value: .7; } div {     position: relative;     width: 300px;     height: 300px;     background: paint(waveDraw);     animation: move 20s infinite linear;     border-radius: 50%;     border: 2px solid var(--color1);     --amplitude: 15;     --gap: 28;     --animation-tick: 700;     --height: 0.7;     --color1: rgba(255, 0, 0, 0.5);     --color2: rgba(255, 0, 0, 0.4);     --color3: rgba(255, 0, 0, 0.3);          transition: --height 8s; }
登錄后復制

可以看到,我們定義了非常多個 CSS 變量,每次,它們都是有意義的:

  • --animation-tick 表示波浪運動的速率
  • --amplitude 波浪的振幅
  • --gap 波峰間距
  • --initHeight 初始高度
  • --color1--color2--color3 我們會疊加 3 層波浪效果,顯得更真實一點,這里 3 個顏色表示 3 層波浪的顏色

定義好這些 CSS 變量后,我們就可以把它們運用在實際的waveDraw 方法中。看看代碼:

registerPaint(     "waveDraw",     class {         static get inputProperties() {             return [                 "--animation-tick",                  "--height",                  "--gap",                 "--amplitude",                 "--color1",                 "--color2",                 "--color3"             ];         }                  paint(ctx, size, properties) {             let tick = Number(properties.get("--animation-tick"));             let initHeight = Number(properties.get("--height"));             let gap = Number(properties.get("--gap"));             let amplitude = Number(properties.get("--amplitude"));             let color1 = properties.get("--color1");             let color2 = properties.get("--color2");             let color3 = properties.get("--color3");                          this.drawWave(ctx, size, tick, amplitude, gap, initHeight, color1);             this.drawWave(ctx, size, tick * 1.21, amplitude / 0.82, gap + 2, initHeight + 0.02, color2);             this.drawWave(ctx, size, tick * 0.79, amplitude / 1.19, gap - 2, initHeight - 0.02, color3);         }                  /**          * ctx          * size          * tick 速率          * amplitude 振幅          * gap 波峰間距          * initHeight 初始高度          * color 顏色          */         drawWave(ctx, size, tick, amplitude, gap, initHeight, color) {             const { width, height } = size;             const initY = height * initHeight;             tick = tick * 2;                          ctx.beginPath();             for (let i = 0; i <= width; i++) {                 ctx.lineTo(i, initY + Math.sin((i + tick) / gap) * amplitude);             }             ctx.lineTo(width, height);             ctx.lineTo(0, height);             ctx.lineTo(0, initY);             ctx.closePath();             ctx.fillStyle = color;             ctx.fill();         }     } );
登錄后復制

可以看到,我們在 paint() 方法中,調用了 this.drawWave()。每次調用 this.drawWave() 都會生成一個波浪圖形,通過 3 層的疊加效果,生成 3 層波浪。并且,把我們在 CSS 中定義的變量全部的應用了起來,分別控制波浪效果的不同參數。

這樣,我們就得到了這樣一個波浪效果:

聊聊怎么利用CSS實現波浪進度條效果

通過控制 CSS 中的 --height 變量,還可以實現高度的變化,從而完成真實的百分比,實現一種進度條效果。

div:hover {     --height: 0; }
登錄后復制

效果如下:

聊聊怎么利用CSS實現波浪進度條效果

很好,非常不錯的效果。有了上述一些 CSS 自定義變量的幫助,我們就可以通過封裝好的 waveDraw 方法,實現不同顏色,不同大小,不同速率的波浪進度條效果了。

我們只需要簡單的改變一下傳入的 CSS 變量參數即可:

<div></div> <div></div> <div></div>
登錄后復制

div {     position: relative;     width: 300px;     height: 300px;     background: paint(waveDraw);     animation: move 20s infinite linear;     border-radius: 50%;     border: 2px solid var(--color1);     --amplitude: 15;     --gap: 28;     --animation-tick: 700;     --height: 0.7;     --color1: rgba(255, 0, 0, 0.5);     --color2: rgba(255, 0, 0, 0.4);     --color3: rgba(255, 0, 0, 0.3);          transition: --height 8s; } div:nth-child(2) {     --amplitude: 6;     --gap: 25;     --animation-tick: 300;     --height: 0.5;     --color1: rgba(28, 90, 199, 0.5);     --color2: rgba(28, 90, 199, 0.4);     --color3: rgba(28, 90, 199, 0.3); } div:nth-child(3) {     --amplitude: 3;     --gap: 30;     --animation-tick: 1200;     --height: 0.3;     --color1: rgba(178, 120, 33, 0.5);     --color2: rgba(178, 120, 33, 0.4);     --color3: rgba(178, 120, 33, 0.3); }
登錄后復制

看看效果如何:

聊聊怎么利用CSS實現波浪進度條效果

CodePen Demo — CSS Hudini Custom Wave Effects !

這樣,借助 CSS Painting API,我們完美的實現了波浪圖形,并且借助它,實現了波浪進度條效果。通過傳入不同的 CSS 變量,我們有了快速批量生成不同效果的能力。彌補了過往 CSS 在波浪效果上的缺陷!

當然,就基于上述的代碼,還是有一些可以優化的空間的:

  • 在上述的 CSS 代碼中,可以看到,我們是傳入了 3 個關于顏色的 CSS 變量,--color1--color2--color3,正常而言,這里傳入 1 個顏色即可,通過轉換成 HSL 顏色表示法,替換 L 色值,得到近似的另外兩個色值即可。當然,這樣做的話會增添非常多的 JavaScript 代碼,所以,本文為了方便大家理解,偷懶直接傳入了 3 個 CSS 顏色變量值;

  • 整個波浪效果單輪的動畫持續時間我設置為了 20s,但是在本文中,沒有去適配動畫的手尾銜接,也就是可能會出現每 20s,波浪效果有一個明顯的跳動的感覺。解決這個問題,有兩個思路

    • 通過精確的計算,讓動畫的最后一幀和動畫的第一幀銜接上
    • --animation-tick 的值設置的非常的大,然后把相應的單輪動畫時間設置的非常長,這樣,基本也感受不到動畫的跳幀
  • 第三個問題可能就在于兼容性

兼容性?

好吧,其實上一篇文章也談到了兼容問題,因為可能有很多看到本篇文章并沒有去翻看前兩篇文章的同學。那么,CSS Painting API 的兼容性到底如何呢?

CanIUse – registerPaint 數據如下(截止至 2022-11-23):

聊聊怎么利用CSS實現波浪進度條效果

Chrome 和 Edge 基于 Chromium 內核的瀏覽器很早就已經支持,而主流瀏覽器中,Firefox 和 Safari 目前還不支持。

CSS Houdini 雖然強大,目前看來要想大規模上生產環境,仍需一段時間的等待。讓我們給時間一點時間!

原文地址:https://juejin.cn/post/7170868201645932551

作者:ChokCoco

(學習視頻分享:web前端)

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
黑料吃瓜网998.SU永久有效 | 亚洲色欲色欲欲WWW在线| 亚洲AV综合A∨一区二区| 亚洲欧美另类激情综合区蜜芽| 麻豆影视视频在线观看完整版| 91人妻人人妻人人爽人人精品| 欧美成人精品欧美一级乱黄 | 亚洲精品国偷拍自产在线观看| 精品精品国产高清A毛片| 在线观看WWW成人片| 欧美乱妇高清无乱码在线观看| 国产精品一线二线三线| 亚洲欧美性爱视频| 久久九九日本韩国精品| 岳胀耸的雪乳奶水| 亚洲精品无码久久毛片 | 精品人伦一区二区三区蜜桃| 国产乱色国产精品免费视频| 激情综合亚洲色婷婷五月APP| 精品一线二线三线精华液| 老熟妇一区二区三区啪啪| 日本MACBOOKPRO高清| 无码AV波多野结衣久久| 免费女同毛片在线播放| 日本免费人成视频在线观看| 午夜亚洲AⅤ无码高潮片| 亚洲一区二区三区在线播放无码| 97久久综合亚洲色HEZYO| 把腿张开老子臊烂你多p晓晓| 国产精品成人3p一区二区三区| 精品久久久久久亚洲精品 | 国产韩国精品一区二区三区久久| 国产一起色一起爱| 免费A级毛片无码免费视频1| 日韩精品无码成人专区| 亚洲国产成人丁香五月激情| 97AV麻豆蜜桃一区二区| 丰满日韩放荡少妇无码视频| 精品无人区一线二线三线区别| 欧美一区二区三区红桃小说| 天堂在\/线中文在线8| 欧美嫩交一区二区三区| 国产丰满老熟女重口对白| 丰满少妇张开双腿无码AV| 亚洲女人操BB在线| 色综合天天视频在线观看| 丰满熟妇大号BBWBBWBBW| 一本无码中文字幕在线观| 天黑黑影院在线观看免费中文| 久久夜色撩人精品国产AV| 人妻丝袜另类欧美偷拍视频| 97久章草在线视频播放| 亚洲国产午夜精品理论片妓女| 色欧美片视频在线观看| 无码午夜成人1000部免费视频| 一本一道AV无码中文字幕﹣百度 | 婷婷开心色四房播播| 夜夜躁婷婷AV蜜桃妖精视频| 抖抈短视频APP下载| 精品一区二区AV天堂| 日本少妇人妻XXXXX18免费| 亚洲国产精品无码久久电影| 成年网站免费视频黄A站| 精品无码久久久久国产动漫3D| 日韩A片无码一区二区五区电影| 亚洲人成人无码WWW影院| 第九午夜不卡影院| 久久亚洲AV成人无码国产最大| 少妇午夜AV一区| 中文字幕日产无线码一区| 国产在线精品一区二区三区直播 | 四十路の五十路熟女豊満AV| 在线 | 一区二区三区四区| 国产精品久久久爽爽爽麻豆色哟哟 | 无码人妻AⅤ一区二区三区| 99品一二三产区区别| 精品一线二线三线精华液| 国产粉嫩呻吟一区二区三区| 韩国V欧美V亚洲V日本| 人人爽人人爽人人片A∨不卡| 日产乱码一二三区别免费麻豆| 视频视频APP在线看| 偷拍区小说区图片区另类呻吟| 皇上御花园HLH| 美国五月婷婷毛片| 日韩欧美午夜成人精品视频| 亚洲狠狠色成人综合网| 亚洲国产精品久久久久婷婷图片| 中文字幕伊人久久| 久久99精品久久久久蜜芽| 女人下边水润紧致好处| 亚洲国产精品无码AV| 国产AⅤ无码专区亚洲AV麻豆| 男女啪啪摸下面喷水网站| 亚洲AV无码久久精品成人| ZOOM另一类ZZO0| 国产精品VA尤物在线观看| 狠狠色噜噜狠狠狠狠97| 免费无码又爽又刺激动态图| 太深太粗太大太猛太爽了视频| 亚洲AV无码不卡在线播放| CHINESE国产AVVIDE| 国产乱码一区二区三区| 男女啪啪摸下面喷水网站| 亚洲爆乳精品无码一区二区| 一本大道无码AV天堂| 狂野欧美激情性XXXX| 欧美亚洲国产SUV| 亚洲国产AV无码专区亚洲AVL| 宝宝又大了1V1| 免费私人家庭影院| 亚洲中文字幕精品久久久久久动漫| СЕКС日本ВИДЕ视频| 国内情侣作爱视频网站| 无码超级大爆乳在线播放| 人妻少妇不满足中文字幕| 在线精品亚洲一区二区绿巨人| 满熟妇XXXX性久久9久久| 香蕉国产成版人视频APP| 潮喷失禁大喷水AⅤ无码| 精品无码一区二区三区水蜜桃| 欧美人与劲物XXXXZ0OZ| 少妇极品熟妇人妻200片| 337P日本欧洲亚洲大胆69影| 久久人人97超碰CAOPORE| 97久久超碰福利国产精品…| 女儿的朋友7中汉字晋通话| ZOOM与人性ZOOM2023| 睡着了强行挺进岳身体| 国产日产精品_国产精品毛片| 亚洲国产成人综合在线不卡| 久久久久亚洲AV成人网人人| 亚洲日韩欧美一区二区三区 | 強暴強姦AV正片一区二区三区 | 亚洲国产精品一区二区美利坚| 国产精品毛片完整版视频| 午夜影视啪啪免费体验区入口| 吃奶呻吟打开双腿做受是免费视频| 欧美精品AⅤ一区二区三区| 99久久精品免费看国产一区二区| 精品久久久久久狼人社区| 试看AAAA啪啪片120秒| YSL千人千色T9和T9的区别| 嫩小BBB揉BBB揉BBBB| 亚洲AV无码久久久久网站蜜桃| 国产无人区码一码二码三MBA| 亚洲国产一区二区A毛片| 日本XXX色视频| 精品久久久无码中文字幕天天| 2021最新久久久视精品爱| 天天做天天爱天天爽综合网 | 男女作爱在线播放免费网站| 中年人妻丰满AV无码久久不卡| 美女下部裸体张开腿视频| 亚洲精品TV久久久久久久久久| 黑人高潮拔也拔不出来| 亚洲AV无码成人YELLOW| 老师露双奶头无遮挡挤奶视频| H精品无码动漫在线观看| 台湾无码AV一区二区三区| 男人操女人视频图片日韩| 99久久人妻无码精品系列| 人妻在线日韩免费视频| 国产午夜毛片V一区二区三区| 亚洲日韩看片成人无码| 拗女稀缺资源一区二区| 国产精品无码久久AV| 亚洲中文字幕无码一区无广告 | 亚洲一区二区三区无码蜜桃| 国产亚洲精久久久久久无码777| 征服丰满人妻老师| 日本老熟妇人妻妇毛多多| 国产成人无码AⅤ片在线观看你| 人人妻熟妇中年乱子伦A| 国产在线精品一区二区三区不卡| 一个吃我奶头两个舔我下面| 欧美综合自拍亚洲图久青草| 成人免费视频CAOPORN| 小寡妇一夜要了六次| 久久无码人妻精品一区二区三区| 爱情岛论坛自拍亚洲品质极速福利 | 啊!摁摁~啊!用力~快点视频| 熟交XXXXⅩ欧美老妇妇牲| 精品无码人妻被多人侵犯aⅴ| 成熟丰满熟妇自慰XXXXX| 99国精产品灬源码1688| 中文字幕亚洲综合久久综合| 亚洲熟女一区二区三区| 日韩电影久久久被窝网| 久久无码一区二区| 国产女人乱子对白AV片| 成人免费无码大片A毛片抽搐 | 中文字幕日韩一区二区不卡| 婷婷五月综合缴情在线视频| 免费观看的A级毛片的网站| 国产无遮挡又黄又爽无VIP| 国产A在亚洲线播放| 杂交BUCSM人类SSBA| 亚洲AⅤ无码日韩AV中文AV伦| 日韩精品无码一区二区视频|