Click Event to Animate Raphael Path Broken in IE - javascript

I have created a Raphael document and am storing the locations like so:
var R = Raphael("paper", 600, 500);
var attr = {
fill: "#fff",
stroke: "#fff",
"stroke-width": 1,
"stroke-linejoin": "round"
};
-- get coords from db assigned to object 'ausData' and create a object 'aus' --
$.each(ausData,function(i,obj) {
attr.fill = myData[i].color;
aus[i] = R.path(obj).attr(attr);
aus[i].id = myData[i].id;
mapIdObj[stateData[i].id] = R.getById(stateData[i].id);//aus[i].id;
});
so the path object is stored in the object mapIdObj
I am then attempting to alter the path object by clicking on a link. in the .success of the jQuery.post.success I am iterating through all the elements, and appending an anchor tag to the page, and on jQuery.post.complete I am attempting to bind a click:
$('#superHappyDiv').append('<a id="button'+st.id+'" class="superButton" name="button'+st.id+'" ref="'+st.id+'" class="" href="javascript:;" title="" target="">x</a>');
$('.superButton').live('click onmousedown',function() {
if (window.console) console.log($(this).attr('ref'));
var thisPath = mapIdObj[$(this).attr('ref')];
thisPath.animate({ 'transform': 's2', opacity: .9 }, 300, "<>");
});
Other answers have pointed to this as working, and it does, but not in IE 7, and 8 at least!
Is there a more efficient way to get this working, or working at all in IE?!
Cheers, Bo

Related

Raphael: Adding Multiple Paths on Array Items

I'm using Raphael. I'm trying to have two separate svg paths on my array options (wheel.people and wheel.leadEntrepreneur) so that I can style them differently. So in essence I want to add another path alongside the one that exists. One is for an svg shape and the other will be for an svg icon. I have managed to construct the shapes using the code below but now need to overlay the icons on top of the shapes. So How do I create an additional path for the icons and apply different styling?
var R = Raphael("paper", 400, 400);
var attr = {
fill: "#333",
stroke: "#fff",
"stroke-width": 1,
"stroke-linejoin": "round",
cursor: "pointer"
};
var wheel = {};
wheel.people = R.path("M205.1,84.2c-0.8-0.4-1.6-0.7-2.5-1.1c-0.1-0.1-0.3-0.1-0.5-0.2c-5.4-2.2-11-3.9-16.6-5 c-0.2,0-0.3-0.1-0.5-0.1c-5.7-1.1-11.5-1.7-17.3-1.7h-0.5c-4.7,0-9.4,0.4-14,1.1l-4.7-6.5l-0.8-1.1v0l-40.8-57 c9.1-3.5,18.4-6.2,27.9-8.1c0.2-0.1,0.3-0.1,0.5-0.1c10.5-2.1,21.2-3.1,31.9-3.1h0.5c10.7,0,21.4,1.1,31.9,3.1 c0.2,0,0.4,0.1,0.5,0.1c0.3,0.1,0.7,0.1,1,0.2l3.6,72v0l0.1,1.2v0L205.1,84.2z").attr(attr);
wheel.leadEntrepreneur = R.path("M285,50l-0.3,0.6l-35.6,62l-0.6,1l-3.3,5.8c-0.5-0.8-1-1.7-1.6-2.5c-0.1-0.1-0.2-0.3-0.3-0.4 c-3.2-4.7-6.9-9.2-11-13.4c0,0-0.1-0.1-0.1-0.1c-0.1-0.1-0.2-0.2-0.3-0.3c-4.2-4.1-8.7-7.8-13.4-11c-0.1-0.1-0.3-0.2-0.4-0.3 c-4.1-2.7-8.5-5.1-12.9-7.1l-0.3-6.2v0l-0.1-1.2v0l-3.6-72c10.1,2.1,20.1,5.1,29.7,9.1c0.2,0.1,0.3,0.1,0.5,0.2 c9.8,4.1,19.3,9.1,28.3,15.1c0.1,0.1,0.3,0.2,0.4,0.3c8.7,5.9,17,12.7,24.8,20.4C284.8,49.8,284.9,49.9,285,50L285,50z").attr(attr);

