Fabric.js fillRule-偶数(减去形状) [英] Fabric.js fillRule - evenodd (subtract shapes)

查看:174
本文介绍了Fabric.js fillRule-偶数(减去形状)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在fabric.js中使用fillRule ='evenodd'在多边形上打孔

I am trying to do hole in the polygon using fillRule = 'evenodd' in fabric.js

globalCompositeOperation对我不起作用,因为我需要查看多边形孔中的形状 像这样

globalCompositeOperation won't work for me, because I need to see shape in the polygon hole like this

这是我的代码:小提琴

有2个示例:

  • Fabric.js 2个多边形(无效)
  • 原生html5 canvas 2多边形(有效)

当我为fabric.js多边形设置fillRule:'evenodd'时,它将转到fabric函数,并将上下文填充设置为'eveneodd'

When I set fillRule: 'evenodd' for fabric.js polygon, it is going to the fabric function and it's setting context fill to 'eveneodd'

_renderFill: function(ctx) {
   ...
      if (this.fillRule === 'evenodd') {
        ctx.fill('evenodd');
      }
      ...
      ctx.restore();
    },

但是仍然不起作用. 请给我一些想法,如果fabric.js,如何使用"enevodd"

But still it doesn't work. Please, give my some idea how to use 'enevodd' if fabric.js

推荐答案

'evenodd'填充规则仅适用于一个结构对象.即使使用组对象,也不能对单独的对象使用此规则并将它们组合在一起.在单独渲染形状的组渲染中,这意味着每个对象都将调用:

The 'evenodd' fill rule works fine with one fabric object. You cannot use this rule for separate objects and combine them together, even if you are using a group object. In a group rendering for the shapes happening separately, which means every object calls:

context.fill(); 

context.fill('evenodd')

Fabric.js中缺少对多个对象使用'evenodd'规则的功能.

Using 'evenodd' rule for multiple objects is missing feature in the Fabric.js.

这是一些解决方法,如何对一个主题多边形和多个减去的多边形使用"evenodd"规则.

Here is some workaround how to use 'evenodd' rule for one subjects polygon and multiple subtracted polygons.

步骤:

  1. 找到减去的多边形到主题多边形的最后一点的最近点.
  2. 按最近的索引对减去的多边形数组进行排序
  3. 将主体与多边形相减成一个.

这里是小提琴.

此代码需要改进.它给出了一个如何使用"evenodd"规则在多边形上打孔的想法.

This code needs to be improved. It gives an idea how to make holes in the polygon using 'evenodd' rule.

var canvas = new fabric.Canvas('c', { selection: false });
var polygons = [];

var subjectPoly = [{x:30,y:10}, {x:300,y:50}, {x:20,y:290}];
var subtractPoly1 = [{x:50,y:50}, {x:200,y:140}, {x:220,y:40}];
var subtractPoly2 = [{x:10,y:10}, {x:300,y:200}, {x:60,y:150}];
var subtractPoly = [];
subtractPoly.push(subtractPoly1);
subtractPoly.push(subtractPoly2);

 var result = combinePolygonArrays(subjectPoly,sortPolygonArray(subtractPoly, closetPoint(subjectPoly[0],subtractPoly)));
  var poly1 = new fabric.Polygon(result, {
  	 fillRule: 'evenodd',
     fill: 'green',
     selectable: false      });      
  canvas.add( poly1);
var c= (new fabric.Circle({
    radius: 50,
    left: 125,
    top: 50,
    fill: 'red'
}));

canvas.add(c);
c.sendToBack();
  
function closetPoint(subjPolyPoint, subtrPoly){
	var minIndexes = [];
	for (var j in subtrPoly){
  	var minLength = Length(subjPolyPoint, subtrPoly[j][0]);
  	var	minIndex = 0;
    for (var i = 1; i < subtrPoly[j].length; i++){
      var newLength = Length(subjPolyPoint, subtrPoly[j][i])
        if (minLength > newLength){
          minLength = newLength;
          minIndex = i;
        }
    }
    minIndexes.push({arrayIndex: j, elementIndex: minIndex});
  }
    return minIndexes;
}

function Length(point1, point2) {      
    var x1 = point1.x,
        x2 = point2.x,
        y1 = point1.y,
        y2 = point2.y;
		    return Math.sqrt((x1 -= x2) * x1 + (y1 -= y2) *y1);
}

function sortPolygonArray(array, indexes){
var result = [];
	for (var i in indexes){
  	var newArray = [];
  	var originalLength = array[indexes[i].arrayIndex].length;
  	while (newArray.length != originalLength){
      if (indexes[i].elementIndex == originalLength){
        indexes[i].elementIndex = 0;
      }
   	 newArray.push(array[indexes[i].arrayIndex][indexes[i].elementIndex]);
   	 indexes[i].elementIndex++;
 	 }
   result.push(newArray);
  }
	
  return result;
}

function combinePolygonArrays(subjPoly, subtrPoly){
	var newArray = subjPoly;
  var lastSubjectPoint = subjPoly[subjPoly.length - 1];
  for (var i in subtrPoly){
  	var firstSubtractedPoint = subtrPoly[i][0];
    newArray = newArray.concat(subtrPoly[i]);
  	newArray.push(firstSubtractedPoint);
 		newArray.push(lastSubjectPoint);
  }
  return newArray;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.4.11/fabric.js"></script>
<canvas id="c" width="500" height="350" style="border:1px solid #ccc"></canvas>

这篇关于Fabric.js fillRule-偶数(减去形状)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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