Форум программистов, компьютерный форум, киберфорум
JavaScript
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/3: Рейтинг темы: голосов - 3, средняя оценка - 5.00
6 / 7 / 1
Регистрация: 11.02.2013
Сообщений: 204
1

Как сделать круговое меню с кликабельными секторами?

05.04.2021, 07:11. Показов 537. Ответов 7

http://lud.ru/navigator/0/ именуемую в дальнейшем тханка.
Варианты : Canvas, Svg, стандартный html с map и пр. Склоняюсь к svg. Но как в svg сделать сектор? Не тупо кривая Безье а именно сектор из круга то есть сначала круг потом вытащить сектор из него.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.04.2021, 07:11
Ответы с готовыми решениями:

Как сделать круговое меню
Всем здравствуйте. У меня возникла такая проблема - хочу сделать круговое меню. Но никак не могу...

Как сделать картинки кликабельными
На моем сайте del есть модуль выводящий картинки и текст. Скриншот:...

Как сделать картинки в слайдере кликабельными
Имеется вот такой слайдер. Изображения по всей длине скоса должны прокликиваться. Но у меня выходит...

Как сделать кликабельными слайдер ? (Widgetkit)
Подскажите пожалуйста, как сделать кликабельными картинки, у меня есть слайдер делал в Widgetkit >...

7
Модератор
2636 / 1561 / 474
Регистрация: 07.09.2019
Сообщений: 2,394
06.04.2021, 11:18 2
Я решил сделать вариант через SVG — вот, потрудился:

HTML5
1
2
3
<svg preserveAspectRatio="xMidYMid meet" x="0" y="0" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="45" />
</svg>
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function surgeon(svg, circle, n, images, links) {
  const points = [];
  for (let i = 2; i <= 2 * n; i += 2) {
    points.push({
      x: circle.cx + Math.cos((i * Math.PI) / n) * circle.r,
      y: circle.cy + Math.sin((i * Math.PI) / n) * circle.r
    });
  }
 
  points.forEach((point, i) => {
    const next_point = points[i + 1] ? points[i + 1] : points[0];
    const d = document.createElementNS("http://www.w3.org/2000/svg", "defs");
    d.innerHTML = `<pattern id = "sector_${i}" patternUnits="userSpaceOnUse" height="100%" width="100%">
    <image xlink:href="${images[i].link}" x = "${images[i].x}%" width="100%" height="100%" />  
    </pattern>`;
    svg.append(d);
    const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute(
      "d",
      `M${circle.cx},${circle.cy} L${point.x},${point.y} A${circle.r},${circle.r} 1 0,1  ${next_point.x},${next_point.y} L${circle.cx},${circle.cy} z`
    );
    path.setAttribute("fill", `url(#sector_${i})`);
    path.style.stroke = "darkblue";
    svg.append(path);
  });
}
const images = [
  {
    link:
      "https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png",
    x: 0
  },
  { link: "https://cyberstatic.net/images/cyberforum_logo.png", x: 0 },
  { link: "https://www.cyberforum.ru/customavatars/avatar605173_26.gif", x: 0 },
  {
    link: "https://www.cyberforum.ru/customavatars/thumbs/avatar357237_20.gif",
    x: 20
  },
  {
    link:
      "https://upload.wikimedia.org/wikipedia/commons/d/d5/CSS3_logo_and_wordmark.svg",
    x: 30
  }
];
surgeon(document.querySelector("svg"), { cx: 50, cy: 50, r: 45 }, 5, images);
document
  .querySelector("svg")
  .insertAdjacentHTML(
    "beforeend",
    `<circle r = 15 cx = "50" cy = "50" fill = "silver" stroke = "darkblue" />`
  );