SVG Snap select a group by it's ID

I'm trying to get an SVG Snap element by it's id. First I create a canvas:
var s = Snap("#svgout"), //creates the canvas
Then I cerate a group:
var rect = s.rect(posx, posy, 40, 40, 6).attr({
fill: "none",
stroke: "#F44336",
strokeWidth: 3,
});
var group = s.group(rect).attr({
cursor: "move",
});
and next I get the id of the group that is defaulted by SVG Snap
var currGroupId = group.id;
Now, when I try to reference my group later in my code and get it by it's id,
s.select(currGroupId);
I get null. How do I properly select an element by it's id?
select will use a cssSelector, as in container.queryAll.
So I don't think Snap sets an id as an svg attribute (do correct me if I'm wrong). Which means if you want to use select, you may have to manually set it.
Also I susect s.select(id) wouldn't work, I think it would have to be s.select('#'.id) but I may be wrong. If you can get a fiddle up, it will be easier to test.
SnapSVG doesn't automatically set the ID attribute of the group. Instead it adds a field to the object itself. One way of getting around this limitation is to do the following.
var s = Snap("#svgout");
var rect = s.rect(posx, posy, 40, 40, 6).attr({
fill: "none",
stroke: "#F44336",
strokeWidth: 3,
});
var group = s.group(rect).attr({
cursor: "move",
});
Explicitly set the ID.
group.attr({
id: group.id
});
var currGroupId = group.id;
select uses CSS selectors. So we must add a '#' to the start of the ID.
s.select("#" + currGroupId);
Note: This method has been tested by me using SnapSVG V0.4.1
If this does not work and you are using jQuery. try:
$("#"+currGroupId);

KineticJS setting stroke programmatically

I have some text, that has a class in the form of "link variabletext" (where variabletext is unique to each link). I'm trying to set this up so that when I mouseover the text, the corresponding object changes color, using jQuery.
A jsFiddle of what I have: http://jsfiddle.net/hdJCn/
The code I'm using:
One
Two
Three
<div id="container"></div>
var stage = new Kinetic.Stage({
container: 'container'
});
var layer = new Kinetic.Layer();
var onecircle = new Kinetic.Ellipse({
x: 100,
y: 100,
radius: {
x: 50,
y: 50
},
strokeWidth: 1,
stroke: 'black'
});
layer.add(onecircle);
stage.add(layer);
$('.link').mouseover(function () {
var numclass = $(this).attr('class').split(' ')[1];
(numclass + 'circle').setStroke('orange');
});
The problem is that it says that the object has no method "setStroke". If I take that same object name and hardcode it (so onecircle.setStroke instead of the above) it works fine. I'm not sure why this is and so far am at a loss.
Figured it out. I had to convert the string to an object:
var obj = eval(numclass+'circle');
And then use obj.setStroke....

How to I scale the Raphael map in Rob Flaherty's US map example?

I'm trying to implement this awesome map, but I can't figure out how to scale it. Changing the size of the container div or the height/width values just crops the underlying map. I think I need paper.scaleAll(.5) in here somewhere, but can't figure it out. Thanks!
<script>
window.onload = function () {
var R = Raphael("container", 1000, 900),
attr = {
"fill": "#d3d3d3",
"stroke": "#fff",
"stroke-opacity": "1",
"stroke-linejoin": "round",
"stroke-miterlimit": "4",
"stroke-width": "0.75",
"stroke-dasharray": "none"
},
usRaphael = {};
//Draw Map and store Raphael paths
for (var state in usMap) {
usRaphael[state] = R.path(usMap[state]).attr(attr);
}
//Do Work on Map
for (var state in usRaphael) {
usRaphael[state].color = Raphael.getColor();
(function (st, state) {
st[0].style.cursor = "pointer";
st[0].onmouseover = function () {
st.animate({fill: st.color}, 500);
st.toFront();
R.safari();
};
st[0].onmouseout = function () {
st.animate({fill: "#d3d3d3"}, 500);
st.toFront();
R.safari();
};
})(usRaphael[state], state);
}
};
</script>
The other answer is almost correct, but you have to set the anchor point of the scale command to 0,0 so that each state is scaled from the same point:
element.transform("s2,2 0,0");
While you're at it, I'd make an R.set() element and add each state to it, so that you can apply the scale just to the states in the event that you add other objects, like a legend, that you do not want to scale:
usRaphael = {},
states = R.set();
//Draw Map and store Raphael paths
for (var state in usMap) {
usRaphael[state] = R.path(usMap[state]).attr(attr);
states.push(usRaphael[state]);
}
Then at the end:
states.transform("s2,2 0,0");
jsFiddle
After you draw the map (outside of your for loops) try the following:
R.forEach(function(element) {
element.transform("s2");
});
I'm not sure what version of Raphael you are using, but my code is assuming the latest. What this does is it iterates over every path on the paper and sets the transform to "scale 2". This will scale all of the paths by 2.

