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

CSS Houdini

前言

最近看了几篇文章,是关于 CSS Houdini 的。作为一个前端搬砖的还真不知道这玩意,虽然不知道的东西挺多的,但是这玩意有点高大上啊。

Houdini 是一组底层 API,它们公开了 CSS 引擎的各个部分,从而使开发人员能够通过加入浏览器渲染引擎的样式和布局过程来扩展 CSS。Houdini 是一组 API,它们使开发人员可以直接访问CSS 对象模型 (CSSOM),使开发人员可以编写浏览器可以解析为 CSS 的代码,从而创建新的 CSS 功能,而无需等待它们在浏览器中本地实现。

具体解释见:CSS Houdini

推荐文章
用CSS Houdini画一片星空

CSS Houdini 实现磁吸效果

CSS Houdini:用浏览器引擎实现高级CSS效果

官方案例
Houdini Samples,可以看看有些东西还是很有意思的。

给textarea加一个方格背景

文章中的效果图:
在这里插入图片描述
文章中提到了渐变,自己尝试了一下没啥思路。但是有一种取巧的方式——背景图,把下面的图片当成背景图不就好了
在这里插入图片描述

 textarea{width: 300px;height: 100px;background-image: url('./abc.png');background-size: 80px 40px;color: white;font-size: 30px;}

我的效果,这不是差不多吗😃
在这里插入图片描述
突然发现自己有点傻叉,自己这个每一行的颜色都是一样的,跟官方的差远了。

Houdini 基本用法

attributeStyleMap 和 computedStyleMap

  • attributeStyleMap 用于处理内联样式,可以进行读写操作
  • computedStyleMap 用于处理非内联样式,只允许读
// Before Houdiniconst size = 30
target.style.fontSize = size + 'px' // "20px"const imgUrl = 'https://www.exampe.com/sample.png'
target.style.background = 'url(' + imgUrl + ')' // "url(https://www.exampe.com/sample.png)"target.style.cssText = 'font-size:' + size + 'px; background: url('+ imgUrl +')'  
// "font-size:30px; background: url(https://www.exampe.com/sample.png)"

上面的代码应该很多人都写过,拿到dom元素直接修改内联样式。简单的样式这样写还是可以的,但是比较复杂的时候就比较容易出错

这时可以使用 attributeStyleMap 和 computedStyleMap

<template><div id="test">111</div>
</template><script>export default {mounted() {let el = document.getElementById('test');// attributeStyleMap 用于处理内联样式,可以进行读写操作el.attributeStyleMap.set('color', 'blue');el.attributeStyleMap.set('font-size', '40px');console.log(el.attributeStyleMap.get('font-size'), el.attributeStyleMap.get('color'), el.attributeStyleMap.get('width'));// computedStyleMap 用于处理非内联样式,只允许读console.log(el.computedStyleMap().get('color').toString(), el.computedStyleMap().get('font-size'));}
};
</script><style lang="scss" scoped>
#test {width: 100px;height: 100px;background: pink;
}
</style>

在这里插入图片描述

自己尝试了一下,有几个需要注意的点:

  • attributeStyleMap ,可以进行读写,但是只能读取到内联样式
  • computedStyleMap() ,只读,可以读取到dom元素上最终的样式
  • 对于有单位的样式,比如width,会返回一个对象;对于五单位样式,比如color,需要调用toString()方法来进行转换
  • 以设置样式来说,不支持链式操作

这里补充一个与computedStyleMap 类似的东西,之前在 css中样式类型及属性值的获取 简单说过,感兴趣的可以看一下

CSS Properties & Values API

可以允许开发者自定义属性和属性值,其实就是css变量。
这个不说了,赶紧用处不大,而且有点习惯使用scss

Paint API

提供了一组与绘制(Paint)过程相关的API,我们可以通过它自定义的渲染规则,例如调整颜色(color)、边框(border)、背景(background)、形状等绘制规则。

文章最开始介绍的如何实现文本域的背景就是通过这种方式来实现的,通常需要创建一个js来编写绘制逻辑,然后使用registerPaint 进行注册。比如:

