Maintain strokeWidth while scaling in fabric js - javascript

Note: I have refereed SO question, but it is not useful for my case, because
1) I am trying to maintain previous border but as of now its recalculate border while scaling.
I have added below code to stop increasing border automatically while scaling the object. Now the issue is I have added a 5px border to object but when scaling the object then it is not maintaining the border which I added earlier.
canvas.on('object:scaling', (e) => {
var o = e.target;
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
o.strokeWidth = o.strokeWidthUnscaled / o.scaleX;
}
});
Now what I want is to prevent increasing of border while scaling the object. Border should remain as it was earlier.
Here is snippet / Codepen
var canvas = new fabric.Canvas('canvas1');
$('.add_shape').click(function() {
var cur_value = $(this).attr('data-rel');
if (cur_value != '') {
switch (cur_value) {
case 'rectangle':
var rect = new fabric.Rect({
left: 50,
top: 50,
fill: '#aaa',
width: 50,
height: 50,
opacity: 1,
stroke: '#000',
strokeWidth: 1
});
canvas.add(rect);
canvas.setActiveObject(rect);
break;
case 'circle':
var circle = new fabric.Circle({
left: 50,
top: 50,
fill: '#aaa',
radius: 50,
opacity: 1,
stroke: '#000',
strokeWidth: 1
});
canvas.add(circle);
canvas.setActiveObject(circle);
break;
}
}
});
canvas.on('object:scaling', (e) => {
var o = e.target;
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
o.strokeWidth = o.strokeWidthUnscaled / o.scaleX;
}
});
/* Control the border */
$('#control_border').change(function() {
var cur_value = parseInt($(this).val());
var activeObj = canvas.getActiveObject();
if (activeObj == undefined) {
alert('Please select the Object');
return false;
}
activeObj.set({
strokeWidth: cur_value
});
canvas.renderAll();
});
button {
max-resolution: 10px;
height: 30px;
}
div {
margin: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-beta.7/fabric.js"></script>
<div>
<button class="add_shape" data-rel="circle">Add Circle</button>
<button class="add_shape" data-rel="rectangle">Add Rectangle</button>
<label class="control-label">Border</label>
<input id="control_border" type="range" min="0" max="10" step="1" value="0" />
</div>
<canvas id="canvas1" width="600" height="300" style="border:1px solid #000000;"></canvas>
Steps
1) Add Rectangle
2) Apply the border (lets say 5)
3) Scale that object
Now you can see the applied border is gone. So how to resolve that?
Update
I have tried below option but its not working, basically i am trying to maintain strokeWidth/Border for objects like rectangle, circle, triangle, line, polygon
What i have tried so far:
//1st try
canvas.on('object:scaling', (e) => {
var o = e.target;
o.strokeWidth = o.strokeWidth / ((o.scaleX + o.scaleY) / 2);
var activeObject = canvas.getActiveObject();
activeObject.set('strokeWidth',o.strokeWidth);
});
//2nd try
canvas.on('object:scaling', (e) => {
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
o.strokeWidth = o.strokeWidthUnscaled / o.scaleX;
}
});
//3rd try
fabric.Object.prototype._renderStroke = function(ctx) {
if (!this.stroke || this.strokeWidth === 0) {
return;
}
if (this.shadow && !this.shadow.affectStroke) {
this._removeShadow(ctx);
}
ctx.save();
ctx.scale(1 / this.scaleX, 1 / this.scaleY);
this._setLineDash(ctx, this.strokeDashArray, this._renderDashedStroke);
this._applyPatternGradientTransform(ctx, this.stroke);
ctx.stroke();
ctx.restore();
};
Questions i have refereed:
https://github.com/kangax/fabric.js/issues/66
Unable to maintain thickness of strokeWidth while resizing in case of Groups in Fabricjs
Fabricjs How to scale object but keep the border (stroke) width fixed
Resize a fabricjs rect to maintain border size
https://github.com/kangax/fabric.js/issues/2012
But not able to found solution.

