工作中碰到需要实现下图所示的多边形,找了资料,找到了使用clip-path的实现
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Clipped Corner Div</title>
<style>
:root {
--clipPath: 10px 0%, 370px 0%, 100% 10px, 100% 84px, 370px 100%, 10px 100%, 0% 84px, 0% 10px;
--borderWidth: 2;
--color: #ffcc00;
}
.box {
margin-left: 200px;
margin-top: 200px;
width: 380px;
height: 94px;
position: relative;
clip-path: polygon(var(--clipPath));
}
img {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.box::before {
content: "";
position: absolute;
z-index: -1;
inset: 0;
mask: paint(borderDraw);
background: var(--color);
}
</style>
</head>
<body>
<div class="box"></div>
<script>
if (CSS.paintWorklet) {
CSS.paintWorklet.addModule('./css.js');
}
</script>
</body>
</html>
css.js
registerPaint(
"borderDraw",
class {
static get inputProperties() {
return ["--borderWidth", "--clipPath"];
}
paint(ctx, size, properties) {
let borderWidth = properties.get("--borderWidth");
let clipPath = properties.get("--clipPath");
const width = size.width;
const height = size.height;
const paths = clipPath.toString().split(",");
const cc = function (obj) {
const x = obj[0];
const y = obj[1];
let fx = 0,
fy = 0;
if (x.indexOf("%") > -1) {
fx = (parseFloat(x) / 100) * width;
} else if (x.indexOf("px") > -1) {
fx = parseFloat(x);
}
if (y.indexOf("%") > -1) {
fy = (parseFloat(y) / 100) * height;
} else if (y.indexOf("px") > -1) {
fy = parseFloat(y);
}
return [fx, fy];
};
var p = cc(paths[0].trim().split(" "));
ctx.beginPath();
ctx.moveTo(p[0], p[1]);
for (var i = 1; i < paths.length; i++) {
let item = paths[i];
p = cc(item.trim().split(" "));
ctx.lineTo(p[0], p[1]);
}
ctx.closePath();
ctx.lineWidth = borderWidth * 2;
ctx.strokeStyle = "#000";
ctx.stroke();
}
}
);