How to use the fabric.js library with the online library url? - javascript

I'm trying to insert the Fabric.js library to test some things with:
<script src='https://unpkg.com/fabric#latest/dist/fabric.js'></script>
But apparently dosen't work...
I'm just trying to do a basic free canvas like:
var canvas = this.__canvas = new fabric.Canvas('c', {
isDrawingMode: true
});
var rect = new fabric.Rect({
top: 100,
left: 100,
width: 60,
height: 70,
fill: 'red',
});
canvas.add(rect);
canvas.renderAll();
But still nothing appears on my project, i can't do or paint anything..
Anyone with some answers?

I think you need canvas element the html in order for fabricjs to work.
There are two ways to fix achieve this
Option 1. - Add canvas element in html.
<canvas id="c"/>
var canvas = this.__canvas = new fabric.Canvas('c', {
isDrawingMode: true
});
var rect = new fabric.Rect({
top: 100,
left: 100,
width: 60,
height: 70,
fill: 'red',
});
canvas.add(rect);
canvas.renderAll();
canvas {
border-style: groove;
}
<canvas id="c" />
<script src='https://unpkg.com/fabric#latest/dist/fabric.js'></script>
Option 2. - Add canvas element in html using javascript.
var mycanvas = document.createElement("canvas");
mycanvas.id = "mycanvas";
document.body.appendChild(mycanvas);
var mycanvas = document.createElement("canvas");
mycanvas.id = "c";
document.body.appendChild(mycanvas);
var canvas = this.__canvas = new fabric.Canvas('c', {
isDrawingMode: true
});
var rect = new fabric.Rect({
top: 100,
left: 100,
width: 60,
height: 70,
fill: 'red',
});
canvas.add(rect);
canvas.renderAll();
canvas {
border-style: groove;
}
<script src='https://unpkg.com/fabric#latest/dist/fabric.js'></script>

Related

Offset issues images when inside group (scaleToWidth)

I'm experiencing an issue when scaling an image inside a group the offset of the image changes. The group consists of a background (Rect) and an image. When scaling the group the offset if the image becomes different. Expected is that the offset remains the same as the background.
I'm using Fabric 4.0.0-beta.6
const canvas = new fabric.Canvas('canvas');
canvas.setWidth(document.body.clientWidth);
canvas.setHeight(document.body.clientHeight);
const bg = new fabric.Rect({
width: 100,
height: 100,
fill: 'red',
});
fabric.Image.fromURL("https://dummyimage.com/300x150/000/fff", function(img) {
img.scaleToWidth(bg.width)
const post = new fabric.Group([bg, img], {
left: 100,
top: 100,
});
post.scaleToWidth(400);
canvas.add(post);
canvas.renderAll();
});
https://jsbin.com/migogekoxu/1/edit?html,css,js,output
Setting the strokeWidth property of the background element to 0 fixed the offset for me.
const canvas = new fabric.Canvas('canvas');
canvas.setWidth(document.body.clientWidth);
canvas.setHeight(document.body.clientHeight);
const bg = new fabric.Rect({
width: 100,
height: 100,
fill: 'red',
strokeWidth: 0, //<---
});
fabric.Image.fromURL("https://dummyimage.com/300x150/000/fff", function(img) {
img.scaleToWidth(bg.width)
const post = new fabric.Group([bg, img], {
left: 100,
top: 100,
});
post.scaleToWidth(400);
canvas.add(post);
canvas.renderAll();
});
<canvas id="canvas"></canvas>
<script src="https://cdn.jsdelivr.net/npm/fabric#4.0.0-beta.6-browser/dist/fabric.min.js"></script>
Obviously that's a bug with fabricJS. If you don't want to fix it on your own in it's source code you can workaround it however.
You can manually correct the position by adding an offset of 0.5 to the image's top and left properties.
For example:
const canvas = new fabric.Canvas('canvas');
const bg = new fabric.Rect({
width: 100,
height: 100,
fill: 'red'
});
fabric.Image.fromURL("https://dummyimage.com/300x150/000/fff", function(img) {
img.scaleToWidth(bg.width);
img.left += 0.5;
img.top += 0.5;
const post = new fabric.Group([bg, img], {
left: 100,
top: 100
});
post.scaleToWidth(400);
canvas.add(post);
canvas.renderAll();
});
<script src="https://cdn.jsdelivr.net/npm/fabric#4.0.0-beta.6-browser/dist/fabric.min.js"></script>
<canvas id="canvas" width="600" height="400"></canvas>

fabric.js how to use fromObject api

