将canvas转换为svg时只需要裁剪内容 [英] when convert canvas to svg need only cropped content

查看:1127
本文介绍了将canvas转换为svg时只需要裁剪内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用HTML5 CANVAS和fabric js。最后将它转换为SVG.we可以上传图像并裁剪成圆形,矩形,...。图像也被裁剪并在其上添加文字。我面临的问题是图像没有被裁剪成svg.It显示像下面的完整图像。我已经尝试 viewBox 也在 toSVG 。请建议我做什么或如果我是做错了。

I am using the HTML5 CANVAS with fabric js. Finally will be converted it into SVG.we can upload images and crop into circle,rectangle,.. .The image also being cropped and added text on it.The problem which i am facing is the images are not being cropped into svg.It shows full images like below.i have tried viewBox also in toSVG.Please suggest me what to do or if i am doing anything wrong.

$(function(){
var canvas = new fabric.Canvas('Canvas',{backgroundColor: '#ffffff',preserveObjectStacking: true});
canvas.clipTo = function (ctx) {
ctx.arc(250, 300, 200, 0, Math.PI*2, true);
};

fabric.Image.fromURL('https://fabric-canvas.s3.amazonaws.com/Tulips.jpg', function(oImg) {
              canvas.add(oImg);
            });       
            
canvas.add(new fabric.IText('Welcome ', {
              left : fabric.util.getRandomInt(50,50),
              top:fabric.util.getRandomInt(430, 430)
              }));
              
       
            canvas.renderAll();
            

$('#tosvg_').on('click',function(){
$('#svgcontent').html(canvas.toSVG());
});
            
});
            
            

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.18/fabric.js"></script>

<div class="container">
    <div id='canvascontain' width='1140' height='600' style='left:0px;background-color:rgb(240,240,240)'>
    <canvas id="Canvas" width='1140' height='600'></canvas>
    </div>
    
    <input type='button' id='tosvg_' value='create SVG'>
    <div id='svgcontent'></div>

推荐答案

我查看了结构文档,找不到任何方法将画布的 clipTo 属性传递给生成的SVG。因此,我认为将SVG图像裁剪为圆形的最佳(唯一)方法是在其中插入一些额外的SVG元素。我不是一块一块地解释,而是粘贴一些我想出的注释JS代码。

I looked through the fabric documentation and could not find any methods for carrying over the canvas's clipTo property to the generated SVG. So I think the best (only) way to crop the SVG image to a circle, is to insert some additional SVG elements into it. Rather than explaining piece by piece, I'll just paste some commented JS code I came up with for this.

$(function(){
  var canvas = new fabric.Canvas('Canvas',{backgroundColor: '#ffffff',preserveObjectStacking: true});
  canvas.clipTo = function (ctx) {
    ctx.arc(250, 300, 200, 0, Math.PI*2, true);
  };
  
  // Using a JQuery deferred object as a promise.  This is used to
  // synchronize execution, so that the SVG is never created before
  // the image is added to the canvas.
  var dImageLoaded = $.Deferred();
  
  fabric.Image.fromURL('https://fabric-canvas.s3.amazonaws.com/Tulips.jpg', function(oImg) {
    // Insert the image object below any existing objects, so that
    // they appear on top of it.  Then resolve the deferred.
    canvas.insertAt(oImg, 0);
    dImageLoaded.resolve();
  });
  
  canvas.add(new fabric.IText('Welcome ', {
    left : fabric.util.getRandomInt(50,50),
    top:fabric.util.getRandomInt(430, 430)
  }));
  
  canvas.renderAll();
  
  
  $('#tosvg_').on('click',function(){
    // Wait for the deferred to be resolved.
    dImageLoaded.then(function () {
      // Get the SVG string from the canvas.
      var svgString = canvas.toSVG({
        viewBox: {
          x: 50,
          y: 100,
          width: 400,
          height: 400,
        },
        width: 400,
        height: 400,
      });
      
      // SVG content is not HTML, nor even standard XML, so doing
      // $(svgString) might mutilate it.  Therefore, even though we
      // will be modifying the SVG before displaying it, we need to
      // insert it straight into the DOM before we can get a JQuery
      // selector to it.
      
      // The plan is to hide the svgcontent div, append the SVG,
      // modify it, and then show the svcontent div, to prevent the
      // user from seeing half-baked SVG.
      var $svgcontent = $('#svgcontent').hide().html(svgString);
      var $svg = $svgcontent.find('svg');
      
      // Create some SVG elements to represent the clip path, and
      // append them to $svg.  To create SVG elements, we need to use
      // document.createElementNS, not document.createElement, which
      // is also what $('<clipPath>') and $('<circle>') would call.
      var $clipPath = $(document.createElementNS('http://www.w3.org/2000/svg', 'clipPath'))
          .attr('id', 'clipCircle')
          .appendTo($svg);
      var $circle = $(document.createElementNS('http://www.w3.org/2000/svg', 'circle'))
          .attr('r', 200)
          .attr('cx', 250)
          .attr('cy', 300)
          .appendTo($clipPath);
      
      // This part is brittle, since it blindly writes to the
      // transform attributes of the image and text SVG elements.
      
      // SVG clip paths clip content relative to the pre-transformed
      // coordinates of the element.  The canvas.toSVG method places
      // the image and the text each inside of group elements, and
      // transforms the group elements.  It does not transform the
      // image and text.  Because transforms work equally well on
      // image and text as on groups, we move the transform attribute
      // from the two groups to their contents.  Then, we can use the
      // same clip-path on all groups.
      
      // If the contents of the groups already had transforms, we
      // would need to create multiple clip paths - one for each group
      // - based on the groups' transforms.
      $svg.find('g').each(function () {
        var $g = $(this);
        // Move transform attribute from group to its children, and
        // give the group a clip-path attribute.
        $g.children().attr('transform', $g.attr('transform'));
        $g.removeAttr('transform').attr('clip-path', 'url(#clipCircle)');
      });
      $('#svgcontent').show();
    });
  });
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.18/fabric.js"></script>

<div class="container">
    <div id='canvascontain' width='1140' height='600' style='left:0px;background-color:rgb(240,240,240)'>
    <canvas id="Canvas" width='1140' height='600'></canvas>
    </div>
    
    <input type='button' id='tosvg_' value='create SVG'>
    <div id='svgcontent'></div>
</div>

我注意到欢迎文字的一部分会被修剪,但我会留给你移动它。

I noticed that part of the Welcome text gets clipped, but I'll leave it to you to move that.

这篇关于将canvas转换为svg时只需要裁剪内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