时间:2021-05-08
来源:https://medium.com/better-programming,作者:Ferenc Almasi
现代Web应用对图像的需求量很大,它们占据网络下载的大部分字节。通过优化它们,你可以更好地利用它们的性能。如果你碰巧使用几何图形作为背景图像,有一个替代方案:你可以使用 CSS Paint API [1] 以编程方式生成背景。
在本教程中,我们将探讨其功能,并探讨如何使用它来动态创建与分辨率无关的动态背景。这将是本教程的输出:
参考阅读:CSS届的绘图板CSS Paint API简介
设置项目
首先,创建一个新的 index.html 文件,并编写如下代码:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>:art: CSS Paint API</title> <link rel="stylesheet" href="styles.css" /> </head> <body> <textarea class="pattern"></textarea> <script> if ('paintWorklet' in CSS) { CSS.paintWorklet.addModule('pattern.js'); } </script> </body></html>有几件事要注意:
什么是worklet?
Paint worklet是一个定义了应该画在画布上的内容的类。它们的工作原理与 canvas 元素类似。如果你以前有这方面的知识,代码会看起来很熟悉。然而,它们并不是100%相同的。例如,在worklet中还不支持文本渲染方法。
在这里,我们还要定义CSS样式。这是我们要使用worklet的地方:
.pattern { width: 250px; height: 250px; border: 1px solid #000; background-image: paint(pattern);}我添加了一个黑色的边框,这样我们可以更好地看到 textarea 。要引用一个paint worklet,你需要把 paint(worklet-name) 作为一个值传递给 background-image 属性。但是 pattern 是从哪里来的呢?我们还没有定义它,所以让我们把它作为我们的下一步。
定义Worklet
打开 pattern.js 并添加以下内容:
class Pattern { paint(context, canvas, properties) { }}registerPaint('pattern', Pattern);在这里可以使用 registerPaint 方法注册 paintWorklet 。你可以在此处定义的CSS中引用第一个参数。第二个参数是定义应在canvas上绘画的类。它具有一个包含三个参数的 paint 方法:
contextPaintRenderingContext2DCanvasRenderingContext2D APIcanvas :这是我们的canvas,一个 PaintSize 对象,只有两个属性:width和height。
properties :这将返回一个 StylePropertyMapReadOnly 对象,我们可以使用该对象通过JavaScript读取CSS属性及其值。
绘制矩形
下一步是显示一些东西,所以让我们绘制矩形。将以下内容添加到 paint 方法中:
paint(context, canvas, properties) { for (let x = 0; x < canvas.height / 20; x++) { for (let y = 0; y < canvas.width / 20; y++) { const bgColor = (x + y) % 2 === 0 ? '#FFF' : '#FFCC00'; context.shadowColor = '#212121'; context.shadowBlur = 10; context.shadowOffsetX = 10; context.shadowOffsetY = 1; context.beginPath(); context.fillStyle = bgColor; context.rect(x * 20, y * 20, 20, 20); context.fill(); } }}我们在这里所做的就是创建一个嵌套循环,以循环遍历画布的宽度和高度。由于矩形的大小为20,因此我们要将矩形的高度和宽度除以20。
在第4行,我们可以使用模数运算符在两种颜色之间切换。我还为深度添加了一些阴影。最后,我们在画布上绘制矩形。如果在浏览器中打开它,则应具有以下内容:
使背景动态化
遗憾的是,除了调整 textarea 的大小和一窥Paint API是如何重绘一切的,这大部分还是静态的。所以,让我们通过添加我们可以改变的自定义CSS属性来让事情变得更加动态。
打开你的 styles.css 并在其中添加以下几行:
.pattern { width: 250px; height: 250px; border: 1px solid #000; background-image: paint(pattern);+ --pattern-color: #FFCC00;+ --pattern-size: 23;+ --pattern-spacing: 0;+ --pattern-shadow-blur: 10;+ --pattern-shadow-x: 10;+ --pattern-shadow-y: 1; }你可以通过在CSS属性前加上 — 来定义自定义CSS属性。这些属性可以被 var() 函数使用。但在我们的案例中,我们将在我们的paint worklet中使用它。
在CSS中检查支持
为确保支持Paint API,我们还可以检查CSS中的支持。为此,我们有两个选择:
访问绘画worklet中的参数
要读取 pattern.js 中的这些参数,您需要向定义paint worklet的类中添加一个新方法:
class Pattern { // `inputProperties`方法返回的任何东西,paint worklet都可以访问。 static get inputProperties() { return [ '--pattern-color', '--pattern-size', '--pattern-spacing', '--pattern-shadow-blur', '--pattern-shadow-x', '--pattern-shadow-y' ]; }}要在 paint 方法内部访问这些属性,可以使用 properties.get :
paint(context, canvas, properties) { const props = { color: properties.get('--pattern-color').toString().trim(), size: parseInt(properties.get('--pattern-size').toString()), spacing: parseInt(properties.get('--pattern-spacing').toString()), shadow: { blur: parseInt(properties.get('--pattern-shadow-blur').toString()), x: parseInt(properties.get('--pattern-shadow-x').toString()), y: parseInt(properties.get('--pattern-shadow-y').toString()) } };}对于颜色,我们需要将其转换为字符串。其他所有内容都需要转换为数字。这是因为 properties.get 返回 CSSUnparsedValue 。
properties.get的返回值
为了使内容更具可读性,我创建了两个新函数来为我们处理解析:
paint(context, canvas, properties) { const getPropertyAsString = property => properties.get(property).toString().trim(); const getPropertyAsNumber = property => parseInt(properties.get(property).toString()); const props = { color: getPropertyAsString('--pattern-color'), size: getPropertyAsNumber('--pattern-size'), spacing: getPropertyAsNumber('--pattern-spacing'), shadow: { blur: getPropertyAsNumber('--pattern-shadow-blur'), x: getPropertyAsNumber('--pattern-shadow-x'), y: getPropertyAsNumber('--pattern-shadow-y') } };}现在我们要做的就是用相应的 prop 值替换for循环中的所有内容:
for (let x = 0; x < canvas.height / props.size; x++) { for (let y = 0; y < canvas.width / props.size; y++) { const bgColor = (x + y) % 2 === 0 ? '#FFF' : props.color; context.shadowColor = '#212121'; context.shadowBlur = props.shadow.blur; context.shadowOffsetX = props.shadow.x; context.shadowOffsetY = props.shadow.y; context.beginPath(); context.fillStyle = bgColor; context.rect(x * (props.size + props.spacing), y * (props.size + props.spacing), props.size, props.size); context.fill(); }}现在回到你的浏览器,试着改变一下。
在DevTools中编辑背景 总结
为什么CSS Paint API对我们有用?有哪些用例?
最明显的是,它减小了响应的大小。通过消除图像的使用,你可以节省一个网络请求和几千字节。这样可以提高性能。
对于使用DOM元素的复杂CSS效果,你还可以减少页面上的节点数量。因为你可以用Paint API创建复杂的动画,所以不需要额外的空节点。
在我看来,最大的好处是它的可定制性远高于静态背景图片。API还可以创建与分辨率无关的图像,所以你不用担心错过单一屏幕尺寸。
如果你今天选择使用CSS Paint API,请确保你提供polyfill,因为它仍然没有被广泛采用。如果你想调整完成的项目,你可以从这个 GitHub仓库 [2] 中克隆它。
绿皮书正式版:经过前两个版本的积累和历经三年的全面重写,这本书终于达成技术剖析和用户体验的完美契合。
广深铸就宏篇:论深,本书深究JS之所以然,举世无可出其右;论广,本书遍历语义之细部,看罢再无机理之惑。
超语言之思想:万法归宗异曲同工,剥去JS外壳,本书居高处辨析语言奥义的技术大局观,适用于所有编程语言。
修炼重在重学:混合App|Node服务端|FaaS云原生|前端智能化时代,回归本质重修这门基础课才能走得更远更快。
参考资料 [1]
CSS Paint API: https://developer.mozilla.org/en-US/docs/Web/API/CSS_Painting_API
[2]
GitHub仓库: https://github.com/flowforfrank/css-paint
到此这篇关于使用 CSS Paint API 动态创建与分辨率无关的可变背景效果的文章就介绍到这了,更多相关CSS Paint API 可变背景内容请搜索以前的文章或继续浏览下面的相关文章,希望大家以后多多支持!
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
分辨率达到1920*1080是全高清标准,与尺寸无关。不能以此分辨率的大小来判断尺寸的大小。分辨率只是决定了位图图像细节的精细程度,运用在显示屏上只是代表显示屏
为了简化对图片压缩的调用,提供最简洁与合理的api压缩逻辑,对于压缩为Bitmap根据屏幕分辨率动态适配最佳大小,对于压缩为File优化底层libjpeg的压缩
显示器的分辨率越高,显示效果越清晰。且分辨率可以从显示分辨率与图像分辨率两个方向来分类。 显示器通常也被称为监视器。显示器是属于电脑的I/O设备,即输入输出设
横向分辨率一般用848,实际上这不是标准的分辨率,横向848到1280之间的都可以叫480P。分辨率可以从显示分辨率与图像分辨率两个方向来分类。显示分辨率(屏幕
网页视频全屏按钮无效的原因是设备显示器是大分辨率,而网页一般都是小分辨率,可能是设置了低分辨率,所以才全屏看到,现在也可以调回来,但不使用最佳分辨率,效果不太好