Reputation: 15
I am trying to make some simple buttons on Raphael.js. So I stuck in the last step. Here is my JSFiddle So my buttons keep the active state after you press them. But I trying to make pressed button inactive, when I press another.
I was trying to get st.node.state value with the loop inside the onclick function but it's just not working for me. Here is my code:
for(var i in aus) {
(function (st) {
st.node.state = 0;
st.node.onmouseover = function() {
st.animate({fill: "#8fbf27", stroke: "#fff"}, 100);
};
st.node.onmouseout = function() {
st.animate({fill: "#555", stroke: "#fff"}, 100);
if(this.state == 1){
st.animate({fill: "#fff", stroke: "#fff"}, 100);
}else {
st.animate({fill: "#555", stroke: "#fff"}, 100);
}
};
st.node.onclick = function() {
if(this.state == 0) {
this.state = 1;
st.animate({fill: "#fff", stroke: "#fff"}, 100);
}else {
this.state = 0;
st.animate({fill: "#555", stroke: "#fff"}, 100);
}
};
})(aus[i]);
Upvotes: 0
Views: 3895
Reputation: 34072
Something like this should work. This lets the elements animate themselves based on state. On click, if the element is being activated, loop through and deactivate the others.
// An animator function which will animate based on node state
var animate = function(st) {
var fill = st.node.state ? "#fff" : "#555";
st.animate({fill: fill, stroke: "#fff"}, 100);
}
for (i in aus) {
(function (st) {
st.node.state = 0;
st.node.onmouseover = function () {
if (!this.state) st.animate({fill: "#8fbf27", stroke: "#fff"}, 100);
};
st.node.onmouseout = function () {
animate(st);
};
st.node.onclick = function () {
this.state = 1 - this.state;
animate(st);
// if the node is deactivated stop now
if (!this.state) return;
// otherwise deactivate and animate the other nodes
for (i in aus) {
// if node is `this` or node is already deactivated, continue
if (aus[i].node === this || !aus[i].node.state) continue;
// otherwise deactivate and animate
aus[i].node.state = 0;
animate(aus[i]);
}
};
}(aus[i]));
}
Alternatively, if only one is activated at a time, you might just store a reference to the one activated node and avoid looping.
// A reference to the active element
var activeEl;
// animate based on whether the st is the active element
var animate = function(st) {
var fill = activeEl === st ? "#fff" : "#555";
st.animate({fill: fill, stroke: "#fff"}, 100);
}
for (i in aus) {
(function (st) {
st.node.onmouseover = function () {
if (!this.state) st.animate({fill: "#8fbf27", stroke: "#fff"}, 100);
};
st.node.onmouseout = function () {
animate(st);
};
st.node.onclick = function () {
if (!activeEl || activeEl !== st) {
var el = activeEl;
activeEl = st;
if (el) animate(el);
} else {
activeEl = null;
}
animate(st);
};
}(aus[i]));
}
Upvotes: 3