FabricJS - Selection of polygon in non-occupied space - fabricjs

This JSFiddle shows two shapes; a circle and a diamond (which has been drawn as a polygon):
var canvas = new fabric.Canvas('c');
canvas.add( new fabric.Circle({
top: 10, left: 10,
radius: 15,
fill: 'orange'
}));
canvas.add( new fabric.Polygon(
[
{x: 50, y: 0},
{x: 100, y: 100},
{x: 50, y: 200},
{x: 0, y: 100}
],{
fill: 'red',
hasBorders: false, hasControls: false, hasRotatingPoint: false, lockMovementX: true, lockMovementY: true,
}));
I am having problems with the bounding box of the diamond which is preventing the user from selecting the circle. I would like the user to be able to select the circle by clicking on the portion of it which is visible from behind the diamond.
Is there a way to inform fabric that I only want the bounding area of a polygon to be the area that is affected by the fill colour? i.e. so it would be possible to click the circle?
Note that this is an over-simplified example of my use-case. My real-life polygon is more complicated than a simple diamond, so it would not be possible to use a rotated rectangle instead.

This question kind old and easy but there no answer .
I just leave it here .
You need
perPixelTargetFind: true
JsFiddle

Related

Fabric.js: dashed line with clipping looks different on large canvas size

I use a clipping area with fabric.js to create a graph. However, the grid lines look different on a canvas size bigger than about 1000px. It only occurs with imageSmoothingEnabled: false. See the image. Note: the size of the frames have nothing to do with the size of the canvas.
To create the grid lines, I create one original that is wider than the area, and then clone them. The cloned lines are added to the clipArea object. Here is the relevant code.
HTML:
<canvas id="canvas" width="966" height="520"></canvas>
Javascript:
var canvas = new fabric.StaticCanvas('canvas', {
imageSmoothingEnabled: false
});
var rect = new fabric.Rect({
originX: 'left',
originY: 'top',
fill: 'transparent',
width: x1-x0,
height: y1-y0
});
var clipArea = new fabric.Group([rect], {
originX: 'left',
originY: 'top',
width: canvas.width*2,
height: canvas.height*2,
left: -canvas.width,
top: -canvas.height
});
rect=clipArea.item(0)
rect.set({left: x0,top: y0});
clipArea.clipPath = rect;
canvas.add(clipArea);
var yline = new fabric.Line([0, 0, 1200, 0], {
originX: 'left',
originY: 'center',
stroke: myFrameColor,
strokeWidth: 2,
strokeDashArray: [1, 3.4]
});
// clipArea.add(yline)
Of course I could draw the gridlines in a different way without using clipping, but I need a clipping area anyway. And I'd like to understand why this is happening.

how to make a hole through only overlay Rectangle using fabric js?

I am working on image cropper using fabric js version 1.7.22.
As usually, every cropper display black transparent overlay over the image (where image look like dull), and also display one Rect. (crop Area where image look full with color).
we can create this functionality using fabric js with background image and fabric.Rect object.
My problem is that when I use GlobalCompositeOperation with destination-out property to fabric.Rect object. It will make hole through canvas.
In simple word :
when I add globalCompositeOperation to destination-out, it will make hole through canvas also.
Expected result of canvas:
Current Result of canvas:
I have made one codepen for demonstration :
https://codepen.io/mayurkukadiya0/pen/zYYWOGL?editors=0110
I have found one codepen also for do same but they are add multiple canvas for display image in separate layer and rect and overlay in separate layer
Is there any way to do this without add external any canvas or css image behind canvas ?
Here is that reference : https://codepen.io/s0nnyv123/pen/eravaN
try using setOverlayImage
here'a demonstration, based on your codepen
var canvas = new fabric.Canvas('canvas', {preserveObjectStacking: 'true'});
canvas.setHeight(300);
canvas.setWidth(300);
canvas.setOverlayImage('https://images.pexels.com/videos/856973/free-video-856973.jpg?auto=compress&cs=tinysrgb&dpr=1&w=500', canvas.renderAll.bind(canvas), {
top: 0,
left: 0,
width: 300,
height:300,
lockMovementX: true,
lockMovementY: true,
lockRotation: true,
selectable: false,
globalCompositeOperation: 'destination-atop',
});
var overlay = new fabric.Rect({
left: 0,
top: 0,
width: 300,
height: 300,
fill: '#00000050',
selectable: false,
globalCompositeOperation: 'source-over'
});
canvas.add(overlay);
var rect = new fabric.Rect({
left: 100,
top: 100,
width: 100,
height: 100,
fill: '#451245',
globalCompositeOperation: 'destination-out'
});
canvas.add(rect);
canvas.renderAll();