Selecting a node in Raphael/JavaScript

The following code mostly works (thanks to a good answer a couple of days ago!) all except for the last little bit:
things.square[1].node.setAttribute("id","clicker");
$("#clicker").click(function(){
$("#canvas_things1").fadeOut();
$("#canvas_things2").fadeIn();
});
I think the problem is this line:
things.square[1].node.setAttribute("id","clicker");
I would have thought that square[1].node would work, but it seems not. Can someone spot what's wrong?
<script type="text/javascript" charset="utf-8">
$("document").ready(function() {
var RM = Raphael("canvas", 1000, 500);
var attr = { // for the visible shapes
fill: "#bbb", "fill-opacity": 1,
stroke: "#222", "stroke-width": 0.3,
};
var attr2 = { // for the invisible hovering areas
fill: "green", "fill-opacity": 0.0,
stroke: "red", "stroke-width": 0,
};
var things = {};
/* Square */ things.square = [ RM.path("m 154.21525,71.431259 74.32805,0 0,70.496711 -74.32805,0 0,-70.496711 z").attr(attr),
RM.path("m 271.25132,77.933263 58.07304,0 0,56.409037 -58.07304,0 0,-56.409037 z").attr(attr2) ];
/* Triangle */ things.triangle = [ RM.path("m 154.02932,222.44063 36.78089,-58.23641 34.48208,58.2364 -71.26297,1e-5").attr(attr),
RM.path("m 271.25132,165.71032 58.07304,0 0,56.40903 -58.07304,0 0,-56.40903 z").attr(attr2) ];
for (var shape in things) {
shape[0].color = Raphael.getColor();
(function (shape, sh) {
shape[1][0].onmouseover = function () {
shape[0].animate({fill:shape[0].color, stroke:"#ccc"}, 500);
document.getElementById(sh)[0].style.display = "block";
shape[0].toFront(); R.safari();
};
shape[1][0].onmouseout = function () {
shape[0].animate({fill:"#bbb", stroke:"#222"}, 500);
document.getElementById(sh)[0].style.display = "none";
shape[0].toFront(); R.safari();
};
})(things[sh], sh);
} // end for every member of things
things.square[1].node.setAttribute("id","clicker");
$("#clicker").click(function(){
$("#canvas_things1").fadeOut();
$("#canvas_things2").fadeIn();
});
}); // end the document ready function
</script>
The id attribute is set properly.
Try it out with this jQuery (click on the 1st red square)
Notice, that I had to rip out your for loop. This is because the self executing anonymous function was causing a runtime error due to being called with undefined variables.
sh is never defined, but it is used here:
})(things[sh], sh); // sh is never defined!
} // end for every member of things
I would have replaced the for loop but I don't understand what you're trying to do.
At any rate, I would suggest using the Raphael custom event handler .hover().
PS: Watch your unnecessary comas (you have 4):
stroke: "#222", "stroke-width": 0.3, // <== Trailing comma
};
I think it's because things.square doesn't map to a single element in your SVG when you have multiple paths. There's two approaches that should work:
Loop through each of the path elements in things.square and apply the click function to each of them (won't be able to use the id attribute then).
Use a group add-on to put all your paths inside a <g> element in the SVG, then apply your function to that instead.

Categories

Resources