Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement half-circle menu (sub item) with CSS and JavaScript on mobile web? [closed]

I want to use a half-circle menu when I surf the mobile web with my right hand. Can somebody teach me how to implement half-circle menu (sub item) with CSS and JavaScript on mobile web? I have tried it with CSS transform:rotate and border-radius, but it could not be worked successfully.

There is a half-circle menu button, this button can open and close menu. When I click the menu button, the main-level will be popped up. Then I click "Main 1", the sub-level (Sub 1-1, Sub 1-2, Sub 1-3) will be popped up.

As just mentioned, When I click "Main 6", the sub-level (Sub 6-1, Sub 6-2, Sub 6-3) will be popped up.

Here is the architecture of the menu:

Menu
   Main 1
      Sub 1-1
      Sub 1-2
      Sub 1-3
   Main 2
      Sub 2-1
      Sub 2-2
      Sub 2-3
   Main 3
      Sub 3-1
      Sub 3-2
      Sub 3-3
   Main 4
      Sub 4-1
      Sub 4-2
      Sub 4-3
   Main 5
      Sub 5-1
      Sub 5-2
      Sub 5-3
   Main 6
      Sub 6-1
      Sub 6-2
      Sub 6-3
like image 433
Alan Chen Avatar asked Feb 23 '14 09:02

Alan Chen


3 Answers

You could do this with SVG. When you click on first-ring buttons or (Main 1, Main 2...) it will update text of second-ring buttons or (Sub 1 1, Sub 2 1...), and this is just for demo purpose. You can use js to change links inside <a xlink:href=""></a> instead of just text.

var firstRing = $('.first-ring');
var secondRing = $('.second-ring');
var siblings = firstRing.siblings('.second-ring');
var open = $('#open');

open.click(function() {
  firstRing.toggleClass('show');

  if (!firstRing.hasClass('show')) {
    siblings.removeClass('show');
  }
});

firstRing.children('g').click(function() {
  var data = $(this).data('url');
  siblings.addClass('show');

  secondRing.children('g').children('a').children('text').each(function() {
    var text = $(this).text().split(' ');
    $(this).text(text[0] + ' ' + data + ' ' + text[2]);
  });
});
svg {
  position: fixed;
  top: 50%;
  right: 0;
  transform: translateY(-50%);
  font-size: 12px;
}

g {
  fill: white;
  transition: all 0.3s ease-in;
  cursor: pointer;
}

text {
  fill: white;
}

g:not(.first-ring):not(.second-ring):hover {
  opacity: 0.6;
}

.first-ring, .second-ring {
  opacity: 0;
}

.show {
  opacity: 1;
}

