当前位置: 首页 > 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设计模式:一、六大设计原则-05:接口隔离原则

文章目录 一、定义&#xff1a;接口隔离原则二、模拟场景&#xff1a;接口隔离原则三、违背方案&#xff1a;接口隔离原则3.1 工程结构3.2 英雄技能调用3.2.1 英雄技能接口3.2.2 英雄&#xff1a;后裔3.2.3 英雄&#xff1a;廉颇 3.3 单元测试 四、改善代码&#xff1a;接口隔离…...

第63步 深度学习图像识别:多分类建模误判病例分析(Tensorflow)

基于WIN10的64位系统演示 一、写在前面 上两期我们基于TensorFlow和Pytorch环境做了图像识别的多分类任务建模。这一期我们做误判病例分析&#xff0c;分两节介绍&#xff0c;分别基于TensorFlow和Pytorch环境的建模和分析。 本期以健康组、肺结核组、COVID-19组、细菌性&am…...

OpenCv读/写视频色差 方案

OpenCv read / write video color differenceOpenCv读/写视频色差 感谢博主&#xff1a; OpenCv读/写视频色差答案 - 爱码网 有没有办法让 OpenCV 使用正确的转换&#xff1f;&#xff1f; 是的&#xff0c;使用 GStreamer 后端而不是 FFmpeg 后端&#xff0c;颜色看起来很完…...

【传输层】网络基础 -- UDP协议 | TCP协议

再谈端口号端口号范围划分netstatpidof UDPUDP的特点面向数据报UDP的缓冲区 基于UDP的应用层协议 TCP认识TCP协议的报头理解封装解包理解可靠性TCP工作模式16位窗口大小6位标志位URGACKPSHRSTSYNFIN 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序 在TCP/I…...

Android开发之性能测试工具Profiler

前言 性能优化问题&#xff0c;在我们开发时都会遇到&#xff0c;但是在小厂和对自己要求不严格的情况下&#xff0c;我都很少去做性能优化&#xff1b; 在性能优化上&#xff0c;基本大家都是通过自己的开发经验和性能分析工具来发现问题&#xff0c;今天给大家分享一下小编最…...

SpringBoot初级开发--多环境配置的集成(9)

在Springboot的开发中&#xff0c;我们经常要切换各种各样的环境配置&#xff0c;比如现在是开发环境&#xff0c;然后又切换到生产环境&#xff0c;这个时候用多环境配置就是一个明智的选择。接下来我们沿用上一章的工程来配置多环境配置工程。 1.准备多环境配置文件 这里我…...

(数学) 剑指 Offer 39. 数组中出现次数超过一半的数字 ——【Leetcode每日一题】

❓ 剑指 Offer 39. 数组中出现次数超过一半的数字 难度&#xff1a;简单 数组中有一个数字出现的次数超过数组长度的一半&#xff0c;请找出这个数字。 你可以假设数组是非空的&#xff0c;并且给定的数组总是存在多数元素。 示例 1: 输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输…...

如何用PS把roughness贴图转换成Smoothness,并放入Metallic贴图的a通道。

1&#xff1a;用PS打开Roughness贴图 2&#xff1a;选择反相&#xff0c;装换成Smoothness贴图 3&#xff1a;新建一个大小相等的psd文件&#xff0c;或者打开Metallic贴图 4&#xff1a;如果没有金属度贴图&#xff0c;就把新建的图画成纯黑色 5&#xff1a;选择图层蒙版->…...

了解XSS攻击与CSRF攻击

什么是XSS攻击 XSS&#xff08;Cross-Site Scripting&#xff0c;跨站脚本攻击&#xff09;是一种常见的网络安全漏洞&#xff0c;它允许攻击者在受害者的浏览器上执行恶意脚本。这种攻击通常发生在 web 应用程序中&#xff0c;攻击者通过注入恶意脚本来利用用户对网站的信任&…...

安全测试-django防御安全策略

django安全性 django针对安全方面有一些处理&#xff0c;学习如何进行处理设置&#xff0c;也有利于学习安全测试知识。 CSRF 跨站点请求伪造&#xff08;Cross-Site Request Forgery&#xff0c;CSRF&#xff09;是一种网络攻击方式&#xff0c;攻击者欺骗用户在自己访问的网…...