Ниже — обзор возможных способов нарисовать такую «нестандартную» фигуру (четыре круга по кругу, два из которых соединены «перемычкой» в виде вогнутого песочных часов), и готовые примеры для трёх наиболее удобных подходов.
Варианты подходов
- SVG — лучший вариант для векторной точной графики. Простой контроль форм (arc, path, Beziers), легко масштабируется и стилизуется CSS/SMIL/JS.
- Canvas 2D — рисуете программно (arc, bezierCurveTo). Удобно для анимаций и динамики.
- Чистый CSS — через clip-path/path(), маски (mask-image), многослойные градиенты; кроссбраузерность хуже, но можно обойтись без SVG.
- SVG + булевы операции (mask/clipPath или сторонние утилиты) — когда нужен точный union/subtract.
- Библиотеки: Paper.js, Snap.svg, D3.js, Fabric.js — упрощают создание кривых и булевых операций.
- Растер/PNG/SVG в графическом редакторе (Inkscape/Illustrator) — если не нужна программная генерация.
Рекомендую SVG — далее привожу готовый пример (центр страницы, 4 круга по окружности, левый и правый соединены вогнутой «песочницей»).
1) SVG (рекомендуется)
- код можно вставить прямо в HTML; легко менять радиусы/позиции/цвет.
Пример (вставьте в тело страницы):
```
<svg viewBox="0 0 400 400" width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="#fafafa"/>
<g transform="translate(0,0)" fill="#4a90e2" stroke="#2f6fb0" stroke-width="2">
<!-- параметры: центр 200,200; расстояние до центров 80; радиус кругов 30 -->
<!-- четыре круга (право, верх, лево, низ) -->
<circle cx="280" cy="200" r="30"/>
<circle cx="200" cy="120" r="30"/>
<circle cx="120" cy="200" r="30"/>
<circle cx="200" cy="280" r="30"/>
<!-- перемычка между левым (120,200) и правым (280,200) -->
<!-- верхний и нижний кривые делают «вогнутость» (hourglass) -->
<path d="
M 120 170
C 160 120, 240 120, 280 170
L 280 230
C 240 280, 160 280, 120 230
Z
"/>
</g>
</svg>
```
Пояснения: путь (path) описывает верхнюю кубическую Безье-кривую от верхней точки левого круга до верхней точки правого круга с контрольными точками, смещёнными внутрь (это даёт вогнутость). Затем идёт линия вниз и нижняя кривая возвращается обратно — в итоге закрытая «лента» hourglass. Кружки и перемычка имеют одинаковый fill, поэтому визуально выглядят как единая фигура.
2) Canvas 2D
- подходит, если нужна анимация или динамическая генерация.
Пример:
```
<canvas id="c" width="400" height="400"></canvas>
<script>
const c = document.getElementById('c');
const ctx = c.getContext('2d');
const cx = 200, cy = 200, orbit = 80, r = 30;
const left = {x: cx - orbit, y: cy};
const right = {x: cx + orbit, y: cy};
ctx.fillStyle = '#4a90e2';
ctx.strokeStyle = '#2f6fb0';
ctx.lineWidth = 2;
// четыре круга
[[right.x,right.y],[cx,cy-orbit],[left.x,left.y],[cx,cy+orbit]].forEach(p=>{
ctx.beginPath();
ctx.arc(p[0], p[1], r, 0, Math.PI*2);
ctx.fill();
ctx.stroke();
});
// перемычка (hourglass) — верхняя и нижняя кривые
ctx.beginPath();
ctx.moveTo(left.x, left.y - r);
ctx.bezierCurveTo(left.x + 40, left.y - 80, right.x - 40, right.y - 80, right.x, right.y - r);
ctx.lineTo(right.x, right.y + r);
ctx.bezierCurveTo(right.x - 40, right.y + 80, left.x + 40, left.y + 80, left.x, left.y + r);
ctx.closePath();
ctx.fill();
ctx.stroke();
</script>
```
3) CSS / clip-path (без SVG)
- можно использовать clip-path: path('...') или маску. Подходит, если хотите держать всё в DOM-элементе и управлять через CSS.
- caveat: поддержка clip-path: path() не во всех старых браузерах.
Пример (основная идея — вставить SVG-путь в clip-path):
```
<div class="shape"></div>
<style>
.shape{
width:400px;
height:400px;
margin:20px auto;
background:#4a90e2;
/* вставляем тот же путь, что и в SVG */
-webkit-clip-path: path("M 120 170 C 160 120, 240 120, 280 170 L 280 230 C 240 280, 160 280, 120 230 Z M 280 200 A 30 30 0 1 1 280 199.9 Z ...");
clip-path: path("..."); /* потребуется объединить круги и перемычку в один path */
}
</style>
```
Примечание: в clip-path нужно объединить контуры (path) всех элементов (четыре круга + перемычка) — это труднее вручную, поэтому практичнее сделать SVG и использовать его как <svg> или как background-image.
Дополнительные замечания и советы
- Если вам нужна идеально плавная «стыковка» перемычки и кругов (без видимых швов), лучше использовать один объединённый SVG path (union) или настроить кривые так, чтобы контуры точно стыковались с точками окружностей.
- Если надо вырезать часть (boolean subtract), используйте SVG mask или библиотеку, поддерживающую булевы операции (например, Paper.js, или Inkscape/Illustrator для подготовки SVG).
- Для адаптивности делайте всё в координатах viewBox и масштабируйте через CSS.
- Для анимаций: в SVG можно анимировать атрибут d (path) или применять SMIL/CSS/JS-анимации; в Canvas — перерисовывать.
Если хотите, могу:
- прислать готовый SVG path, который объединяет все четыре круга и перемычку в один закрытый контур (для экспортирования);
- сделать адаптивную версию (в процентах) или анимированную (подтяжка/растяжение перемычки);
- подготовить PNG/SVG-файл по вашему цвету и размеру.
Напишите, какой из способов предпочтительнее и нужно ли точное воссоздание прототипа (я сделаю подгонку координат и дам итоговый файл).