Reputation: 347
I want to use a half-circle menu when I surf the mobile web with right hand.
Can somebody teach me how to create half-circle menu (sub item) with CSS, Java Script on mobile web?
the photo link:
1.There is a half-circle menu button, it could be opened and closed.
2.When I click one of main level item, the sub item could be drop down.
Sincerely thanks.
Upvotes: 3
Views: 1747
Reputation: 94319
You can use SVG to achieve this design in HTML5 since most mobile browsers nowadays support SVG.
http://jsfiddle.net/DerekL/dQBzd/show
http://jsfiddle.net/DerekL/dQBzd/
function drawMenu(selected) {
$("svg").empty();
var texts = ["國際", "生活", "文教", "健康", "科技", "新奇"],
subTexts = [
["這裡", "有一大堆", "目錄"],
["A", "B", "C"],
["A", "B", "C"],
["A", "B", "C"],
["資訊3C", "科學發展", "自然環境", "科技熱門"],
["A", "B", "C"]
];
var isSelected = selected !== undefined,
columns = texts.length,
angle = 12, //Angle (degree) of each menu
subAngle = 8, //Angle (degree) of each submenu
angleOut = (180 - angle * columns - (isSelected ? subAngle * subTexts[selected].length : 0)) / 2 * Math.PI / 180;
angle *= Math.PI / 180;
subAngle *= Math.PI / 180;
var originX = 300,
originY = 300,
upper = getXY(angleOut, 220),
lower = getXY(Math.PI - angleOut, 220);
$("<path/>").attr("d", [
"M", upper[0], upper[1],
"L", originX, originY,
"L", lower[0], lower[1]
].join(" ")).appendTo("svg");
for (var i = 0; i < columns; i++) {
var group = $("<g>").addClass("item button").attr("data-menu", i).appendTo("svg");
group.addClass(isSelected && selected == i ? "selected" : "");
var angleCur = angleOut + angle * i +
((isSelected && selected < i) ? subAngle * subTexts[selected].length : 0),
originX = 300,
originY = 300,
topL = getXY(angleCur, 300),
topR = getXY(angleCur, 220),
bottL = getXY(angleCur + angle, 300),
bottR = getXY(angleCur + angle, 220);
createSlice([topL, topR, bottL, bottR], group);
$("<text>").html(texts[i]).attr({
x: (topL[0] + topR[0] + bottL[0] + bottR[0]) / 4 - 50 / 2,
y: (topL[1] + topR[1] + bottL[1] + bottR[1]) / 4 + 40 / 4
}).appendTo(group);
createSlice([
getXY(angleCur, 220), getXY(angleCur, 50),
getXY(angleCur + angle, 220), getXY(angleCur + angle, 50)
], group);
if (isSelected && i == selected) {
for (var j = 0; j < subTexts[selected].length; j++) {
var angleSub = angleCur + angle + subAngle * j,
g = $("<g>").addClass("subItem").appendTo("svg");
createSlice([
getXY(angleSub, 220), getXY(angleSub, 50),
getXY(angleCur + angle + subAngle * (j + 1), 220),
getXY(angleCur + angle + subAngle * (j + 1), 50)
], g);
$("<text>").html(subTexts[selected][j]).attr({
x: 100,
y: 316,
transform: "rotate(" + [-((angleSub) * 180 / Math.PI - 90),
300, 300
].join(",") + ")"
}).appendTo(g);
}
}
}
(function () {
var group = $("<g>").addClass("menu button").appendTo("svg"),
top = getXY(angleOut, 50),
bott = getXY(Math.PI - angleOut, 50);
$("<path/>").attr("d", [
"M", top[0], top[1],
"L", originX, originY,
"L", bott[0], bott[1],
"A", 50, 50, angle * columns, 0, 1, top[0], top[1],
"Z"
].join(" ")).addClass("button").appendTo(group);
$("<text>").html("menu").attr({
x: 255,
y: 303
}).appendTo(group);
})();
$("body").html($("body").html());
$("svg g.item").click(function () {
drawMenu(
$(this).attr("class").indexOf("selected")!==-1?
undefined:
+$(this).data("menu")
);
});
}
function getXY(angle, len) {
return [300 - len * Math.sin(angle),
300 - len * Math.cos(angle)];
}
function createSlice(coords, parent) {
var angle = 12 * Math.PI / 180,
topL = coords[0],
topR = coords[1],
bottL = coords[2],
bottR = coords[3];
$("<path/>").attr("d", [
"M", topL[0], topL[1],
"L", topR[0], topR[1],
"A", 300, 300, angle, 0, 0, bottR[0], bottR[1],
"L", bottL[0], bottL[1],
"A", 300, 300, angle, 0, 1, topL[0], topL[1],
"Z"
].join(" ")).addClass("button").appendTo(parent);
}
drawMenu(); //You can also do drawMenu(index), where "index" is the selected menu
Paths (shapes):
<path/>
<text>Text</text>
In my example, all SVG nodes are JavaScript-generated in order to calculate the correct coordinates for the lines.
Not everyone is willing to or has the patient to mess with these nasty SVG nodes. Don't worry, Raphaël to the rescue!
Raphaël is a rich vector graphic library that let you draw and animate vector graphics with very few code. If you are that kind of person then you should definitely try this out.
Upvotes: 8