stroke line not showing in fabric js - fabricjs

i want to clippath my image with rectangle box. My rectangle box have stroke line. but after clippath stroke line of box not looking as much width i have given to it. half of stroke line hiding by image object.
demo
SS for demo
let canvas = new fabric.Canvas('c', {
preserveObjectStacking: true,
backgroundColor: '#fff',
devicePixelRatio: true,
enableRetinaScaling: true,
controlsAboveOverlay: true,
});
var box1 = new fabric.Rect({
left: 20,
top: 20,
width: 200 ,
height: 350,
fill:'#dbdbdb',
lockScalingX: 'true',
lockScalingY: 'true',
selectable: false,
stroke: 'black',
strokeWidth: 3,
dirty: true,
absolutePositioned: true,
objectCaching: false,
originX: 'left',
originY: 'top',
});
canvas.add(box1);
canvas.sendToBack(box1);
canvas.requestRenderAll();
var box2 = new fabric.Rect({
left: 250,
top: 20,
width: 200 ,
height: 350,
fill:'#dbdbdb',
lockScalingX: 'true',
lockScalingY: 'true',
selectable: false,
stroke: 'black',
strokeWidth: 3,
dirty: true,
absolutePositioned: true,
objectCaching: false,
perPixelTargetFind:true,
originX: 'left',
originY: 'top',
});
canvas.add(box2);
canvas.sendToBack(box2);
canvas.requestRenderAll();
fabric.Image.fromURL('https://cdn.pixabay.com/photo/2021/02/08/16/03/dinosaur-5995333_1280.png', function(img) {
img.set({
left: 20,
top: 20,
originX: 'left',
originY: 'top',
objectCaching: false,
clipPath: box1,
scaleX:0.2,
scaleY:0.4,
});
canvas.add(img).renderAll();
});
fabric.Image.fromURL('https://cdn.pixabay.com/photo/2021/02/08/16/03/dinosaur-5995333_1280.png', function(img) {
img.set({
left: 240,
top: 20,
originX: 'left',
originY: 'top',
objectCaching: false,
clipPath: box2,
scaleX:0.2,
scaleY:0.4,
});
canvas.add(img).renderAll();
});

Related

Fabricjs: moving the circle on box edges

I have 4 lines and a circle. Current the circle can moving to anywhere but I want limit moving for it only on the lines. The example as bellow. I can not found the solution for it.
How can I do that, please help me. Thank you.
var canvas = new fabric.Canvas('canvas');
var line = new fabric.Line([
100, 100, 300, 200
], {
stroke: 'red',
selectable: false
})
var line2 = new fabric.Line([
300, 200, 300, 300
], {
stroke: 'red',
selectable: false
})
var line3 = new fabric.Line([
300, 300, 150, 300
], {
stroke: 'red',
selectable: false
})
var line4 = new fabric.Line([
150, 300, 100, 100
], {
stroke: 'red',
selectable: false
})
var circle = new fabric.Circle({
radius: 10,
fill: '',
stroke: 'red',
strokeWidth: 3,
originX: 'center',
originY: 'center',
top: 100,
left: 100
});
canvas.on('object:moving', function (e) {
})
canvas.add(line);
canvas.add(line2);
canvas.add(line3);
canvas.add(line4);
canvas.add(circle);
canvas.renderAll();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.1/fabric.min.js"></script>
<canvas id="canvas" width="400" height="400" style="border:1px solid #d3d3d3; position: absolute;">
</canvas>

clippath not working proper with stroke line

i have used latest fabric version(5.1). where i want to clip path my image with rectangle box. my rectangle box have stroke line. but after clip path stroke line of box not looking as much width i have given to it. half of stroke line hiding by image object. i want clip path image inner area of rectangle box and stroke line should not overwrite by image object.please help me try to fix it.
i have created demo `
let canvas = new fabric.Canvas('c', {
preserveObjectStacking: true,
backgroundColor: '#fff',
devicePixelRatio: true,
enableRetinaScaling: true,
controlsAboveOverlay: true,
});
var box1 = new fabric.Rect({
left: 20,
top: 20,
width: 200 ,
height: 350,
fill:'#dbdbdb',
lockScalingX: 'true',
lockScalingY: 'true',
selectable: false,
stroke: 'black',
strokeWidth: 3,
dirty: true,
absolutePositioned: true,
objectCaching: false,
originX: 'left',
originY: 'top',
});
canvas.add(box1);
canvas.sendToBack(box1);
canvas.requestRenderAll();
var box2 = new fabric.Rect({
left: 250,
top: 20,
width: 200 ,
height: 350,
fill:'#dbdbdb',
lockScalingX: 'true',
lockScalingY: 'true',
selectable: false,
stroke: 'black',
strokeWidth: 3,
dirty: true,
absolutePositioned: true,
objectCaching: false,
perPixelTargetFind:true,
originX: 'left',
originY: 'top',
});
canvas.add(box2);
canvas.sendToBack(box2);
canvas.requestRenderAll();
fabric.Image.fromURL('https://cdn.pixabay.com/photo/2021/02/08/16/03/dinosaur-5995333_1280.png', function(img) {
img.set({
left: 20,
top: 20,
originX: 'left',
originY: 'top',
objectCaching: false,
clipPath: box1,
scaleX:0.2,
scaleY:0.4,
});
canvas.add(img).renderAll();
});
fabric.Image.fromURL('https://cdn.pixabay.com/photo/2021/02/08/16/03/dinosaur-5995333_1280.png', function(img) {
img.set({
left: 240,
top: 20,
originX: 'left',
originY: 'top',
objectCaching: false,
clipPath: box2,
scaleX:0.2,
scaleY:0.4,
});
canvas.add(img).renderAll();
});
`

clippath with stroke line not showing in fabric js

i want to clipPath my image with rectangle box. My rectangle box have stroke line. but after clipPath stroke line of box not looking as much width i have given to it. half of stroke line hiding by image object.
[screenshot][1] [1]: https://i.stack.imgur.com/uIQfW.png
[demo here-][2] [2]: https://jsfiddle.net/0zk965gf/12/
let canvas = new fabric.Canvas('c', {
preserveObjectStacking: true,
backgroundColor: '#fff',
devicePixelRatio: true,
enableRetinaScaling: true,
controlsAboveOverlay: true,
});
var box1 = new fabric.Rect({
left: 20,
top: 20,
width: 200 ,
height: 350,
fill:'#dbdbdb',
lockScalingX: 'true',
lockScalingY: 'true',
selectable: false,
stroke: 'black',
strokeWidth: 3,
dirty: true,
absolutePositioned: true,
objectCaching: false,
originX: 'left',
originY: 'top',
});
canvas.add(box1);
canvas.sendToBack(box1);
canvas.requestRenderAll();
var box2 = new fabric.Rect({
left: 250,
top: 20,
width: 200 ,
height: 350,
fill:'#dbdbdb',
lockScalingX: 'true',
lockScalingY: 'true',
selectable: false,
stroke: 'black',
strokeWidth: 3,
dirty: true,
absolutePositioned: true,
objectCaching: false,
perPixelTargetFind:true,
originX: 'left',
originY: 'top',
});
canvas.add(box2);
canvas.sendToBack(box2);
canvas.requestRenderAll();
fabric.Image.fromURL('https://cdn.pixabay.com/photo/2021/02/08/16/03/dinosaur-5995333_1280.png', function(img) {
img.set({
left: 20,
top: 20,
originX: 'left',
originY: 'top',
objectCaching: false,
clipPath: box1,
scaleX:0.2,
scaleY:0.4,
});
canvas.add(img).renderAll();
});
fabric.Image.fromURL('https://cdn.pixabay.com/photo/2021/02/08/16/03/dinosaur-5995333_1280.png', function(img) {
img.set({
left: 240,
top: 20,
originX: 'left',
originY: 'top',
objectCaching: false,
clipPath: box2,
scaleX:0.2,
scaleY:0.4,
});
canvas.add(img).renderAll();
});

Fabric.js insertAt not working as expected

