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
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>
No SVG, just plain css.
Basically,
border-radius:r px;overflow: hidden
). overflow:hidden
wrapper, if the enlarged last menu (‚menu 5‘) bothers you...➪ 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
..
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With