Jump to content

JavaScript SVG change use attribute


JacekQ

Recommended Posts

Hello, I would like to have script that will highlight row and column on SVG. I've done something like this:

<html><body>  <svg id="svg_img" width="100" height="100" viewBox="0 0 100 100">    <rect id="vbox_0" x="0" y="0" width="20" height="100" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="vbox_1" x="20" y="0" width="20" height="100" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="vbox_2" x="40" y="0" width="20" height="100" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="vbox_3" x="60" y="0" width="20" height="100" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="vbox_4" x="80" y="0" width="20" height="100" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="hbox_0" x="0" y="0" width="100" height="20" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="hbox_1" x="0" y="20" width="100" height="20" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="hbox_2" x="0" y="40" width="100" height="20" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="hbox_3" x="0" y="60" width="100" height="20" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <rect id="hbox_4" x="0" y="80" width="100" height="20" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />    <script>      var         svg = document.getElementById('svg_img'),         pt = svg.createSVGPoint(),         hbox_prev = '',         vbox_prev = '';			      svg.addEventListener('mouseout', function(evt)      {        if (hbox_prev != '')        {          box = document.getElementById(hbox_prev);          box.setAttribute('fill', 'white');          box.setAttribute('fill-opacity', '0.1');        };        hbox_prev = '';        if (vbox_prev != '')        {          box = document.getElementById(vbox_prev);          box.setAttribute('fill', 'white');          box.setAttribute('fill-opacity', '0.1');        };        vbox_prev = '';      }, false);		      svg.addEventListener('mousemove',function(evt)      {        var loc = cursorPoint(evt);			        var box_id = 'hbox_' + Math.floor(loc.y / 20);        var box = document.getElementById(box_id);        box.setAttribute('fill', 'red');        box.setAttribute('fill-opacity', '0.5');        if ((hbox_prev != '') && (hbox_prev != box_id))         {          box = document.getElementById(hbox_prev);          box.setAttribute('fill', 'white');          box.setAttribute('fill-opacity', '0.1');        };			        hbox_prev = box_id;        box_id = 'vbox_' + Math.floor(loc.x / 20);        box = document.getElementById(box_id);        box.setAttribute('fill', 'red');        box.setAttribute('fill-opacity', '0.5');        if ((vbox_prev != '') && (vbox_prev != box_id))         {          box = document.getElementById(vbox_prev);          box.setAttribute('fill', 'white');          box.setAttribute('fill-opacity', '0.1');        };        vbox_prev = box_id;      }, false);      function cursorPoint(evt)      {        pt.x = evt.clientX;         pt.y = evt.clientY;        return pt.matrixTransform(svg.getScreenCTM().inverse());      }    </script>	  </svg></body></html>

And it's working. But I'm trying to use defs and I don't know how to change fill, fill-opacity attributes with use element.

<html><body><svg id="svg_img" width="100" height="100" viewBox="0 0 100 100">  <defs>    <rect id="box" x="0" y="0" width="20" height="20" stroke="grey" stroke-width="1" fill="white" fill-opacity="0.1" />  </defs>    <use id="vbox_0" xlink:href="#box" transform="scale(1, 5)" />  <use id="vbox_1" xlink:href="#box" transform="scale(1, 5) translate(20)" />  <use id="vbox_2" xlink:href="#box" transform="scale(1, 5) translate(40)" />  <use id="vbox_3" xlink:href="#box" transform="scale(1, 5) translate(60)" />  <use id="vbox_4" xlink:href="#box" transform="scale(1, 5) translate(80)" />    <use id="hbox_0" xlink:href="#box" transform="scale(5, 1)" />  <use id="hbox_1" xlink:href="#box" transform="scale(5, 1) translate(0, 20)" />  <use id="hbox_2" xlink:href="#box" transform="scale(5, 1) translate(0, 40)" />  <use id="hbox_3" xlink:href="#box" transform="scale(5, 1) translate(0, 60)" />  <use id="hbox_4" xlink:href="#box" transform="scale(5, 1) translate(0, 80)" />    <script>    var       svg = document.getElementById('svg_img'),       pt = svg.createSVGPoint(),        box = SVGRectElement,       hbox_prev = '',       vbox_prev = '';          svg.addEventListener('mouseout', function(evt)    {      if (hbox_prev != '')      {        box = document.getElementById(hbox_prev);        box.setAttribute('fill', 'white');        box.setAttribute('fill-opacity', '0.1');      };            hbox_prev = '';            if (vbox_prev != '')      {        box = document.getElementById(vbox_prev);        box.setAttribute('fill', 'white');        box.setAttribute('fill-opacity', '0.1');      };            vbox_prev = '';    }, false);        svg.addEventListener('mousemove',function(evt)    {      var loc = cursorPoint(evt);            var box_id = 'hbox_' + Math.floor(loc.y / 20);      box = svg.getElementById(box_id);      box.setAttribute('fill', 'red');      box.setAttribute('fill-opacity', '0.5');            if ((hbox_prev != '') && (hbox_prev != box_id))       {        box = svg.getElementById(hbox_prev);        box.setAttribute('fill', 'white');        box.setAttribute('fill-opacity', '0.1');      };            hbox_prev = box_id;            box_id = 'vbox_' + Math.floor(loc.x / 20);      box = svg.getElementById(box_id);      box.setAttribute('fill', 'red');      box.setAttribute('fill-opacity', '0.5');            if ((vbox_prev != '') && (vbox_prev != box_id))       {        box = svg.getElementById(vbox_prev);        box.setAttribute('fill', 'white');        box.setAttribute('fill-opacity', '0.1');      };            vbox_prev = box_id;    }, false);    function cursorPoint(evt)    {      pt.x = evt.clientX;       pt.y = evt.clientY;      return pt.matrixTransform(svg.getScreenCTM().inverse());    }  </script></svg></body></html>

Is there a way to change use element attribute?

--

Best regards

Jacek Q.

Link to comment
Share on other sites

It doesn't work. If you save second example and open it in browser then move cursor over image and choose check element you will see something like this

<use id="vbox_1" transform="scale(1, 5) translate(20)" xlink:href="#box"></use><use id="vbox_2" transform="scale(1, 5) translate(40)" xlink:href="#box"></use><use id="vbox_3" transform="scale(1, 5) translate(60)" xlink:href="#box"></use><use id="vbox_4" transform="scale(1, 5) translate(80)" xlink:href="#box" fill="red" fill-opacity="0.5"></use><use id="hbox_0" transform="scale(5, 1)" xlink:href="#box"></use><use id="hbox_1" transform="scale(5, 1) translate(0, 20)" xlink:href="#box"></use><use id="hbox_2" transform="scale(5, 1) translate(0, 40)" xlink:href="#box"></use><use id="hbox_3" transform="scale(5, 1) translate(0, 60)" xlink:href="#box"></use><use id="hbox_4" transform="scale(5, 1) translate(0, 80)" xlink:href="#box" fill="red" fill-opacity="0.5"></use>

But there are no red boxes on the image :(

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...