<!DOCTYPE html>
<html>
<script src="resources/test-runner-paint-worklet.js"></script>
<style>
#example {
max-width: 100px;
--border-top-width: 10;
--border-right-width: 20;
--border-bottom-width: 30;
--border-left-width: 40;
--border-top-color: red;
--border-right-color: green;
--border-bottom-color: cyan;
--border-left-color: blue;
}
.multi-border {
border-style: solid;
border-image: paint(border-colors);
border-image-slice:
var(--border-top-width)
var(--border-right-width)
var(--border-bottom-width)
var(--border-left-width);
border-width:
calc(var(--border-top-width) * 1px)
calc(var(--border-right-width) * 1px)
calc(var(--border-bottom-width) * 1px)
calc(var(--border-left-width) * 1px);
}
</style>
<body>
<div id=example class=multi-border></div>
<script>
[
'--border-top-color',
'--border-right-color',
'--border-bottom-color',
'--border-left-color',
].map((name) => {
CSS.registerProperty({
name: name,
syntax: '<color>+',
inherits: false,
initialValue: 'currentcolor',
});
});
[
'--border-top-width',
'--border-right-width',
'--border-bottom-width',
'--border-left-width',
].map((name) => {
CSS.registerProperty({
name: name,
syntax: '<number>',
inherits: false,
initialValue: '0',
});
});
</script>
<script id="code" type="text/worklet">
registerPaint('border-colors', class {
static get inputProperties() {
return [
'--border-top-width',
'--border-right-width',
'--border-bottom-width',
'--border-left-width',
'--border-top-color',
'--border-right-color',
'--border-bottom-color',
'--border-left-color',
];
}
paint(ctx, size, styleMap) {
const t = 0;
const r = size.width;
const b = size.height;
const l = 0;
const tw = parseFloat(styleMap.get('--border-top-width'));
const rw = parseFloat(styleMap.get('--border-right-width'));
const bw = parseFloat(styleMap.get('--border-bottom-width'));
const lw = parseFloat(styleMap.get('--border-left-width'));
const ti = tw;
const ri = size.width - rw;
const bi = size.height - bw;
const li = lw;
let tp, rp, bp, lp, colors;
const updateProgression = function() {
tp = tw / colors.length;
rp = rw / colors.length;
bp = bw / colors.length;
lp = lw / colors.length;
}
colors = styleMap.getAll('--border-top-color');
updateProgression();
for (let i = 0; i < colors.length; i++) {
ctx.fillStyle = colors[i];
this.fillQuad(ctx,
li - lp * i, ti - tp * i,
li - lp * (i+1), ti - tp * (i+1),
ri + lp * (i+1), ti - tp * (i+1),
ri + lp * i, ti - tp * i);
}
colors = styleMap.getAll('--border-right-color');
updateProgression();
for (let i = 0; i < colors.length; i++) {
ctx.fillStyle = colors[i];
this.fillQuad(ctx,
ri + rp * i, ti - tp * i,
ri + rp * (i+1), ti - tp * (i+1),
ri + rp * (i+1), bi + bp * (i+1),
ri + rp * i, bi + bp * i);
}
colors = styleMap.getAll('--border-bottom-color');
updateProgression();
for (let i = 0; i < colors.length; i++) {
ctx.fillStyle = colors[i];
this.fillQuad(ctx,
ri + rp * i, bi + bp * i,
ri + rp * (i+1), bi + bp * (i+1),
li - lp * (i+1), bi + bp * (i+1),
li - lp * i, bi + bp * i);
}
colors = styleMap.getAll('--border-left-color');
updateProgression();
for (let i = 0; i < colors.length; i++) {
ctx.fillStyle = colors[i];
this.fillQuad(ctx,
li - lp * i, bi + bp * i,
li - lp * (i+1), bi + bp * (i+1),
li - lp * (i+1), ti - tp * (i+1),
li - lp * i, ti - tp * i);
}
}
fillQuad(ctx, x1, y1, x2, y2, x3, y3, x4, y4) {
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.lineTo(x4, y4);
ctx.lineTo(x1, y1);
ctx.fill();
}
});
</script>
<script>
importPaintWorkletThenEndTest(document.getElementById('code').textContent);
</script>
</body>
</html>