Unable to freedraw perfectly in all directions using Fabricjs - javascript

I am trying to free draw a circle in Fabricjs awesome library , but I am getting some issue when it comes to free draw a circle.
I am able to achieve the same for Rectangle free drawing but failing to achieve perfection when drawing a circle.
Here's the code :
`
var canvas = new fabric.Canvas('canvas2');
var circle, isDown, origX, origY;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
circle = new fabric.Circle({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
radius: pointer.x-origX,
angle: 0,
fill: '',
stroke:'red',
strokeWidth:3,
});
canvas.add(circle);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if(origX>pointer.x){
circle.set({ left: Math.abs(pointer.x) });
}
if(origY>pointer.y){
circle.set({ top: Math.abs(pointer.y) });
}
circle.set({ radius: Math.abs(origY - pointer.y)/2 });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});
`
Here's the Fiddle!

Look my updated fiddle:
http://jsfiddle.net/8u1cqasa/10/
I modified your mouse:move function to take in account of position and strokeWidth;
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
var radius = Math.abs(origY - pointer.y)/2;
if (radius > circle.strokeWidth) {
radius -= circle.strokeWidth/2;
}
circle.set({ radius: radius});
if(origX>pointer.x){
circle.set({originX: 'right' });
} else {
circle.set({originX: 'left' });
}
if(origY>pointer.y){
circle.set({originY: 'bottom' });
} else {
circle.set({originY: 'top' });
}
canvas.renderAll();
});

Related

Cut a part of background image and drag it as an object in fabric JS

