亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > CSS > 正文

CSS Houdini實現動態波浪紋效果

2024-07-11 09:00:09
字體:
來源:轉載
供稿:網友

CSS Houdini 號稱 CSS 領域最令人振奮的革新。CSS 本身長期欠缺語法特性,可拓展性幾乎為零,并且新特性的支持效率太低,兼容性差。而 Houdini 直接將 CSS 的 API 暴露給開發者,以往完全黑盒的瀏覽器解析流開始對外開放,開發者可以自定義屬于自己的 CSS 屬性。

背景

我們知道,瀏覽器在渲染頁面時,首先會解析頁面的 HTML 和 CSS,生成渲染樹(rendering tree),再經由布局(layout)和繪制(painting),呈現出整個頁面內容。在 Houdini 出現之前,這個流程上我們能操作的空間少之甚少,尤其是 layout 和 painting 環節,可以說是完全封閉,極大地限制了 CSS 的靈活性。社區中 sass、less、stylus 等 CSS 預處理技術的出現大多都源于這個原因,它們都希望通過預編譯,突破 CSS 的局限性,讓 CSS 擁有更強大的組織和編寫能力。所以慢慢地,我們都不再手寫 CSS,更方便、更靈活的 CSS 擴展語言成了 web 開發的主角。看到這樣的情況,CSS Houdini 終于坐不住了。

什么是 CSS Houdini?

CSS Houdini 對外開放了瀏覽器解析流程的一系列 API,這些 API 允許開發者介入瀏覽器的 CSS engine 運作,帶來了更多的 CSS 解決方案。

CSS Houdini 主要提供了以下幾個 API:

CSS Properties and Values API

允許在 CSS 中定義變量和使用變量,是目前兼容性最好的一個 API;

Layout API

允許開發者編寫自己的 Layout Module,自定義諸如 display 這類的布局屬性;

Painting API

允許開發者編寫自己的 Paint Module,自定義諸如 background-image 這類的繪制屬性。

基礎:三步用上 Painting API

1、HTML 中通過 Worklets 載入樣式的自定義代碼:

<div class="rect"></div><script>  if ("paintWorklet" in CSS) {    CSS.paintWorklet.addModule("paintworklet.js");  }</script>

Worklets 也是 Houdini 提供的 API 之一,負責加載和執行樣式的自定義 JS 代碼。它類似于 Web Worker,是一個運行于主代碼之外的獨立工作進程,但比 Worker 更為輕量,負責 CSS 渲染任務最為合適。

2、新建一個 paintworklet.js,利用 registerPaint 方法注冊一個 paint 類 rect,定義 paint 屬性的繪制邏輯:

registerPaint(  "rect",  class {    static get inputProperties() {      return ["--rect-color"];    }    paint(ctx, geom, properties) {      const color = properties.get("--rect-color")[0];      ctx.fillStyle = color;      ctx.fillRect(0, 0, geom.width, geom.height);    }  });

上邊定義了一個名為 rect 的 paint 屬性類,當 rect 被使用時,會實例化 rect 并自動觸發 paint 方法執行渲染。paint 方法中,我們獲取節點 CSS 定義的 --rect-color 變量,并將元素的背景填充為指定顏色。ctx 參數是一個 Canvas 的 Context 對象,因此 paint 的邏輯跟 Canvas 的繪制方式一樣。

3、CSS 中使用的時候,只需要調用 paint 方法:

.rect {  width: 100vw;  height: 100vh;  background-image: paint(rect);  --rect-color: rgb(255, 64, 129);}

這是一個自定義 CSS 背景色屬性的簡單實現,看得出利用 CSS Houdini,我們可以像操作 canvas 一樣靈活自如地實現我們想要的樣式功能。

進階:實現動態波紋

根據上述步驟,我們演示一下如何用 CSS Painting API 實現一個動態波浪的效果:

<!-- index.html --><div id="wave"></div><style>  #wave {    width: 20%;    height: 70vh;    margin: 10vh auto;    background-color: #ff3e81;    background-image: paint(wave);  }</style><script>  if ("paintWorklet" in CSS) {    CSS.paintWorklet.addModule("paintworklet.js");    const wave = document.querySelector("#wave");    let tick = 0;      requestAnimationFrame(function raf(now) {      tick += 1;      wave.style.cssText = `--animation-tick: ${tick};`;      requestAnimationFrame(raf);    });  }</script>// paintworklet.jsregisterPaint('wave', class {  static get inputProperties() {    return ['--animation-tick'];  }  paint(ctx, geom, properties) {    let tick = Number(properties.get('--animation-tick'));    const {      width,      height    } = geom;    const initY = height * 0.4;    tick = tick * 2;    ctx.beginPath();    ctx.moveTo(0, initY + Math.sin(tick / 20) * 10);    for (let i = 1; 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 + Math.sin(tick / 20) * 10);    ctx.closePath();    ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';    ctx.fill();  }})

