Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 46 additions & 8 deletions kaviraj/svgCutouts.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
function applyCornerCircleCutoutsV2() {
function applyCornerCircleCutoutsV3() {
const targets = document.querySelectorAll('[data-cutout="true"], [data-cutout-child="true"]');

targets.forEach((container, index) => {
const isChild = container.getAttribute("data-cutout-child") === "true";
const hasInset = container.getAttribute("data-cutout-inset") === "true";

// Prevent duplication if SVG already injected
if (container.querySelector("svg.cutout-svg")) return;
Expand Down Expand Up @@ -48,9 +49,8 @@ function applyCornerCircleCutoutsV2() {
svg.style.left = "0";
svg.style.zIndex = "-1";

container.insertBefore(svg, container.firstChild); // Inject SVG
container.insertBefore(svg, container.firstChild);

// Apply cutout mask logic
const parentWidth = container.offsetWidth;
const parentHeight = container.offsetHeight;

Expand All @@ -59,23 +59,61 @@ function applyCornerCircleCutoutsV2() {
svg.setAttribute("viewBox", `0 0 ${parentWidth} ${parentHeight}`);

const maskId = `cutout-mask-${index}`;

// Apply mask to the container itself
container.style.mask = `url(#${maskId})`;
container.style.webkitMask = `url(#${maskId})`; // For Safari
container.style.webkitMask = `url(#${maskId})`;

// Create <defs> and <mask>
const defs = document.createElementNS("http://www.w3.org/2000/svg", "defs");
const mask = document.createElementNS("http://www.w3.org/2000/svg", "mask");
mask.setAttribute("id", maskId);
mask.setAttribute("maskUnits", "userSpaceOnUse");

// Base white rect
const whiteRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
whiteRect.setAttribute("width", "100%");
whiteRect.setAttribute("height", "100%");
whiteRect.setAttribute("fill", "white");
mask.appendChild(whiteRect);

// Optional inset logic
if (hasInset) {
const insetWidthPercent = parseFloat(container.getAttribute("data-inset-width") || "40");
const insetPadding = parseFloat(container.getAttribute("data-inset-padding") || "10");

const insetTotalWidth = (insetWidthPercent / 100) * parentWidth;
const insetRectWidth = insetTotalWidth - insetPadding * 2;
const insetRectHeight = parentHeight - insetPadding * 2;
const insetX = parentWidth - insetRectWidth - insetPadding;
const insetY = insetPadding;
const expandedRadius = radius + insetPadding;

// Inset black rect
const insetRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
insetRect.setAttribute("width", insetRectWidth);
insetRect.setAttribute("height", insetRectHeight);
insetRect.setAttribute("x", insetX);
insetRect.setAttribute("y", insetY);
insetRect.setAttribute("fill", "black");
mask.appendChild(insetRect);

// Inset white corner circles
const insetCircleData = [
[parentWidth - insetTotalWidth, 0], // Top-left
[parentWidth, 0], // Top-right
[parentWidth - insetTotalWidth, parentHeight], // Bottom-left
[parentWidth, parentHeight], // Bottom-right
];

insetCircleData.forEach(([cx, cy]) => {
const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
circle.setAttribute("cx", cx);
circle.setAttribute("cy", cy);
circle.setAttribute("r", expandedRadius);
circle.setAttribute("fill", "white");
mask.appendChild(circle);
});
}

// Outer corner cutouts
const positions = [
[0 - offset, 0 - offset],
[parentWidth + offset, 0 - offset],
Expand All @@ -97,7 +135,7 @@ function applyCornerCircleCutoutsV2() {
});
}

window.addEventListener("load", applyCornerCircleCutoutsV2);
window.addEventListener("load", applyCornerCircleCutoutsV3);
window.addEventListener("resize", () => {
document.querySelectorAll("svg.cutout-svg").forEach(el => el.remove());
applyCornerCircleCutoutsV2();
Expand Down