当前位置: 首页 > news >正文

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

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 前端性能优化清单

相关文章:

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

开门见山&#xff0c;直接上货 &#x1f50d; CSS Houdini是什么&#xff1f; “Houdini”一词引用自“Harry Houdini”&#xff0c;他是一位20世纪的著名魔术师&#xff0c;亦被称为史上最伟大的魔术师、逃脱术师及特级表演者。 我们都知道&#xff0c;浏览器在渲染网页显示样…...

DC/DC开关电源学习笔记(二)开关电源的分类

&#xff08;二&#xff09;开关电源的分类 1.DC/DC类开关电源2.AC/DC变换器3.电路结构分类4.功率开关管分类5.电路拓扑分类 根据变换方式&#xff0c;电源产品有下列四大类&#xff1b; &#xff08;1&#xff09;&#xff1a;第一大类&#xff1a;AC/DC开关电源&#xff1b; …...

conda创建python虚拟环境

1.查看当前存在那些虚拟环境 conda env list conda info -e 2.conda安装虚拟环境 conda create -n my_env_name python3.6 2.1在anaconda下改变python版本 当前3.7 安装3.7 conda create -n py37 python3.7 conda activate py37 conda create -n py37 python3.7conda a…...

Python 操作 MongoDB 数据库介绍

MongoDB 是一款面向文档型的 NoSQL 数据库&#xff0c;是一个基于分布式文件存储的开源的非关系型数据库系统&#xff0c;其内容是以 K/V 形式存储&#xff0c;结构不固定&#xff0c;它的字段值可以包含其他文档、数组和文档数组等。其采用的 BSON&#xff08;二进制 JSON &am…...

【ES6】Generator 函数

Generator 函数是 ES6 引入的一种新的函数类型&#xff0c;它既可以生成一个序列&#xff0c;又可以在某个条件下停止执行&#xff0c;并在需要时恢复执行。Generator 函数非常适合处理那些需要按需计算的场景&#xff0c;例如处理大数据、生成随机数等。 Generator 函数的基本…...

「操作系统」1. 基础

前言&#xff1a;操作系统基础八股文 文章目录 一 、操作系统基础1.1 什么是操作系统&#xff1f;1.2 什么是系统调用1.3 什么是中断 &#x1f680; 作者简介&#xff1a;作为某云服务提供商的后端开发人员&#xff0c;我将在这里与大家简要分享一些实用的开发小技巧。在我的职…...

Docker安装Oracl数据库!

安装Docker 查看是否安装docker: yum list installed | grep docker 安装docker: yum -y install docker 启动docker: systemctl start docker 查看docker启劝状态: systemctl status docker 查看docker版本: docker --version 设置docker开机自启动: systemctl en…...

QT子窗口为QWidget类型时,窗口背景不透明的实现方法

1...

leecode 数据库:1158. 市场分析 I

数据导入&#xff1a; SQL Schema&#xff1a; Create table If Not Exists Users (user_id int, join_date date, favorite_brand varchar(10)); Create table If Not Exists Orders (order_id int, order_date date, item_id int, buyer_id int, seller_id int); Create tab…...

简单shell脚本的编写

文章目录 简单使用shell脚本参数判断整数的比较运算符字符串的比较运算shell脚本流程控制shell脚本循环for循环批量添加用户批量ping IP地址检测同一局域网&#xff0c;多台主机存活情况检测同一局域网&#xff0c;多台主机存活情况多线程检测主机存活情况 while循环case选择语…...

汽车售后接待vr虚拟仿真实操演练作为岗位培训的重要工具和手段

汽车虚拟仿真教学软件是一种基于虚拟现实技术的教学辅助工具。它能够模拟真实的汽车环境和操作场景&#xff0c;让学生能够通过虚拟仿真来学习和实践汽车相关知识和技能。与传统的教学方式相比&#xff0c;汽车虚拟仿真教学软件具有更高的视觉沉浸感和互动性&#xff0c;能够更…...

登录校验-Filter-登录校验过滤器

目录 思路 登录校验Filter-流程 步骤 流程图 登录校验Filter-代码 过滤器类 工具类 测试登录 登录接口功能请求 其他接口功能请求 前后端联调 思路 前端访问登录接口&#xff0c;登陆成功后&#xff0c;服务端会生成一个JWT令牌&#xff0c;并返回给前端&#xff0…...

Vue3列表竖向滚动(包含使用swiper的翻页效果)

一、使用element-plus表格进行滚动&#xff1a; 可以满足的需求&#xff1a;表格一行一行竖向滚动&#xff0c;类似走马灯。 不能满足的需求&#xff1a;表格分页竖向滚动&#xff0c;有翻页的效果。 代码&#xff1a; <template><el-table:data"tableData"…...

OS 死锁处理

如果P先申请mutex 则mutex从1置零&#xff0c;假设申请到的empty 0则empty变成-1阻塞态 同理C中mutex从0变为-1&#xff0c;那么如果想离开阻塞态&#xff0c;那么就需要执行V&#xff08;empty&#xff09;但是如果执行V&#xff08;empty&#xff09;就需要P&#xff08;mu…...

Java实现根据按图搜索商品数据,按图搜索获取1688商品详情数据,1688拍立淘接口,1688API接口封装方法

要通过按图搜索1688的API获取商品详情跨境属性数据&#xff0c;您可以使用1688开放平台提供的接口来实现。以下是一种使用Java编程语言实现的示例&#xff0c;展示如何通过1688开放平台API获取商品详情属性数据接口&#xff1a; 首先&#xff0c;确保您已注册成为1688开放平台…...

如何避免重复消费消息

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…...

【若依框架RuoYi-Vue-Plus 图片回显不显示问题,OSS文件上传或者本地上传】

