使用 CSS Paint API 可以动态创建与分辨率无关的可变背景效果。步骤如下:
第一步:安装 CSS Paint Api 支持
CSS Paint API 是一个比较新的标准,目前只有部分浏览器支持,需要在 CSS 中通过 -webkit-paint
或 -moz-paint
属性来标明。具体地,在 CSS 中添加 -webkit-paint
标明支持该标准。因此,最好在 Safari 和 Chrome 浏览器中实验,以避免兼容性问题。
第二步:定义绘制逻辑
在 CSS 中定义自定义绘制逻辑,通过JavaScript代码将背景渲染到元素中。先定义一个 <svg>
元素将它作为 SVG 的背景,再在其中通过 JavaScript 绘制背景。
<style>
.my-element {
background-image: paint(my-paint);
width: 100%;
height: 200px;
}
</style>
<svg>
<rect width="100%" height="100%" fill="#F00" />
<rect x="10%" y="10%" width="80%" height="80%" fill="#FF0" />
</svg>
<script>
registerPaint('my-paint', class {
static get inputProperties() {
return ['--my-color'];
}
paint(ctx, size, props) {
const color = props.get('--my-color').toString();
ctx.fillStyle = color;
ctx.fillRect(0, 0, size.width, size.height);
}
});
</script>
如上代码,定义了一个 .my-element
选择器,背景使用 paint()
函数来指定。在 SVG 元素中,我们定义了两个 <rect>
元素以及它们的属性。然后通过 registerPaint()
函数注册了一个名字为 my-paint
的新的绘制逻辑。
在 inputProperties
中返回待渲染背景的属性(在上述示例中为 --my-color
),在绘制过程中使用 ctx.fillRect
绘制了一个填充了指定颜色背景的矩形。
第三步:应用绘制逻辑
在页面的任意场景下,都可以灵活应用编写好的自定义绘制逻辑。当元素的宽度、高度、边框、和 padding 等属性发生变化时,当滚动条在元素内滚动时,都会触发 Paint API 重新绘制背景。
以下是一个在滚动容器中,动态应用自定义绘制逻辑的示例:
<style>
.my-scrollable-element {
overflow: auto;
width: 500px;
height: 300px;
border: 2px solid #000;
padding: 10px;
}
.my-scrollable-element::-webkit-scrollbar {
display: none;
}
.my-custom-background {
background-image: paint(custom-paint);
}
</style>
<div class="my-scrollable-element">
<div class="my-custom-background">
This is some scrolling content with a custom background
</div>
</div>
<script>
registerPaint('custom-paint', class {
paint(ctx, size, props) {
const {width, height} = size;
const centerX = width / 2;
const centerY = height / 2;
const radius = Math.min(centerX, centerY);
const numCircles = 5;
for (let i = 0; i < numCircles; i++) {
const pct = i / (numCircles - 1);
const maxRadius = radius * pct;
const circleRadius = maxRadius * 0.7;
const red = Math.floor((1 - pct) * 255);
const color = `rgb(${red},0,0)`;
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(centerX, centerY, circleRadius, 0, 2*Math.PI, false);
ctx.fill();
}
}
});
</script>
在这个示例中,我们定义了一个 .my-scrollable-element
容器,在其中定义了一个自定义背景的元素.my-custom-background
。registerPaint()
方法同样定义了一个名为 custom-paint
的绘制逻辑,用于在自定义背景上绘制多个环形圆。这个背景基本不受多种属性的影响,当滚动容器内滚动时,容器背景的位置和颜色都是随着滚动发生变化。