How to fill diagonal in fabricjs

enter image description here
enter image description here
I am using Fabricjs. It's version is 2.4.5.
I want to fill diagonal line both side at different time.
Right Striped Diagonal :
https://i.hizliresim.com/P1My55.png
Left Striped Diagonal :
https://i.hizliresim.com/JZ20pQ.png
I tried like this fill each 0.01 white and black. But i could not set diagonal. My code is working, if image height big.
The higher the polygon height, the more horizontal the lines are.
canvas = new fabric.Canvas('canvas');
let points = [
{x: 0, y: 0},
{x: 300, y: 0},
{x: 300, y: 350},
{x: 0, y: 350}
];
let polygon = new fabric.Polygon(points, {
fill : 'white',
stroke : 'black',
strokeWidth : 5,
selectable: true,
objectCaching: false,
lockScalingX: true,
lockScalingY: true,
lockMovementX: true,
lockMovementY: true,
lockRotation: true
});
let colorStops = {};
for (let i = 0; i <= 100; i++) {
let key = (i / 100);
colorStops[key] = i % 2 === 0 ? "black" : "white";
}
polygon.setGradient('fill', {
x1: -polygon.width,
y1: -polygon.height,
x2: polygon.width,
y2: polygon.height,
colorStops: colorStops
});
canvas.add(polygon);
canvas.renderAll();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.5/fabric.min.js"></script>
<canvas id="canvas" width="600" height="600" class="canvas"></canvas>
Fiddle

Image clipping with visible overflow in Fabricjs

I want to clip image, BUT default clipping behaviour just hiding a part of image which out of border. Is there a way to make it visible and set less opacity for overflowed content?
There's one of old clipping examples I told about. It also using lodash to bind clip name to object:
return _.bind(clipByName, pug)(ctx)
Is there a way to replace this functionality with vanilla es5?
I found unclear solution. Again.
Background color of canvas could make an opacity and background image could be clipping object (w/o clipping by itself).
Also, loaded image shoul define globalCompositeOperation set to source-atop.
var canvas = new fabric.Canvas('c');
var clipingRect = new fabric.Rect({
originX: 'left',
originY: 'top',
top: 50,
left: 50,
height: 300,
width: 300,
fill: 'white',
selectable: false
});
canvas.backgroundColor = 'rgba(255,255,0,0.5)';
canvas.setBackgroundImage(clipingRect);
fabric.Image.fromURL('http://placeimg.com/640/480/any', function(fimg) {
canvas.add(fimg.set({
left: 0,
top: 0,
width: canvas.getWidth(),
height: canvas.getHeight(),
globalCompositeOperation: 'source-atop'
}));
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.12/fabric.min.js"></script>
<canvas id="c" width="400" height="400"></canvas>

Detect fabric js object edges and avoid overlap

I have a fabric triangle
var fabObj = new fabric.Triangle({
left: 250,
top: 250,
fill: 'white',
width: 60,
height: 60,
name:'triangle',
borderColor: '#f0000',
cornerSize: 8,
transparentCorners: true,
hasControls:true,
lockScalingX:true,
lockScalingY:true
});
$scope.canvas.add(fabObj);
$scope.canvas.setActiveObject(fabObj);
$scope.canvas.renderAll();
It creates the triangle like following
I want another triangle to fit on either side but could not overlap each other
Have tried this code but it only detect corners (square boundary of triangle )
https://stackoverflow.com/a/31153459/3377733
Please refer to this following fiddle
http://jsfiddle.net/m0jjc23v/23/
Fabric.js is not build to handle such scenarios. It's better to use Matter JS http://brm.io/matter-js/
They do handle all physics properties.

Resources