如何在SVG上绘制形状与给定图像数据完全相同的Polyline对象

时间:2019-04-12 04:43:48

标签: javascript svg canvas

Doughnut picture

例如,给定上面的图像,我想要做的是在SVG上绘制完全相同形状的折线对象(我创建了一个“绘图”,或者我应该说基于SVG的“画笔”工具,这就是为什么我使用折线,以便用户可以用鼠标绘画,甚至可以用橡皮擦使用他或她的鼠标)。以下是我将如何实现这一目标。

  1. 在画布上下文上绘制给定图像。
  2. 获取所有颜色为#000000的像素的坐标。
  3. 使用该坐标列表在SVG上创建一条折线。

,通过这个过程,我得到了doughnut drawin with svg polyline的结果(现在这只是一个丑陋的示例结果,因为我不得不用手手工绘制它。但是我的目的是使形状相同输入图片)

但是我不确定这是否是唯一的方法,甚至不确定我是否应该坚持使用SVG。还有其他好的方法可以做到这一点吗?还是使用画布代替SVG会更容易?

2 个答案:

答案 0 :(得分:2)

可以用圆形绘制此形状。
使用由圆圈组成的蒙版制作的切口

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
    width="405" height="401" viewBox="0 0 405 401" >  
<defs>
<mask id="msk1" >
	<rect width="100%" height="100%" fill="white" />
<g fill="black">
	<circle cx="202" cy="200" r="40"   />
	<circle cx="260" cy="298" r="40"   />
	<circle cx="215" cy="303" r="20"   />
</g>
</mask>
</defs>	
<circle cx="202" cy="200" r="98"  fill="black" mask="url(#msk1)" />

答案 1 :(得分:1)

这是假设您已经有一个SVG路径。

要绘制多边形,您将需要使用M命令来分割路径。在下一个示例中,我手动进行了操作,但是您可以动态地进行操作。这很重要,因为否则您将在多边形中被分割。

您还需要设置精度,即多边形点之间的距离。

请阅读我的代码中的注释。

let paths = document.querySelectorAll("#theGroup path");
let precision = 5;//how far one of other the points of the polygon are
let points = [];// the array of points

// for each path in the array of paths 
paths.forEach(p=>{
  // get the total length
  let totalLength = p.getTotalLength();
  // get the number of points for the polygon in base of the precision
  let numPoints = ~~(totalLength / precision);
  // calculate the segment length
  let segmentLength = totalLength / numPoints;
 
  for(let i = 0; i <= numPoints; i++ ){
  let point = p.getPointAtLength(i*segmentLength);
  // get the coordinates of this point and push it
  points.push(point.x);
  points.push(point.y);
}
})

//set the value for the points attribute of the polygon
poly.setAttributeNS(null,"points", points.join())
svg{border:1px solid; width:90vh;}
path{fill:none}
<svg viewBox="0 0 531 531">
<g id="theGroup">
	<path id="donut" d="M268.64,76.066c70.065,2.632,125.154,32.347,163.73,91.372
		c14.944,22.864,23.47,48.161,27.698,75.22c3.987,25.512,2.188,50.551-3.64,75.354c-4.821,20.522-13.383,39.648-24.866,57.406
		c-2.003,3.099-3.899,3.396-7.365,1.548c-30.011-16.005-64.509-10.767-87.731,14.13c-6.295,6.748-9.985,15.893-15.108,23.783
		c-1.548,2.384-3.508,5.256-5.938,6.189c-19.202,7.375-32.874,20.547-41.279,39.064c-1.911,4.211-4.254,5.562-8.308,5.085
		c-13.198-1.554-26.507-2.515-39.562-4.873c-30.46-5.502-57.275-19.262-81.055-38.724c-28.703-23.491-49.496-52.646-61.424-88.046
		c-7.479-22.198-11.34-44.892-10.42-68.225c2.042-51.761,20.944-96.305,57.854-133.023c22.272-22.156,48.427-37.859,78.3-47.183
		C228.671,79.17,248.365,75.884,268.64,76.066z"/> 
                      
<path id="hole" d="M340.466,271.259c0.179-40.212-32.175-73.14-72.067-73.348
		c-40.072-0.208-73.264,32.326-73.485,72.032c-0.226,40.441,32.218,73.372,72.436,73.522
		C307.646,343.616,340.286,311.382,340.466,271.259z"/>
</g>
  
  <polygon id="poly" fill="gold" points = "" />
</svg>