CSS Houdini完成动态性波浪纹纹实际效果

日期:2021-02-28 类型:科技新闻 

关键词:如何创建网站,免费网站建站,网站建设文章,网站建设7个基本流程,自动建站

CSS Houdini 号称 CSS 行业最让人振作的创新。CSS 自身长期性缺乏英语的语法特点,可扩展性基本上为零,而且新特点的适用高效率太低,适配性差。而 Houdini 立即将 CSS 的 API 曝露给开发设计者,过去彻底黑盒的访问器分析流刚开始扩大开放,开发设计者能够自定属于自身的 CSS 特性。

情况

大家了解,访问器在3D渲染网页页面时,最先会分析网页页面的 HTML 和 CSS,转化成3D渲染树(rendering tree),再经过合理布局(layout)和绘图(painting),展现出全部网页页面內容。在 Houdini 出現以前,这个步骤上大家能实际操作的室内空间少之很少,特别是 layout 和 painting 阶段,能够说是彻底封闭式,巨大地限定了 CSS 的灵便性。小区中 sass、less、stylus 等 CSS 预解决技术性的出現大多数都源于这个缘故,它们都期待根据预编译程序,提升 CSS 的局限性,让 CSS 有着更强劲的机构和撰写工作能力。因此渐渐地地,大家都已不笔写 CSS,更便捷、更灵便的 CSS 拓展語言变成 web 开发设计的主角。看到这样的状况,CSS Houdini 终究坐不住了。

甚么是 CSS Houdini?

CSS Houdini 扩大开放了访问器分析步骤的1系列 API,这些 API 容许开发设计者干预访问器的 CSS engine 运行,带来了更多的 CSS 处理计划方案。

CSS Houdini 关键出示了下列几个 API:

CSS Properties and Values API

容许在 CSS 中界定自变量和应用自变量,是现阶段适配性最好是的1个 API;

Layout API

容许开发设计者撰写自身的 Layout Module,自定诸如 display 这类的合理布局特性;

Painting API

容许开发设计者撰写自身的 Paint Module,自定诸如 background-image 这类的绘图特性。

基本:3步用上 Painting API

1、HTML 中根据 Worklets 加载款式的自定编码:

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

Worklets 也是 Houdini 出示的 API 之1,负责载入和实行款式的自定 JS 编码。它相近于 Web Worker,是1个运作于主编码以外的单独工作中过程,但比 Worker 更加轻量,负责 CSS 3D渲染每日任务最为适合。

2、新建1个 paintworklet.js,运用 registerPaint 方式申请注册1个 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);
    }
  }
);

上边界定了1个名为 rect 的 paint 特性类,当 rect 被应用时,会案例化 rect 并全自动开启 paint 方式实行3D渲染。paint 方式中,大家获得连接点 CSS 界定的 --rect-color 自变量,并将元素的情况填充为特定色调。ctx 主要参数是1个 Canvas 的 Context 目标,因而 paint 的逻辑性跟 Canvas 的绘图方法1样。

3、CSS 中应用的情况下,只必须启用 paint 方式:

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

这是1个自定 CSS 情况色特性的简易完成,看得出运用 CSS Houdini,大家能够像实际操作 canvas 1样灵便轻松地完成大家要想的款式作用。

进阶:完成动态性波纹

依据上述流程,大家演试1下怎样用 CSS Painting API 完成1个动态性波浪纹的实际效果:

<!-- 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.js
registerPaint('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 正交和溶解以后,大家期待的不规律,能够觉得是固定不动某1時刻,伴随着 x 轴转变,波纹高宽比 y 展现不规律转变;

2)固定不动某点(X 固定不动),波纹高宽比(Y)随時间推动而不规律转变

动态性全过程必须考虑到時间维度,大家期待的不规律,还必须反映在時间的危害中,例如风吹过的前1秒和后1秒,同1个部位的波浪纹高宽比毫无疑问是不规律转变的。

提到不规律,有盆友将会想起了用 Math.random 方式,但是这里的不规律其实不合适用任意数来完成,由于前后左右两次取的任意数是不持续的,而前后左右两个点的波浪纹是持续的。这个不难了解,你见太长成锯齿状的波浪纹吗?又或你见过上1刻 10 米高、下1刻就掉到 2 米的波浪纹吗?

以便完成这类持续不规律的特点,大家弃用 sin 涵数,引进了1个包 simplex-noise。因为危害波高的有两个维度,部位 X 和時间 T,这里必须用到 noise2D 方式,它提早在1个3维的室内空间中,搭建了1个持续的不规律斜面:

// paintworklet.js
import 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();
  }
})

 

改动峰值和偏置项等主要参数,能够再画多1个不1样的波浪纹纹,实际效果以下,竣工!

总结

以上所述是网编给大伙儿详细介绍的CSS Houdini完成动态性波浪纹纹实际效果,期待对大伙儿有一定的协助,假如大伙儿有任何疑惑请给我留言,网编会立即回应大伙儿的。在此也十分谢谢大伙儿对脚本制作之家网站的适用!
假如你感觉本文对你有协助,欢迎转载,烦请注明出处,感谢!