CSS魔术师Houdini,用浏览器引擎实现高级CSS效果

news2024/12/24 9:10:33

fbce5e79f3a74987b5dc1cd239a52e52.png

开门见山,直接上货

🔍 CSS Houdini是什么?

“Houdini”一词引用自“Harry Houdini”,他是一位20世纪的著名魔术师,亦被称为史上最伟大的魔术师、逃脱术师及特级表演者。

我们都知道,浏览器在渲染网页显示样式的时候,浏览器的渲染引擎会对 CSSOM 进行解析——包括布局、绘制和合成过程。而本文要讲的内容 Houdini一组公开 CSS 引擎部分的底层API,它可以让开发者能够人工干预浏览器的渲染进程,Houdini的核心API Painting API就是将我们自定义的js代码插入到浏览器的绘制环节。

Houdini包括以下 API >>>

  • CSS Properties and Values API:顾名思义,就是与css属性相关的一系列 API,用于注册新的 CSS 属性,包括CSS.registerProperty API 和@property关键词(它们俩是等价的),例如我们常用 @property 常用于定义新的css属性,以实现一些css属性的动画过程,例如背景渐变色的变化过程。

  • CSS Typed OM:我们经常使用dom对象的style属性获取/设置它的一些 css 属性值,操作的值都是字符串。而 CSS Typed OM API为我们提供了一些列方法,可以获取/设置具体的css属性值、单位,(你可能觉得它很鸡肋,但是它也有它的优势,例如不用考虑属性的写法、强大的数学操作和单位转换、错误捕获处理、性能更好。

  • CSS Painting API:它可以说是CSS Houdini的核心 API之一,它其实就是css界的canvas,实现给元素设置复杂的自定义背景。使用时像 CSS.registerProperty 注册一个画像,然后就可以把这个画像应用于任何可以设置image的css属性上,例如background-imageborder-imagelist-style-image等。

  • Worklets工作集也是CSS Houdini的核心 API之一。它用于在独立于主要 JavaScript 执行环境的渲染管道的各个阶段运行脚本的 API。它相当于 Web Workers 渲染管道的轻量级版本。它只有一个实例方法Worklet.addModule(),用于将给定 URL 处的脚本模块添加到当前工作集。注册工作集后,你可以像任何其他值一样在 CSS 中使用它。

  • CSS Layout API、CSS Parser API、Font Metrics API:最后这三个 API目前浏览器支持性都几乎为零,所以本文就不做介绍了。

☕ CSS Houdini怎么用?

CSS Houdini使用方法很简单,我总结为有以下几个步骤,我以实现一个波浪线来进行演示(最终效果如下图):

image.png

1. 创建工作集文件

首先我们需要创建一个js文件,我这里取名为curved-line.js,我们要在里面实现自定义的背景效果。

2.使用registerPaint注册工作集

在我们创建的curved-line.js文件中添加以下代码注册工作集:
registerPaint有两个参数:registerPaint(name, classRef),如下代码:

//实现工作集的类的引用。
class CurvedLine {
  //实现自定义css效果的代码
}

//注册Worklets工作集  "curved-line": 要注册的工作集类的名称
registerPaint("curved-line", CurvedLine);

3.在工作集类中实现炫酷效果

绘图工作集类我们需要关注以下 4 个函数:

  • contextOptions:该函数定义了一个上下文选项contextOptions(),如下面的例子中返回一个简单的对象,声明允许 alpha 透明度;
  • inputProperties,要使用哪些CSS自定义属性(只能使用var变量,不可以使用css内置属性);
  • inputArguments,CSS中使用paint函数除了模块名外的其他参数,指定其类型;
  • paint:最关键的方法,定义绘制行为。ctx的使用和canvas一致,size表示绘制的大小,包括width、height等信息,properties就是inputProperties静态方法里定义的属性,args就是paint的入参,跟inputArguments定义的对应。

下面是这 4 个方法的使用示例:

//file.js  工作集类方法示例
registerPaint('paint-color-example', class {  
  static get inputProperties() {   
    return ['--my-color'];  
  }  
    
  static get inputArguments() {   
    return [''];  
  }  
    
  static get contextOptions() {   
    return {alpha: true};  
  }  
  
  paint(ctx, size, properties, args) {  
    ctx.fillStyle = properties.get('--my-color');  
    ctx.beginPath();  
    ...  
});

以下是绘制曲线的代码(不多说了,就是用canvas绘制曲线):

// curved-line.js
if (typeof registerPaint !== "undefined") {
  class CurvedLine {
    static get inputProperties() {
      return [
        "--curved-lineColor",
        "--curved-lineSpread",
        "--curved-lineWidth",
        "--curved-lineHeight",
      ];
    }

    paint(ctx, size, properties) {
      const lineWidth = parseInt(properties.get('--curved-lineWidth')) || 3;
      const lineHeight = parseInt(properties.get('--curved-lineHeight')) || size.height;
      const color = String(properties.get('--curved-lineColor')) || 'black';
      const spread = parseInt(properties.get('--curved-lineSpread')) || 50;

      const offset = (lineHeight < size.height) ? (size.height - lineHeight) / 2 : 0;
      const midPoint = lineHeight / 2;

      ctx.lineWidth = lineWidth;
      ctx.strokeStyle = color;
      ctx.beginPath();
      ctx.moveTo(0, midPoint + offset);
      
      let curStep = spread;
      while (curStep < size.width + spread) {
        const cp1x = curStep;
        const cp1y = (lineHeight * 1.5) + offset;
        const cp2x = curStep + spread;
        const cp2y = 0 - midPoint + offset;
        const x = curStep + spread * 2;
        const y = midPoint + offset;

        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
        curStep = curStep + (spread * 3);
      }
      ctx.stroke();
    }
  }

  registerPaint("curved-line", CurvedLine);
}

4. 将自定义的工作集添加到当前工作集

你要知道想要实现 CSS Houdini,即从原生层面扩展 CSS,就必须要以Worklets工作集的方式将自定义css的代码注册到渲染引擎的进程中。上面我们也提到了Worklets的使用方法:使用 Worklet.addModule() 实例方法将指定 URL 处的脚本模块添加到当前工作集,如下:

需要注意的是:

  • Worklets可以使用的类有很多种,例如网络音频工作集AudioWorklet,高性能程序动画工作集AnimationWorklet,绘图工作集PaintWorklet等,我们这里只使用了 PaintWorklet;
  • 工作集必须是个单独的js文件,并通过 Worklet.addModule() 引入;
  • Worklet 允许ESM静态导入,即使用import导入,但是不支持import()动态导入,会抛出异常!

在index.html或者main.js中添加我们的工作集:

<script>
  CSS.paintWorklet.addModule("curved-line.js");
</script>

5. 使用paint()函数设置炫酷背景

.line{
    width: 400px;
    height: 200px;
    --curved-lineHeight:20;
    --curved-lineWidth:4;
    --curved-lineColor: green;
    --curved-lineSpread:15;
    background: paint(curved-line);
}

<div class="line"></div>

大功告成~~~🎉🎉🎉

🍭 CSS Houdini 的优点

以往我们实现复杂的效果往往都需要使用js和css进行配合,而使用 Houdini 后,相比 JavaScript ,它能够更快的解析。因为 Houdini 的代码不会像js一样等待 cssom 布局绘制完成后然后又可能造成回流重绘,它是被注入到浏览器渲染引擎的渲染进程中的。

在 JavaScript 中键入 CSS 值以及填充或发明新的 CSS 而不会影响性能终于成为可能。Houdini具有增强网络创造力的潜力。

🍭 CSS Houdini 的兼容性

目前 Houdini 的核心 API Painting API 兼容性还不是很好,使用时注意判断浏览器是否支持。

image.png

🎨 Houdini 案例

以下网站有一些很有意思的 Houdini Demo,感兴趣的可以看下:
https://houdini.how/

思考:因为利用 paint 绘制图案是静态单次绘制,没有办法只通过工作集来实现连续的动画过程,但是可以配合animation进行多次渲染,尤其是 steps 逐帧动画,配合 Houdini ,可以创造很多有意思的动画,例如steps配合 paint 绘制时钟(注意paint的ctx对象不支持绘制文本)。

最后

我是喜欢归纳总结前端相关知识的前端阿彬,尽力持续输出原创优质文章,欢迎点赞关注😘

表情包2.webp

往期文章
# ☕ 通过和vue语法逐一比对,快速上手前端框架黑马svelte
# 🧙‍♀️css魔法:伪元素content ➕ css函数
# 玩转css逐帧动画,纯css让哥哥动起来💃
# 🕸2023 前端 SEO 无死角解读
# 我给自己搭建的前端导航网站,你们都别用🤪
# 2023 最新最细 vite+vue3+ts 多页面项目架构,建议收藏备用!
# 浅谈 强制缓存/协商缓存 怎么用?
# 2023 前端性能优化清单

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/954270.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL的字符转义

表象 表结构如下: 其中 content 字段存放json之后的数据,这个json数据里面 extra 字段的内容又是一段json,如下: INSERT INTO future.test_escape_character( id, title, content, is_del )VALUES ( 2, 我的博客, {"web_id":31415,"name":"清澄秋…

搭建Ubuntu本地web小游戏网站并通过内网穿透实现公网用户远程访问的步骤指南

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《高效编程技巧》《cpolar》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 前言1. 本地环境服务搭建2. 局域网测试访问3. 内网穿透3.1 ubuntu本地安装cpolar内网穿透3.2 创建隧道3.3 测试公网访…

ActiveMQ配置初探

文章目录 配置wrapper相关配置wrapper是干什么用的MQ的运行内存修改【需修改】修改内容题外话 wrapper.log配置【需修改】引起的问题优化方式 activemq.xml相关配置官网介绍配置管理后台的认证授权【建议修改】配置broker【根据自己需求更改】配置允许jmx监控关闭消息通知持久化…

YOLO V5 和 YOLO V8 对比学习

参考文章&#xff1a; 1、YOLOv5 深度剖析 2、如何看待YOLOv8&#xff0c;YOLOv5作者开源新作&#xff0c;它来了&#xff01;? 3、anchor的简单理解 完整网络结构 YOLO v5和YOLO v8的Head部分 YOLO v8的Head 部分相比 YOLOv5 改动较大&#xff0c;换成了目前主流的解耦头结构…

半导体晶片机器视觉测量及MARK点视觉定位

半导体晶片机器视觉测量及MARK点视觉定位 客户的需求: 检测内容&#xff1a; SMT行业晶片位置角度与PCB板Mark点位置的测试测量 检测要求&#xff1a; 精度0.04mm&#xff0c;移动速度100mm/s 视觉可行性分析: 对样品进行了光学实验&#xff0c;并进行图像处理&#xff0c…

华为OD机试 - 硬件产品销售方案 - 回溯(Java 2023 B卷 200分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、补充说明五、解题思路六、Java算法源码七、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;…

【SVN】 代码版本管理工具使用步骤以及全局忽略不需要提交的文件夹

2023年&#xff0c;第36周。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; SVN是Subversion的简称&#xff0c;是一个开源的版本控制系统&#xff0c;用于管理软件开发过程中的代码版本和文件变更。 它提供了跟踪文件修改、协同开发、版本回…

上海市青少年算法2023年7月月赛(丙组)

T1先行后列 题目描述 从 1 开始的 nm 个整数按照先行后列的规律排列如下: 给定 n 与 m,再给定一个数字 c,请输出 c 所在的行数与列数。 输入格式 第一行:两个整数表示 n 与 m 第二行:一个整数表示 c 输出格式 两个整数:表示 c 所在的行数与列数。 数据范围 1≤n,m≤10000…

Oracle DBlink使用方法

DBlink作用&#xff1a;在当前数据库中访问另一个数据库中的表中的数据 create public database link dblink名称 connect to 对方数据库用户名 identified by 对方数据库用户密码 using (DESCRIPTION (ADDRESS_LIST (ADDRESS (PROTOCOL TCP)(HOST 要连接的数据库所在服务…

封闭式园区人员定位及轨迹跟踪管理系统的功能和作用

在当今充满竞争的商业环境中&#xff0c;企业安全和员工管理变得尤为重要。尤其是在封闭式园区这样的环境中&#xff0c;确保员工的安全和准确管理变得尤为关键。为了满足这一需求&#xff0c;封闭式园区人员定位及轨迹跟踪管理系统应运而生&#xff0c;该系统结合了最新科技和…

回文链表00

题目链接 回文链表 题目描述 注意点 回文的定义&#xff1a;回文就是反转以后和以前一样的就是回文结构用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题 解答思路 用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题要求有限遍历且避免使用O(n) 额外空间&#xff0c;避免使用 O…

护眼台灯拒交智商税!明基/SUKER书客/米家三款热门护眼台灯深度测评

Hello我是装修研究爱好者&#xff0c;最近后台收到多位家长们咨询&#xff0c;让推荐一款儿童护眼台灯 要求灯光质量和光源稳定&#xff0c;光线舒适护眼效果好的台灯&#xff0c;为此我开始整理儿童护眼台灯攻略 选护眼灯时首先必须关注与护眼相关的指标&#xff0c;其次在考…

打造高效便利的同城跑腿外卖小程序

随着移动互联网的发展&#xff0c;人们的生活方式发生了翻天覆地的变化。外卖行业作为其中的一部分&#xff0c;正日益蓬勃发展。为了满足用户对便利的需求&#xff0c;我们可以开发一个名为“同城跑腿外卖小程序”的应用&#xff0c;让用户能够轻松地下单外卖、送货上门以及处…

python编辑器推荐及配置

vscode首推,(个人喜好) 安装Python解释器 打开Python官网 https://www.python.org/ 在 Downloads 下面选择自己的对应系统&#xff0c;本文以 Windows 为例 下载完成后解压&#xff0c;双击 .exe 文件开始安装 注意勾选下面选项&#xff0c;将其 python.exe 添加到环境变量…

OA项目之会议通知(查询是否参会反馈详情)

目录 会议查询 是否参会 反馈详情 讲解思路 会议通知SQL语句分析 反馈详情SQL语句分析 后台代码编写 前端代码编写 效果预览 会议查询 MeetingFeedBack.java package com.zking.oa.model;import org.lisen.mvc.util.AutoIncrement; import org.lisen.mvc.util.…

Ubuntu入门04——目录与文件

目录 1.显示当前工作目录 2.更改目录 3.创建工作目录 4.删除工作目录 5.移动文件或者文件夹 6.文件夹and文件查看命令 7. 回到根目录&#xff0c;回到上一级 8.删除工作目录 9.查看目录和文件 10.以树状图列出目录内容 11.文件查找 12.在数据库中查找文件或目录 1…

从零开始学习数据服务API的最佳指南

随着互联网的快速发展&#xff0c;数据已经成为企业和个人的重要资产。为了更好地利用这些数据&#xff0c;数据服务API&#xff08;Data Service API&#xff09;应运而生。本文将为您介绍如何从零开始学习数据服务API的最佳指南&#xff0c;并推荐一款优秀的产品FDL&#xff…

[C/C++]内存管理,对内存进行操作

目录 一.内存结构 二.内存拷贝函数 三.栈空间与堆空间 四.变量的四种存储类型 五.函数返回值使用指针 六.常见错误总结 &#x1f388;个人主页&#xff1a;北海 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏✨收录专栏&#xff1a;C/C&…

如何让Midjourney角色保持一致的5个核心技巧

hi&#xff0c;同学们&#xff0c;我是赤辰&#xff0c;本期是赤辰第2期AI教程或推荐实用AI工具&#xff0c;文章底部准备了粉丝福利&#xff0c;看完可以领取&#xff01; 今天给大家介绍Midjourney5个控制AI绘画角色一致性的技巧。 近期整理了学员在使用Midjourney生图时遇…

KVM中的四种简单网络模型

KVM中的四种简单网络模型&#xff0c;分别如下&#xff1a; 1、隔离模型&#xff08;QEMU内置的用户模式网络&#xff08;user mode networking&#xff09;&#xff09;&#xff1a;虚拟机之间组建网络&#xff0c;该模式无法与宿主机通信&#xff0c;无法与其他网络通信&…