用jv中的svg捕获整个div

时间:2017-05-05 07:18:02

标签: javascript jquery html svg

我想将整个div作为图像捕获并保存在本地以进行校对。我已经搜索并阅读了很多关于svg的文章到图像或div到图像。

我为此尝试了一些js库。但是当我尝试从div捕获图像时,有些只捕获div内容,而有些只捕获svg内容。

s.jpga.jpg

html2canvas(contentDiv, {
    onrendered: function(can) {
      dirty.appendChild(can);
    }
  });
// first convert your svg to png
exportInlineSVG(svg, function(data, canvas) {
  svg.parentNode.replaceChild(canvas, svg);
  // then call html2canvas
  html2canvas(contentDiv, {
    onrendered: function(can) {
      can.id = 'canvas';
      clean.appendChild(can);
    }
  });
})


function exportInlineSVG(svg, receiver, params, quality) {
  if (!svg || !svg.nodeName || svg.nodeName !== 'svg') {
    console.error('Wrong arguments : should be \n exportSVG(SVGElement, function([dataURL],[canvasElement]) || IMGElement || CanvasElement [, String_toDataURL_Params, Float_Params_quality])')
    return;
  }

  var xlinkNS = "http://www.w3.org/1999/xlink";
  var clone;
  // This will convert an external image to a dataURL
  var toDataURL = function(image) {

    var img = new Image();
    // CORS workaround, this won't work in IE<11
    // If you are sure you don't need it, remove the next line and the double onerror handler
    // First try with crossorigin set, it should fire an error if not needed
    img.crossOrigin = 'Anonymous';

    img.onload = function() {
      // we should now be able to draw it without tainting the canvas
      var canvas = document.createElement('canvas');
      var bbox = image.getBBox();
      canvas.width = bbox.width;
      canvas.height = bbox.height;
      // draw the loaded image
      canvas.getContext('2d').drawImage(this, 0, 0, bbox.width, bbox.height);
      // set our original <image>'s href attribute to the dataURL of our canvas
      image.setAttributeNS(xlinkNS, 'href', canvas.toDataURL());
      // that was the last one
      if (++encoded === total) exportDoc()
    }

    // No CORS set in the response    
    img.onerror = function() {
        // save the src
        var oldSrc = this.src;
        // there is an other problem
        this.onerror = function() {
            console.warn('failed to load an image at : ', this.src);
            if (--total === encoded && encoded > 0) exportDoc();
          }
          // remove the crossorigin attribute
        this.removeAttribute('crossorigin');
        // retry
        this.src = '';
        this.src = oldSrc;
      }
      // load our external image into our img
    img.src = image.getAttributeNS(xlinkNS, 'href');
  }

  // The final function that will export our svgNode to our receiver
  var exportDoc = function() {
      // check if our svgNode has width and height properties set to absolute values
      // otherwise, canvas won't be able to draw it
      var bbox = svg.getBBox();
      // avoid modifying the original one
      clone = svg.cloneNode(true);
      if (svg.width.baseVal.unitType !== 1) clone.setAttribute('width', bbox.width);
      if (svg.height.baseVal.unitType !== 1) clone.setAttribute('height', bbox.height);

      parseStyles();

      // serialize our node
      var svgData = (new XMLSerializer()).serializeToString(clone);
      // remember to encode special chars
      var svgURL = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(svgData);

      var svgImg = new Image();

      svgImg.onload = function() {
        // if we set a canvas as receiver, then use it
        // otherwise create a new one
        var canvas = (receiver && receiver.nodeName === 'CANVAS') ? receiver : document.createElement('canvas');
        // IE11 doesn't set a width on svg images...
        canvas.width = this.width || bbox.width;
        canvas.height = this.height || bbox.height;
        canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height);

        // try to catch IE
        try {
          // if we set an <img> as receiver
          if (receiver.nodeName === 'IMG') {
            // make the img looks like the svg
            receiver.setAttribute('style', getSVGStyles(receiver));
            receiver.src = canvas.toDataURL(params, quality);
          } else {
            // make the canvas looks like the canvas
            canvas.setAttribute('style', getSVGStyles(canvas));
            // a container element
            if (receiver.appendChild && receiver !== canvas)
              receiver.appendChild(canvas);
            // if we set a function
            else if (typeof receiver === 'function')
              receiver(canvas.toDataURL(params, quality), canvas);
          }
        } catch (ie) {
          console.warn("Your ~browser~ has tainted the canvas.\n The canvas is returned");
          if (receiver.nodeName === 'IMG') receiver.parentNode.replaceChild(canvas, receiver);
          else receiver(null, canvas);
        }
      }
      svgImg.onerror = function(e) {
        if (svg._cleanedNS) {
          console.error("Couldn't export svg, please check that the svgElement passed is a valid svg document.");
          return;
        }
        // Some non-standard NameSpaces can cause this issues
        // This will remove them all
        function cleanNS(el) {
          var attr = el.attributes;
          for (var i = 0; i < attr.length; i++) {
            if (attr[i].name.indexOf(':') > -1) el.removeAttribute(attr[i].name)
          }
        }
        cleanNS(svg);
        for (var i = 0; i < svg.children.length; i++)
          cleanNS(svg.children[i]);
        svg._cleanedNS = true;
        // retry the export
        exportDoc();
      }
      svgImg.src = svgURL;
    }
    // ToDo : find a way to get only usefull rules
  var parseStyles = function() {
    var styleS = [],i;
    // transform the live StyleSheetList to an array to avoid endless loop
    for (i = 0; i < document.styleSheets.length; i++)
      styleS.push(document.styleSheets[i]);
    // Do we have a `<defs>` element already ?
    var defs = clone.querySelector('defs') || document.createElementNS('http://www.w3.org/2000/svg', 'defs');
    if (!defs.parentNode)
      clone.insertBefore(defs, clone.firstElementChild);

    // iterate through all document's stylesheets
    for (i = 0; i < styleS.length; i++) {
      var style = document.createElement('style');
      var rules = styleS[i].cssRules,
        l = rules.length;
      for (var j = 0; j < l; j++)
        style.innerHTML += rules[j].cssText + '\n';

      defs.appendChild(style);
    }
    // small hack to avoid border and margins being applied inside the <img>
    var s = clone.style;
    s.border = s.padding = s.margin = 0;
    s.transform = 'initial';
  }
  var getSVGStyles = function(node) {
    var dest = node.cloneNode(true);
    svg.parentNode.insertBefore(dest, svg);
    var dest_comp = getComputedStyle(dest);
    var svg_comp = getComputedStyle(svg);
    var mods = "";
    for (var i = 0; i < svg_comp.length; i++) {
      if (svg_comp[svg_comp[i]] !== dest_comp[svg_comp[i]])
        mods += svg_comp[i] + ':' + svg_comp[svg_comp[i]] + ';';
    }
    svg.parentNode.removeChild(dest);
    return mods;
  }

  var images = svg.querySelectorAll('image'),
    total = images.length,
    encoded = 0;
  // Loop through all our <images> elements
  for (var i = 0; i < images.length; i++) {
    // check if the image is external
    if (images[i].getAttributeNS(xlinkNS, 'href').indexOf('data:image') < 0)
      toDataURL(images[i]);
    // else increment our counter
    else if (++encoded === total) exportDoc()
  }
  // if there were no <image> element
  if (total === 0) exportDoc();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div id="contentDiv" style="width: 50%;">
  <img class="" src="s.jpg" width="75%">
  <svg xmlns="http://www.w3.org/2000/svg" id="svg" height="100%">
    <defs>  
      <clipPath id="my-path">
        <text id="texty" style="font-weight:bold;" x="60" y="300" font-size="60">test</text>
      </clipPath>
    </defs>
    <image xlink:href="a.jpg" clip-path="url(#my-path)" width="100%" height="100%" id="filler" preserveAspectRatio="none"></image>
  </svg>
</div>
<div id="clean">clean:<br></div>
<div id="dirty">dirty :<br></div>
<style type="text/css">
 svg {
  position: relative; 
  top: -531px;
  left: 120px;
 }
</style>

我附上了三张照片。 s.jpg图像是我在主div中的主要图像。用户可以用纹理颜色写出自己的名字是主图像。要写文本我在主div中使用了svg,而对于纹理,我使用a.jpg作为隐藏图像。

我使用html2canvas js库将div转换为图像但我没有得到我想要的输出。请帮我找出解决这个问题的方法。 Thanx提前

0 个答案:

没有答案