I need a widget displaying the months of the year. I implemented using SVG and not by Canvas because I needed the capability of SVG to assign events to any element of the picture.
- The user should be able to select a month by clicking on it
- The widget should give an event for every month change
- The user should be able to deselect a month by clicking on it or at the center of the wheel.
It really works! Try it.
Usage (MonthWheel.htm):
<!DOCTYPE html>
<html>
<head>
<title>svg</title>
<script type="text/javascript" src="dom.js"></script>
<script type="text/javascript" src="MonthWheel.js"></script>
<script type="text/javascript">
window.onload = function () {
var oWheel = new MonthWheel($("divSeasons"), 400, 400);
oWheel.eLang = "en";
oWheel.MonthChanged = function () {
if (oWheel.nMonth === -1) return;
$("divChanges").a$({
t: MonthWheel.Months[oWheel.nMonth][oWheel.eLang]+ " "});
};
oWheel.Show();
};
</script>
</head>
<body>
<div id="divSeasons"></div>
<div id="divChanges"></div>
</body>
</html>
The code for
dom.js is in an older post.
MontWheel.js:
function MonthWheel(oContainer,nWidth,nHeight) {
var that = this;
this.oContainer = oContainer;
this.eLang = "en";
this.nWidth = 100;
this.nHeight = 100;
this.nMonth = -1;
//events
this.MonthChanged =null;
if (typeof nWidth === "number") {
this.nWidth = nWidth;
if (typeof nHeight === "number") {
this.nHeight = nHeight;
}
}
this.SelectMonth = function () {
var nMonth = parseInt(this.attributes["nMonth"].nodeValue);
nMonth = (nMonth === that.nMonth) ? -1 : nMonth;
that.SetMonth(nMonth);
};
this.SetMonth = function (nMonth) {
if (typeof nMonth !== "number") nMonth = -1;
if (nMonth === that.nMonth) return;
that.nMonth = nMonth;
that.Show();
if (typeof that.MonthChanged === "function") that.MonthChanged();
}
}
MonthWheel.Months=[
{ en: "Jan", el: "Ιαν", color: "44f", stroke: "008" }
, { en: "Feb", el: "Φεβ", color: "08f", stroke: "048" }
, { en: "Mar", el: "Μαρ", color: "0f8", stroke: "084" }
, { en: "Apr", el: "Απρ", color: "4f4", stroke: "080" }
, { en: "May", el: "Μαι", color: "8f4", stroke: "480" }
, { en: "Jun", el: "Ιουν", color: "cf0", stroke: "680" }
, { en: "Jul", el: "Ιουλ", color: "ff0", stroke: "880" }
, { en: "Aug", el: "Αυγ", color: "fc0", stroke: "860" }
, { en: "Sep", el: "Σεπ", color: "f80", stroke: "840" }
, { en: "Oct", el: "Οκτ", color: "f44", stroke: "800" }
, { en: "Nov", el: "Νοε", color: "f48", stroke: "804" }
, { en: "Dec", el: "Δεκ", color: "84f", stroke: "408" }
];
MonthWheel.prototype.Show = function () {
var oFra = document.createDocumentFragment();
var nRadius = 1000, nRad = 1000;
var oSvg = oFra.a$("svg:svg", {
width: this.nWidth.toString() + "px",
height: this.nHeight.toString() + "px",
viewBox: "-" + (nRadius + 100).toString() +
" -" + (nRadius + 100).toString() +
" " + (2 * (nRadius + 100)).toString() +
" " + (2 * (nRadius + 100)).toString()
});
var nMonth = 0, oMonth, oPath, oText;
var nX, nY, nAngle = 0, nAngle2 = Math.PI / 6;
oSvg.a$("svg:circle", { r: nRadius, style:"fill:#ccc;cursor:pointer;"
}).onclick = this.SetMonth;
for (nMonth = 0; nMonth < 12; nMonth++) {
nRad = (nMonth === this.nMonth) ? nRadius * 1.07 : nRadius;
oMonth = MonthWheel.Months[nMonth];
nAngle = nMonth * Math.PI / 6;
nX = nRad * Math.sin(nAngle);
nY = -1 * nRad * Math.cos(nAngle);
nX2 = nRad * Math.sin(nAngle + Math.PI / 6);
nY2 = -1 * nRad * Math.cos(nAngle + Math.PI / 6);
oPath = oSvg.a$("svg:path", {
id: "pat" + oMonth.en,
nMonth: nMonth,
style: "fill:#" + oMonth.color + ";stroke:#" + oMonth.stroke +
";strokeWidth:20;cursor:pointer;",
d: "M" +
nX.toString() + "," + nY.toString() +
" A" + nRad.toString() + "," + nRad.toString() + " 0 0 1 " +
nX2.toString() + "," + nY2.toString() +
" L" + (nX2 / 2).toString() + "," + (nY2 / 2).toString() +
" A " + (nRad / 2).toString() + "," + (nRad / 2).toString() + " 0 0 0 " +
(nX / 2).toString() + "," + (nY / 2).toString() + " z"
});
oPath.onclick = this.SelectMonth;
oText = oSvg.a$("svg:text", { x: (nX + nX2) * 3 / 8, y: (nY + nY2) * 3 / 8,
t: oMonth[this.eLang], nMonth: nMonth,
style:"fontSize:100px;textAnchor:middle;cursor:pointer;color:#ccc;" });
oText.onclick = this.SelectMonth;
}
this.oContainer.innerHTML = "";
this.oContainer.appendChild(oFra);
}
No comments:
Post a Comment