paintworklet 中,利用 sin 函數繪制波浪線,由于 AnimationWorklets 尚處于實驗階段,開放較少,這里我們在 worklet 外部用 requestAnimationFrame API 來做動畫驅動,讓波浪紋動起來。完成后能看到下邊這樣的效果。


 

然而事實上這個效果略顯僵硬,sin 函數太過于規則了,現實中的波浪應該是不規則波動的,這種不規則主要體現在兩個方面:

1)波紋高度(Y)隨位置(X)變化而不規則變化


 

把圖按照 x-y 正交分解之后,我們希望的不規則,可以認為是固定某一時刻,隨著 x 軸變化,波紋高度 y 呈現不規則變化;

2)固定某點(X 固定),波紋高度(Y)隨時間推進而不規則變化

動態過程需要考慮時間維度,我們希望的不規則,還需要體現在時間的影響中,比如風吹過的前一秒和后一秒,同一個位置的波浪高度肯定是不規則變化的。

提到不規則,有朋友可能想到了用 Math.random 方法,然而這里的不規則并不適合用隨機數來實現,因為前后兩次取的隨機數是不連續的,而前后兩個點的波浪是連續的。這個不難理解,你見過長成鋸齒狀的波浪嗎?又或者你見過上一刻 10 米高、下一刻就掉到 2 米的波浪嗎?

為了實現這種連續不規則的特征,我們棄用 sin 函數,引入了一個包 simplex-noise。由于影響波高的有兩個維度,位置 X 和時間 T,這里需要用到 noise2D 方法,它提前在一個三維的空間中,構建了一個連續的不規則曲面:

// paintworklet.jsimport SimplexNoise from 'simplex-noise';const sim = new SimplexNoise(() => 1);registerPaint('wave', class {  static get inputProperties() {    return ['--animation-tick'];  }  paint(ctx, geom, properties) {    const tick = Number(properties.get('--animation-tick'));    this.drawWave(ctx, geom, 'rgba(255, 255, 255, 0.4)', 0.004, tick, 15, 0.4);    this.drawWave(ctx, geom, 'rgba(255, 255, 255, 0.5)', 0.006, tick, 12, 0.4);  }    /**   * 繪制波紋   */  drawWave(ctx, geom, fillColor, ratio, tick, amp, ih) {    const {      width,      height    } = geom;    const initY = height * ih;    const speedT = tick * ratio;    ctx.beginPath();    for (let x = 0, speedX = 0; x <= width; x++) {      speedX += ratio * 1;      var y = initY + sim.noise2D(speedX, speedT) * amp;      ctx[x === 0 ? 'moveTo' : 'lineTo'](x, y);    }    ctx.lineTo(width, height);    ctx.lineTo(0, height);    ctx.lineTo(0, initY + sim.noise2D(0, speedT) * amp);    ctx.closePath();    ctx.fillStyle = fillColor;    ctx.fill();  }})

 

修改峰值和偏置項等參數,可以再畫多一個不一樣的波浪紋,效果如下,完工!

總結