I want to implement importing data from one template into another without affecting data from the other. Using deserialization API loadFromJson will empty the canvas data first, so I want to use toObect method to export the data, and then use toFromObject to import, but the object cannot display correctly after the import, may I ask if there is any solution?Or is there another implementation?thank you
demo: https://jsfiddle.net/laibin/gpvef0k5/2/
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/3.3.2/fabric.min.js"></script>
<canvas id="canvas" style="border: 1px solid black" height=480 width=460></canvas>
<button id="btn">导出</button>
<canvas id="canvas_template" style="border: 1px solid black; margin-top: 20px" height=480 width=660></canvas>
Javascript:
var canvas = new fabric.Canvas('canvas');
var canvas_template = new fabric.Canvas('canvas_template');
var circle = new fabric.Circle({
radius: 50, left: 275, top: 75, fill: '#aac'
})
var triangle = new fabric.Triangle({
width: 100, height: 100, left: 50, top: 300, fill: '#cca'
});
var rect1 = new fabric.Rect({
width: 200, height: 100, left: 0, top: 50, angle: 30,
fill: 'rgba(255,0,0,0.5)'
});
var group = new fabric.Group([circle, triangle, rect1])
canvas.add(group).setActiveObject(group);
canvas.renderAll();
document.querySelector('#btn').addEventListener('click',function() {
var data = group.toObject();
let newGroup = new fabric.Group([]);
fabric.Group.fromObject(data, function(obj) {
console.log('newGroup', obj)
canvas_template.setActiveObject(obj).renderAll();
})
})
You never added the resulting object to canvas, that's why you didn't see it, only the selection made by setActiveObject(). You should add the object in the fromObject() callback:
fabric.Group.fromObject(data, function(obj) {
canvas_template.add(obj) // <- like this
console.log('newGroup', obj)
canvas_template.setActiveObject(obj).renderAll();
})

No able to save fabric canvas as image using FileSaver.js

