Позвольте мне показать вам мою идею, когда вы помещаете изображение в путь, поэтому этот путь может быть его параметром, зависящим от фильтра, и если вы хотите переместить путь и все внутри него, использование группы - это, как мне кажется. На самом деле это изображение не находится внутри пути, но похоже, что это так. Я действительно надеюсь, что у fabricjs может быть другое дочернее дерево для объектов, поэтому каждый ребенок объекта может быть активен только внутри этого объекта, но, по-видимому, эта идея не подходит для текущей версии. Я хотел бы попытаться сделать один, все еще изучая источник fabric.js. http://jsfiddle.net/hellomaya/kjzZR/5/
Эта функция isPointInPoly адаптирована здесь https://github.com/substack/point-in-polygon и код создания фильтра с сайта fabricjs.com.
Ваш вопрос интересен, также полезен в аналогичном продукте.
var canvas = new fabric.Canvas('c1');
var src = "http://fiddle.jshell.net/img/logo.png";
canvas.backgroundColor = "#ccc";
canvas.renderAll();
var padding = 0;
fabric.Image.fromURL(src, function (img) {
img.set({
originX: 'left',
originY: 'top',
left: 120,
top: 20
});
var points = [{
x: 185,
y: 0
}, {
x: 250,
y: 100
}, {
x: 385,
y: 170
}, {
x: 0,
y: 245
}];
var polygon = new fabric.Polygon([{
x: 185,
y: 0
}, {
x: 250,
y: 100
}, {
x: 385,
y: 170
}, {
x: 0,
y: 245
}], {
left: 0,
top: 0,
originX: 'left',
originY: 'top',
fill: 'transparent',
stroke: 'black',
stokeWidth: 1
});
console.log(polygon.width + ":" + polygon.height);
canvas.add(img);
canvas.add(polygon);
polygon.selectable = false;
fabric.Image.filters.Redify = fabric.util.createClass({
type: 'Redify',
applyTo: function (canvasEl) {
var context = canvasEl.getContext('2d'),
imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
data = imageData.data;
var width = imageData.width;
var height = imageData.height;
width = Math.ceil (img.width);
height = Math.ceil (img.height);
console.log (width + ":" + height);
//console.log ("left=" + img.left + ":top=" + img.top);
for (var i = 0, len = data.length; i < len; i += 4) {
//data[i + 1] = 0;
//data[i + 2] = 0;
var x = Math.ceil(i/4);
var y = Math.ceil(x/width);
x = x % width;
x = x * img.scaleX + img.left;
y = y * img.scaleY + img.top;
//console.log (x + ":" + y);
if (!isPointInPoly(points, {
x: x,
y: y
})) {
//alert (x + ":" + y);
//data[i + 1] = 0;
//data[i + 2] = 0;
data[i + 3] = 0;
}
}
context.putImageData(imageData, 0, 0);
}
});
fabric.Image.filters.Redify.fromObject = function (object) {
return new fabric.Image.filters.Redify(object);
};
img.filters.push(new fabric.Image.filters.Redify());
canvas.on("object:moving", function() {
img.applyFilters(canvas.renderAll.bind(canvas));
});
function isPointInPoly(vs, pt) {
var x = pt.x,
y = pt.y;
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i].x,
yi = vs[i].y;
var xj = vs[j].x,
yj = vs[j].y;
var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi)/(yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
}
//polygon.selectable = false;
});
Я предлагаю: 1. использовать некоторый 2D-геометрию javascript для обнаружения пересечения между изображением и контуром 2. использовать фильтр для удаления частей изображения за пределами пути, чтобы он не отображался. Я никогда не пробовал, но для fabricjs я не знал, что мы можем сделать, чтобы решить вашу проблему. – Tom