This has become much easier as of Fabric.js version 2.7.0. There is now a strokeUniform property that when enabled, prevents the stroke width from being affected by the object's scale values.
obj.set('strokeUniform', true);
https://github.com/fabricjs/fabric.js/pull/5546
var canvas = new fabric.Canvas('canvas1');
$('.add_shape').click(function() {
var cur_value = $(this).attr('data-rel');
if (cur_value != '') {
switch (cur_value) {
case 'rectangle':
var rect = new fabric.Rect({
left: 50,
top: 50,
fill: '#aaa',
width: 50,
height: 50,
opacity: 1,
stroke: '#000',
strokeWidth: 1,
noScaleCache: false,
strokeUniform: true,
});
canvas.add(rect);
canvas.setActiveObject(rect);
break;
case 'circle':
var circle = new fabric.Circle({
left: 50,
top: 50,
fill: '#aaa',
radius: 50,
opacity: 1,
stroke: '#000',
strokeWidth: 1,
noScaleCache: false,
strokeUniform: true
});
canvas.add(circle);
canvas.setActiveObject(circle);
break;
}
}
});
/* Control the border */
$('#control_border').change(function() {
var cur_value = parseInt($(this).val());
var activeObj = canvas.getActiveObject();
if (activeObj == undefined) {
alert('Please select the Object');
return false;
}
activeObj.set({
strokeWidth: cur_value
});
canvas.renderAll();
});
button {
max-resolution: 10px;
height: 30px;
}
div {
margin: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.7.0/fabric.min.js"></script>
<div>
<button class="add_shape" data-rel="circle">Add Circle</button>
<button class="add_shape" data-rel="rectangle">Add Rectangle</button>
<label class="control-label">Border</label>
<input id="control_border" type="range" min="0" max="10" step="1" value="0" />
</div>
<canvas id="canvas1" width="600" height="300" style="border:1px solid #000000;"></canvas>

Set strokeWidth to strokeWidthUnscaled for first time then set # at scalling, for caching make it false only when scalling after modified change it.
object.strokeWidth = object.strokeWidthUnscaled/((object.scaleX+object.scaleY)/2);
And for selecting new stroke width, do this
var newStrokeWidth = cur_value / ((activeObj.scaleX + activeObj.scaleY) / 2)
activeObj.set({
strokeWidth: newStrokeWidth,
strokeWidthUnscaled : cur_value
});
Example
var canvas = new fabric.Canvas('canvas1');
var globalStrokeWidth = 1;
$('.add_shape').click(function() {
var cur_value = $(this).attr('data-rel');
if (cur_value != '') {
switch (cur_value) {
case 'rectangle':
var rect = new fabric.Rect({
left: 50,
top: 50,
fill: '#aaa',
width: 50,
height: 50,
opacity: 1,
stroke: '#000',
strokeWidth: globalStrokeWidth
});
canvas.add(rect);
canvas.setActiveObject(rect);
break;
case 'circle':
var circle = new fabric.Circle({
left: 50,
top: 50,
fill: '#aaa',
radius: 50,
opacity: 1,
stroke: '#000',
strokeWidth: globalStrokeWidth
});
canvas.add(circle);
canvas.setActiveObject(circle);
break;
}
}
});
canvas.on('object:scaling', (e) => {
var o = e.target;
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
if(o.objectCaching) o.objectCaching = false;
o.strokeWidth = o.strokeWidthUnscaled / ((o.scaleX + o.scaleY) / 2);
}
});
canvas.on('object:modified', (e) => {
var o = e.target;
if(!o.objectCaching) o.objectCaching = true;
canvas.renderAll();
});
/* Control the border */
$('#control_border').change(function() {
var cur_value = parseInt($(this).val());
globalStrokeWidth = cur_value;
var activeObj = canvas.getActiveObject();
if (activeObj == undefined) {
alert('Please select the Object');
return false;
}
var newStrokeWidth = cur_value / ((activeObj.scaleX + activeObj.scaleY) / 2)
activeObj.set({
strokeWidth: newStrokeWidth,
strokeWidthUnscaled : cur_value
});
activeObj.setCoords();
canvas.renderAll();
});
button {
max-resolution: 10px;
height: 30px;
}
div {
margin: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-beta.7/fabric.js"></script>
<div>
<button class="add_shape" data-rel="circle">Add Circle</button>
<button class="add_shape" data-rel="rectangle">Add Rectangle</button>
<label class="control-label">Border</label>
<input id="control_border" type="range" min="0" max="10" step="1" value="0" />
</div>
<canvas id="canvas1" width="600" height="300" style="border:1px solid #000000;"></canvas>

While working on this issue, I've noticed that after resizing an object value of width and height doesn't change, it only changes scaleX and scaleY.
To maintain the stroke width, you need to reset scaleX and scalyY to 1 and also update width and height with new values.
For rectangle:
var currObj = canvas.getActiveObject();
if (currObj.type === 'rect') {
var newWidth = currObj.width * currObj.scaleX,
newHeight = currObj.height * currObj.scaleY;
currObj.set({
'width': newWidth,
'height': newHeight,
scaleX: 1,
scaleY: 1
});
}
For Ellipse:
var currObj = canvas.getActiveObject();
if (currObj.type === 'ellipse') {
var newRX = currObj.rx * currObj.scaleX,
newRY = currObj.ry * currObj.scaleY;
currObj.set({
'rx': newRX,
'ry': newRY,
scaleX: 1,
scaleY: 1
});
}
Don't forget to call canvas.renderAll() later;
http://jsfiddle.net/eLoamgrq/5/

In object:scaling, I commented out the calculation based on scale. Since the unscaled was = 1 and it was divided by scaling it always resulted in the border equaling a fraction (rather than staying put).
var canvas = new fabric.Canvas('canvas1');
$('.add_shape').click(function() {
var cur_value = $(this).attr('data-rel');
if (cur_value != '') {
switch (cur_value) {
case 'rectangle':
var rect = new fabric.Rect({
left: 50,
top: 50,
fill: '#aaa',
width: 50,
height: 50,
opacity: 1,
stroke: '#000',
strokeWidth: 1
});
canvas.add(rect);
canvas.setActiveObject(rect);
break;
case 'circle':
var circle = new fabric.Circle({
left: 50,
top: 50,
fill: '#aaa',
radius: 50,
opacity: 1,
stroke: '#000',
strokeWidth: 1
});
canvas.add(circle);
canvas.setActiveObject(circle);
break;
}
}
});
canvas.on('object:scaling', (e) => {
var o = e.target;
if (!o.strokeWidthUnscaled && o.strokeWidth) {
o.strokeWidthUnscaled = o.strokeWidth;
}
if (o.strokeWidthUnscaled) {
//o.strokeWidth = o.strokeWidthUnscaled / o.scaleX;
}
});
/* Control the border */
$('#control_border').change(function() {
var cur_value = parseInt($(this).val());
var activeObj = canvas.getActiveObject();
if (activeObj == undefined) {
alert('Please select the Object');
return false;
}
activeObj.set({
strokeWidth: cur_value
});
canvas.renderAll();
});
button {
max-resolution: 10px;
height: 30px;
}
div {
margin: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.0.0-beta.7/fabric.js"></script>
<div>
<button class="add_shape" data-rel="circle">Add Circle</button>
<button class="add_shape" data-rel="rectangle">Add Rectangle</button>
<label class="control-label">Border</label>
<input id="control_border" type="range" min="0" max="10" step="1" value="0" />
</div>
<canvas id="canvas1" width="600" height="300" style="border:1px solid #000000;"></canvas>

If your object is inside a group, strokeUniform property does not work. In that case you can reduce the scaling of the inner object and update its width and height property on scaling. Example:
object.on('scaling', function() {
object.item(0).set('scaleX', 1/object.scaleX);
object.item(0).set('scaleY', 1/object.scaleY);
var newobjwidth = Math.round(object.width * object.scaleX);
var newobjheight = Math.round(object.height * object.scaleY);
object.item(0).set('width', newobjwidth);
object.item(0).set('height', newobjheight);
object.item(0).setCoords();
}
If your object is blurry delete it and add it again after scaling.

Related

How can I get IDs of items on Canvas uploaded as JSON in Fabric JS?

I have a canvas and I am loading this canvas from JSON. There are two group elements and they have their own ID (ID: 1047,1048). I keep the ID numbers to be deleted in an array of 1048,1049,1050.
var toDelete = ['1048', '1049', '1050'] ;
After JSON is loaded, if there is an item belonging to the ID in the array, I want it to be deleted. How can I do that?
According to the comparison, the ID number 1048 should be deleted.
I wrote function such code to throw incoming IDs into an array, but it didn't work.
MY PEN
function loadedIdsFunction(){ // I wrote this function to get incoming IDs but it didn't work
var loadedIds = []; //IDs of items from JSON Canvas
document.getElementById("c").fabric = canvas;
canvas.getObjects().forEach(function(o) {
if(o.type == 'group'){
loadedIds.push(o.id);
}
});
}
var canvas = new fabric.Canvas('c');
var json = '{"version":"3.1.0","objects":[{"type":"group","version":"3.1.0","originX":"left","originY":"top","left":194,"top":157,"width":40,"height":80,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":"1047","objects":[{"type":"rect","version":"3.1.0","originX":"left","originY":"top","left":-20,"top":-15,"width":35,"height":50,"fill":"blue","stroke":"blue","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0,"id":"1047"},{"type":"text","version":"3.1.0","originX":"center","originY":"top","left":0,"top":-40,"width":36,"height":20.34,"fill":"red","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"white","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"text":"1047","fontSize":18,"fontWeight":"normal","fontFamily":"Quicksand","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"left","textBackgroundColor":"","charSpacing":0,"styles":{}}]},{"type":"group","version":"3.1.0","originX":"left","originY":"top","left":640,"top":473,"width":40,"height":80,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":"1048","objects":[{"type":"rect","version":"3.1.0","originX":"left","originY":"top","left":-20,"top":-15,"width":35,"height":50,"fill":"blue","stroke":"blue","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0,"id":"1048"},{"type":"text","version":"3.1.0","originX":"center","originY":"top","left":0,"top":-40,"width":36,"height":20.34,"fill":"red","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"white","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"text":"1048","fontSize":18,"fontWeight":"normal","fontFamily":"Quicksand","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"left","textBackgroundColor":"","charSpacing":0,"styles":{}}]}],"backgroundImage":{"type":"image","version":"3.1.0","originX":"left","originY":"top","left":0,"top":0,"width":780,"height":646,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"crossOrigin":"","cropX":0,"cropY":0,"src":"https://i1.wp.com/onideal.com/wp-content/uploads/2020/03/Schlafzimmer-Grundriss-ideale-Position-Bett-Moebel-Kleiderschrank-dreieckchen-4-780x646.jpg?fit=780%2C646&ssl=1","filters":[]}}'
canvas.loadFromJSON(json, () => canvas.renderAll(), (o, object) => {
// console.log(o, object.on);
object.on('selected', () => {
console.log(object.id);
});
});
//canvas.setBackgroundImage('https://i.hizliresim.com/iBHC0t.jpg', canvas.renderAll.bind(canvas));
//var uniqid = "0";
var uniqids = 0;
$("#door").on("click", function(e) {
rect = new fabric.Rect({
id: uniqid,
left: 40,
top: 40,
width: 35,
height: 50,
fill: 'blue',
stroke: 'blue',
strokeWidth: 5,
strokeUniform: false,
hasControls: true,
});
var uniqid = uniqids.toString();
var text = new fabric.Text(uniqid, {
fontSize: 30,
originX: 'center',
originY: 'right'
});
var group = new fabric.Group([rect, text], {
left: 0,
top: 100,
});
canvas.add(group);
uniqids++;
});
//*****************************
canvas.on('mouse:wheel', function(opt) {
var delta = opt.e.deltaY;
var zoom = canvas.getZoom();
zoom *= 0.999 ** delta;
if (zoom > 20) zoom = 20;
if (zoom < 0.01) zoom = 0.01;
canvas.setZoom(zoom);
opt.e.preventDefault();
opt.e.stopPropagation();
})
$('#getid').click(function() {
var activeObject = canvas.getActiveObjects();
alert(canvas.getActiveObject().id);
});
//***************************************
$("#save").on("click", function(e) {
$(".save").html(canvas.toSVG());
});
$('#delete').click(function() {
var activeObject = canvas.getActiveObjects();
canvas.discardActiveObject();
canvas.remove(...activeObject);
});
#c {
background-color: grey;
margin-top: 10px;
}
button {
padding: 10px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.1.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<button id="door">Door</button>
<button id="delete">Delete Door</button>
<button id="save">Save</button>
<button id="getid">GET ID</button>
<p>Save bastıktan sonra altta SVG dosyası oluşur</p>
<br>
<canvas id="c" width="800" height="800"></canvas>
<br>
<p class="save">
</p>
You can filter the all the objects based on their id, if the id is in the list, remove the item. Like this:
canvas.getObjects()
.filter(obj =>
['1048', '1049', '1050'].includes(obj.id)
)
.forEach(item => canvas.remove(item));
canvas.renderAll();
var canvas = new fabric.Canvas('c');
var json = '{"version":"3.1.0","objects":[{"type":"group","version":"3.1.0","originX":"left","originY":"top","left":194,"top":157,"width":40,"height":80,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":"1047","objects":[{"type":"rect","version":"3.1.0","originX":"left","originY":"top","left":-20,"top":-15,"width":35,"height":50,"fill":"blue","stroke":"blue","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0,"id":"1047"},{"type":"text","version":"3.1.0","originX":"center","originY":"top","left":0,"top":-40,"width":36,"height":20.34,"fill":"red","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"white","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"text":"1047","fontSize":18,"fontWeight":"normal","fontFamily":"Quicksand","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"left","textBackgroundColor":"","charSpacing":0,"styles":{}}]},{"type":"group","version":"3.1.0","originX":"left","originY":"top","left":640,"top":473,"width":40,"height":80,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"id":"1048","objects":[{"type":"rect","version":"3.1.0","originX":"left","originY":"top","left":-20,"top":-15,"width":35,"height":50,"fill":"blue","stroke":"blue","strokeWidth":5,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":0,"ry":0,"id":"1048"},{"type":"text","version":"3.1.0","originX":"center","originY":"top","left":0,"top":-40,"width":36,"height":20.34,"fill":"red","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"white","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"text":"1048","fontSize":18,"fontWeight":"normal","fontFamily":"Quicksand","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"left","textBackgroundColor":"","charSpacing":0,"styles":{}}]}],"backgroundImage":{"type":"image","version":"3.1.0","originX":"left","originY":"top","left":0,"top":0,"width":780,"height":646,"fill":"rgb(0,0,0)","stroke":null,"strokeWidth":0,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"crossOrigin":"","cropX":0,"cropY":0,"src":"https://i1.wp.com/onideal.com/wp-content/uploads/2020/03/Schlafzimmer-Grundriss-ideale-Position-Bett-Moebel-Kleiderschrank-dreieckchen-4-780x646.jpg?fit=780%2C646&ssl=1","filters":[]}}'
canvas.loadFromJSON(json, () => {
canvas.getObjects()
.filter(obj => ['1048', '1049', '1050'].includes(obj.id))
.forEach(item => canvas.remove(item));
canvas.renderAll();
}, (o, object) => {
// console.log(o, object.on);
object.on('selected', () => {
console.log(object.id);
});
});
//canvas.setBackgroundImage('https://i.hizliresim.com/iBHC0t.jpg', canvas.renderAll.bind(canvas));
//var uniqid = "0";
var uniqids = 0;
$("#door").on("click", function(e) {
rect = new fabric.Rect({
id: uniqid,
left: 40,
top: 40,
width: 35,
height: 50,
fill: 'blue',
stroke: 'blue',
strokeWidth: 5,
strokeUniform: false,
hasControls: true,
});
var uniqid = uniqids.toString();
var text = new fabric.Text(uniqid, {
fontSize: 30,
originX: 'center',
originY: 'right'
});
var group = new fabric.Group([rect, text], {
left: 0,
top: 100,
});
canvas.add(group);
uniqids++;
});
//*****************************
canvas.on('mouse:wheel', function(opt) {
var delta = opt.e.deltaY;
var zoom = canvas.getZoom();
zoom *= 0.999 ** delta;
if (zoom > 20) zoom = 20;
if (zoom < 0.01) zoom = 0.01;
canvas.setZoom(zoom);
opt.e.preventDefault();
opt.e.stopPropagation();
})
$('#getid').click(function() {
var activeObject = canvas.getActiveObjects();
alert(canvas.getActiveObject().id);
});
//***************************************
$("#save").on("click", function(e) {
$(".save").html(canvas.toSVG());
});
$('#delete').click(function() {
var activeObject = canvas.getActiveObjects();
canvas.discardActiveObject();
canvas.remove(...activeObject);
});
/*
canvas.on('mouse:over', function(e) {
e.target.set('fill', 'red');
canvas.renderAll();
});
canvas.on('mouse:out', function(e) {
e.target.set('fill', 'green');
canvas.renderAll();
});
*/
#c {
background-color: grey;
margin-top: 10px;
}
button {
padding: 10px 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.1.0/fabric.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<button id="door">Door</button>
<button id="delete">Delete Door</button>
<button id="save">Save</button>
<button id="getid">GET ID</button>
<p>Save bastıktan sonra altta SVG dosyası oluşur</p>
<br>
<canvas id="c" width="800" height="800"></canvas>
<br>
<p class="save">
</p>
https://codepen.io/moshfeu/pen/gOMBQqL?editors=0010

Fabricjs trouble getting radio button to set fabric object change

I'm having trouble getting my radio button to change the object added to the fabric canvas on click. Each time the radio button is changed the new icon color remains the green, where it should have changed to the selected color.
The behavior that I'm looking for is when you select the green, yellow, or red radio button the next icon placed on the canvas should become that selected color.
Any ideas?
function iconSet() {
var canvas = new fabric.Canvas('c');
if (document.getElementById("green").checked == true) {
var iconGreen = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: 'green'
});
canvas.add(iconGreen);
canvas.on('mouse:move', function(obj) {
iconGreen.top = obj.e.y - 30;
iconGreen.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
iconGreen.top = -100;
iconGreen.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(iconGreen.clone());
canvas.renderAll();
})
} else if (document.getElementById("yellow").checked == true) {
var iconYellow = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: 'yellow'
});
canvas.add(iconYellow);
canvas.on('mouse:move', function(obj) {
iconYellow.top = obj.e.y - 30;
iconYellow.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
iconYellow.top = -100;
iconYellow.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(iconYellow.clone());
canvas.renderAll();
})
} else if (document.getElementById("red").checked == true) {
var iconRed = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: 'red'
});
canvas.add(iconRed);
canvas.on('mouse:move', function(obj) {
iconRed.top = obj.e.y - 30;
iconRed.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
iconRed.top = -100;
iconRed.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(iconRed.clone());
canvas.renderAll();
})
}
}
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
Green<input name="iconType" type="radio" id="green" onclick="iconSet()" /> Yellow
<input name="iconType" type="radio" id="yellow" onclick="iconSet()" /> Red
<input name="iconType" type="radio" id="red" onclick="iconSet()" />
<canvas id="c" width="600" height="600"></canvas>
As you are creating every time new fabric.Triangle instead of that you can create once and when radio button values changed, just will update color of existing fabricTriangle by using fabricTriangle.setFill() method.
See below code snippet
document.getElementById('green').checked = true;
var canvas = new fabric.Canvas('c'),
fabricTriangle = getfabricTriangle('green');
canvas.on('mouse:move', function(obj) {
fabricTriangle.top = obj.e.y - 30;
fabricTriangle.left = obj.e.x - 10;
canvas.renderAll()
});
canvas.on('mouse:out', function(obj) {
fabricTriangle.top = -100;
fabricTriangle.left = -100;
canvas.renderAll()
});
canvas.on('mouse:up', function(obj) {
canvas.add(fabricTriangle.clone());
canvas.renderAll();
});
canvas.add(fabricTriangle)
function getfabricTriangle(color) {
if (!fabricTriangle) {
//If it is not created then first will create and return..
return new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: color
});
} /*else {
//just changing the color of exiting fabric.Triangle...
fabricTriangle.setFill(color)
}*/
}
function iconSet() {
fabricTriangle.setFill(document.querySelector('input[type="radio"]:checked').value)
}
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
Green
<input name="iconType" type="radio" id="green" onclick="iconSet()" value="green" />
Yellow
<input name="iconType" type="radio" id="yellow" onclick="iconSet()" value="yellow" />
Red
<input name="iconType" type="radio" id="red" onclick="iconSet()" value="red" />
<canvas id="c" width="600" height="600"></canvas>
Try to Declare canvas and obejct variable globally and change fill property of object and trigger method of canvas on change of radio button
icon.setFill("yellow");
canvas.renderAll();
canvas.trigger('object:modified', {target: icon});
Example
var canvas = new fabric.Canvas('c');
var iconTriangle = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill:"green"
});
canvas.add(iconTriangle);
canvas.on('mouse:move', function(obj) {
iconTriangle.top = obj.e.y - 30;
iconTriangle.left = obj.e.x - 10;
canvas.renderAll()
});
canvas.on('mouse:out', function(obj) {
iconTriangle.top = -100;
iconTriangle.left = -100;
canvas.renderAll()
});
canvas.on('mouse:up', function(obj) {
canvas.add(iconTriangle.clone());
canvas.renderAll();
});
function iconSet() {
if (document.getElementById("green").checked == true) {
iconTriangle.setFill("green");
canvas.renderAll();
}
else if (document.getElementById("yellow").checked == true) {
iconTriangle.setFill("yellow");
canvas.renderAll();
}
else if (document.getElementById("red").checked == true) {
iconTriangle.setFill("red");
canvas.renderAll();
}
}
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
Green<input name="iconType" type="radio" id="green" onclick="iconSet()" /> Yellow
<input name="iconType" type="radio" id="yellow" onclick="iconSet()" /> Red
<input name="iconType" type="radio" id="red" onclick="iconSet()" />
<canvas id="c" width="300" height="300"></canvas>
The problem is that you create canvas and the icons to add to it inside a function and afterwards you lose track of them. It's not a problem to define a variable inside the function, but you need to have a guarantee to be able to refer to it later. var variables are function-scoped, which means that you will not be able to reach those variables from outside the function call, even if you call the function again. Also, you recreate these objects, yet, instead of that, you would need to ensure that you are able to keep track of the variables that you intend to use and to not recreate your canvas object. A quick fix is here:
var canvas = new fabric.Canvas('c');
var icons = {
green: null,
yellow: null,
red: null
};
function iconSet() {
for (var ic in icons)
if (icons[ic]) {
canvas.remove(icons[ic]);
icons[ic] = null;
}
if (document.getElementById("green").checked == true) {
var iconGreen = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: 'green'
});
canvas.add(icons.green = iconGreen);
canvas.on('mouse:move', function(obj) {
iconGreen.top = obj.e.y - 30;
iconGreen.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
iconGreen.top = -100;
iconGreen.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(iconGreen.clone());
canvas.renderAll();
})
} else if (document.getElementById("yellow").checked == true) {
var iconYellow = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: 'yellow'
});
canvas.add(icons.yellow = iconYellow);
canvas.on('mouse:move', function(obj) {
iconYellow.top = obj.e.y - 30;
iconYellow.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
iconYellow.top = -100;
iconYellow.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(iconYellow.clone());
canvas.renderAll();
})
} else if (document.getElementById("red").checked == true) {
var iconRed = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: 'red'
});
canvas.add(icons.red = iconRed);
canvas.on('mouse:move', function(obj) {
iconRed.top = obj.e.y - 30;
iconRed.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
iconRed.top = -100;
iconRed.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(iconRed.clone());
canvas.renderAll();
})
}
}
along the ideas I have explained, see the Fiddle. You might want to refactor this further, but this is a good start.
This is probably what you need. I have also cleaned up the code make it shorter JsFiddle: https://jsfiddle.net/96nceasu/3/
var canvas = new fabric.Canvas('c');
function iconSet(ele){
var icon = new fabric.Triangle({
width: 62.5,
height: 50,
originX: 'center',
originY: 'center',
fill: ele.id
});
canvas.add(icon);
canvas.on('mouse:move', function(obj) {
icon.fill = ele.id;
icon.top = obj.e.y - 30;
icon.left = obj.e.x - 10;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
icon.top = -100;
icon.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(icon.clone());
canvas.renderAll();
})
}
canvas{
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
Green<input name="iconType" type="radio" id="green" onclick="iconSet(this)" /> Yellow
<input name="iconType" type="radio" id="yellow" onclick="iconSet(this)" /> Red
<input name="iconType" type="radio" id="red" onclick="iconSet(this)" />
<canvas id="c" width="600" height="600"></canvas>

How can I delete a fabric canvas arrow?

I created an arrow using Fabric.js group functionality by grouping Rectangle and Triangle.
Unfortunately I am not able to delete it as a group.
I figured out that getActiveObject() for a single object works fine. Instead, while debugging getActiveGroup() gives error.
var canvas = new fabric.Canvas('canvas');
canvas.setHeight(window.innerHeight * 0.75);
canvas.setWidth(window.innerWidth * 0.75);
//-------------------------Group - Rectangle and Triangle----------------------------------------------
window.addArrow = function() {
var rect = new fabric.Rect({
left: 0,
top: 0,
stroke: 'red',
fill: 'red',
width: 1,
height: 50,
});
rect.hasRotatingPoint = true;
canvas.add(rect);
var triangle = new fabric.Triangle({
width: 10,
height: 10,
fill: 'red',
left: -4,
top: -10
});
var group = new fabric.Group([rect, triangle], {
left: 150,
top: 100,
angle: 90
});
canvas.add(group);
}
//-------------------------Group Delete----------------------------------------------
window.deleteObject = function() {
return canvas.getActiveObject() == null ? canvas.getActiveGroup() : canvas.getActiveObject();
}
function getActiveGroup() {
canvas.getActiveGroup().forEachObject(function(o) {
canvas.remove(o)
});
}
function getActiveObject() {
canvas.remove(canvas.getActiveObject());
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.min.js"></script>
<canvas id="canvas" width="800" height="600" style="border:1px solid red;"></canvas>
<button onClick="addArrow()">Arrow</button>
<button onClick="deleteObject()">Delete</button>
Because you didn't set any active object you cannot use getActiveObject.
In this case you may use getObjects:
canvas.getObjects('group') // in order to get the group
canvas.getObjects('rect') // in order to get the rectangle
var canvas = new fabric.Canvas('canvas');
canvas.setHeight(window.innerHeight * 0.75);
canvas.setWidth(window.innerWidth * 0.75);
//-------------------------Group - Rectangle and Triangle----------------------------------------------
window.addArrow = function() {
var rect = new fabric.Rect({
left: 0,
top: 0,
stroke: 'red',
fill: 'red',
width: 1,
height: 50,
});
rect.hasRotatingPoint = true;
canvas.add(rect);
var triangle = new fabric.Triangle({
width: 10,
height: 10,
fill: 'red',
left: -4,
top: -10
});
var group = new fabric.Group([rect, triangle], {
left: 150,
top: 100,
angle: 90
});
canvas.add(group);
}
//-------------------------Group Delete----------------------------------------------
window.deleteObject = function() {
// remove group....
canvas.getObjects('group').forEach(function(ele,idx) {
canvas.remove(ele);
});
canvas.getObjects('rect').forEach(function(ele,idx) {
canvas.remove(ele);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.min.js"></script>
<canvas id="canvas" width="800" height="600" style="border:1px solid red;"></canvas>
<button onClick="addArrow()">Arrow</button>
<button onClick="deleteObject()">Delete</button>
use sub classing in fabric.js for creating arrow object so that single object is only needed. So handling will be easier.
[http://fabricjs.com/fabric-intro-part-3#subclassing][1]

FabricJS circle to show radius

I am using fabricjs in my project but I want to show the radius of the circle on the fabric. Could I ask how to do this. There could be up to 20 circles which I will need this information for and the circles will have controls on so they can be expanded with the radius text adjusting to compensate.
http://jsfiddle.net/wayneker/a3q5c40r/
var canvas = new fabric.Canvas('canvas');
var circle = new fabric.Circle({
left: 50,
top: 50,
fill: "",
radius: 40,
hasControls: false,
hasRoatatingPoint: false,
stroke: 'red',
strokeWidth: 1
});
canvas.add(circle); 
If this isn't possible, can a user set the radius via an input?
I'm not really sure what you are trying to do. In the example below I have a button that ads a group to the canvas of a circle and text box. When one of those groups are selected a range input appears that lets you change the radius. on change we reach in to the group and update the text and radius of the circle.
window.canvas = new fabric.Canvas('canvas');
function getCircleGroup(radius = 40) {
var text = new fabric.Text(radius.toString(), {
left: 50,
top: 50,
});
var circle = new fabric.Circle({
left: 50,
top: 50,
fill: "",
radius: radius,
hasControls: false,
hasRoatatingPoint: false,
stroke: 'red',
strokeWidth: 1
});
return new fabric.Group([ circle, text ], {
lockScalingX: true,
lockScalingY: true,
});
}
var button = document.querySelector('button');
button.addEventListener('click', () => {
var group = getCircleGroup();
canvas.add(group);
canvas.setActiveObject(group);
canvas.renderAll();
});
canvas.on('object:selected', (o) => {
var r = document.querySelector('.radiusChange');
r.style.display = 'block';
r.querySelector('input').value = o.radius;
})
canvas.on('selection:cleared', () => {
var r = document.querySelector('.radiusChange');
r.style.display = 'none';
});
var radiusChanger = document.querySelector('.radiusChange input')
radiusChanger.addEventListener('change', (e) => {
var group = canvas.getActiveObject();
var top = group.top;
var left = group.left;
group.item(0).setRadius(parseInt(e.target.value));
group.item(1).text = e.target.value;
group._calcBounds();
group._updateObjectsCoords();
group.top = top;
group.left = left;
canvas.renderAll();
})
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.6/fabric.min.js"></script>
<button>add circle</button>
<div class="radiusChange" style="display:none;">
<br />change radius: <input type="range" max=100 min=10 step=1 /></div>
<canvas id="canvas" width="300" height="300" style="border:1px solid;"></canvas>

Why does polygon gets misplaced when i pass transformed points?

Below is my code , when I modify the object I get transformed points so when I pass those transformed points, it places the object at slightly different position. I want have the modified shapes point's coordinates for which i multiplied each point with transform matrix and got new points, but when i pass those points to draw the same polygon, it places slightly at different position. So do i have to do any configuration?, My jsfiddle is https://jsfiddle.net/sL2np4wj/7/
<!-- fabric js code -->
<!DOCTYPE html>
<head>
<meta charset="UTF-8" />
<title>Fabric</title>
<script src="fabric.js\dist\fabric.min.js"></script>
<script src="js/fabric.canvasex"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"></script>
<style>
#canvas-container {
position: relative;
width: 640px;
height: 480px;
box-shadow: 0 0 5px 1px black;
margin: 10px auto;
border: 5px solid transparent;
}
#canvas-container.over {
border: 5px;
}
#images img.img_dragging {
opacity: 0.4;
}
</style>
</head>
<body>
<div id="images">
<img draggable="true" id="triangle" src="Images\triangle.png" width="50" height="50"></img><br/>
<img draggable="true" id="pentagon" src="Images\polygon.png" width="50" height="50"></img><br/>
<img draggable="true" id="rectangle" src="Images\square.png" width="50" height="50"></img><br/>
<img draggable="true" id="hexagon" src="Images\hexagon.png" width="50" height="50"></img><br/>
</div>
<div id="canvas-container">
<canvas id="canvas" width="640" height="480"></canvas>
</div>
<script>
$(document).ready(function() {
var canvas = new fabric.Canvas('canvas');
canvas.setBackgroundImage('file:///D:/New folder/Images/roi_image.png', canvas.renderAll.bind(canvas), {
width: canvas.width,
height: canvas.height,
backgroundColor:'white',
originX: 'left',
originY: 'top'
});
function handleDragStart(e) {
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
this.classList.add('img_dragging');
}
function handleDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
e.dataTransfer.dropEffect = 'copy';
return false;
}
function handleDragEnter(e) {
this.classList.add('over');
}
function handleDragLeave(e) {
this.classList.remove('over');
}
function handleDrop(e) {
if (e.stopPropagation) {
e.stopPropagation();
e.preventDefault();
}
var img = document.querySelector('#images img.img_dragging');
console.log('event: ', e);
console.log('image: ', img.id);
if(img.id === 'triangle') {
console.log('image: hereTriangle');
var id="shape"+0;
var points=[{"x":431.46311475409834,"y":182.35576211353316},{"x":366.0532786885246,"y":208.33652422706632},{"x":366.0532786885246,"y":156.375}];
var triangle = new fabric.Polygon(points,{
id:id,
fill: "transparent",
strokeWidth:0.75,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
transparentCorners: false
});
canvas.add(triangle);
//triangle.transformMatrix = [ 1, 0, 0, 1, 0, 0 ];
}else if(img.id === 'rectangle'){
var points1=regularPolygonPoints(4,30);
var rect = new fabric.Polygon(points1,{
fill: "transparent",
strokeWidth:0.75,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
top:e.layerY,
left:e.layerX,
transparentCorners: false
});
canvas.add(rect);
}else if(img.id === 'pentagon'){
var points=regularPolygonPoints(5,30);
var pentagon = new fabric.Polygon(points,{
width: 50,
height: 50,
fill: "transparent",
strokeWidth:0.25,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
top:e.layerY,
left:e.layerX,
transparentCorners: false
});
canvas.add(pentagon);
}else if(img.id === 'hexagon'){
var points=regularPolygonPoints(6,30);
var pentagon = new fabric.Polygon(points,{
fill: "transparent",
strokeWidth:0.25,
stroke:'rgb(255,0,0)',
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
transparentCorners: false,
left: e.layerX,
top: e.layerY
});
canvas.add(pentagon);
}else{
console.log('image: here');
var newImage = new fabric.Image(img, {
width: img.width,
height: img.height,
fill:"rgb(0,0,255)",
borderColor: 'red',
cornerColor: 'green',
cornerSize: 6,
transparentCorners: false,
// Set the center of the new object based on the event coordinates relative
// to the canvas container.
left: e.layerX,
top: e.layerY
});
canvas.add(newImage);
}
return false;
}
function regularPolygonPoints(sideCount,radius){
var sweep=Math.PI*2/sideCount;
var cx=radius;
var cy=radius;
var points=[];
for(var i=0;i<sideCount;i++){
var x=cx+radius*Math.cos(i*sweep);
var y=cy+radius*Math.sin(i*sweep);
console.log("VALUE OF X :"+x);
points.push({x:x,y:y});
}
console.log("points "+JSON.stringify(points));
return(points);
}
function handleDragEnd(e) {
// this/e.target is the source node.
[].forEach.call(images, function (img) {
img.classList.remove('img_dragging');
});
}
// Bind the event listeners for the image elements
var images = document.querySelectorAll('#images img');
[].forEach.call(images, function (img) {
img.addEventListener('dragstart', handleDragStart, false);
img.addEventListener('dragend', handleDragEnd, false);
});
// Bind the event listeners for the canvas
var canvasContainer = document.getElementById('canvas-container');
canvasContainer.addEventListener('dragenter', handleDragEnter, false);
canvasContainer.addEventListener('dragover', handleDragOver, false);
canvasContainer.addEventListener('dragleave', handleDragLeave, false);
canvasContainer.addEventListener('drop', handleDrop, false);
canvas.on('object:modified',function(e){
addDeleteBtn(e.target.oCoords.mt.x, e.target.oCoords.mt.y, e.target.width);
var obj=e.target;
var polygon = e.target;
var matrix=[];
matrix=polygon.calcTransformMatrix();
console.log("Matrix : "+JSON.stringify(matrix));
var translatedPoints = polygon.get('points').map(function(p) {
return {
x: matrix[0] * p.x + matrix[2] * p.y + matrix[4],
y: matrix[1] * p.x + matrix[3] * p.y + matrix[5]
};
});
<!-- transformed points -->
console.log("Modified points :"+JSON.stringify(translatedPoints));
});
});

Categories