Мне нужна помощь с HTML / css.
Мой клиент хочет меню изогнутой формы, поэтому вопрос, как?
Вот скриншот меню. Скриншот
Пункты меню выделены красными квадратами, и они должны быть примерно там, где находятся розовые квадраты (на синей полосе).
Должен ли я как-то поместить их в svg или объединить svg с фоновым изображением и расположить пункты меню с помощью flexbox и т. д.?
И он также должен немного реагировать на ширину около 1000 пикселей. Оттуда я переведу меню в мобильную версию, которая у меня уже есть для других страниц.
Приветствуются любые идеи, даже плохие.
Stll, возможно, вы захотите показать нам свои предыдущие попытки и соответствующие части существующего кода. Вы даже можете настроить пример на codepen.io или аналогичном, чтобы предоставить SVG, о котором вы говорите, вместо того, чтобы просто показывать его картина. И как уже упоминал @Paulie_D, вы также можете провести дополнительное исследование, такое как текст следует по пути SVG, и поделиться им с людьми, от которых вы ожидаете помощи.






Глядя на предоставленный вами снимок экрана, есть несколько способов решить эту проблему. Сложность действительно зависит от того, как вы реализуете фоновую графику, как если бы это было фоновое изображение, когда вы изменяете размер, то смещение, необходимое для каждого элемента навигации, будет немного отличаться.
Вот два самых простых решения.
ul {
display: flex;
}
li {
list-style: none;
margin: 0 3rem;
position: relative;
width:100%;
}
li:nth-child(2) {
top: 20px;
}
li:nth-child(3) {
top: 40px;
}
li:nth-child(4) {
top: 50px;
}
li:nth-child(5), li:nth-child(6), li:nth-child(7), li:nth-child(8) {
top: 60px;
}<nav>
<ul>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
<li><a href='#' title=''>Link</a></li>
</ul>
</nav>Первое решение является самым ленивым, вы можете просто компенсировать свои элементы с помощью nth-child - это было бы значительно аккуратнее, если бы вы использовали SCSS, так как вы могли бы бросить его в итератор. (В конечном итоге скомпилированный код получился бы похожим на выше) Обратной стороной этого метода является то, что он по-настоящему отзывчив, вам, вероятно, потребуется добавить несколько медиа-запросов разных размеров, чтобы согласовать фоновую кривую со ссылками.
И подход javascript: -
let endingCurve = 80;
let currentCurve = 0;
let navItems = document.querySelectorAll('li');
let offsetPerItem = (endingCurve / navItems.length);
navItems.forEach(item => {
currentCurve = currentCurve + offsetPerItem
item.style.top = `${currentCurve}px`;
});ul {
display: flex;
}
li {
list-style: none;
margin: 0 3rem;
position: relative;
}<nav>
<ul>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
<li><a href='' title=''>Link</a></li>
</ul>
</nav>вы определяете конечную кривую, подсчитываете количество элементов, которые есть в вашей структуре навигации, и делите общее количество на кривую, это определяет общее смещение для каждого элемента, затем вы перебираете каждый элемент и применяете стиль top к каждому элементу. Это в значительной степени javascript-версия nth-child с дополнительным бонусом, заключающимся в том, что вы можете изменить значение endingCurve для увеличения или уменьшения «кривой».
Есть гораздо более элегантные решения javascript, которые вы могли бы создать, если бы предоставили больше информации. Например, исправлена ли кривая фонового изображения, масштабируется ли она с помощью браузера, это svg или другой формат и т.д .. Но это должно дать вам отправную точку либо способ!
Большое спасибо! Я попробую и посмотрю оттуда.
<html>
<body height = "100%" width = "100%">
<svg height = "100%" width = "100%" viewbox = "0 0 100 100" preserveAspectRatio = "none">
<path d = "M 10 10 Q 50 50 90 50 v -40 h -80" fill = "cyan" transform = "scale(1.05,1.05) translate(-4.5,-.5)"/>
<path id = "path" d = "M 10 10 Q 50 50 90 50" fill = "none" stroke = "yellow"/>
<text font-size = "4">
<textPath href = "#path" textPath = "stretch">
<tspan dx = "5">Alternative1</tspan>
<tspan dx = "10">Alternative2</tspan>
<tspan dx = "10">Alternative3</tspan>
</textPath>
</text>
</svg>
</body>
</html>Это действительно хорошая альтернатива, но не совсем то, чего хочет клиент. В любом случае спасибо за уделенное время! (может помочь другим)
Возможно, если вам нужна помощь, вам следует более подробно объяснить, какой именно эффект вы пытаетесь достичь.
Простой и надежный способ сделать это - измерить положение каждого прямоугольника слева и сверху изображения, а также измерить ширину и высоту изображения.
Неважно, какие единицы вы для этого используете - главное, чтобы они были одинаковыми для каждого.
Затем у вас есть ряд смещений сверху / слева и вы можете заставить CSS определять% позиционирование каждого из них слева и сверху изображения.
Затем для каждого набора li: nth-child (n) введите 2 переменные CSS: --left: x; --top: y; что вы измерили и в ul --w:; --час:
Затем разместите n-й дочерний элемент как% от верхнего левого угла изображения с помощью CSS calc.
Хорошо, я тоже попробую это. Спасибо!
Every idea is welcome, even the bad ones.
Вот плохой; если вы действительно делаете нет, хотите вычислить / жестко запрограммировать позиции X, Y.
Использование keyPoints для размещения элемента <text> на пути
Установите dur = "0s", если не хотите анимацию
<style>
svg{
width:90vw;
background:pink;
}
</style>
<svg viewBox = "0 0 200 50">
<path id = "slope" fill = "none" stroke = "red" d = "m10,10c40,0,45,35,180,35"></path>
<text>One
<animateMotion dur = "1s" fill = "freeze" keyPoints = "0;.1" keyTimes = "0;1" calcMode = "linear">
<mpath href = "#slope"></mpath>
</animateMotion>
</text>
<text>Two
<animateMotion dur = "1s" fill = "freeze" keyPoints = "0;.4" keyTimes = "0;1" calcMode = "linear">
<mpath href = "#slope"></mpath>
</animateMotion>
</text>
<text>Three
<animateMotion dur = "1s" fill = "freeze" keyPoints = "0;.75" keyTimes = "0;1"calcMode = "linear">
<mpath href = "#slope"></mpath>
</animateMotion>
</text>
</svg>
Ожидается, что вы, по крайней мере, попытаетесь запрограммировать это для себя. Я бы посоветовал вам сделать дополнительное исследование либо через Google, либо путем поиска SO, попробовать и. если у вас все еще есть проблемы, вернитесь с ваш код и объясните, что вы пробовали.