文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么在CSS中利用Houdini实现一个动态波浪纹效果

2023-06-08 06:10

关注

怎么在CSS中利用Houdini实现一个动态波浪纹效果?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

css是什么意思

css是一种用来表现HTML或XML等文件样式的计算机语言,主要是用来设计网页的样式,使网页更加美化。它也是一种定义样式结构如字体、颜色、位置等的语言,并且css样式可以直接存储于HTML网页或者单独的样式单文件中,而样式规则的优先级由css根据这个层次结构决定,从而实现级联效果,发展至今,css不仅能装饰网页,也可以配合各种脚本对于网页进行格式化。

什么是 CSS Houdini?

CSS Houdini 对外开放了浏览器解析流程的一系列 API,这些 API 允许开发者介入浏览器的 CSS engine 运作,带来了更多的 CSS 解决方案。

怎么在CSS中利用Houdini实现一个动态波浪纹效果

CSS Houdini 主要提供了以下几个 API:

CSS Properties and Values API

允许在 CSS 中定义变量和使用变量,是目前兼容性最好的一个 API;

Layout API

允许开发者编写自己的 Layout Module,自定义诸如 display 这类的布局属性;

Painting API

允许开发者编写自己的 Paint Module,自定义诸如 background-image 这类的绘制属性。

基础:三步用上 Painting API

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 渲染任务最为合适。

新建一个 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 的绘制方式一样。

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 来做动画驱动,让波浪纹动起来。完成后能看到下边这样的效果。

怎么在CSS中利用Houdini实现一个动态波浪纹效果
 

然而事实上这个效果略显僵硬,sin 函数太过于规则了,现实中的波浪应该是不规则波动的,这种不规则主要体现在两个方面:

1)波纹高度(Y)随位置(X)变化而不规则变化

怎么在CSS中利用Houdini实现一个动态波浪纹效果
 

把图按照 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实现一个动态波浪纹效果问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网行业资讯频道了解更多相关知识。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