Добавлено через 1 минуту
https://codepen.io/Berners-Lee... itors=1011
3
Эксперт JS
1597 / 1122 / 474
Регистрация: 11.07.2016
Сообщений: 2,906
06.04.2021, 13:57 3
DrType, а кликабельными их можно сделать, раз меню планируется? Хочется потыкать.
0
394 / 147 / 31
Регистрация: 26.11.2019
Сообщений: 399
06.04.2021, 14:26 4
Цитата Сообщение от magnuz Посмотреть сообщение
Склоняюсь к svg. Но как в svg сделать сектор?
в оригинале канвас
0
6 / 7 / 1
Регистрация: 11.02.2013
Сообщений: 204
06.04.2021, 16:51  [ТС] 5
Реализовал уже сам на svg
0
394 / 147 / 31
Регистрация: 26.11.2019
Сообщений: 399
06.04.2021, 17:23 6
Цитата Сообщение от magnuz Посмотреть сообщение
Реализовал уже сам на svg
тут принято выкладывать решения, кому-нибудь да пригодится
1
Модератор
2636 / 1561 / 474
Регистрация: 07.09.2019
Сообщений: 2,394
06.04.2021, 17:41 7
Balanaar, ну по идее здесь просится многоуровневое меню с деревом адресов...
HTML5
1
2
3
<svg preserveAspectRatio="xMidYMid meet" x="0" y="0" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="45" fill="white" />
</svg>
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
function surgeon(svg, circle, n, images) {
  const points = [];
  for (let i = 2; i <= 2 * n; i += 2) {
    points.push({
      x2: circle.cx + Math.cos((i * Math.PI) / n) * circle.r,
      y2: circle.cy + Math.sin((i * Math.PI) / n) * circle.r,
      x1: circle.cx + Math.cos((i * Math.PI) / n) * circle.lr,
      y1: circle.cy + Math.sin((i * Math.PI) / n) * circle.lr
    });
  }
  for (let i = 0; i < points.length; i++) {
    const point = points[i],
      next_point = i - points.length + 1 ? points[i + 1] : points[0];
    const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
    path.setAttribute(
      "d",
 
      `M${point.x1},${point.y1}  L${point.x2},${point.y2}  A${circle.r},${circle.r} 0 0,1 ${next_point.x2},${next_point.y2}  L${next_point.x1},${next_point.y1} A${circle.lr},${circle.lr} 0 0,0 ${point.x1},${point.y1}`
    );
    path.setAttribute("fill", "white");
    path.style.stroke = "darkblue";
    svg.append(path);
    if (images[i]) {
      const d = document.createElementNS("http://www.w3.org/2000/svg", "defs");
      d.innerHTML = `<pattern id = "sector_${
        circle.name
      }_${i}" patternUnits="userSpaceOnUse" height="100%" width="100%">
    <image xlink:href="${images[i].link}" x = "${
        images[i].x
      }%" width="100%" height="100%" />  
    </pattern>`;
      svg.append(d);
      path.setAttribute("fill", `url(#sector_${circle.name}_${i})`);
      path.dataset.href = images[i].url;
    }
  }
}
// и тут должна была бы быть отражена структура разделов...
const images = [
  {
    url: "https://www.cyberforum.ru/",
    link: "https://www.cyberforum.ru/customavatars/avatar605173_26.gif",
    x: 0
  },
  {
    url: "https://www.cyberforum.ru/html/",
    link:   "https://upload.wikimedia.org/wikipedia/commons/d/d5/CSS3_logo_and_wordmark.svg",
    x: 30
  },
  {
    url: "https://www.cyberforum.ru/javascript-beginners/",
    link:
      "https://upload.wikimedia.org/wikipedia/commons/6/6a/JavaScript-logo.png",
    x: -15
  }
];
surgeon(
  document.querySelector("svg"),
  { name: "mainmenu", cx: 50, cy: 50, r: 45, lr: 25 },
  6,
  new Array(6).fill(images[0])
);
surgeon(
  document.querySelector("svg"),
  { name: "submenu", cx: 50, cy: 50, r: 25, lr: 5 },
  3,
  images
);
document.querySelector("svg").addEventListener("click", function (e) {
  if ((link = e.target.closest("path"))) {
    window.location = link.dataset.href;
  }
});
1
5595 / 2110 / 618
Регистрация: 11.04.2015
Сообщений: 3,559
Записей в блоге: 41
07.04.2021, 01:09 8
Цитата Сообщение от DrType Посмотреть сообщение
Я решил сделать вариант через SVG — вот, потрудился:
Все-таки при работе с SVG лучше делать все в каком-нибудь векторном редакторе. Это и проще и быстрее, да и с результатом работать удобнее. Вот пример того, что я накалякал в Inkscape
PHP/HTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<!DOCTYPE html>
<html>
 