I am drawing a rectangle by using fabric js with mousemove . I want to cut a part of background Image of canvas which comes inside the area of rectangle and then get the cut part of image as an object and paste it anywhere else on canvas. It is like dragging that cut part.
I tried to do it with clipPath:
var marq_rect, isDown, origX, origY, marqer;
canvas.on('mouse:down', function (o) {
isDown = true;
canvas.set({ 'selection': false });
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var pointer = canvas.getPointer(o.e);
marq_rect = new fabric.Rect({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
width: pointer.x - origX,
height: pointer.y - origY,
angle: 0,
fill: 'transparent',
stroke: 'black',
strokeDashArray: [2, 2],
strokeDashOffset: 20,
strokeWidth: 2,
transparentCorners: false,
id: 'marq_rect'
});
canvas.add(marq_rect);
canvas.on('mouse:move', function (o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if (origX > pointer.x) {
marq_rect.set({ left: Math.abs(pointer.x) });
}
if (origY > pointer.y) {
marq_rect.set({ top: Math.abs(pointer.y) });
}
marq_rect.set({ width: Math.abs(origX - pointer.x) });
marq_rect.set({ height: Math.abs(origY - pointer.y) });
canvas.requestRenderAll();
});
canvas.on('mouse:up', function (o) {
isDown = false;
canvas.set({ 'selection': true });
bg_image.clipPath = marq_rect;
canvas.requestRenderAll();
});
It should look like this:
You can see that part of image inside the rect is cut out and can be dragged.
It can also be a circle or any other shape instead of rect.
Thanks in advance.

Draw circle and rectangle in canvas using Fabric js

I'm trying to draw three shapes. Using three separate functions.
line
circle
Rectangle
Three functions are works fine. But if i want to draw a line and circle both(run two functions one after other). First one work fine but second one it will draw the first one and second both in same coordination.And it will repeat.Is there a way to draw a one shape at one time.
var canvas = new fabric.Canvas('canvas1', {
selection: false
});
var line, isDown;
function myFun() {
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [pointer.x, pointer.y, pointer.x, pointer.y];
line = new fabric.Line(points, {
strokeWidth: 20,
fill: '#07ff11a3',
stroke: '#07ff11a3',
originX: 'center',
originY: 'center'
});
canvas.add(line);
});
}
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({
x2: pointer.x,
y2: pointer.y
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
function drawcle() {
var circle, isDown, origX, origY;
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
circle = new fabric.Circle({
left: pointer.x,
top: pointer.y,
radius: 1,
strokeWidth: 2,
stroke: 'red',
fill: 'White',
selectable: false,
originX: 'center',
originY: 'center'
});
canvas.add(circle);
});
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
circle.set({
radius: Math.abs(origX - pointer.x)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
}
function drawrec() {
var line, isDown, origX, origY;
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var pointer = canvas.getPointer(o.e);
line = new fabric.Rect({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
width: pointer.x - origX,
height: pointer.y - origY,
angle: 0,
fill: 'rgba(255,0,0,0.5)',
transparentCorners: false
});
canvas.add(line);
});
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if (origX > pointer.x) {
line.set({
left: Math.abs(pointer.x)
});
}
if (origY > pointer.y) {
line.set({
top: Math.abs(pointer.y)
});
}
line.set({
width: Math.abs(origX - pointer.x)
});
line.set({
height: Math.abs(origY - pointer.y)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.js"></script>
<div class="stamps">
<div class="set1">
<a class="thmb" href="#" onclick="myFun()">Line</a></br>
<a class="thmb" href="#" onclick="drawcle()">Draw Circle</a></br>
<a class="thmb" href="#" onclick="drawrec()">Draw Rectangle</a>
</div>
<div class="area">
<div class="col" id="droppable">
<canvas id="canvas1" width="720" height="560" style="border:1px solid #ccc"></canvas>
</div>
</div>
</div>
function removeEvents(){
canvas.off('mouse:down');
canvas.off('mouse:up');
canvas.off('mouse:move');
}
You can use canvas.off() to remove the event listener from canvas. It was drawing other shapes because its adding the listeners to canvas, so when you call the drawing function remove the attached listeners from canvas then add your current listener.
var canvas = new fabric.Canvas('canvas1', {
selection: false
});
var line, isDown;
function drawLine() {
removeEvents();
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
var points = [pointer.x, pointer.y, pointer.x, pointer.y];
line = new fabric.Line(points, {
strokeWidth: 20,
fill: '#07ff11a3',
stroke: '#07ff11a3',
originX: 'center',
originY: 'center'
});
canvas.add(line);
});
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
line.set({
x2: pointer.x,
y2: pointer.y
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
}
function drawcle() {
var circle, isDown, origX, origY;
removeEvents();
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
circle = new fabric.Circle({
left: pointer.x,
top: pointer.y,
radius: 1,
strokeWidth: 2,
stroke: 'red',
fill: 'White',
selectable: false,
originX: 'center',
originY: 'center'
});
canvas.add(circle);
});
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
circle.set({
radius: Math.abs(origX - pointer.x)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
}
function drawrec() {
var rect, isDown, origX, origY;
removeEvents();
canvas.on('mouse:down', function(o) {
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var pointer = canvas.getPointer(o.e);
rect = new fabric.Rect({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
width: pointer.x - origX,
height: pointer.y - origY,
angle: 0,
fill: 'rgba(255,0,0,0.5)',
transparentCorners: false
});
canvas.add(rect);
});
canvas.on('mouse:move', function(o) {
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if (origX > pointer.x) {
rect.set({
left: Math.abs(pointer.x)
});
}
if (origY > pointer.y) {
rect.set({
top: Math.abs(pointer.y)
});
}
rect.set({
width: Math.abs(origX - pointer.x)
});
rect.set({
height: Math.abs(origY - pointer.y)
});
canvas.renderAll();
});
canvas.on('mouse:up', function(o) {
isDown = false;
});
}
function removeEvents(){
canvas.off('mouse:down');
canvas.off('mouse:up');
canvas.off('mouse:move');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.js"></script>
<div class="stamps">
<div class="set1">
<a class="thmb" href="#" onclick="drawLine()">Line</a></br>
<a class="thmb" href="#" onclick="drawcle()">Draw Circle</a></br>
<a class="thmb" href="#" onclick="drawrec()">Draw Rectangle</a>
</div>
<div class="area">
<div class="col" id="droppable">
<canvas id="canvas1" width="720" height="560" style="border:1px solid #ccc"></canvas>
</div>
</div>
</div>

How to cut or split the rect object into two or more while event is triggered using fabric JavaScript

(function() {
var canvas = new fabric.Canvas("canvas");
fabric.Object.prototype.transparentCorners = false;
var rect = new fabric.Rect({
width: 100,
height: 100,
top: 100,
left: 100,
selectable:false,
fill: 'rgba(255,0,0,0.5)'
});
canvas.add(rect);
var timeoutTriggered = true;
function stopDragging(element) {
element.lockMovementX = true;
element.lockMovementY = true;
}
function onMoving(e) {
if (!timeoutTriggered) {
setTimeout(function() {
stopDragging(e.target);
}, 500);
timeoutTriggered = true;
}
}
canvas.on({
'object:moving': onMoving
});
})();
#canvas {
border: 5px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.11/fabric.js"></script>
<canvas id="canvas" height="500" width="500"></canvas>
rect object
While event is triggered created rect should be divided into two
equal parts.
I need to know whether it is possible or not to cut or split the rect object into two or more while event is triggered using fabric JavaScript.
<canvas ID="c" width="500" height="500" style="border:1px solid #ccc"></canvas>
var canvas = new fabric.Canvas('c', { selection: false });
var rect, isDown, origX, origY;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
var pointer = canvas.getPointer(o.e);
rect = new fabric.Rect({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
width: pointer.x-origX,
height: pointer.y-origY,
angle: 0,
fill: 'rgba(255,0,0,0.5)',
transparentCorners: false
});
canvas.add(rect);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
if(origX>pointer.x){
rect.set({ left: Math.abs(pointer.x) });
}
if(origY>pointer.y){
rect.set({ top: Math.abs(pointer.y) });
}
rect.set({ width: Math.abs(origX - pointer.x) });
rect.set({ height: Math.abs(origY - pointer.y) });
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});

How to free draw ellipse using Fabricjs?

Here's the code for how to draw circle using Fabricjs : Draw Circle using Mouse.
I want to achieve the same for ellipse . Because drawing circle freely will depend on radius but I want to draw a egg shaped or oval shaped area then , radius is not helping me , hence I am looking to use Ellipse here.
Code for free drawing circle :
`
var canvas = new fabric.Canvas("canvas2");
var circle, isDown, origX, origY;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
circle = new fabric.Circle({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
radius: pointer.x-origX,
angle: 0,
fill: '',
stroke:'red',
strokeWidth:3,
});
canvas.add(circle);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
var radius = Math.max(Math.abs(origY - pointer.y),Math.abs(origX - pointer.x))/2;
if (radius > circle.strokeWidth) {
radius -= circle.strokeWidth/2;
}
circle.set({ radius: radius});
if(origX>pointer.x){
circle.set({originX: 'right' });
} else {
circle.set({originX: 'left' });
}
if(origY>pointer.y){
circle.set({originY: 'bottom' });
} else {
circle.set({originY: 'top' });
}
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});
`
Can anyone do it?
you can do similarly to other shape cases:
How to freedraw Circle in fabricjs using mouse?
var canvas = new fabric.Canvas("canvas2");
var ellipse, isDown, origX, origY;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
ellipse = new fabric.Ellipse({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
rx: pointer.x-origX,
ry: pointer.y-origY,
angle: 0,
fill: '',
stroke:'red',
strokeWidth:3,
});
canvas.add(ellipse);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
var rx = Math.abs(origX - pointer.x)/2;
var ry = Math.abs(origY - pointer.y)/2;
if (rx > ellipse.strokeWidth) {
rx -= ellipse.strokeWidth/2
}
if (ry > ellipse.strokeWidth) {
ry -= ellipse.strokeWidth/2
}
ellipse.set({ rx: rx, ry: ry});
if(origX>pointer.x){
ellipse.set({originX: 'right' });
} else {
ellipse.set({originX: 'left' });
}
if(origY>pointer.y){
ellipse.set({originY: 'bottom' });
} else {
ellipse.set({originY: 'top' });
}
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});
<script type="text/javascript" src="http://www.deltalink.it/andreab/fabric/fabric.js" ></script>
<canvas id="canvas2" width=500 height=500 ></canvas>