.main      {fill: #2B2B2B;}
.one       {fill: #2B2B2B;}
.two       {fill: #373737;}
.three     {fill: #444444;}
.four      {fill: #515151;}
.five      {fill: #5E5E5E;}
.six       {fill: #6A6A6A;}
.sub-one   {fill: #777777;}
.sub-two   {fill: #848484;}
.sub-three {fill: #909090;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>


<svg width="400px" height="400px">
  <!-- This is First ring or Menu part-->
  <g id="open">
    <path class="main" d="M395.545,200.03l-0.08-0.12l-0.05,0.12l-22.44,54.17c-7.12-2.97-13.54-7.311-18.909-12.69
		c-5.41-5.41-9.771-11.87-12.75-19.05c-2.86-6.91-4.44-14.49-4.44-22.43c0-7.91,1.56-15.45,4.4-22.33
		c2.96-7.19,7.31-13.66,12.71-19.07c5.42-5.45,11.899-9.83,19.109-12.82L395.545,200.03z" />
    <text transform="matrix(1 0 0 1 351.7607 206.0303)" class="st1 st3">MENU</text>
  </g>

  <!-- This is second-ring -->
  <g class="first-ring">
    <g data-url="1">
      <path class="one" d="M373.095,145.81c-7.21,2.99-13.689,7.37-19.109,12.82l-50.94-50.9c12.06-12.08,26.47-21.82,42.5-28.46
		L373.095,145.81z" />
      <text transform="matrix(0.5061 0.8625 -0.8625 0.5061 332.1963 107.73)" class="st1 st3">Main 1</text>
    </g>
    <g data-url="2">
      <path class="two" d="M353.985,158.63c-5.4,5.41-9.75,11.88-12.71,19.07l-66.58-27.45c6.609-16.02,16.31-30.44,28.35-42.52
		L353.985,158.63z" />
      <text transform="matrix(0.8283 0.5603 -0.5603 0.8283 295.585 136.9624)" class="st1 st3">Main 2</text>
    </g>
    <g data-url="3">
      <path class="three" d="M341.275,177.7c-2.841,6.88-4.4,14.42-4.4,22.33h-72c0-17.63,3.49-34.44,9.82-49.78L341.275,177.7z" />
      <text transform="matrix(0.9946 0.1039 -0.1039 0.9946 283.0908 183.2314)" class="st1 st3">Main 3</text>
    </g>
    <g data-url="4">
      <path class="four" d="M341.315,222.46l-66.53,27.57c-6.391-15.4-9.91-32.29-9.91-50h72
		C336.875,207.97,338.455,215.55,341.315,222.46z" />
      <text transform="matrix(0.9891 -0.1475 0.1475 0.9891 283.0898 225.0303)" class="st1 st3">Main4</text>
    </g>
    <g data-url="5">
      <path class="five" d="M354.065,241.51l-50.841,51c-12.08-12.06-21.8-26.46-28.439-42.479l66.53-27.57
		C344.295,229.64,348.655,236.1,354.065,241.51z" />
      <text transform="matrix(0.8627 -0.5057 0.5057 0.8627 299.6768 268.6953)" class="st1 st3">Main 5</text>
    </g>
    <g data-url="6">
      <path class="six" d="M372.975,254.2l-27.56,66.53c-15.89-6.601-30.2-16.25-42.19-28.221l50.841-51
		C359.435,246.89,365.854,251.23,372.975,254.2z" />
      <text transform="matrix(0.6338 -0.7735 0.7735 0.6338 332.1963 300.0664)" class="st1 st3">Main 6</text>
    </g>
  </g>

  <!-- This is third-ring or sub part -->
  <g class="second-ring">
    <g>
      <a xlink:href="">
        <path class="sub-one" d="M345.545,79.27c-16.03,6.64-30.44,16.38-42.5,28.46c-12.04,12.08-21.74,26.5-28.35,42.52l-54.061-22.3
		c9.59-23.18,23.66-44.03,41.141-61.47c17.46-17.42,38.319-31.45,61.5-40.99L345.545,79.27z" />
        <text transform="matrix(0.7099 0.7043 -0.7043 0.7099 263.1514 75.9663)" class="st1 st3">Sub 1 1</text>
      </a>
    </g>

    <g>
      <a xlink:href="">
        <path class="sub-two" d="M274.785,250.03l-54.02,22.399c-9.271-22.29-14.391-46.75-14.391-72.4c0-25.53,5.07-49.87,14.26-72.08
		l54.061,22.3c-6.33,15.34-9.82,32.15-9.82,49.78C264.875,217.74,268.395,234.63,274.785,250.03z" />
        <text transform="matrix(1 0 0 1 213.585 200.1899)" class="st1 st3">Sub 1 2</text>
      </a>
    </g>

    <g>
      <a xlink:href="">
        <path class="sub-three" d="M345.415,320.73l-22.28,53.779c-23.01-9.49-43.74-23.41-61.109-40.68c-17.51-17.41-31.631-38.24-41.26-61.4
		l54.02-22.399c6.64,16.02,16.359,30.42,28.439,42.479C315.215,304.48,329.525,314.13,345.415,320.73z" />
        <text transform="matrix(0.7305 -0.6829 0.6829 0.7305 266.9395 328.9912)" class="st1 st3">Sub 1 3</text>
      </a>
    </g>

  </g>
</svg>
like image 192
Nenad Vracar Avatar answered Nov 02 '22 01:11

Nenad Vracar


enter image description here

No SVG, just plain css.

Basically,

  • just turn rectangles over the same corner with increasing angles. Like a paper fan.
  • Put the whole thing at the outermost level into a circle (border-radius:r px;overflow: hidden).
  • Repeat for any further, outer rings.
  • Add another outer overflow:hidden wrapper, if the enlarged last menu (‚menu 5‘) bothers you...
  • Javascript is only needed, as soon as you deal with clicks and want to toggle outer rings visibility for sub-options...

http://codepen.io/fnocke/pen/Vazobq?editors=0100

This is simplified stylus syntax (similar to less, sass), see codepen➝‘view compiled’ for full css:

li
  position absolute
  top 50%
  display block
  transform-origin top right
  overflow hidden
  width r
  height r

li:nth-of-type(1)
  transform: rotate(60deg)
  background #000
li:nth-of-type(2)
  transform: rotate(40deg)
  background #222
..
like image 21
Frank Nocke Avatar answered Nov 01 '22 23:11

Frank Nocke


You have to use an SVG library. Trying to make it with basic HTML elements and jQuery is probably possible using image maps, but wrapping it around jQuery will make you want to kill yourself.

I recommend d3.js since it not only handles presentation part (looks, animations) but also data with which you'll feed it.

like image 2
user291196 Avatar answered Nov 01 '22 23:11

user291196