<head>
    <meta charset='utf-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <title>Page</title>
    <meta name='viewport' content='width=device-width, initial-scale=1'>
</head>
 
<body>
 
    <style>
        #svg8 path {
            stroke: #000000;
            stroke-width: 0.678002;
            filter: url(#filter962)
        }
 
        #svg8 path:hover {
            stroke-width: 3;
        }
 
        #svg8 path:active {
            opacity: .5;
        }
 
        #svg8 path:nth-child(1) {
            fill: aliceblue;
        }
 
        #svg8 path:nth-child(2) {
            fill: rgb(24, 192, 100);
        }
 
        #svg8 path:nth-child(3) {
            fill: rgb(144, 87, 182);
        }
 
        #svg8 path:nth-child(4) {
            fill: rgb(114, 20, 221);
        }
 
        #svg8 path:nth-child(5) {
            fill: rgb(131, 209, 41);
        }
 
        #svg8 path:nth-child(6) {
            fill: rgb(182, 40, 94);
        }
 
        #svg8 path:nth-child(7) {
            fill: rgb(19, 188, 218);
        }
 
        #svg8 path:nth-child(8) {
            fill: rgb(207, 37, 51);
        }
    </style> <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg"
        xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
        xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" width="210mm" height="100mm" viewBox="0 0 210 100"
        version="1.1" id="svg8" inkscape:version="1.0.2-2 (e86c870879, 2021-01-15)" sodipodi:docname="sector8.svg">
        <defs id="defs2">
            <inkscape:path-effect effect="copy_rotate" starting_point="0,0" origin="102.39375,53.975"
                id="path-effect944" is_visible="true" lpeversion="1" method="normal" num_copies="8" starting_angle="0"
                rotation_angle="60" gap="-0.01" copies_to_360="true" mirror_copies="false" split_items="false" />
            <inkscape:path-effect effect="copy_rotate" starting_point="0,0" origin="44.676235,49.588267"
                id="path-effect901" is_visible="true" lpeversion="1" method="normal" num_copies="8" starting_angle="0"
                rotation_angle="46.1" gap="-0.01" copies_to_360="true" mirror_copies="false" split_items="false" />
            <inkscape:path-effect effect="copy_rotate" starting_point="0,0" origin="44.676235,49.588267"
                id="path-effect840" is_visible="false" lpeversion="1" method="normal" num_copies="8" starting_angle="0"
                rotation_angle="60" gap="0" copies_to_360="true" mirror_copies="false" split_items="false" />
            <filter inkscape:collect="always" style="color-interpolation-filters:sRGB" id="filter962" x="-2.5761118e-05"
                width="1.0000515" y="-2.5761117e-05" height="1.0000515">
                <feGaussianBlur inkscape:collect="always" stdDeviation="0.0032021104" id="feGaussianBlur964" />
            </filter>
        </defs>
        <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0"
            inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1" inkscape:cx="444" inkscape:cy="198"
            inkscape:document-units="mm" inkscape:current-layer="layer1" inkscape:document-rotation="0" showgrid="false"
            inkscape:window-width="1366" inkscape:window-height="728" inkscape:window-x="0" inkscape:window-y="0"
            inkscape:window-maximized="0" />
        <metadata id="metadata5">
            <rdf:RDF>
                <cc:Work rdf:about="">
                    <dc:format>image/svg+xml</dc:format>
                    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
                    <dc:title></dc:title>
                </cc:Work>
            </rdf:RDF>
        </metadata>
        <g inkscape:label="Слой 1" inkscape:groupmode="layer" id="layer1">
            <path id="path833"
                d="m 448.75781,203.39453 79.82227,0.45313 A 149.16099,149.16099 0 0 0 484.7832,98.419922 l -56.76172,56.121098 a 69.342393,69.342393 0 0 1 20.73633,48.85351 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path982"
                d="M 428.87891,252.60156 485,309.36328 A 149.16099,149.16099 0 0 0 528.58008,204 a 149.16099,149.16099 0 0 0 0,-0.15234 l -79.82227,-0.45313 a 69.342393,69.342393 0 0 1 0.004,0.60547 69.342393,69.342393 0 0 1 -19.88281,48.60156 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path980"
                d="m 380.02539,273.33789 -0.45312,79.82227 A 149.16099,149.16099 0 0 0 485,309.36328 l -56.12109,-56.76172 a 69.342393,69.342393 0 0 1 -48.85352,20.73633 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path978"
                d="m 330.81836,253.45898 -56.76172,56.1211 a 149.16099,149.16099 0 0 0 105.36328,43.58008 149.16099,149.16099 0 0 0 0.15235,0 l 0.45312,-79.82227 a 69.342393,69.342393 0 0 1 -0.60547,0.004 69.342393,69.342393 0 0 1 -48.60156,-19.88282 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path976"
                d="m 310.08203,204.60547 -79.82226,-0.45313 a 149.16099,149.16099 0 0 0 43.79687,105.42774 l 56.76172,-56.1211 a 69.342393,69.342393 0 0 1 -20.73633,-48.85351 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path974"
                d="M 329.96094,155.39844 273.83984,98.634766 A 149.16099,149.16099 0 0 0 230.25977,204 a 149.16099,149.16099 0 0 0 0,0.15234 l 79.82226,0.45313 A 69.342393,69.342393 0 0 1 310.07812,204 69.342393,69.342393 0 0 1 329.96094,155.39844 Z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path972"
                d="M 379.26758,54.839844 A 149.16099,149.16099 0 0 0 273.83984,98.634766 l 56.1211,56.763674 a 69.342393,69.342393 0 0 1 48.85351,-20.73828 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
            <path id="path970"
                d="m 379.26758,54.839844 -0.45313,79.820316 a 69.342393,69.342393 0 0 1 0.21875,-0.002 69.342393,69.342393 0 0 1 0.38672,0 69.342393,69.342393 0 0 1 48.60156,19.88282 L 484.7832,98.419922 a 149.16099,149.16099 0 0 0 -105.36328,-43.580078 149.16099,149.16099 0 0 0 -0.14648,0 149.16099,149.16099 0 0 0 -0.006,0 z"
                transform="matrix(0.26458333,0,0,0.26458333,-53.975,-10.847917)" />
        </g>
    </svg>
 
    <script>
        document.getElementById("svg8").addEventListener("click", function (evt)
        {
            if (evt.target.tagName == "path")
            {
                document.getElementById("lastClicked").textContent = evt.target.id;
            }
        });
    </script>
    <div><span>Last clicked sector id: </span><span id="lastClicked"></span></div>
 
</body>
 
</html>
Добавил стиль, яваскрипта совсем чуть-чуть и все довольно просто.
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.04.2021, 01:09

Заказываю контрольные, курсовые, дипломные работы и диссертации здесь.

Как сделать круговое движение квадрата в данном коде?
public partial class Form1 : Form { int x = 300; int y = 500; ...

Круговое многоуровневое меню
Всем привет. Пытаюсь создать круговое меню и застрял. Посидев весь день в поисках ответов...

Круговое меню Control
Нужно сделать круговое меню (Control). Типа нажимаешь на кругленькую пуговку и из нее в разные...

стильное круговое меню на jquery
Помогите пожалуйста найти менюшку для сайта в виде круга посередине, при нажатии на который...

Подключить круговое меню к теме Wordpress
Здравствуйте форумчане. Помогите разобраться с проблемой. Заказчик хочет, чтобы в его теме...

Как сделать массив кнопок не кликабельными, а другой массив кликабельным?
Есть 2 массива кнопок. Мне нужно, чтобы один массив был кликабельным, а другой нет, но при нажатии...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.