以上所述是小編給大家介紹的CSS Houdini實現動態波浪紋效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产成人综合一区二区三区| 欧美成人免费va影院高清| 日韩av电影免费观看高清| 日韩美女写真福利在线观看| 久久91超碰青草是什么| 国产精品福利观看| 国产91在线高潮白浆在线观看| 亚洲网在线观看| 欧美精品久久久久久久| 亚洲精品动漫久久久久| 欧美精品一区二区免费| 国产日韩综合一区二区性色av| 日韩久久免费电影| 亚洲天堂视频在线观看| 91亚洲国产精品| 亚洲iv一区二区三区| 欧美成人小视频| 日韩有码在线观看| 欧美激情亚洲自拍| 啪一啪鲁一鲁2019在线视频| 91免费在线视频| 色噜噜国产精品视频一区二区| 中国日韩欧美久久久久久久久| 疯狂做受xxxx高潮欧美日本| 日韩精品视频在线播放| 国色天香2019中文字幕在线观看| 蜜臀久久99精品久久久久久宅男| 亚洲老司机av| 中文字幕日韩在线播放| 国产精品www网站| 久久视频免费观看| 日韩精品在线视频美女| 亚洲精品在线视频| 91po在线观看91精品国产性色| 亚洲欧美日韩爽爽影院| 欧美xxxx综合视频| 麻豆国产精品va在线观看不卡| 懂色aⅴ精品一区二区三区蜜月| 亚洲日韩欧美视频| 日本中文字幕成人| 久久久久久久久久久久久久久久久久av| 久久伊人精品一区二区三区| 亚洲在线第一页| 亚洲欧美自拍一区| 日韩成人在线观看| 亚洲专区中文字幕| 久久免费国产精品1| 国产精品久久久久久av福利软件| 亚洲xxxx视频| 国产精品91在线观看| 国产69精品久久久久久| 国产成人亚洲综合| 国产欧美亚洲视频| 亚洲在线一区二区| 高清一区二区三区四区五区| 久久久亚洲天堂| 色偷偷亚洲男人天堂| 国产午夜精品美女视频明星a级| 亚洲精品电影网站| 中日韩午夜理伦电影免费| 成人精品视频在线| 久久久久久久网站| 国产成人一区二区在线| 欧美精品中文字幕一区| 日日噜噜噜夜夜爽亚洲精品| 亚洲第一精品自拍| 久久精品人人爽| 精品中文字幕在线| 久久久久久久久久久网站| 欧美激情第一页xxx| 欧美激情区在线播放| 久久久99久久精品女同性| 亚洲欧洲免费视频| 国产日韩中文字幕在线| 亚洲精品一区在线观看香蕉| 日本精品视频在线播放| 亚洲黄页网在线观看| 中文字幕日韩欧美| 中文字幕av一区| 日本亚洲精品在线观看| 欧美高清视频一区二区| 精品中文字幕视频| 在线视频欧美日韩精品| 97精品欧美一区二区三区| 欧美成人午夜视频| 97激碰免费视频| 国产精品视频免费观看www| 亚洲电影成人av99爱色| 中文字幕精品久久久久| 亚洲福利视频在线| 高清视频欧美一级| 日本视频久久久| 日韩在线视频观看正片免费网站| 久久久久久欧美| 国精产品一区一区三区有限在线| 久久中文精品视频| 欧美丝袜美女中出在线| 亚洲免费电影在线观看| 欧美一级淫片丝袜脚交| 综合久久五月天| 51午夜精品视频| 亚洲jizzjizz日本少妇| 日韩av免费看| 狠狠躁夜夜躁人人爽天天天天97| 亚洲影院污污.| 日韩免费在线视频| 国产一区二区三区精品久久久| 精品国偷自产在线| 亚洲欧美第一页| 最近2019中文字幕大全第二页| 欧美精品中文字幕一区| 亚洲精品国产精品国自产观看浪潮| 欧美成人四级hd版| 亚洲欧美在线第一页| 国产一区二区香蕉| 亚洲精品一区二区三区不| 日韩免费观看网站| 九九久久精品一区| 国产精品视频1区| 97精品国产97久久久久久春色| 久久全球大尺度高清视频| 国产成人小视频在线观看| 欧美麻豆久久久久久中文| 亚洲人成电影网站色xx| 国产日韩欧美一二三区| 国产精品亚洲视频在线观看| 欧美成人免费va影院高清| 精品无人国产偷自产在线| 欧美电影免费观看| 欧美整片在线观看| 久久精品视频网站| 欧美老女人在线视频| 久久久视频在线| 国产精品免费一区豆花| 亚洲综合小说区| 欧美猛交ⅹxxx乱大交视频| 久久九九精品99国产精品| 亚洲www在线观看| 亚洲国产精品专区久久| 国产精品久久久av久久久| 国产福利视频一区| 国产亚洲精品综合一区91| 亚洲激情电影中文字幕| 国产精品99久久99久久久二8| 成人字幕网zmw| 国产91精品黑色丝袜高跟鞋| 国产丝袜精品第一页| 久久久久国产精品一区| 亚洲免费一在线| 精品免费在线视频| 亚洲成人999| 久久久久久国产精品| 亚洲精品国产综合区久久久久久久| 高潮白浆女日韩av免费看| 亚洲精品xxxx| 欧美与黑人午夜性猛交久久久| 欧美大片在线看| 综合网中文字幕| 久久99国产精品自在自在app| 亚洲激情视频网| 久久亚洲春色中文字幕| 欧美激情一区二区久久久| 午夜精品一区二区三区在线视频| 亚洲免费成人av电影|