I have included Fabric.js and Filesaver.js in my code but still
I am getting "Uncaught SecurityError: Failed to execute 'toBlob' on 'HTMLCanvasElement': Tainted canvases may not be exported." error whenever I am trying to save the fabric canvas.
I referred: https://www.youtube.com/watch?v=ng8OJ6a-wQY
Is there a way I could be able to save the canvas to a shared directory location?
//-----------------------------Getting hold of Canvas---------------------------------------
var canvas = new fabric.Canvas('canvas');
canvas.setHeight(window.innerHeight * 0.75);
canvas.setWidth(window.innerWidth * 0.75);
drawBackground();
//--------------------------Image Rendering-------------------------------------------------
function drawBackground() {
fabric.Image.fromURL('https://upload.wikimedia.org/wikipedia/commons/f/f9/Phoenicopterus_ruber_in_S%C3%A3o_Paulo_Zoo.jpg', function(img) {
img.crossOrigin = "Anonymous";
img.scaleToWidth(window.innerWidth * 0.75);
img.scaleToHeight(window.innerHeight * 0.75);
canvas.setBackgroundImage(img);
canvas.renderAll();
});
}
//------------------------Rectangle---------------------------------------------------------
window.addRect = function() {
var box = new fabric.Rect({
left: 0,
top: 0,
stroke: 'red',
fill: 'rgba(255,0,0,.4)',
width: 50,
height: 50,
});
box.hasRotatingPoint = false;
canvas.add(box);
}
//---------------------Circle-------------------------------------------------------------
window.addCircle = function() {
var circle = new fabric.Circle({
left: 0,
top: 0,
radius: 50,
stroke: 'green',
fill: 'transparent',
});
circle.hasRotatingPoint = false;
canvas.add(circle);
}
//-----------------------Line Arrow-----------------------------------------------------
window.addArrow = function() {
var arrowbox = new fabric.Rect({
left: 0,
top: 0,
stroke: 'red',
fill: 'red',
width: 1,
height: 50,
});
var arrowtriangle = new fabric.Triangle({
width: 10, height: 10, fill: 'red', left: -4, top: -10
});
var arrowgroup = new fabric.Group([ arrowbox, arrowtriangle ], {
left: 150,
top: 100,
angle: 90
});
canvas.add(arrowgroup);
}
//-----------------------Save Canvas---------------------------------------------------------
window.saveCanvas = function(){
canvas.getElement().toBlob(function(blob){
saveAs(blob, annotation.png);
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.min.js"></script>
<script src="https://fastcdn.org/FileSaver.js/1.1.20151003/FileSaver.min.js"></script>
<canvas id="canvas" width="800" height="600" style="border:1px solid red;"></canvas>
<button onClick="addCircle()">Circle</button>
<button onClick="addRect()">Box</button>
<button onClick="addArrow()">Arrow</button>
<button onClick="saveCanvas()">Save</button>
I am also facing same problem using fabric js. My current solution is encode the canvas element to base64 string using toDataUrl() and send it to server side code to decode it again, then write it as image file. I am using PHP on the server side

Fabric JS Custom cursor style

I need to change the cursor types as "Handwriting" on hover shapes...
var canvas = window._canvas = new fabric.Canvas('ImgCanvas');
function changeCursor(cursorType) {
canvas.defaultCursor = "Handwriting";
}
I tried this but not working
You can change the hoverCursor directly to the single shape, or globally to the entire canvas. Take a look to the snippet below.
var canvas = this.__canvas = new fabric.Canvas('c');
// pointer for all
canvas.hoverCursor = 'pointer';
var rect = new fabric.Rect({
left: 50,
top: 30,
width: 100,
height: 100,
fill: 'green',
angle: 20,
});
var rect2 = new fabric.Rect({
left: 180,
top: 30,
width: 100,
height: 100,
fill: 'green',
angle: 20,
});
canvas.add(rect);
canvas.add(rect2);
canvas.renderAll();
var canvas2 = this.__canvas = new fabric.Canvas('c2');
var rect = new fabric.Rect({
left: 120,
top: 30,
width: 100,
height: 100,
fill: 'green',
angle: 20,
// pointer for the selected shape
hoverCursor: "pointer"
});
canvas2.add(rect);
canvas2.renderAll();
p{font-family:'arial'}
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.js"></script>
<p>Applied Globally</p>
<canvas height=200 width=300 id="c" style="border:1px solid black"></canvas>
<p>Applied individually</p>
<hr/>
<canvas height=200 width=300 id="c2" style="border:1px solid black"></canvas>
Surendhar,
To change cursor over the shape you need to defined as:
canvas.hoverCursor = 'cursor type'
This is a list of cursors
If you need custom cursor you have to create div element on top the fabric canvas with custom cursor. When you have event 'mouseover' the shape just specified canvas.hoverCursor = 'none', and show custom one.
You can check this fiddle it is simple example of custom cursor. You have to revisit this code in order to work without refreshing of custom cursor. It is all about mouse-over events of custom cursor. You have to disable mouse-over event of each div element of custom cursor.
For fabric 4.6, besides the default cursors, also be able to set custom cursor with png:
const canvas = new fabric.Canvas('c');
const cursorUrl = 'https://ossrs.net/wiki/images/figma-cursor.png';
canvas.defaultCursor = `url(" ${cursorUrl} "), auto`;
canvas.hoverCursor = `url(" ${cursorUrl} "), auto`;
canvas.moveCursor = `url(" ${cursorUrl} "), auto`;
CodePen
Here's a simple way to customize the cursor and create a hand grab effect when moving an object.
this.canvas = new fabric.Canvas('canvas', {
defaultCursor:'default',
hoverCursor: 'grab',
moveCursor:'grabbing',
selection: true,
backgroundColor: '#ffffff',
});
Here you find the list of all cursors
https://www.w3schools.com/cssref/playit.asp?filename=playcss_cursor&preval=alias
To change the cursor of a fabric.js object, you can set the hoverCursor or moveCursor to your own image.
E.g:
object.set({hoverCursor: 'url("https://s3-us-west-2.amazonaws.com/s.cdpn.io/9632/happy.png"), auto'});

Fabric.js - Attach object creation to mouse click

When you create a new fabric object, you can specify the location for it to appear on the canvas. Is there a way to attach the generated object to the mouse and then place the object on click (or touch)?
E.g. way to generate a circle which appears on the canvas.
var circle = new fabric.Circle({
radius: 20, fill: 'green', left: 100, top: 100
});
It's fairly easy to update the position of an object to match that of the mouse's position and on mouse:up clone that object and place it on the canvas.
var canvas = new fabric.Canvas('c');
var mousecursor = new fabric.Circle({
left: 0,
top: 0,
radius: 5,
fill: '#9f9',
originX: 'right',
originY: 'bottom',
})
canvas.add(mousecursor);
canvas.on('mouse:move', function(obj) {
mousecursor.top = obj.e.y - mousecursor.radius;
mousecursor.left = obj.e.x - mousecursor.radius;
canvas.renderAll()
})
canvas.on('mouse:out', function(obj) {
// put circle off screen
mousecursor.top = -100;
mousecursor.left = -100;
canvas.renderAll()
})
canvas.on('mouse:up', function(obj) {
canvas.add(mousecursor.clone())
canvas.renderAll()
})
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>
var canvas = new fabric.Canvas('c');
var mousecursor = new fabric.Circle({
left: 0,
top: 0,
radius: 50,
fill: '#9f9',
originX: 'right',
originY: 'bottom',
})
canvas.add(mousecursor);
canvas.on('mouse:move', function(obj) {
mousecursor.top = obj.e.y;
mousecursor.left = obj.e.x;
canvas.renderAll()
})
canvas {
border: 1px solid #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.js"></script>
<canvas id="c" width="600" height="600"></canvas>

Categories

Resources