Jquery 基于SVG路径的Fabric.js多重裁剪
我有一个画布,上面有许多svg路径,我的目标是将图像拖放到画布上, 我能够做到这一点,当图像被放置在画布上时,我希望根据放置图像的svg路径来剪裁图像 我发布了很多次同样的问题,这次我将我的页面链接分享给你们,请看一下js代码,我不明白有什么问题,当我使用ctx.rect()方法用矩形剪裁图像时,当我拖动图像时,rect没有移动,但是,当我在画布上绘制相同的路径时,它会随着图像移动吗 我想在放置图像的路径中绘制并拖动图像 这里是该页面的链接,我使用的是来自fabricjs.com/kitchensink/page的一个示例svg文件Jquery 基于SVG路径的Fabric.js多重裁剪,jquery,fabricjs,Jquery,Fabricjs,我有一个画布,上面有许多svg路径,我的目标是将图像拖放到画布上, 我能够做到这一点,当图像被放置在画布上时,我希望根据放置图像的svg路径来剪裁图像 我发布了很多次同样的问题,这次我将我的页面链接分享给你们,请看一下js代码,我不明白有什么问题,当我使用ctx.rect()方法用矩形剪裁图像时,当我拖动图像时,rect没有移动,但是,当我在画布上绘制相同的路径时,它会随着图像移动吗 我想在放置图像的路径中绘制并拖动图像 这里是该页面的链接,我使用的是来自fabricjs.com/kitchen
将图像拖放到页面上显示的头像边缘。让我向您展示我的想法,当您将图像放入路径时,此路径可以是其基于过滤器的参数,如果您想移动路径及其内部的所有内容,我认为使用组是一种方式。实际上,该图像不在路径内,但看起来像是在路径内。我真的希望fabricjs可以为对象创建另一个子树,这样对象的每个子对象都只能在该对象内活动,但显然这种想法不适合当前版本。我想尝试制作一个,仍然在学习fabric.js源代码 此isPointInPoly函数改编自此处,过滤器创建代码来自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;
});
var canvas=newfabric.canvas('c1');
var src=”http://fiddle.jshell.net/img/logo.png";
canvas.backgroundColor=“#ccc”;
canvas.renderAll();
var=0;
fabric.Image.fromURL(src,function(img){
img.set({
原文:“左”,
原创:“top”,
左:120,
前20名
});
变量点=[{
x:185,
y:0
}, {
x:250,
y:100
}, {
x:385,
y:170
}, {
x:0,,
y:245
}];
var polygon=新结构。多边形([{
x:185,
y:0
}, {
x:250,
y:100
}, {
x:385,
y:170
}, {
x:0,,
y:245
}], {
左:0,,
排名:0,
原文:“左”,
原创:“top”,
填充:'透明',
笔画:“黑色”,
宽度:1
});
console.log(polygon.width+“:“+polygon.height);
canvas.add(img);
canvas.add(多边形);
polygon.selective=false;
fabric.Image.filters.Redify=fabric.util.createClass({
键入:“重新定义”,
应用程序:功能(画布){
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;
宽度=数学单元(img.宽度);
高度=数学单元(img.高度);
console.log(宽度+”:“+高度);
//console.log(“left=“+img.left+”:top=“+img.top”);
对于(变量i=0,len=data.length;iy)!=(yj>y))和&(x<(xj-xi)*(y-yi)/(yj-yi)+xi);
如果(相交)内部=!内部;
}
返回内部;
}
//polygon.selective=false;
});
让我向您展示我的想法,当您将图像放入路径时,此路径可以是其基于过滤器的参数,如果您想移动路径及其内部的所有内容,我认为使用group是一种方式。实际上,该图像不在路径内,但看起来像是在路径内。我真的希望fabricjs可以为对象创建另一个子树,这样对象的每个子对象都只能在该对象内活动,但显然这种想法不适合当前版本。我想尝试制作一个,仍然在学习fabric.js源代码
此isPointInPoly函数改编自此处,过滤器创建代码来自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;
});
var canvas=newfabric.canvas('c1');
var src=”http://fiddle.jshell.net/img/logo.png";
canvas.backgroundColor=“#ccc”;
canvas.renderAll();
var=0;
fabric.Image.fromURL(src,function(img){
img.set({
原文:“左”,
原创:“top”,
左:120,
前20名
});
变量点=[{
x:185,
y:0
}, {
x:250,
y:100
}, {
x:385,
y:170
}, {
x:0,,
y:245
}];
var polygon=新结构。多边形([{