I want to make two groups of objects as layers with fabric.js. But although I put the second one with a lower z-index, it is still on top. See the code example below. What is wrong?
var canvas = new fabric.StaticCanvas('canvas');
var render_items = function() {
var rect1 = new fabric.Rect({
originX: 'left',
originY: 'top',
left: 25,
top: 10,
width: 50,
height: 50,
fill: 'red'
});
var layerA = new fabric.Group([rect1], {
originX: 'left',
originY: 'top'
});
canvas.insertAt(layerA, 100);
var rect2 = new fabric.Rect({
originX: 'left',
originY: 'top',
left: 30,
top: 20,
width: 50,
height: 50,
fill: 'blue'
});
var layerB = new fabric.Group([rect2], {
originX: 'left',
originY: 'top'
});
canvas.insertAt(layerB, 50);
}();
#canvas {
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.min.js"></script>
<canvas id="canvas" width="200" height="200"></canvas>
Fabric.JS doesn't really have true z-index functionality as you see with css. Instead, objects on the canvas work like an array where the index of each object determines where it sits in the stacking order. Using canvas.insertAt() lets you specify a specific index to insert the object in the array, and the length of the array is always determined by how many objects there are in your canvas.
Inserting an object at an index of 0 will therefore shift the other objects within the array so that the new object is rendered at the bottom of the stacking order.
var canvas = new fabric.StaticCanvas('canvas');
var render_items = function() {
var rect1 = new fabric.Rect({
originX: 'left',
originY: 'top',
left: 25,
top: 10,
width: 50,
height: 50,
fill: 'red'
});
var layerA = new fabric.Group([rect1], {
originX: 'left',
originY: 'top'
});
canvas.insertAt(layerA, 0);
var rect2 = new fabric.Rect({
originX: 'left',
originY: 'top',
left: 30,
top: 20,
width: 50,
height: 50,
fill: 'blue'
});
var layerB = new fabric.Group([rect2], {
originX: 'left',
originY: 'top'
});
canvas.insertAt(layerB, 0);
}();
#canvas {
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.min.js"></script>
<canvas id="canvas" width="200" height="200"></canvas>

Fabric.js animate onchange callback not working

The documentation of Fabric.js on animation mentions this onChange callback:
onChange: canvas.renderAll.bind(canvas)
However, when I try to substitute this with a custom function, the animation does not show. See this example; the down animation does not show, only the up animation. What is wrong with this code?
var canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.set({
hasControls: false,
selectable: false,
hoverCursor: 'default',
originX: 'center',
originY: 'center'
});
rect1 = new fabric.Rect({
left: 200,
top: 0,
width: 50,
height: 50,
fill: 'red',
opacity: 0
});
canvas.add(rect1);
var button01 = new fabric.Circle({
left: 20,
top: 20,
radius: 10,
fill: '#c0c0c0',
strokeWidth: 1,
stroke: '#808080',
hoverCursor: 'pointer'
});
canvas.add(button01);
button01.on('mousedown', function(options) {
animate_down()
});
var text1 = new fabric.Text("Animate", {
fontFamily: 'Arial',
fontSize: 12,
fill: 'black',
left: 58,
top: 20,
});
canvas.add(text1);
function animate_down() {
rect1.animate({
'top': 300,
'opacity': 1
}, {
onChange: function() {
canvas.renderAll.bind(canvas)
/* some other code */
},
onComplete: animate_up,
duration: 2000,
});
}
function animate_up() {
rect1.animate({
'top': 0,
'opacity': 0
}, {
onChange: canvas.renderAll.bind(canvas),
duration: 2000,
});
}
#canvas {
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.min.js"></script>
<canvas id="canvas" width="300" height="300"></canvas>
You need to call canvas.requestRenderAll(); inside your callback. As you are just binding canvas to canvas.renderAll, but never called. Docs
DEMO
var canvas = new fabric.Canvas('canvas');
fabric.Object.prototype.set({
hasControls: false,
selectable: false,
hoverCursor: 'default',
originX: 'center',
originY: 'center'
});
rect1 = new fabric.Rect({
left: 200,
top: 0,
width: 50,
height: 50,
fill: 'red',
opacity: 0
});
canvas.add(rect1);
var button01 = new fabric.Circle({
left: 20,
top: 20,
radius: 10,
fill: '#c0c0c0',
strokeWidth: 1,
stroke: '#808080',
hoverCursor: 'pointer'
});
canvas.add(button01);
button01.on('mousedown', function(options) {
animate_down()
});
var text1 = new fabric.Text("Animate", {
fontFamily: 'Arial',
fontSize: 12,
fill: 'black',
left: 58,
top: 20,
});
canvas.add(text1);
function animate_down() {
rect1.animate({
'top': 300,
'opacity': 1
}, {
onChange: function() {
canvas.requestRenderAll();
/* some other code */
},
onComplete: animate_up,
duration: 2000,
});
}
function animate_up() {
rect1.animate({
'top': 0,
'opacity': 0
}, {
onChange: canvas.requestRenderAll.bind(canvas),
duration: 2000,
});
}
#canvas {
border:1px solid #000000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.5/fabric.min.js"></script>
<canvas id="canvas" width="300" height="300"></canvas>

Resources