Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Как сделать изогнутые прямоугольники (bent rectangle) в SVG

#javascript #html #css #css3 #svg


У меня есть проект, над которым я работаю. Необходимо сделать круговую навигацию
с кнопками, которые выглядят как сегменты вокруг Iron Man, изображенной ниже.

Я могу рисовать простые фигуры, но я затрудняюсь нарисовать эти полосы с изогнутой
формой, как на рисунке ниже. 

Я включил пример clip path, и я думаю, что SVG - это то, что мне нужно.  

HTML

CSS .button { background: radial-gradient(circle at 50% 160%,transparent 45%,red 44.5%,red 85%,transparent 85%); -webkit-clip-path: polygon(5% 0, 100% 0, 65% 90%, 35% 90%); clip-path: polygon(20% 0, 80% 0, 65% 90%, 35% 90%); }


Ответы

Ответ 1



Дополнительные примеры сегментов 6 сегментов Подставляем в скрипт, количество сегментов и черта- dash=0.8 пробел - gap = 0.2 const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 40; let perimeter = 2*Math.PI*R let dash = .8*perimeter/6; let gap = .2*perimeter/6; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:20px; stroke:purple;fill:none;} 6 сегментов черта- dash=0.2 пробел - gap = 0.8 const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 40; let perimeter = 2*Math.PI*R let dash = .2*perimeter/6; let gap = .8*perimeter/6; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:20px; stroke:yellowgreen;fill:none;} 12 сегментов черта- dash=0.2 пробел - gap = 0.8 const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 40; let perimeter = 2*Math.PI*R let dash = .2*perimeter/12; let gap = .8*perimeter/12; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:20px; stroke:purple;fill:none;} 10 сегментов + background черта- dash=0.9 пробел - gap = 0.1 const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 40; let perimeter = 2*Math.PI*R let dash = .9*perimeter/10; let gap = .1*perimeter/10; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:20px; stroke:greenyellow;fill:gold;} Шестеренка const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 30; let perimeter = 2*Math.PI*R let dash = .5*perimeter/20; let gap = .5*perimeter/20; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:14px; stroke:gray;fill:gray;} Update Благодарю за идею @UModeL Подсолнух const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 30; let perimeter = 2*Math.PI*R let dash = .7*perimeter/35; let gap = .3*perimeter/35; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:22px; stroke:#FFEB3B; fill:#4d4d4d;}

Ответ 2



Сначала я создаю один сегмент (path). Затем я снова использую его, с помощью вращения. const SVG_NS = 'http://www.w3.org/2000/svg'; const SVG_XLINK = "http://www.w3.org/1999/xlink"; const deg = 180 / Math.PI; let R = 50;//внешний радиус let r = 35;// внутренний радиус let A = 2*Math.PI/7;// угол для сегмента + пробел let a = 2*A/3; // угол для сегмента let path = document.createElementNS(SVG_NS, 'path'); let p1 = {x:0,y:-R} let p2 = { x : R*Math.cos(a - Math.PI/2), y : R*Math.sin(a - Math.PI/2) } let p3 = { x : r*Math.cos(a - Math.PI/2), y : r*Math.sin(a - Math.PI/2) } let p4 = { x : 0, y : -r } let d = `M${p1.x},${p1.y} A${R},${R} 0 0,1,${p2.x},${p2.y} L${p3.x},${p3.y} A${r},${r} 0 0,0,${p4.x},${p4.y} L${p1.x},${p1.y}Z `; path.setAttributeNS(null, "d", d); path.setAttributeNS(null, "id", "arc"); defs.appendChild(path); for(let i = 0; i < 7; i++){ let use = document.createElementNS(SVG_NS, 'use'); use.setAttributeNS(SVG_XLINK, "xlink:href", "#arc") use.setAttributeNS(null, "fill", "gold"); use.setAttributeNS(null, "transform", `rotate(${i*A*deg})`); svg.appendChild(use); } Или даже проще: на этот раз я использую stroke-dasharray, и я вычисляю размер для штриха и пробелов const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 40; let perimeter = 2*Math.PI*R let dash = .7*perimeter/7; let gap = .3*perimeter/7; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:20px; stroke:black;fill:none;} Примечания: код можно использовать как генератор любого количества сегментов. Можно изменять также длину штриха и пробела, получая геометрически точные сегменты. Пример с 5 сегментами: const SVG_NS = 'http://www.w3.org/2000/svg'; let R = 40; let perimeter = 2*Math.PI*R let dash = .8*perimeter/5; let gap = .2*perimeter/5; let dasharray = document.createElementNS(SVG_NS, 'circle'); dasharray.setAttributeNS(null, "r", R); dasharray.setAttributeNS(null, "stroke-dasharray", `${dash}, ${gap}`); svg.appendChild(dasharray); circle{stroke-width:20px; stroke:dodgerblue;fill:none;} Ещё примеры Вращение сегментов при наведении circle { stroke-width:20px; stroke:purple; fill:transparent; } circle:hover { stroke:dodgerblue; -webkit-animation: rotate 6s linear infinite; animation: rotate 6s linear infinite; } @-webkit-keyframes rotate { 100% {-webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); transform: rotate(360deg);} } @keyframes rotate { 100% {-webkit-transform: rotate(360deg); -ms-transform: rotate(360deg); transform: rotate(360deg);} }

Комментариев нет:

Отправить комментарий