premasagar / pablo

Pablo is a lightweight, expressive JavaScript SVG library. Pablo creates interactive drawings with SVG (Scalable Vector Graphics), giving access to all of SVG's granularity and power.
https://pablojs.com
MIT License
413 stars 16 forks source link

dataUrl should support all svg elements but don't convert svg:clipPath nor svg:image #100

Open miromarchi opened 7 years ago

miromarchi commented 7 years ago

Hi, I'm trying to convert D3 code with inline styles to .png image. Everything is included in the generated image except <defs><clipPath... and <image ... Is this known or I am doing something wrong? Is there any workaround? Thanks!!!

premasagar commented 7 years ago

Hi @miromarchi - thanks for the report. From a quick test I don't see that happening. Could you share a stripped-down version of the svg markup and your code? What browser are you using (there is an issue reported for IE11, #99)?

miromarchi commented 7 years ago

Hi. thanks for replying. I switched to a very different way of having the images, so I am not generating from svg anymore. But, for this issue's sake, here is my test code.

<html>
<script type="text/javascript" src="./pablo.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>

<body>
  <script type="text/javascript">
  data = [10, 20, 30, 40, 50];
  let svg = d3.select('body').append('svg')
    .attr('id', 'pablo-svg')
    .attr("width", 500).attr("height", 500);
  // .style("background-color", "yellow");

  let clip = svg.append('defs')
    .append('clipPath')
    .attr('id', 'pablo-clip')
    .append('svg:circle')
    .attr('cx', 250)
    .attr('cy', 250)
    .attr('r', 150);

  svg.selectAll('circle')
    .data(data)
    .enter()
    .append('circle')
    .attr("r", 45)
    .style("fill", "purple")
    .attr("cx", d => 25 * d / 3).attr("cy", d => 25 * d / 3);

  let image = svg.append('svg:image')
    .attr('xlink:href', 'image.jpg')
    .attr('clip-path', 'url(#pablo-clip)')
    .attr('width', 400)
    .attr('height', 500)
    .attr('x', 0)
    .attr('y', 0)
    .style('opacity', 1);

  let pabloSvg = Pablo('#pablo-svg');
  let download = pabloSvg.download('jpeg', 'circle.jpg', function(result) {
    // alert(result.error ? 'Fail' : 'Success');
  });

  let pabloImg = pabloSvg.toImage();
  pabloImg.appendTo(pabloSvg);
  </script>
</body>

</html>

if you put some image.jpg in the same dir, you could see that only the purple dots are included in the generated image. Right? I'm on linux, chrome

premasagar commented 7 years ago

Thanks a lot for it. I'll look into it when I'm next in the Pablo zone.

I wonder if the same happens if the SVG is generated with Pablo, rather than d3. Possibly an issue with the namespaced attribute xlink:href not being applied properly? Do you need to add the attribute xmlns:xlink="http://www.w3.org/1999/xlink" to the svg element?

miromarchi commented 7 years ago

Thank you!

I just added

    .attr('xmlns', 'http://www.w3.org/2000/svg')
    .attr('xmlns:xlink', 'http://www.w3.org/1999/xlink')

to the svg. Is what you meant? No changes though.