一、问题 1.设计表 product&#xff08;商品表&#xff09; 有 id &#xff08;id&#xff09; name&#xff08;商品名&#xff09;icon&#xff08;图标&#xff09; 2.使用若依代码生成功能&#xff0c;导入product表&#xff0c;代码生成。 3.将生成的代码导入到项目中得到…...

docker搭建rocketmq环境

准备局域网 nameserver和broker在同一网段才能够互相访问&#xff0c;我们先创建一个局域网。 创建rocketmq-network&#xff0c;让nameserver、broker在同一个网段&#xff1a; docker network create --driverbridge \ --subnet192.168.2.10/24 rocketmq-network安装names…...

uwsgi部署多进程django apscheduler与问题排查

&#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是Zeeland&#xff0c;开源建设者与全栈领域优质创作者。&#x1f4dd; CSDN主页&#xff1a;Zeeland&#x1f525;&#x1f4e3; 我的博客&#xff1a;Zeeland&#x1f4da; Github主页: Undertone0809 (Zeeland)&…...

git difftool对比差异,避免推送不相关内容

问题 在利用git进行版本管理的时候&#xff0c;经常会由于对其他不相关的代码&#xff0c;做了一些小改动&#xff0c;例如删除了一个空行&#xff0c;多了一个缩进等。 为避免将这些不相关的改动也提交到远程&#xff0c;对PR造成不必要的影响&#xff0c;可以利用git diff命…...

Java中的5大AI框架!

前言在AI技术爆发的这两年里&#xff0c;我一直在思考一个问题&#xff1a;Python有LangChain&#xff0c;JavaScript有LangChain.js&#xff0c;我们Java开发者拿什么来构建AI应用&#xff1f;这个问题在2024-2025年终于有了答案。随着Spring AI的1.0 GA发布、LangChain4j的持…...

深入解析RK3576 Android14中camera3_profiles_rkxxxx.xml的自定义数据格式支持

1. RK3576 Android14相机配置文件的秘密 最近在调试RK3576平台的相机模块时&#xff0c;遇到了一个棘手的问题&#xff1a;需要为定制摄像头添加特殊数据格式。当我打开camera3_profiles_rkxxxx.xml文件时&#xff0c;发现它只支持BLOB、YCbCr_420_888和IMPLEMENTATION_DEFINED…...

2026进口调节阀品牌选型参考:产品质量与售后响应如何影响实际应用

2026年&#xff0c;进口调节阀在石油化工、电力、制药、冶金和新能源项目中仍有稳定需求。用户在查找进口调节阀品牌或调节阀厂家时&#xff0c;比较关注产品的认证情况、制造基地布局、工况适应能力和服务响应速度。本文整理了一些选型时常见的考虑要点&#xff0c;并介绍美国…...

Phi-3-mini-4k-instruct-gguf参数详解:温度0.0时技术文档摘要的逻辑连贯性分析

Phi-3-mini-4k-instruct-gguf参数详解&#xff1a;温度0.0时技术文档摘要的逻辑连贯性分析 1. 模型概述与核心能力 Phi-3-mini-4k-instruct-gguf是微软Phi-3系列中的轻量级文本生成模型GGUF版本&#xff0c;专为高效推理场景优化。该模型在问答、文本改写、摘要整理等任务中表…...

导出浏览器网络日志 har 后缀的日志是什么 怎么打开

导出浏览器网络日志 har 后缀的日志是什么 怎么打开 一、实机演示二、har 后缀的日志是什么 .har 后缀的日志文件是一种专门用于记录和分析网页网络活动的文件格式。 &#x1f4c4; HAR 文件是什么&#xff1f; HAR 的全称是 HTTP ARchive。它本质上是一个标准的 JSON 文件&…...

SAP增强开发实战:如何用STARTING NEW TASK避免BAPI_TRANSACTION_COMMIT的坑?

SAP增强开发实战&#xff1a;如何用STARTING NEW TASK避免BAPI_TRANSACTION_COMMIT的坑&#xff1f; 在SAP标准增强开发中&#xff0c;当我们需要在出口函数里调用BAPI修改或创建业务单据时&#xff0c;总会遇到一个经典难题&#xff1a;如何在增强点安全地提交事务&#xff1f…...

如何一站式解决漫画格式转换难题:CBconvert完整指南

如何一站式解决漫画格式转换难题&#xff1a;CBconvert完整指南 【免费下载链接】cbconvert CBconvert is a Comic Book converter 项目地址: https://gitcode.com/gh_mirrors/cb/cbconvert 还在为不同设备上的漫画格式兼容性问题而烦恼吗&#xff1f;CBconvert作为一款…...

Cursor Pro免费激活指南:3步解锁AI编程工具的完整功能

Cursor Pro免费激活指南&#xff1a;3步解锁AI编程工具的完整功能 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your tri…...

OpenCode效果实测:基于Qwen3-4B的代码生成质量与速度展示

OpenCode效果实测&#xff1a;基于Qwen3-4B的代码生成质量与速度展示 1. 项目概览与技术背景 OpenCode是2024年开源的AI编程助手框架&#xff0c;采用Go语言开发&#xff0c;主打"终端优先、多模型、隐私安全"的设计理念。该项目将大语言模型(LLM)包装成可插拔的Ag…...

收藏!小白程序员必看:Agent和工作流是最佳拍档,教你如何协同它们(附案例)

文章探讨了AI智能体&#xff08;Agent&#xff09;和工作流工具的关系&#xff0c;指出它们并非竞争对手&#xff0c;而是最佳拍档。Agent擅长自主决策和动态规划&#xff0c;适用于探索性和不确定性任务&#xff1b;工作流则负责流程编排和确定性执行&#xff0c;适用于重复性…...