How to freedraw Circle in fabricjs using mouse?

I am using Fabricjs in my project and now working on drawing circle using Fabricjs library.
I am able to do it but it is not very proper on x-axis , as dragging on x-axis seems improper whereas dragging on y-axis works fine.
Can anybody fix it to work on any axis.
Also there are 2-3 questions on stackoverflow that are not properly answered regarding Circle out of which I asked 1 previously.
Here's the Fiddle of the work I have done so far:
Draw Circle
Code :
`
var canvas = new fabric.Canvas("canvas2");
var circle, isDown, origX, origY;
canvas.on('mouse:down', function(o){
isDown = true;
var pointer = canvas.getPointer(o.e);
origX = pointer.x;
origY = pointer.y;
circle = new fabric.Circle({
left: origX,
top: origY,
originX: 'left',
originY: 'top',
radius: pointer.x-origX,
angle: 0,
fill: '',
stroke:'red',
strokeWidth:3,
});
canvas.add(circle);
});
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
var radius = Math.abs(origY - pointer.y)/2;
if (radius > circle.strokeWidth) {
radius -= circle.strokeWidth/2;
}
circle.set({ radius: radius});
if(origX>pointer.x){
circle.set({originX: 'right' });
} else {
circle.set({originX: 'left' });
}
if(origY>pointer.y){
circle.set({originY: 'bottom' });
} else {
circle.set({originY: 'top' });
}
canvas.renderAll();
});
canvas.on('mouse:up', function(o){
isDown = false;
});
`
See update fiddle.
You have just to select the minimum or maximum from x and y when selecting the radius.
http://jsfiddle.net/8u1cqasa/17/
I modified (again) your mouse:move function to take in account both movements.
canvas.on('mouse:move', function(o){
if (!isDown) return;
var pointer = canvas.getPointer(o.e);
var radius = Math.max(Math.abs(origY - pointer.y),Math.abs(origX - pointer.x))/2;
if (radius > circle.strokeWidth) {
radius -= circle.strokeWidth/2;
}
circle.set({ radius: radius});
if(origX>pointer.x){
circle.set({originX: 'right' });
} else {
circle.set({originX: 'left' });
}
if(origY>pointer.y){
circle.set({originY: 'bottom' });
} else {
circle.set({originY: 'top' });
}
canvas.renderAll();
});

Categories