gpt4 book ai didi

javascript - 当将canvas转换为svg时只需要裁剪内容

转载 作者:行者123 更新时间:2023-12-01 02:58:09 26 4
gpt4 key购买 nike

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

$(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>

最佳答案

我查看了 Fabric 文档,但找不到任何将 Canvas 的 clipTo 属性传递给生成的 SVG 的方法。所以我认为将 SVG 图像裁剪为圆形的最佳(唯一)方法是在其中插入一些额外的 SVG 元素。我不会逐段解释,而是粘贴一些我为此想出的带注释的 JS 代码。

$(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>

我注意到欢迎文本的一部分被剪掉了,但我将让您来移动它。

关于javascript - 当将canvas转换为svg时只需要裁剪内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46603510/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com