Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

d3, html in svg, animating opacity takes div out of position, why?

Some context:

I've made a force layout, and I've attached divs to my svg g nodes, so that I can display nice paragraphs of text. I'm trying to create transitions that fade out the inserted divs.

The problem:

Whenever I initiate a transition on the opacity style attribute of my div, it pops out of the positioning flow. I've isolated the issue in the linked fiddle. It's not related to the force layout, but I am using the foreign elements so that I can place html in a svg-based force layout.

here's an example, and the fiddle:

var foreign = d3.select("body")
    .append("svg")
    .attr("height", 200)
    .attr("width", 300)
    .append("svg:g")
    .attr("transform", 
          "translate(40, 20)")
    .append("svg:foreignObject")
    .attr("width", "100px")
    .attr("height", "50px");

var outer = foreign.append("xhtml:div")
    .attr("class", "outer");

var inner = outer.append("xhtml:div")
    .attr("class", "inner")
    .text("inner div");

outer.transition()
    .duration(3000)
    .style("opacity", 0.0);

And a screenshot visual, from the fiddle (note how it seems to duplicate the div)

state right before transition:

enter image description here

state during transition:

enter image description here

I'm using Chrome 28 on OS X 10.6.8 to view it. It gets even funkier on Safari, with elements flashing in and out of visibility.

like image 609
BenjaminGolder Avatar asked Nov 12 '22 23:11

BenjaminGolder


1 Answers

The problem still does not seem to be fixed on Google Chrome (v49.0.2623.110). Here's a fiddle still showing the issue for me.

<svg width="500">
  <g transform="translate(0,50)">
    <foreignObject width="500" height="200">
      <fieldset>
        <input type="text" value="A" style="opacity: 0.9;">
        <input type="text" value="B" style="opacity: 1;">
      </fieldset>
    </foreignObject>
  </g>
</svg>

Seems the combination of 'g:translate' and 'foreignObject' is not well handled with webkit browsers. Apparently, "transferring" the vertical/horizontal shift from the 'g:translate' to the 'x' or 'y' tags of the foreign objects fix the problem. Proof here.

<svg width="500">
  <g>
    <foreignObject width="500" height="200" y="50">
      <fieldset>
        <input type="text" value="A" style="opacity: 0.9;">
        <input type="text" value="B" style="opacity: 1;">
      </fieldset>
    </foreignObject>
  </g>
</svg>
like image 151
Adrien Baland Avatar answered Nov 15 '22 11:11

Adrien Baland