manipulate svg file within a fabric.js canvas - javascript
I am trying to manipulat an svg file with fabric.js. I am loading the svg string fabric.loadSVGFromString into the canvas correctly. My question is how can I manipulate some parts of the svg.
For example, I imported an electronic breadbord with lot of holes as shown in the pic below .
How could I detect if a hole has been clicked? How could I get the clicked part?
Thank you
I did a very short demo of what you could do.
The point is create a svg that can be imported as single shapes, lock the shapes on the canvas, then handle click events.
var canvas = new fabric.Canvas("bb");
svg = '<svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" x="0in" y="0in" width="6.50331in" height="2.1in" viewBox="0 0 468.238 151.2" ><g partID="57380"><g id="breadboardbreadboard"> <g id="background"> <rect fill="#D9D9D9" height="151.199" width="468.238" y="0"/> </g> <g id="stripes"><rect fill="#B3B0B0" height="0.4" width="468.238" y="20.932"/> <rect fill="#B3B0B0" height="0.4" width="468.238" y="129.475"/> </g> <g > <rect fill="#FF0000" height="0.4" width="468.238" y="19.2"/> <rect fill="#FF0000" height="0.4" width="468.238" y="148.799"/> <rect fill="#0000FF" height="0.4" width="468.238" y="2.4"/> <rect fill="#0000FF" height="0.4" width="468.238" y="132"/> </g> <g > <rect fill="#CCC9C9" height="7.2" width="468.238" y="71.2"/> </g> <g id="sockets"> <g id="pin1A"> <path fill="#BFBFBF" d="M8.526,115.2c0,-1.322,1.072,-2.394,2.394,-2.394s2.394,1.071,2.394,2.394"/> <path fill="#E6E6E6" d="M13.313,115.2c0,1.322,-1.072,2.394,-2.394,2.394s-2.394,-1.071,-2.394,-2.394"/> <circle r="1.197" fill="#383838" cx="10.92" cy="115.2"/> </g> <g id="pin1B"> <path fill="#BFBFBF" d="M8.526,108c0,-1.322,1.072,-2.395,2.394,-2.395s2.394,1.072,2.394,2.395"/> <path fill="#E6E6E6" d="M13.313,108c0,1.321,-1.072,2.393,-2.394,2.393S8.526,109.322,8.526,108"/> <circle r="1.197" fill="#383838" cx="10.92" cy="108"/> </g> <g id="pin1C"> <path fill="#BFBFBF" d="M8.526,100.799c0,-1.321,1.072,-2.393,2.394,-2.393s2.394,1.071,2.394,2.393"/> <path fill="#E6E6E6" d="M13.313,100.799c0,1.322,-1.072,2.395,-2.394,2.395s-2.394,-1.072,-2.394,-2.395l0,0"/> <circle r="1.197" fill="#383838" cx="10.92" cy="100.8"/> </g></g></g></svg>';
fabric.loadSVGFromString(svg, function(objs) {
var obj;
for(var i = 0; i < objs.length; i++) {
obj = objs[i];
obj.lockMovementX = true;
obj.lockMovementY = true;
obj.hasControls= false;
canvas.add(obj);
}});
canvas.on("object:selected", function(evt) {
var id = evt.target.id;
if (id.slice(0,3) == 'pin') {
alert(id.slice(3,5));
}
});
<script src="http://www.deltalink.it/andreab/fabric/fabric.js"></script>
<canvas width="600" height="400" id="bb" ></canvas>
One approach is this:
first you have to store an array of coords of each hole on your breadboard image
after you load your background image loop over each entry in that array and create a shape (say, fabric.Circle) over the corresponding hole
right after a shape is created attach a mousedown event handler to this shape
do your click processing in that event handler
Here are a couple of references that can help you with that:
http://fabricjs.com/per-pixel-drag-drop/
mouse:down vs. mousedown in fabric.js
Related
Add filter to SVG dynamically
I have the following SVG image inline on a webpage: const svg = document.getElementById('svg'); const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter'); filter.setAttribute('id', 'image'); filter.setAttribute('x', '0%'); filter.setAttribute('y', '0%'); filter.setAttribute('width', '100%'); filter.setAttribute('height', '100%'); const feImage = document.createElementNS('http://www.w3.org/2000/svg', 'feImage'); feImage.setAttribute('xlink:href', 'http://lorempixel.com/100/100/'); filter.appendChild(feImage); svg.querySelector('defs').appendChild(filter); svg.querySelector('circle').setAttribute('filter', 'url(#image)'); <svg width="200" height="200" viewBox="0 0 200 200" id="svg"> <defs></defs> <circle cx="100" cy="100" r="50" fill="none" stroke-width="2" stroke="gray"></circle> </svg> Now I would like to add an image filter to this svg dynamically and then apply the filter to the circle. But what happens is the circle becomes invisible the filter does not work. When I add the filter to the svg hardcoded everything works just fine: <svg width="200" height="200" viewBox="0 0 200 200" id="svg"> <defs> <filter id="image" x="0%" y="0%" width="100%" height="100%"> <feImage xlink:href="http://lorempixel.com/100/100/"></feImage> </filter> </defs> <circle cx="100" cy="100" r="50" fill="none" stroke-width="2" stroke="gray" filter="url(#image)"></circle> </svg> My question is why doesn't this work?
You need to use: document.createElementNS(…) for svg elements and in this case setAttributeNS(…) as well; For instance change: const filter = document.createElement('filter'); to const filter = document.createElementNS('http://www.w3.org/2000/svg', 'filter'); Additionally change: feImage.setAttribute('xlink:href', 'http://lorempixel.com/100/100/'); to feImage.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', 'http://lorempixel.com/100/100/'); fiddle
move SVG group on path trail based on percentage of whole path trail
I am trying to find a way to move an group (id="avatar") inside an SVG with jQuery based on an percentage of the whole trail of an path element (id="path" > path), inside the SVG. So set the avatar with transform->translate to the right position dynamically for example 20% of the trail. So te input is 20, then it should be set on 20% of the trail of #path > path. I can't find any sort of function or parsing mechanism to archive this goal. Any suggestions? The SVG is used in the browser as an whole SVG html5 element with all their nested SVG tags. So not loade like in an img->src. SVG image: SVG code: <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 600" xml:space="preserve"> <style type="text/css"> .st5{fill:#43A592;stroke:#8C6239;stroke-width:0.5;stroke-miterlimit:10;} .st6{fill:none;stroke:#603813;stroke-width:8;stroke-linecap:square;stroke-miterlimit:10;} .st7{fill:none;stroke:#603813;stroke-width:8;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:5.0414,12.0993;} .st8{fill:#405813;} .st9{fill:#7FBFD6;} </style> <g id="path"> <path class="st7" d="M253.83,291.92C438.6,278.28,338.5,457,422.2,429.99c87.72-28.31-71.17-110.68,22.64-190.57 c54.07-46.05,161.79-22.03,138.18,79.89c-13.69,59.11-53.79,87.21-30.99,132.4c0,0,20.26,23.49,61.35,18.96"/> </g> <g id="avatar" transform="translate(10,20)"> <g> <g> <circle class="st9" cx="276.22" cy="290.06" r="26.83"/> <path class="st8" d="M276.22,317.69c-15.23,0-27.62-12.39-27.62-27.62s12.39-27.62,27.62-27.62s27.62,12.39,27.62,27.62 S291.45,317.69,276.22,317.69z M276.22,264.04c-14.35,0-26.03,11.68-26.03,26.03s11.68,26.03,26.03,26.03 s26.03-11.68,26.03-26.03S290.57,264.04,276.22,264.04z"/> </g> <g> <g> <path class="st16" d="M264.95,293.51c-0.35-0.11-0.74,0.03-0.93,0.35l-4.62,7.56c-0.35,0.58,0.02,1.33,0.7,1.39 c3.16,0.29,11.31,1.43,23.76,5.78c0.44,0.15,0.86-0.3,0.65-0.73C283.15,305.1,278.44,297.84,264.95,293.51z"/> </g> <g> <path class="st16" d="M284.68,279.17c-2.01-6.83-8.8-10.85-15.17-8.97c-0.04,0.01-0.09,0.03-0.13,0.04 c-0.06-0.01-0.13-0.01-0.19-0.02c-0.07,0.05-0.13,0.09-0.19,0.14c-6.04,2.09-9.34,8.94-7.39,15.59c0,0-0.76,2.95-2.22,5.82 c0,0,6.79-0.4,8.31-7.6c0,0,0.02,0.05,0,0l9.33-2.75c0.01,0.03,0,0,0,0c8.13,6.32,13.75,1.44,13.75,1.44 S287.35,280.89,284.68,279.17z"/> </g> <g> <path class="st8" d="M296.91,298.57c-0.04-0.3-0.29-0.52-0.59-0.52h-3.56c-0.33,0-0.6,0.27-0.6,0.6c0,1.34-0.33,1.94-0.6,2.2 c-0.18,0.18-0.4,0.27-0.65,0.26c-0.47-0.01-1.14-0.76-1.62-1.83c-1.25-2.77-3.05-3.78-4.49-4.12v-1.83 c0-0.07,0.06-0.12,0.12-0.12h1.72c0.09,0,0.19-0.02,0.27-0.06c0.25-0.12,0.37-0.39,0.33-0.64c-0.46-2.69-1.3-5.53-1.85-7.27 c3.56-0.05,5.75-1.89,5.78-1.92c0.15-0.13,0.22-0.32,0.2-0.51c-0.02-0.19-0.13-0.36-0.3-0.46c-0.03-0.02-3.07-1.76-5.62-3.38 c-0.17-0.11-0.31-0.28-0.37-0.47c-2.19-6.54-8.67-10.46-14.95-9.07l0.35-0.89c0.12-0.31-0.04-0.67-0.36-0.78 c-0.31-0.11-0.65,0.07-0.77,0.37l-0.34,0.87c-0.05,0.14-0.23,0.19-0.35,0.1l-0.69-0.52c-0.27-0.2-0.65-0.14-0.85,0.13 c-0.19,0.27-0.11,0.64,0.15,0.84l0.74,0.55c-5.7,2.43-8.79,9.05-7.12,15.55c0.05,0.2,0.04,0.4-0.03,0.59 c-0.34,0.99-1.18,3.34-2.03,5.27c-0.07,0.15-0.08,0.32-0.02,0.47c0.09,0.24,0.32,0.38,0.56,0.38c0.01,0,0.03,0,0.04,0 c0.04,0,2.17-0.17,4.39-1.48c0.22,0.56,0.48,1.26,0.69,2.01c-0.4,0.06-0.78,0.29-1,0.66c0,0,0,0,0,0l-4.62,7.56 c-0.28,0.45-0.3,1-0.06,1.47c0.24,0.47,0.69,0.78,1.21,0.83c2.93,0.27,11.11,1.37,23.62,5.75c0.12,0.04,0.25,0.06,0.37,0.06 c0.32,0,0.62-0.13,0.84-0.38c0.3-0.34,0.37-0.83,0.17-1.24c-0.72-1.48-2.29-4.05-5.38-6.8c0.84,0.21,1.68,0.35,2.49,0.42 c0.07,0.01,0.14,0.01,0.2,0.01c0.64,0,1.26-0.23,1.72-0.66c0.47-0.43,0.72-1.02,0.72-1.67v-2.29c2.23,0.86,2.77,2.18,3.39,3.7 c0.38,0.93,0.76,1.89,1.54,2.82c0.8,0.96,1.75,1.43,2.91,1.43c0.27,0,0.56-0.03,0.85-0.08 C296.75,303.92,297.15,300.37,296.91,298.57z M285.22,280.22c1.65,1.04,3.43,2.09,4.44,2.68c-1.61,0.93-5.77,2.54-11.3-1.25 l5.51-1.62C284.32,279.9,284.81,279.97,285.22,280.22z M272.69,270.34c4.78,0,9.32,3.21,11.14,8.16 c0.05,0.15-0.03,0.3-0.18,0.35l-5.99,1.76c-0.1,0.03-0.21-0.03-0.24-0.14c-0.25-1-0.74-2.77-1.58-4.6 c-1.2-2.63-2.68-4.48-4.37-5.47C271.89,270.36,272.29,270.34,272.69,270.34z M269.12,271.08c0.15-0.15,0.37-0.21,0.57-0.15 c4.12,1.11,6.06,7.7,6.59,9.9c0.02,0.1-0.03,0.2-0.13,0.23l-7.73,2.27c-0.1,0.03-0.2-0.02-0.23-0.12 C267.48,281.06,265.68,274.45,269.12,271.08z M266.97,272c-0.94,1.77-1.27,4.06-0.98,6.79c0.22,2.01,0.72,3.77,1.04,4.74 c0.03,0.1-0.02,0.21-0.13,0.24l-4.61,1.35c-0.15,0.04-0.3-0.05-0.34-0.2C260.81,279.76,262.91,274.58,266.97,272z M261.95,286.82c0.08-0.24,0.28-0.42,0.52-0.49l4.57-1.34c-1.35,4.32-4.91,5.64-6.67,6.03 C261.03,289.4,261.63,287.72,261.95,286.82z M283.89,307.97c-12.54-4.37-20.77-5.48-23.74-5.75c-0.16-0.01-0.23-0.13-0.25-0.17 c-0.02-0.05-0.07-0.18,0.01-0.31c0,0,4.62-7.56,4.62-7.56c0.05-0.08,0.15-0.12,0.24-0.09c4.49,1.44,8.93,3.51,12.67,6.42 C280.02,302.53,282.4,305.02,283.89,307.97z M283.61,292.61v6.31c0,0.39-0.19,0.64-0.34,0.79c-0.26,0.24-0.63,0.36-1.02,0.33 c-1.17-0.09-2.44-0.37-3.64-0.79c-1.06-0.37-2.07-0.89-3.02-1.5c-1.62-1.04-3.49-2.05-5.65-2.99l0.5-2.38 c0.07-0.31-0.13-0.6-0.44-0.7c-1.28-0.42-1.67-1.57-1.78-2.09c-0.27-1.19,0.05-2.43,0.76-3.03c1.42-1.2,2.76-0.33,2.89-0.25 c0.24,0.15,0.43,0.18,0.67,0.05c0.11-0.06,0.19-0.19,0.22-0.29c0.29-0.78,0.7-2.03,1.06-3.08l3.08-0.91 c2.69,2.03,5.14,2.88,7.21,3.1c0.49,1.49,1.29,4.12,1.8,6.69c0.02,0.08-0.04,0.15-0.12,0.15h-1.58 C283.88,292.01,283.61,292.28,283.61,292.61z"/> </g> </g> </g> </g> </svg>
In order to get the position of a point on a path you need to use path.getPointAtLength. Here is what I've done: I've moved the avatar in a <defs> element so that I can use it latter. Also I've translated everything in the avatar in the origin of the svg canvas. The <use> elements can get an x and a y attributes in order to be able to position the used element on the svg canvas. In Javascript I'm calculating the x and y for the avatar using the path.getPointAtLength method. In this demo an input type range changes the position of the avatar on the path; In your code you have a transform attribute for the avatar. I'm using this transform for the use element. Also: for the demo I've changed the value of the viewBox attribute of your svg element. You may change it back at what you want. let pathlength = path.getTotalLength(); let pos = path.getPointAtLength(0); theUse.setAttributeNS(null,"x", pos.x); theUse.setAttributeNS(null,"y", pos.y); theRange.addEventListener("input", ()=>{ let perc = parseInt(theRange.value); let leng = pathlength * perc/100; pos = path.getPointAtLength(leng); theUse.setAttributeNS(null,"x", pos.x); theUse.setAttributeNS(null,"y", pos.y); }) svg{border:1px solid;overflow:visible; width:95vh; display:block; margin:1em auto;} <input type="range" id="theRange" value="0"/> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="230 200 400 300" xml:space="preserve"> <style type="text/css"> .st5{fill:#43A592;stroke:#8C6239;stroke-width:0.5;stroke-miterlimit:10;} .st6{fill:none;stroke:#603813;stroke-width:8;stroke-linecap:square;stroke-miterlimit:10;} .st7{fill:none;stroke:#603813;stroke-width:8;stroke-linecap:square;stroke-miterlimit:10;stroke-dasharray:5.0414,12.0993;} .st8{fill:#405813;} .st9{fill:#7FBFD6;} </style> <defs> <g id="avatar" transform="translate(-276.22, -290.06)"> <g> <g> <circle class="st9" cx="276.22" cy="290.06" r="26.83"/> <path class="st8" d="M276.22,317.69c-15.23,0-27.62-12.39-27.62-27.62s12.39-27.62,27.62-27.62s27.62,12.39,27.62,27.62 S291.45,317.69,276.22,317.69z M276.22,264.04c-14.35,0-26.03,11.68-26.03,26.03s11.68,26.03,26.03,26.03 s26.03-11.68,26.03-26.03S290.57,264.04,276.22,264.04z"/> </g> <g> <g> <path class="st16" d="M264.95,293.51c-0.35-0.11-0.74,0.03-0.93,0.35l-4.62,7.56c-0.35,0.58,0.02,1.33,0.7,1.39 c3.16,0.29,11.31,1.43,23.76,5.78c0.44,0.15,0.86-0.3,0.65-0.73C283.15,305.1,278.44,297.84,264.95,293.51z"/> </g> <g> <path class="st16" d="M284.68,279.17c-2.01-6.83-8.8-10.85-15.17-8.97c-0.04,0.01-0.09,0.03-0.13,0.04 c-0.06-0.01-0.13-0.01-0.19-0.02c-0.07,0.05-0.13,0.09-0.19,0.14c-6.04,2.09-9.34,8.94-7.39,15.59c0,0-0.76,2.95-2.22,5.82 c0,0,6.79-0.4,8.31-7.6c0,0,0.02,0.05,0,0l9.33-2.75c0.01,0.03,0,0,0,0c8.13,6.32,13.75,1.44,13.75,1.44 S287.35,280.89,284.68,279.17z"/> </g> <g> <path class="st8" d="M296.91,298.57c-0.04-0.3-0.29-0.52-0.59-0.52h-3.56c-0.33,0-0.6,0.27-0.6,0.6c0,1.34-0.33,1.94-0.6,2.2 c-0.18,0.18-0.4,0.27-0.65,0.26c-0.47-0.01-1.14-0.76-1.62-1.83c-1.25-2.77-3.05-3.78-4.49-4.12v-1.83 c0-0.07,0.06-0.12,0.12-0.12h1.72c0.09,0,0.19-0.02,0.27-0.06c0.25-0.12,0.37-0.39,0.33-0.64c-0.46-2.69-1.3-5.53-1.85-7.27 c3.56-0.05,5.75-1.89,5.78-1.92c0.15-0.13,0.22-0.32,0.2-0.51c-0.02-0.19-0.13-0.36-0.3-0.46c-0.03-0.02-3.07-1.76-5.62-3.38 c-0.17-0.11-0.31-0.28-0.37-0.47c-2.19-6.54-8.67-10.46-14.95-9.07l0.35-0.89c0.12-0.31-0.04-0.67-0.36-0.78 c-0.31-0.11-0.65,0.07-0.77,0.37l-0.34,0.87c-0.05,0.14-0.23,0.19-0.35,0.1l-0.69-0.52c-0.27-0.2-0.65-0.14-0.85,0.13 c-0.19,0.27-0.11,0.64,0.15,0.84l0.74,0.55c-5.7,2.43-8.79,9.05-7.12,15.55c0.05,0.2,0.04,0.4-0.03,0.59 c-0.34,0.99-1.18,3.34-2.03,5.27c-0.07,0.15-0.08,0.32-0.02,0.47c0.09,0.24,0.32,0.38,0.56,0.38c0.01,0,0.03,0,0.04,0 c0.04,0,2.17-0.17,4.39-1.48c0.22,0.56,0.48,1.26,0.69,2.01c-0.4,0.06-0.78,0.29-1,0.66c0,0,0,0,0,0l-4.62,7.56 c-0.28,0.45-0.3,1-0.06,1.47c0.24,0.47,0.69,0.78,1.21,0.83c2.93,0.27,11.11,1.37,23.62,5.75c0.12,0.04,0.25,0.06,0.37,0.06 c0.32,0,0.62-0.13,0.84-0.38c0.3-0.34,0.37-0.83,0.17-1.24c-0.72-1.48-2.29-4.05-5.38-6.8c0.84,0.21,1.68,0.35,2.49,0.42 c0.07,0.01,0.14,0.01,0.2,0.01c0.64,0,1.26-0.23,1.72-0.66c0.47-0.43,0.72-1.02,0.72-1.67v-2.29c2.23,0.86,2.77,2.18,3.39,3.7 c0.38,0.93,0.76,1.89,1.54,2.82c0.8,0.96,1.75,1.43,2.91,1.43c0.27,0,0.56-0.03,0.85-0.08 C296.75,303.92,297.15,300.37,296.91,298.57z M285.22,280.22c1.65,1.04,3.43,2.09,4.44,2.68c-1.61,0.93-5.77,2.54-11.3-1.25 l5.51-1.62C284.32,279.9,284.81,279.97,285.22,280.22z M272.69,270.34c4.78,0,9.32,3.21,11.14,8.16 c0.05,0.15-0.03,0.3-0.18,0.35l-5.99,1.76c-0.1,0.03-0.21-0.03-0.24-0.14c-0.25-1-0.74-2.77-1.58-4.6 c-1.2-2.63-2.68-4.48-4.37-5.47C271.89,270.36,272.29,270.34,272.69,270.34z M269.12,271.08c0.15-0.15,0.37-0.21,0.57-0.15 c4.12,1.11,6.06,7.7,6.59,9.9c0.02,0.1-0.03,0.2-0.13,0.23l-7.73,2.27c-0.1,0.03-0.2-0.02-0.23-0.12 C267.48,281.06,265.68,274.45,269.12,271.08z M266.97,272c-0.94,1.77-1.27,4.06-0.98,6.79c0.22,2.01,0.72,3.77,1.04,4.74 c0.03,0.1-0.02,0.21-0.13,0.24l-4.61,1.35c-0.15,0.04-0.3-0.05-0.34-0.2C260.81,279.76,262.91,274.58,266.97,272z M261.95,286.82c0.08-0.24,0.28-0.42,0.52-0.49l4.57-1.34c-1.35,4.32-4.91,5.64-6.67,6.03 C261.03,289.4,261.63,287.72,261.95,286.82z M283.89,307.97c-12.54-4.37-20.77-5.48-23.74-5.75c-0.16-0.01-0.23-0.13-0.25-0.17 c-0.02-0.05-0.07-0.18,0.01-0.31c0,0,4.62-7.56,4.62-7.56c0.05-0.08,0.15-0.12,0.24-0.09c4.49,1.44,8.93,3.51,12.67,6.42 C280.02,302.53,282.4,305.02,283.89,307.97z M283.61,292.61v6.31c0,0.39-0.19,0.64-0.34,0.79c-0.26,0.24-0.63,0.36-1.02,0.33 c-1.17-0.09-2.44-0.37-3.64-0.79c-1.06-0.37-2.07-0.89-3.02-1.5c-1.62-1.04-3.49-2.05-5.65-2.99l0.5-2.38 c0.07-0.31-0.13-0.6-0.44-0.7c-1.28-0.42-1.67-1.57-1.78-2.09c-0.27-1.19,0.05-2.43,0.76-3.03c1.42-1.2,2.76-0.33,2.89-0.25 c0.24,0.15,0.43,0.18,0.67,0.05c0.11-0.06,0.19-0.19,0.22-0.29c0.29-0.78,0.7-2.03,1.06-3.08l3.08-0.91 c2.69,2.03,5.14,2.88,7.21,3.1c0.49,1.49,1.29,4.12,1.8,6.69c0.02,0.08-0.04,0.15-0.12,0.15h-1.58 C283.88,292.01,283.61,292.28,283.61,292.61z"/> </g> </g> </g> </g> </defs> <g> <path class="st7" id="path" d="M253.83,291.92C438.6,278.28,338.5,457,422.2,429.99c87.72-28.31-71.17-110.68,22.64-190.57 c54.07-46.05,161.79-22.03,138.18,79.89c-13.69,59.11-53.79,87.21-30.99,132.4c0,0,20.26,23.49,61.35,18.96"/> </g> <use id="theUse" transform="translate(0,20)" xlink:href="#avatar" /> </svg>
Use element from response text in JS code
I do some logic to get file content. I have SVG file and I need to read file in code I do this by using $.ajax() function $.ajax({ method: 'get', url: shapes.svg, dataType: 'html' }).then(function (value) { // HTML code from SVG file. console.log(value); }); The problem starts here... Now I have plain text and I need document in order to be able to use JS functions. I need exactly getBBox() So, I want to use something like document.createElment() but it only accepts HTML tag name not all element with its attributes. below is part of the response from SVG file <svg x="0" y="0" width="2200" height="2200" version="1.1" xmlns="http://www.w3.org/2000/svg" id="svgimportshapes" xlink="http://www.w3.org/1999/xlink"> <g xmlns="http://www.w3.org/2000/svg" data-paper-data=""unlocked"" id="ShapeLayer" fill="none" fill-rule="nonzero" stroke="none" stroke-width="none" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"> <text x="1018.68119" y="511.99246" id="text" fill="#000000" stroke="none" stroke-width="1" font-family="helvetica" font-weight="normal" font-size="18" text-anchor="start">Parterre places debout</text> </svg>
You need to add it to DOM first in order to get the bounding box. Below example uses a temp div which is offset -10000px left of the screen, svg is added there and getBBox() returns the value. Remove the element after you get the bbox. It's not an optimal solution but you get the idea. $(document).ready(function(){ var svgstr= '<svg x="0" y="0" width="2200" height="2200" version="1.1" xmlns="http://www.w3.org/2000/svg" id="svgimportshapes" xlink="http://www.w3.org/1999/xlink"> <g xmlns="http://www.w3.org/2000/svg" data-paper-data=""unlocked"" id="ShapeLayer" fill="none" fill-rule="nonzero" stroke="none" stroke-width="none" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="none" style="mix-blend-mode: normal"> <text x="1018.68119" y="511.99246" id="text" fill="#000000" stroke="none" stroke-width="1" font-family="helvetica" font-weight="normal" font-size="18" text-anchor="start">Parterre places debout</text> </svg>' var svgElement = $(svgstr) $("#temp").append(svgElement) var bbox = svgElement[0].getBBox() svgElement.remove() console.log(bbox) }) <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="temp" style="position:absolute;left:-10000px"></div>
how to detect mouseover rects inside SVG
I have simple SVG chart like this: <svg id="ss" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" class="chart" width="1000" height="300" > <g> <rect fill="#aaaaaa" stroke-width="0" stroke="none" height="1" width="1000" y="200" x="0" /> </g> <g class="bar"> <rect height="81.858" width="30" y="118.142" x="10" /> </g> <g class="bar"> <rect height="111.6012" width="30" y="88.3988" x="55" /> </g> <g class="bar"> <rect height="66.98639999999999" width="30" y="133.0136" x="100" /> </g> </svg> How to use pure javascript to detect mouse over the rect element? And knowing which rect element is being over?
What's wrong with directly assigning the event? var rects = document.querySelectorAll( 'rect' ); for( var rect of rects ) { rect.addEventListener( 'mouseover', cb ); } function cb(){ // the "this" object is your reference to the rect hovered over console.log( this ); }
Changing colour using Javascript [duplicate]
I created a SVG file contains 5 polygons, then I need to embed Javascript so 4 of the polygons' color changes to Red when mouseover, and when mouseout, the color changes to Green. I tried to write the code but it didn't work, what could be the problem? Thanks for help and tips! <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> <svg width="26cm" height="24cm" viewBox="0 0 2600 2400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <script type="text/javascript"> <![CDATA[ document.getElementById("test").onmouseover = function(){changeColor()}; function changeColor() { document.getElementById("test").style.color = "red"; } document.getElementById("test").onmouseout = function(){changeColor()}; function changeColor() { document.getElementById("test").style.color = "green"; } ]]> </script> <circle cx="1600" cy="700" r="600" fill="yellow" stroke="black" stroke-width="3"/> <ellipse id="test" cx="1300" cy="500" rx="74" ry="120" fill="blue" stroke="black" stroke-width="3" onmouseover="javascript:red();" onmouseout="javascript:green();"/> <ellipse id="test" cx="1850" cy="500" rx="74" ry="120" fill="blue" stroke="black" stroke-width="3" onmouseover="javascript:red();" onmouseout="javascript:green();"/> <rect id="test" x="1510" y="650" width="160" height="160" fill="blue" stroke="black" stroke-width="3" onmouseover="javascript:red();" onmouseout="javascript:green();"/> <polygon id="test" points="1320,800 1370,1080 1820,1080 1870,800 1820,1000 1370,1000" name="mouth" fill="blue" stroke="black" stroke-width="3" onmouseover="javascript:red();" onmouseout="javascript:green();"/> </svg>
For what you are doing I would recommend using pure CSS. Here is some working code. svg:hover .recolor { fill: red; } As you see, you can just use the :hover event in CSS to recolor the necessary elements. And set them to your default color (green), which will take effect when the user is not hovered.
You have various errors you've two functions called changeColor, functions must have unique names SVG does not use color to colour elements, instead it uses fill (and stroke). id values must be unique, you probably want to replace id by class and then use getElementsByClassName instead of getElementById. If you do that you'll need to cope with more than one element though. I've not completed that part, you should try it yourself so you understand what's going on. I've removed all but one id from my version so you can see it working on the left eye. document.getElementById("test").onmouseover = function(){changeColor()}; function changeColor() { document.getElementById("test").style.fill = "red"; } document.getElementById("test").onmouseout = function(){changeColor2()}; function changeColor2() { document.getElementById("test").style.fill = "green"; } <svg width="26cm" height="24cm" viewBox="0 0 2600 2400" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink"> <circle cx="1600" cy="700" r="600" fill="yellow" stroke="black" stroke-width="3"/> <ellipse id="test" cx="1300" cy="500" rx="74" ry="120" fill="blue" stroke="black" stroke-width="3"/> <ellipse cx="1850" cy="500" rx="74" ry="120" fill="blue" stroke="black" stroke-width="3" /> <rect x="1510" y="650" width="160" height="160" fill="blue" stroke="black" stroke-width="3" /> <polygon points="1320,800 1370,1080 1820,1080 1870,800 1820,1000 1370,1000" name="mouth" fill="blue" stroke="black" stroke-width="3"/> </svg>