/* checkboardWorklet.js */class CheckerboardPainter {paint(ctx, geom, properties) {const colors = ['red', 'green', 'blue'];const size = 32;for(let y = 0; y < geom.height/size; y++) {for(let x = 0; x < geom.width/size; x++) {const color = colors[(x + y) % colors.length];ctx.beginPath();ctx.fillStyle = color;ctx.rect(x * size, y * size, size, size);ctx.fill();}}}
}// 注册checkerboard
registerPaint('checkerboard', CheckerboardPainter);
/* index.html */
<script>CSS.paintWorklet.addModule('path/to/checkboardWorklet.js')  // 添加checkboardWorklet到paintWorklet
</script>
/* index.html */
<!doctype html>
<textarea></textarea>
<style>textarea {background-image: paint(checkerboard);  // 使用paint()方法调用checkboard绘制背景}
</style>

但是在vue中, CSS.paintWorklet.addModule('path/to/checkboardWorklet.js') 这一步失败了,无法请求的js文件,应该是需要进行设置。
因为不知道如何处理,所以采用第二种方式

示例:绘制一个矩形

//  js
let blobURL = URL.createObjectURL(new Blob(['(',function() {class CheckerboardPainter {static get inputProperties() {return ['--rect-color'];}paint(ctx, geom, properties, args) {// ctx 一个 Canvas 的 Context 对象,因此 paint 中的绘制方式跟 canvas 绘制是一样的。// geom 包含节点的尺寸信息,同时也是 canvas 可绘制范围(画板)的尺寸信息。// properties 包含节点的 CSS 属性,需要调用静态方法 inputProperties 声明注入。// CSS 中调用 Paint 类时传入的参数,需要调用静态方法 inputArguments 声明注入const color = properties.get('--rect-color')[0];ctx.fillStyle = color;ctx.fillRect(0, 0, geom.width, geom.height);}}registerPaint('checkerboard', CheckerboardPainter);}.toString(),')()'], { type: 'application/javascript' })
);export default blobURL;// 使用
<template><div><div class="rect"></div></div>
</template><script>import blobURL from './checkerboard.js';
export default {mounted() {CSS.paintWorklet.addModule(blobURL);}
};
</script><style lang="scss" scoped>
.rect {width: 100px;height: 100px;--rect-color: red;background-image: paint(checkerboard);
}
</style>

在这里插入图片描述
官方示例文本域

let blobURL = URL.createObjectURL(new Blob(['(',function() {class CheckerboardPainter {paint(ctx, geom, properties, args) {const colors = ['red', 'green', 'blue'];// 方块的尺寸const size = 32;for (let y = 0; y < geom.height / size; y++) {for (let x = 0; x < geom.width / size; x++) {const color = colors[(x + y) % colors.length];ctx.beginPath();ctx.fillStyle = color;ctx.rect(x * size, y * size, size, size);ctx.fill();}}}}registerPaint('checkerboard', CheckerboardPainter);}.toString(),')()'], { type: 'application/javascript' })
);export default blobURL;<template><div><textarea></textarea></div>
</template>
<script>import blobURL from './checkerboard.js';
export default {mounted() {CSS.paintWorklet.addModule(blobURL);}
};
</script><style lang="scss" scoped>
textarea {background-image: paint(checkerboard);
}
</style>

在这里插入图片描述
要玩好Paint API,还是需要对canvas非常熟悉才行。

Animation API

提供了一组与合成(composite)渲染相关的API,我们可以通过它调整绘制层级和自定义动画。

略,现在有一些很不错的js动画库,没必要用这个写动画。

Layout API

提供了一组与布局(Layout)过程相关的API,我们可以通过它自定义的布局规则,类似于实现诸如flex、grid等布局,自定义元素或子元素的对齐(alignment)、位置(position)等布局规则。

略,这个一般人玩不了,也没必要看了。

磁吸效果

效果:https://codepen.io/HelKyle/pen/zYWozde
效果图:
在这里插入图片描述

let blobURL = URL.createObjectURL(new Blob(['(',function() {class MagnetMatrixPaintWorklet {// 鼠标位置、点的颜色、大小、间隔、影响半径static get inputProperties() { return ['--mouse-x', '--mouse-y', '--magnet-color', '--magnet-size', '--magnet-gap', '--magnet-radius']; }paint(ctx, size, props) {const mouseX = parseInt(props.get('--mouse-x'));const mouseY = parseInt(props.get('--mouse-y'));const color = props.get('--magnet-color');const lineWidth = parseInt(props.get('--magnet-size'));const gap = parseInt(props.get('--magnet-gap'));const radius = parseInt(props.get('--magnet-radius'));ctx.lineCap = 'round';for (let i = 0; i * gap < size.width; i++) {for (let j = 0; j * gap < size.height; j++) {const posX = i * gap;const posY = j * gap;const distance = Math.sqrt(Math.pow(posX - mouseX, 2) + Math.pow(posY - mouseY, 2));const width = distance < radius ? (1 - distance / radius * distance / radius) * gap * 0.4 : 0;const startPosX = posX - width * 0.5;const endPosX = posX + width * 0.5;const rotate = Math.atan2(mouseY - posY, mouseX - posX);ctx.save();ctx.beginPath();ctx.translate(posX, posY);ctx.rotate(rotate);ctx.translate(-posX, -posY);ctx.moveTo(startPosX, posY);ctx.strokeStyle = color;ctx.lineWidth = lineWidth;ctx.lineCap = 'round';ctx.lineTo(endPosX, posY);ctx.stroke();ctx.closePath();ctx.restore();}}}}registerPaint('magnet-matrix', MagnetMatrixPaintWorklet);}.toString(),')()'], { type: 'application/javascript' })
);export default blobURL;
<template><div class="demo"></div>
</template>
<script>import blobURL from './checkerboard.js';
export default {mounted() {if ('paintWorklet' in CSS) {CSS.paintWorklet.addModule(blobURL);}let div = document.getElementsByTagName('div')[0];div.addEventListener('mouseenter', e => {div.style.setProperty('--mouse-x', e.clientX);div.style.setProperty('--mouse-y', e.clientY);});div.addEventListener('mousemove', e => {div.style.setProperty('--mouse-x', e.clientX);div.style.setProperty('--mouse-y', e.clientY);});div.addEventListener('mouseleave', () => {div.style.setProperty('--mouse-x', -999);div.style.setProperty('--mouse-y', -999);});},
};
</script><style lang="scss" scoped>
div {box-sizing: border-box;padding: 0;margin: 0;
}.demo {width: 100vw;height: 100vh;padding: 80px;--magnet-color: rgb(97, 123, 255);--magnet-size: 2;--magnet-gap: 20;--magnet-radius: 150;background: paint(magnet-matrix);
}
</style>

相关文章:

CSS Houdini

前言 最近看了几篇文章&#xff0c;是关于 CSS Houdini 的。作为一个前端搬砖的还真不知道这玩意&#xff0c;虽然不知道的东西挺多的&#xff0c;但是这玩意有点高大上啊。 Houdini 是一组底层 API&#xff0c;它们公开了 CSS 引擎的各个部分&#xff0c;从而使开发人员能够通…...

C++引用

这里写目录标题引用引用的基本使用引用做函数参数引用作为函数返回值引用的本质常量引用引用与指针的区别&的三种作用引用 引用的基本使用 作用&#xff1a; 给变量起别名 语法&#xff1a; 数据类型 &别名 原名 引用的本质是给变量起别名&#xff0c;因此&#xff0…...

YOLOv6-目标检测论文解读

文章目录摘要问题算法网络设计BackboneNeckHead标签分配SimOTA&#xff08;YOLOX提出&#xff09;&#xff1a;TAL&#xff08;Task alignment learning&#xff0c;TOOD提出&#xff09;损失函数分类损失框回归损失目标损失行业有用改进自蒸馏图像灰度边界填充量化及部署实验消…...

【factoryio】使用SCL编写 <机械手控制> 程序

使用虚拟工厂软件和博图联合仿真来编写【scl】机械手控制程序 文章目录 目录 文章目录 前言 二、程序编写 1.机械手运行部分 2.启动停止部分 3.急停复位部分 三、完整代码 总结 前言 在前面我们一起写过了许多案例控制的编写&#xff0c;在这一章我们一起来编写一下一个…...

QT学习记录散件

fromLocal8Bit() qt中fromLocal8Bit()函数可以设置编码。 因为QT默认的编码是unicode&#xff0c;不能显示中文的 而windows默认使用&#xff08;GBK/GB2312/GB18030&#xff09; 所以使用fromLocal8Bit()函数&#xff0c;可以实现从本地字符集GB到Unicode的转换&#xff0c;从…...

[SSD科普之1] PCIE接口详解及应用模式

PCI-Express(peripheral component interconnect express)是一种高速串行计算机扩展总线标准&#xff0c;它原来的名称为“3GIO”&#xff0c;是由英特尔在2001年提出的&#xff0c;旨在替代旧的PCI&#xff0c;PCI-X和AGP总线标准。一、PCI-E x1/x4/x8/x16插槽模式PCI-E有 x1/…...

Linux设备驱动模型与 sysfs实现分析

RTOS和Linux系统上开发驱动的方式非常的不同,在RTOS系统下,驱动和驱动之间并没有实质性的联系,不同的驱动和BSP之间仅仅通过一层很薄很薄的设备管理框架聚合在一起构成RTOS的设备管理子系统。图形化表示如下: 设备驱动&BSP之间互相独立,互不影响,互不依赖,独立实现,…...

软考高级之制定备考计划

制定备考计划 高项准备时间最好是三个月以上&#xff0c;分为三个阶段来复习。 第一个阶段——熟悉知识点 第二个阶段——刷题 第三个阶段——冲刺复习 具体操作 第一个阶段 这个阶段的复习以教材和视频为主&#xff0c;掌握重要知识点。基础知识要打牢。例如&#xff1…...

[Pytorch] Linear层输出nan

参考链接&#xff1a; https://discuss.pytorch.org/t/well-formed-input-into-a-simple-linear-layer-output-nan/74720/11 总结原因&#xff1a; numpy需要更新 PS. 查看numpy版本号 打开Anaconda Prompt 进入环境 输入命令conda activate envname 然后输入pip show numpy…...

2023-2-19-What is ‘ template<typename E, E V> ‘?

目录C里面template怎么用inline函数模板类模板函数模板特化C里面template怎么用 template是什么? template其实是C的一种语法糖&#xff0c;本意是去简化程序员的工作. void swap(int *a,int *b){int temp *a;*a *b;*b temp; }比如在写一个交换函数的的时候,参数为两个in…...

华为OD机试题 - 字符串加密(JavaScript)

最近更新的博客 华为OD机试题 - 任务总执行时长(JavaScript) 华为OD机试题 - 开放日活动(JavaScript) 华为OD机试 - 最近的点 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试题 - 最小步骤数(JavaScript) 华为OD机试题 - 任务混部(JavaScript) 华为OD机试题 - N 进…...

美团前端一面手写面试题

实现斐波那契数列 // 递归 function fn (n){if(n0) return 0if(n1) return 1return fn(n-2)fn(n-1) } // 优化 function fibonacci2(n) {const arr [1, 1, 2];const arrLen arr.length;if (n < arrLen) {return arr[n];}for (let i arrLen; i < n; i) {arr.push(arr[…...

2D图像处理:缺陷检测--仿照Halcon的Variation Model

文章目录 基于 C++&Opencv 的检测结果(Robust模式-MAD)一、Variation Model1.1 准备和训练模型方法1.2 比较模板方法1.3 过滤(保留符合缺陷特征的区域)二、参考基于 C++&Opencv 的检测结果(Robust模式-MAD) 一、Variation Model Halcon中的Variation Model主要是将待…...

JavaScript 注释

JavaScript 注释可用于提高代码的可读性。JavaScript 注释JavaScript 不会执行注释。我们可以添加注释来对 JavaScript 进行解释&#xff0c;或者提高代码的可读性。单行注释以 // 开头。本例用单行注释来解释代码&#xff1a;实例// 输出标题&#xff1a;document.getElementB…...

浅谈使用CDN加速的OSS

目录引出OSS对象存储服务CDNCDN加速OSS资源总结引出 之前&#xff0c;我在写项目的时候&#xff0c;因为项目中存在音视频的存储&#xff0c;然后我看圈子里面的人都是使用OSS对象存储来处理&#xff0c;然后我也跟风去使用了&#xff0c;然后在之后&#xff0c;我一个朋友问我…...

华为OD机试题 - 服务依赖(JavaScript)

最近更新的博客 华为OD机试题 - 任务总执行时长(JavaScript) 华为OD机试题 - 开放日活动(JavaScript) 华为OD机试 - 最近的点 | 备考思路,刷题要点,答疑 【新解法】 华为OD机试题 - 最小步骤数(JavaScript) 华为OD机试题 - 任务混部(JavaScript) 华为OD机试题 - N 进…...

整合K8s+SpringCloudK8s+SpringBoot+gRpc

本文使用K8s当做服务注册与发现、配置管理&#xff0c;使用gRpc用做服务间的远程通讯一、先准备K8s我在本地有个K8s单机二、准备service-providerpom<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.…...

Django框架之模型视图--HttpResponse对象

HttpResponse对象 视图在接收请求并处理后&#xff0c;必须返回HttpResponse对象或子对象。HttpRequest对象由Django创建&#xff0c;HttpResponse对象由开发人员创建。 1 HttpResponse 可以使用django.http.HttpResponse来构造响应对象。 HttpResponse(content响应体, con…...

Linux下的Jenkins安装教程

当前环境 CentOS 7.8Java 11&#xff08;注意当前jenkins支持的Java版本最低为Java11&#xff09;FinalShell 3.9&#xff08;操作环境&#xff09; 安装Jenkins PS&#xff1a;不建议使用Docker安装Jenkins&#xff0c;因为使用Jenkins的时候一般会调用外部程序&#xff0c;…...

[软件工程导论(第六版)]第5章 总体设计(课后习题详解)

文章目录1. 为每种类型的模块耦合举一个具体例子。2. 为每种类型的模块内聚举一个具体例子。3. 用面向数据流的方法设计下列系统的软件结构。4. 美国某大学共有200名教师&#xff0c;校方与教师工会刚刚签订一项协议。按照协议&#xff0c;所有年工资超过$26000&#xff08;含$…...

【OSG学习笔记】Day 18: 碰撞检测与物理交互

物理引擎&#xff08;Physics Engine&#xff09; 物理引擎 是一种通过计算机模拟物理规律&#xff08;如力学、碰撞、重力、流体动力学等&#xff09;的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互&#xff0c;广泛应用于 游戏开发、动画制作、虚…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...