Finding the svg image center - svg

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>

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 ...

Node JS Sharp - Maintain SVG Font When Converting To JPG

I am using the sharp library to create dynamic JPEG license plate images.
Basically, I have a PNG that is a vanity license plate with no numbers. Then I create an svg in code like so
const svg = new Buffer(
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${x} ${y} 500 40">
<defs>
<style type="text/css">
<![CDATA[
#font-face {
font-family: LicensePlate;
src: url('LicensePlate.ttf');
}
svg {
width: 100%;
height: 100%;
}
]]>
</style>
</defs>
<text x="0" y="0" font-family="LicensePlate" font-size="${fontsize}" letter-spacing="${letterspace}">
${platenumber.toUpperCase()}
</text>
</svg>`
);
Passing in the desired width, height, and license plate number. Then I use the sharp library to overlay my SVG in the middle of the license plate. This all works just fine.
However, I have imported a custom license plate font (LicensePlate.ttf). In order to debug my in-code SVG image I made an actual svg image file that I open in the browser to make sure that it all looks correct, which it does.
The problem is that when the final JPEG file is created it does not contain my custom font. Instead it falls back on Verdana.
My question is, is there any way I can maintain the SVG font while creating the image with sharp?
Thanks!
Full Code
function createImage(platenumber) {
//Trying to create some sort of responsiveness
let fontsize = 80;
let letterspace = 10;
let width = 300;
let height = 90;
let x = 0;
let y = -45;
const inputlength = platenumber.length;
//Minumum Length
if (inputlength == 2) {
x = -200;
}
if (inputlength == 3) {
x = -150;
}
if (inputlength == 4) {
x = -130;
}
if (inputlength == 5) {
x = -105;
}
if (inputlength == 6) {
x = -65;
}
try {
console.log('stream is duplex, ', pipe instanceof stream.Duplex);
//Read the svg code into a buffer with a passed in plate number
const svg = new Buffer(
`<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${x} ${y} 500 40">
<defs>
<style type="text/css">
<![CDATA[
#font-face {
font-family: LicensePlate;
src: url('LicensePlate.ttf');
}
svg {
width: 100%;
height: 100%;
}
]]>
</style>
</defs>
<text x="0" y="0" font-family="LicensePlate" font-size="${fontsize}" letter-spacing="${letterspace}">
${platenumber.toUpperCase()}
</text>
</svg>`
);
const plateid = rand.generate(10);
//Create a write stream to a randomly generated file name
const write = new fs.createWriteStream(`plates/${plateid}.jpg`);
//Create the sharp pipeline
const pipeline = pipe
.overlayWith(svg, { gravity: sharp.gravity.center })//we center the svg image over the top of whatever image gets passed into the pipeline
.jpeg();//we convert to JPG because it is a compressed file format and will save space (we could also do webp if we really want to be slick about it)
//Create the read stream from the license plate template
const read = new fs.createReadStream('plate-2.png')
.pipe(pipeline)//pipe out sharp pipeline
.pipe(write);//add the write stream so that our sharp pipeline knows where to put the image
return plateid;
} catch (e) {
console.log(e);
return null;
}
}
SVG Image
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="90" viewBox="0 -50 500 40">
<defs>
<style type="text/css">
<![CDATA[
#font-face {
font-family: LicensePlate;
src: url('LicensePlate.ttf');
}
]]>
</style>
</defs>
<text x="0" y="0" font-family="LicensePlate" font-size="150" letter-spacing="10">
Pl#T3#
</text>
</svg>
Exact Font
Here is a link to the exact font I used
http://www.fontspace.com/dave-hansen/license-plate
I dealt with this problem by installing the font in my OS, when the file is being converted, the libraries can only access OS fonts.

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

positioning <object> on svg path

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>

Resources