iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >怎么在CSS中利用Houdini实现一个动态波浪纹效果
  • 301
分享到

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

2023-06-08 06:06:49 301人浏览 泡泡鱼
摘要

怎么在CSS中利用Houdini实现一个动态波浪纹效果?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。css是什么意思css是一种用来表现html或XML等文件样式的计算机语

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

--结束END--

本文标题: 怎么在CSS中利用Houdini实现一个动态波浪纹效果

本文链接: https://www.lsjlt.com/news/252151.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 生态系统中流行库和框架的贡献指南
    作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
    99+
    2024-05-14
    框架 c++ 流行库 git
  • C++ 生态系统中流行库和框架的社区支持情况
    c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
    99+
    2024-05-14
    生态系统 社区支持 c++ overflow 标准库
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-14
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-14
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-14
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-14
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-14
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-14
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-14
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-14
    golang 数据库备份 mysql git 标准库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作