positioning <object> on svg path - svg

I have a bunch of objects that are using the same svg path which is basically an arrow. I want to position the objects on another svg path of a circle so the arrows look like they are "radiating" outward.
I read a few articles that say using <object> for svg gives you more control but I cant find how to position <object>'s onto another svg <object> path(circle).
rather than just manually rotating each <object> I would like to position them all along a path so animating them in the future would be easier. I want them to move out a bit from the center on rollover and I imagine the animation for that would be easier with a path rather than manually animating each arrow.
I can animate along path like here
http://demo.hongkiat.com/scalable-vector-graphics-animation/
and by changing the path on "following Path" to a circle but I dont want to animate, just position....
UPDATE: The only thing I seem to be able to find online to get an element onto a path is animationTransform or to animate something along a path but I want to only position elements along another element(path) like this:
The extra arrow sticking out is how I plan on animating it in the future on rollover...but for now I just am curious how to position the arrows. Also I don't have much but its a start and I got working finally. Any help appreciated!
http://jsfiddle.net/74JRf/1/
I was just thinking, would it be better to rotate the arrows into a circle with css3, or svg?

This is similar to the previous answer, except it uses your imported paths as the arrows, rather than polygons.
Firstly, your imported paths are humongus so they are too big for my 400x400 svg.
Therfore, I have to scale them down to a reasonable size for my svg. I chose 80px as the height of the arrow. To do this, I have to get the actual size of the imported paths, which I have placed in a element. I use getBBox() to do this as follows.
//--get actual size---
var bb=importedPaths.getBBox()
var bbx=bb.x
var bby=bb.y
var bbw=bb.width
var bbh=bb.height
//---find the center point of this <g>---
var cx=bbx+.5*bbw
var cy=bby+.5*bbh
//---set desired size, i.e. scale the import--
var heightSize=80
var scale=heightSize/bbh
//---translate so it's bottom is centered is at (0,0)
var transX=(-cx)*scale
var transY=(-cy-.5*bbh)*scale
importedPaths.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")
Now I have this sized and located with bottom of arrow centered at(0,0), so I can use it to make elements for symbols.
I make a copy of the re-sized import as the black arrow and gray arrow and place them in a <defs> element. <defs> are used to store/hide elements used for symbols.
//---create your symbol objects from transformed import, by placing <g> in defs--
var blackArrow=importedPaths.cloneNode(true)
blackArrow.id="myBlackArrow"
myDefs.appendChild(blackArrow)
var grayArrow=importedPaths.cloneNode(true)
grayArrow.id="myGrayArrow"
grayArrow.setAttribute("fill","silver")
myDefs.appendChild(grayArrow)
The following is a html file where you can see this in action. I have included a textarea showing how the svg is created. (I left the original arrow at upper left). Note: works OK in IE and Chrome, with FF not fully rendering the group of arrows.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<div style='padding:5px;background-color:gainsboro;'>OK in:IE11/CH32, but FF23 does not fully render arrow in in circle<br /></div>
<br />
<br />
<br />
<center>
<div id=svgDiv style='width:400px;height:400px;background-color:lightgreen'>
<svg id="mySVG" width="400" y="400" overflow="visible" >
<defs id="myDefs">
</defs>
<g id="importedPaths" fill="black"><path d="M2553.826,1137.28l-2.772-1.719l29.799,1445.434l195.02,1.004l9.765-1448.729 c0,0-63.94,42.007-113.36,42.007S2553.826,1137.28,2553.826,1137.28z" /><path d="M2451.84,1058.265c0,0,171.983,75.005,216.505,75.005s188.535-75.005,188.535-75.005l-190.691-366.037 L2451.84,1058.265z" /></g>
</svg>
</div>
<button onClick=placeArrowsAroundCircle()>Place Arrows Around Circle</button><br />
<br />SVG Source:<br />
<textarea id=svgSourceValue style='font-size:110%;font-family:lucida console;width:90%;height:200px'></textarea>
</center>
<script id=myScript>
var NS="http://www.w3.org/2000/svg"
var xref="http://www.w3.org/1999/xlink"
//--place this at the center of this svg---
var centerX=200
var centerY=200
//---every 30 degrees around a center point--
//---button---
function placeArrowsAroundCircle()
{
for(var k=0;k<12;k++)
{
var rotateAngle=k*30
var grayArrow=document.createElementNS(NS,"use")
grayArrow.setAttributeNS(xref,"href", "#myGrayArrow")
grayArrow.setAttribute("onmouseover", "hilite(evt)")
grayArrow.setAttribute("onmouseout", "unhilite(evt)")
grayArrow.setAttribute("rotateAngle", rotateAngle)
grayArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
mySVG.appendChild(grayArrow)
}
for(var k=0;k<12;k++)
{
var rotateAngle=k*30+15 //--offset 15 degrees---
var blackArrow=document.createElementNS(NS,"use")
blackArrow.setAttributeNS(xref,"href", "#myBlackArrow")
blackArrow.setAttribute("onmouseover", "hilite(evt)")
blackArrow.setAttribute("onmouseout", "unhilite(evt)")
blackArrow.setAttribute("rotateAngle", rotateAngle)
blackArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
mySVG.appendChild(blackArrow)
}
svgSourceValue.value=svgDiv.innerHTML
}
//--onmouseover---
function hilite(evt)
{
//---IE and Chrome---
if(evt.target.correspondingUseElement)
var target=evt.target.correspondingUseElement
else //---FF---
var target=evt.target
var rotateAngle=target.getAttribute("rotateAngle")
target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")scale(1,1.3)")
}
//---onmouseout--
function unhilite(evt)
{
//---IE and Chrome---
if(evt.target.correspondingUseElement)
var target=evt.target.correspondingUseElement
else //---FF---
var target=evt.target
var rotateAngle=target.getAttribute("rotateAngle")
target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
}
document.addEventListener("onload",init(),false)
//---adjust(transform) the imported paths so they fit this svg viewPort---
function init()
{
//--get actual size---
var bb=importedPaths.getBBox()
var bbx=bb.x
var bby=bb.y
var bbw=bb.width
var bbh=bb.height
//---find the center point of this <g>---
var cx=bbx+.5*bbw
var cy=bby+.5*bbh
//---set desired size, i.e. scale the import--
var heightSize=80
var scale=heightSize/bbh
//---translate so it's bottom is centered is at (0,0)
var transX=(-cx)*scale
var transY=(-cy-.5*bbh)*scale
importedPaths.setAttribute("transform","translate("+transX+" "+transY+")scale("+scale+" "+scale+")")
//---create your symbol objects from transformed import, by placing <g> in defs--
var blackArrow=importedPaths.cloneNode(true)
blackArrow.id="myBlackArrow"
myDefs.appendChild(blackArrow)
var grayArrow=importedPaths.cloneNode(true)
grayArrow.id="myGrayArrow"
grayArrow.setAttribute("fill","silver")
myDefs.appendChild(grayArrow)
//---see textarea---
svgSourceValue.value=svgDiv.innerHTML
}
</script>
</body>
</html>

Your application demonstrates the neat dynamic aspects of SVG. I hope my answer is not too verbose :)
Create your 'arrows' so their center/bottom point is at(0,0) - This is used when placing them around a circle, and for the 'hilite/extend' feature for onmouseover.
I would recommend using a polygon rather than a path for each black and gray arrow.
Place then in a <defs> for creating the needed use elements.
e.g
<defs>
<polygon id="myBlackArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80" fill="black" />
<polygon id="myGrayArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80" fill="silver" />
</defs>
Then, with a bit of Javascript you can build the arrows around a center point:
var NS="http://www.w3.org/2000/svg"
var xref="http://www.w3.org/1999/xlink"
var centerX=200
var centerY=200
//---every 40 degrees around a center point--
function placeArrowsAroundCircle()
{
for(var k=0;k<9;k++)
{
var rotateAngle=k*40
var grayArrow=document.createElementNS(NS,"use")
grayArrow.setAttributeNS(xref,"href", "#myGrayArrow")
grayArrow.setAttribute("onmouseover", "hilite(evt)")
grayArrow.setAttribute("onmouseout", "unhilite(evt)")
grayArrow.setAttribute("rotateAngle", rotateAngle)
grayArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
mySVG.appendChild(grayArrow)
}
for(var k=0;k<9;k++)
{
var rotateAngle=k*40+20
var blackArrow=document.createElementNS(NS,"use")
blackArrow.setAttributeNS(xref,"href", "#myBlackArrow")
blackArrow.setAttribute("onmouseover", "hilite(evt)")
blackArrow.setAttribute("onmouseout", "unhilite(evt)")
blackArrow.setAttribute("rotateAngle", rotateAngle)
blackArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
mySVG.appendChild(blackArrow)
}
}
The two functions attached to each arrow for mouseover/out will extend/contract the target arrow( the arrow are scaled to 1.3 in the y direction).
//--onmouseover---
function hilite(evt)
{
//---IE and Chrome---
if(evt.target.correspondingUseElement)
var target=evt.target.correspondingUseElement
else //---FF---
var target=evt.target
var rotateAngle=target.getAttribute("rotateAngle")
target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")scale(1,1.3)")
}
//---onmouseout--
function unhilite(evt)
{
//---IE and Chrome---
if(evt.target.correspondingUseElement)
var target=evt.target.correspondingUseElement
else //---FF---
var target=evt.target
var rotateAngle=target.getAttribute("rotateAngle")
target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
}
Below is an example you can place in an .htm document to see it work. This tested OK for IE/CH/FF
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<center>
<div id="svgDiv" style='background-color:lightblue;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
<defs>
<polygon id="myBlackArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80" fill="black" />
<polygon id="myGrayArrow" points="10,0 -10,0 -10,-80 -15,-80 0,-100 15,-80 10,-80" fill="silver" />
</defs>
</svg>
</div>
<button onClick=placeArrowsAroundCircle()>Place Arrows Around Circle</button>
</center>
<script id=myScript>
var NS="http://www.w3.org/2000/svg"
var xref="http://www.w3.org/1999/xlink"
var centerX=200
var centerY=200
//---every 40 degrees around a center point--
//---button---
function placeArrowsAroundCircle()
{
for(var k=0;k<9;k++)
{
var rotateAngle=k*40
var grayArrow=document.createElementNS(NS,"use")
grayArrow.setAttributeNS(xref,"href", "#myGrayArrow")
grayArrow.setAttribute("onmouseover", "hilite(evt)")
grayArrow.setAttribute("onmouseout", "unhilite(evt)")
grayArrow.setAttribute("rotateAngle", rotateAngle)
grayArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
mySVG.appendChild(grayArrow)
}
for(var k=0;k<9;k++)
{
var rotateAngle=k*40+20
var blackArrow=document.createElementNS(NS,"use")
blackArrow.setAttributeNS(xref,"href", "#myBlackArrow")
blackArrow.setAttribute("onmouseover", "hilite(evt)")
blackArrow.setAttribute("onmouseout", "unhilite(evt)")
blackArrow.setAttribute("rotateAngle", rotateAngle)
blackArrow.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
mySVG.appendChild(blackArrow)
}
}
//--onmouseover---
function hilite(evt)
{
//---IE and Chrome---
if(evt.target.correspondingUseElement)
var target=evt.target.correspondingUseElement
else //---FF---
var target=evt.target
var rotateAngle=target.getAttribute("rotateAngle")
target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")scale(1,1.3)")
}
//---onmouseout--
function unhilite(evt)
{
//---IE and Chrome---
if(evt.target.correspondingUseElement)
var target=evt.target.correspondingUseElement
else //---FF---
var target=evt.target
var rotateAngle=target.getAttribute("rotateAngle")
target.setAttribute("transform","translate("+centerX+" "+centerY+")rotate("+rotateAngle+")")
}
</script>
</body>
</html>

Related

SVG PATH Creation is not creating in exact path using mouse XY Co ordinates

I am drawing the SVG Path using XY Coordinates of element and mouse move. SVG path is not appending with correct Mouse point.
This is my code snippet
<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" >
<g><path id=""></path></g> </svg>
<script>
.
.
.
var coord = getMousePosition(evt);
var getpos = document.getElementById(id).getBoundingClientRect();
var CTM = svg.getScreenCTM();
var pathValue = "M "+getpos.x+" "+getpos.y+" "+coord.x+" "+coord.y;
document.getElementById(id).setAttribute("d", pathValue);
.
.
</script>
.........
Looks like you are missed the 'L' command of your svg path...
let path;
addEventListener('mousedown', function(e) {
svg.innerHTML += `<path
fill=none
stroke-width=5
stroke="hsl(${Math.random()*360},66%,66%)"
d="M${e.x},${e.y}"
/>`;
path = svg.querySelector('path:last-child');
})
addEventListener('mouseup', function() {
path = null;
})
addEventListener('mousemove', function(e) {
path && path.setAttribute('d', path.getAttribute('d') + `L${e.x},${e.y}`);
})
addEventListener('resize', function() {
svg.setAttribute('width', innerWidth);
svg.setAttribute('height', innerHeight);
})
dispatchEvent(new Event('resize'));
body {
margin: 0;
overflow: hidden;
}
<svg id=svg></svg>
Click "Run code snippet" and try to draw in snippet frame ...

How can i make a svg <rect> box dynamic with changeable <text>?

How can i make a svg rect box dynamic with changeable text ? Like in my code, if the text "Hello" will more than 30 character ?
<svg version="1.1" viewBox="0 0 500 500" preserveAspectRatio="xMinYMin meet" class="svg-content">
<g>
<rect x="0" y="0" width="100" height="100" stroke-width="5" stroke="#000000" fill="none"></rect> ?
<text x="0" y="50" font-family="Verdana" font-size="35" fill="blue">Hello</text>
</g>
</svg>
Probably the best approach would be to have the rect preset at specific width. Then create tspans to fill the text element, and dynamically resize the rect height as the characters exceed the preset width.
Below is an example:
<!DOCTYPE HTML>
<html>
<head>
<title>Wrap Text Rectangle</title>
</head>
<body onload=wrapTextRect()>
Place this text:<br>
<textarea id="myTextValue" style='width:400px;height:60px;'>
Hello!
</textarea><br>
<button onClick=wrapTextRect()> Wrap text in rect</button>
<div id="svgDiv" style='background-color:lightgreen;width:400px;height:400px;'>
<svg id="mySVG" width="400" height="400">
<rect id=myRect x=50 y=50 rx=10 ry=10 width=100 fill="#4682b4" stroke='black' stroke-width=5 opacity=.5 />
<text id=myText font-size=14 font-family="arial" fill="white" />
</svg>
</div>
SVG Source:<br>
<textarea id=sourceValue style=width:500px;height:300px></textarea>
<script>
var NS="http://www.w3.org/2000/svg"
//---onload and button---
function wrapTextRect()
{
//---clear previous---
for(var k=myText.childNodes.length-1;k>=0;k--)
myText.removeChild(myText.childNodes.item(k))
var padding=10
var width=+myRect.getAttribute("width")-padding
var x=+myRect.getAttribute("x")
var y=+myRect.getAttribute("y")
var fontSize=+myText.getAttribute("font-size")
var text=myTextValue.value
var words = text.split(' ');
var text_element = document.getElementById('myText');
var tspan_element = document.createElementNS(NS, "tspan"); // Create first tspan element
var text_node = document.createTextNode(words[0]); // Create text in tspan element
tspan_element.setAttribute("x", x+padding);
tspan_element.setAttribute("y", y+padding+fontSize);
tspan_element.appendChild(text_node); // Add tspan element to DOM
text_element.appendChild(tspan_element); // Add text to tspan element
//---[EDIT] a single word that exceeds preset rect with---
if(words.length==1)
{
var len = tspan_element.getComputedTextLength()
if(len>+myRect.getAttribute("width"))
myRect.setAttribute("width", len+2*padding)
}
//---end [EDIT]------------------
for(var i=1; i<words.length; i++)
{
var len = tspan_element.firstChild.data.length // Find number of letters in string
tspan_element.firstChild.data += " " + words[i]; // Add next word
if (tspan_element.getComputedTextLength() > width-padding)
{
tspan_element.firstChild.data = tspan_element.firstChild.data.slice(0, len); // Remove added word
var tspan_element = document.createElementNS(NS, "tspan"); // Create new tspan element
tspan_element.setAttribute("x", x+padding);
tspan_element.setAttribute("dy", fontSize);
text_node = document.createTextNode(words[i]);
tspan_element.appendChild(text_node);
text_element.appendChild(tspan_element);
}
}
var height = text_element.getBBox().height +2*padding; //-- get height plus padding
myRect.setAttribute('height', height); //-- change rect height
//---show svg source---
sourceValue.value=svgDiv.innerHTML
}
</script>
</body>
</html>

How to display svg markers that contain links to other svgs in HERE maps?

I am trying to display svg markers using the HERE Javascript API. I have followed the documentation, however my twist is that my svg contains links to other svgs. The reason for this is that I would like to display markers that have the same pin shape, but a different icon in the centre of the pin. As the icons will also be used in other places on my website, it makes sense to save the svgs separately so they only need updating in one place.
I can get standard svgs to display as markers, but when I try and nest the svgs, no marker is displayed on the map.
This is my code so far:
pin.svg - This is the basic pin shape that all markers will use
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="46.093765"
height="63.352634">
<g
transform="translate(-8.9327811,-0.45623957)"
id="layer1">
<path
d="M 22.15625,0 A 21.544797,22.053723 0 0 0 0,22.0625 21.544797,22.053723 0 0 0 10.40625,40.9375 c 1.062265,1.795846 11.125,19.40625 11.125,19.40625 l 12.125,-20.0625 A 21.544797,22.053723 0 0 0 43.09375,22.0625 21.544797,22.053723 0 0 0 22.15625,0 z"
transform="translate(10.432788,1.9651232)"
id="path5014"
style="fill:#cccccc;fill-opacity:1;stroke:#6e6e6e;stroke-width:2;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
<path
d="m 50.723066,23.370655 a 17.218699,16.540131 0 1 1 -34.437397,0 17.218699,16.540131 0 1 1 34.437397,0 z"
transform="matrix(0.94189641,0,0,1.0010512,0.4199413,0.48436132)"
id="path5019"
style="fill:#ffffff;fill-opacity:1;stroke:none" />
</g>
</svg>
here-example.svg - This is the example from the HERE site. I am using it as an icon that gets placed inside the pin
<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg">
<rect stroke="black" fill="red" x="1" y="1" width="22" height="22" />
<text x="12" y="18" font-size="12pt" font-family="Arial" font-weight="bold" text-anchor="middle" fill="yellow">
C
</text>
</svg>
pin-with-icon.svg - This is my nested svg - it pulls in the pin and the icon and overlaps them
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<image x="20" y="20" width="300" height="80" xlink:href="pin.svg" />
<image x="120" y="32" width="100" height="30" xlink:href="here-example.svg" />
</svg>
index.html - This is where the HERE map is used and I try and display the markers. It makes heavy use of the HERE developer documentation. Replace <App_ID> and <App_Code> with the HERE credentials. In this page I also try and load the problematic svg into a div to prove that it works.
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<script src="http://js.api.here.com/v3/3.0/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-ui.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-mapevents.js" type="text/javascript" charset="utf-8"></script>
<script src="http://code.jquery.com/jquery.min.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="http://js.api.here.com/v3/3.0/mapsjs-ui.css" />
</head>
<body>
<div style="width: 640px; height: 480px" id="mapContainer"></div>
<!-- Display the svg just to prove that the loads correctly -->
<div id="svgPin"></div>
<script>
// Initialize the platform object:
var platform = new H.service.Platform({
'app_id': '<App_ID>',
'app_code': '<App_Code>'
});
// Obtain the default map types from the platform object
var maptypes = platform.createDefaultLayers();
// Instantiate (and display) a map object:
var map = new H.Map(
document.getElementById('mapContainer'),
maptypes.normal.map,
{
zoom: 6,
center: { lng: 13.4, lat: 52.51 }
});
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Example with svg pins not showing (svg contains links to other svgs)
var svgMarkupRetrieval = $.get('pin-with-icon.svg', function (svg) {
// Just to prove that the svg is loaded correctly
$('#svgPin').html(svg);
var icon = new H.map.Icon(svg);
// Add the first marker
var marker1 = new H.map.Marker({ lat: 52.4, lng: 13.3 },
{ icon: icon });
map.addObject(marker1);
// Add the second marker.
var marker2 = new H.map.Marker({ lat: 51.45, lng: 13.3 },
{ icon: icon });
map.addObject(marker2);
}, 'text');
// Example with svg pins showing (from HERE developer guide)
var svgMarkupRetrieval = $.get('here-example.svg', function (svg) {
var icon = new H.map.Icon(svg);
// Add the first marker
var marker3 = new H.map.Marker({ lat: 50.4, lng: 13.3 },
{ icon: icon });
map.addObject(marker3);
// Add the second marker.
var marker4 = new H.map.Marker({ lat: 49.45, lng: 13.3 },
{ icon: icon });
map.addObject(marker4);
}, 'text');
</script>
</body>
</html>
To use the code, create each file with the name I specify and put them in a folder in IIS. index.html has to be run through IIS, otherwise a cross origin request error occurs.
The pin-with-icon.svg loads separately (I load it under the map), as do the standard svg markers. But I cannot see why the markers I create using pin-with-icon.svg do not show on the map. Any help would be appreciated.
Use H.map.DomMarker and H.map.DomIcon

Finding the svg image center

Am a new in svg .I want to find out the svg image center programically,also display a 'dots' in center point.
Here i created a simple svg.How to shows dots in the center point.
<!DOCTYPE html>
<html>
<body>
<svg height="210" width="400">
<path d="M75 0 L56 105 L225 200 Z" />
</svg>
</body>
</html>
You'd need to do...
<script type="text/javascript">
var svg = document.querySelector("svg");
var svgns = "http://www.w3.org/2000/svg";
// get the center
var el = document.querySelector("path");
var bbox = el.getBBox();
var center = {
x: bbox.left + bbox.width/2,
y: bbox.top + bbox.height/2
};
// create the dot
var dot = document.createElementNS(svgns, circle);
dot.setAttribute("cx", center.x);
dot.setAttribute("cy", center.y);
dot.setAttribute("r", 10);
svg.appendChild(dot);
</script>

draggable rect in svg drags only diagnolly on the screen

I tried making a small program where in I wrote code to drag a rectangle in svg. The program is quite simple. My problem is that the rectangle drags only diagnolly on the screen and not on the entire web page.
Here is my code..
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="100%" height="100%"
onload="Init( evt )" >
<script type="text/ecmascript">
//<![CDATA[
var svgDocument;
var svgRoot;
var newP;
var bmousedown=0;
var myCirc;
function Init(evt){
svgRoot= document.getElementsByTagName("svg")[0];
newP = svgRoot.createSVGPoint();
myCirc = document.getElementById("mycirc");
}
function getMouse(evt){
var position = svgRoot.createSVGPoint();
position.x = evt.clientX;
position.y = evt.clientY;
return position;
}
function onMouseDown(evt){
bmousedown=1;
newP=getMouse(evt);
doUpdate();
}
function onMouseMove(evt){
if(bmousedown){
newP=getMouse(evt);
doUpdate();
}
}
function onMouseUp(evt){
bmousedown=0;
}
function doUpdate(){
myCirc.setAttributeNS(null, "x", newP.x );
myCirc.setAttributeNS(null, "y", newP.y );
}
// ]]></script>
<rect id="mycirc" fill: #bbeeff" x="0" y="0" width="80" height="80"
pointer-events="visible"
onmousedown="onMouseDown(evt)"
onmousemove="onMouseMove(evt)"
onmouseup="onMouseUp(evt)"/>
</svg>
Please help me as I am unable to understand why does it not move on the entire screen.
i see the problem recreated on firefox, but it's not a single problem, your code is all over the place. i suggest going back to the drawing board before posting specific questions.
i'd also recommend a good reference on SVG or using a JS vector graphics library, as it would simplify things a little and will ease up the development a lot, if you're not interested in getting down to the nitty-gritty.
Here is the correct solution: http://jsfiddle.net/mihaifm/5GHJs/
The mistakes I think you made:
onload="Init( evt )" makes the variable evt global, a bad and useless thing to have. All the functions are also global, but this should be ok for this example.
the function calls for onmousedown etc. were using this global evt. (wrong). In order to get the correct event for each call you need to register some handlers.

Resources