Skip to content

Instantly share code, notes, and snippets.

@chrishow
Created July 3, 2024 14:41
Show Gist options
  • Save chrishow/079f389e7096f0fa1efac086893ddf8a to your computer and use it in GitHub Desktop.
Save chrishow/079f389e7096f0fa1efac086893ddf8a to your computer and use it in GitHub Desktop.
Octopus not SVG
<div class=container>
<ol class='in items'>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
<li>Item</li>
</ol>
<div class=head>
Lorem Ipsum
</div>
</div>
const itemLists = document.querySelectorAll('.items');
itemLists.forEach((itemList) => {
const items = itemList.querySelectorAll(':scope > li');
const numItems = items.length;
itemList.style.setProperty('--itemCount', numItems);
console.log('numItems: ', numItems);
items.forEach((item, i) => {
const arm = document.createElement('div');
arm.style.setProperty('--index', i+1);
let svg;
if(i == ((numItems + 1) / 2 ) - 1) {
svg = getFlatSvg();
arm.classList.add('middle');
} else if(i > numItems / 2 - 1) {
svg = getCurveSvg();
arm.classList.add('bottom');
} else {
svg = getCurveSvg();
}
arm.appendChild(svg);
item.prepend(arm);
});
});
function getCurveSvg() {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
// viewBox="0 0 100 100" preserveAspectRatio="none"
svg.setAttribute('viewBox', "0 0 100 100");
svg.setAttribute('preserveAspectRatio', "none");
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute('vector-effect', 'non-scaling-stroke');
path.setAttribute('d', 'm 0 4 C 80 2, 40 96, 100 98');
svg.appendChild(path);
return svg;
}
function getFlatSvg() {
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
// viewBox="0 0 100 100" preserveAspectRatio="none"
svg.setAttribute('viewBox', "0 0 100 100");
svg.setAttribute('preserveAspectRatio', "none");
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute('vector-effect', 'non-scaling-stroke');
path.setAttribute('d', 'm 0 4 h 100');
svg.appendChild(path);
return svg;
}
:root {
--bg-color: hotpink;
--fg-color: white;
--item-vertical-padding: .25em;
--item-vertical-margin: .5em;
/* font-size: 12px; */
}
body {
font-family: system-ui, sans-serif;
font-weight: normal;
}
.container {
color: var(--fg-color);
display: grid;
width: 80%;
border: 1px grey solid;
grid-template-columns: 2fr 1fr 2fr;
align-items: center;
line-height: 1
}
.items {
margin: 0;
padding: 0;
list-style: none;
position: relative;
}
.items li {
background-color: var(--bg-color);
margin: var(--item-vertical-margin) 0 var(--item-vertical-margin) 0.5em;
padding: var(--item-vertical-padding) 0.5em;
border-radius: 0.5em;
width: calc(50% - 1em);
}
.items li div {
position: absolute;
z-index: -1;
/* background-color: rgba(0, 255, 0, 0.5); */
height: calc(
50% -
(
(var(--index) - 1) * (var(--item-vertical-padding) * 2)
) -
(
(var(--index) - 1) * (var(--item-vertical-margin) * 1)
) -
(
(var(--index) - 1) * 1em
) + var(--item-vertical-padding)
);
right: -1em;
width: calc(50% + 2em);
margin-top: calc(-1 * (var(--item-vertical-padding)));
padding-block: calc(var(--item-vertical-padding) + 0.5em);
padding-block: 0.5em;
}
.items li div.bottom {
/* background-color: blue; */
/* background-color: rgba(0, 255, 0, 0.5); */
height: calc(
50% -
(
(var(--itemCount) - var(--index) + 0) * (var(--item-vertical-padding) * 2)
) -
(
(var(--itemCount) - var(--index) + 0) * (var(--item-vertical-margin) * 1)
) -
(
(var(--itemCount) - var(--index) + 0) * 1em
) - var(--item-vertical-padding)
);
top: 50%;
/* left: calc(var(--index) * 1em); */
margin-top: calc(-1 * (var(--item-vertical-padding)));
}
.items li div.middle {
top: auto;
bottom: initial;
margin-top: 0;
}
.items li div.middle svg {
height: 1em;
}
.items li div.bottom svg {
transform: scaleY(-1);
}
.items li div svg {
width: 100%;
height: calc(100% - 1em);
overflow: visible;
}
.items li div svg path {
stroke: hotpink;
fill: transparent;
stroke-width: 10;
}
.items.out li {
margin: 0.5em 0.5em 0.5em 0;
}
.head {
background-color: var(--bg-color);
aspect-ratio: 1;
width: 100%;
border-radius: 50%;
text-align: center;
display: flex;
justify-content: center;
flex-direction: column;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment