Coder Social home page Coder Social logo

fabricjs / fabric.js Goto Github PK

View Code? Open in Web Editor NEW
27.5K 476.0 3.4K 219.12 MB

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser

Home Page: http://fabricjs.com

License: Other

JavaScript 53.45% HTML 0.08% Mustache 0.10% TypeScript 46.33% CSS 0.01% Vue 0.03%

fabric.js's Introduction

Fabric.js

A simple and powerful Javascript HTML5 canvas library.


🩺 πŸ§ͺ CodeQL


cdnjs jsdelivr Gitpod Ready-to-Code

NPM Downloads per month Bower


Sponsor asturur Sponsor melchiar Sponsor ShaMan123 Patreon


Features

  • Out of the box interactions such as scale, move, rotate, skew, group...
  • Built in shapes, controls, animations, image filters, gradients, patterns, brushes...
  • JPG, PNG, JSON and SVG i/o
  • Typed and modular
  • Unit tested

Supported Browsers/Environments

Context Supported Version Notes
Firefox βœ”οΈ modern version (tbd)
Safari βœ”οΈ version >= 10.1
Opera βœ”οΈ chromium based
Chrome βœ”οΈ modern version (tbd)
Edge βœ”οΈ chromium based
Edge Legacy ❌
IE11 ❌
Node.js βœ”οΈ Node.js installation

Fabric.js Does not use transpilation by default, the browser version we support is determined by the level of canvas api we want to use and some js syntax. While JS can be easily transpiled, canvas API can't.

Migrating to v6

v6 is a MAJOR effort including migrating to TS and es6, countless fixes, rewrites and features.
Currently in beta, refer to #8299 for guidance.

$ npm install fabric@beta --save
// or
$ yarn add fabric@beta

Installation

$ npm install fabric --save
// or
$ yarn add fabric

Browser

cdnjs jsdelivr

See browser modules for using es6 imports in the browser or use a dedicated bundler.

Node.js

Fabric.js depends on node-canvas for a canvas implementation (HTMLCanvasElement replacement) and jsdom for a window implementation on node. This means that you may encounter node-canvas limitations and bugs.

Follow these instructions to get node-canvas up and running.

Quick Start

// v6
import { Canvas, Rect } from 'fabric'; // browser
import { StaticCanvas, Rect } from 'fabric/node'; // node

// v5
import { fabric } from 'fabric';
Plain HTML
<canvas id="canvas" width="300" height="300"></canvas>

<script src="https://cdn.jsdelivr.net/npm/fabric"></script>
<script>
  const canvas = new fabric.Canvas('canvas');
  const rect = new fabric.Rect({
    top: 100,
    left: 100,
    width: 60,
    height: 70,
    fill: 'red',
  });
  canvas.add(rect);
</script>
ReactJS
import React, { useEffect, useRef } from 'react';
import * as fabric from 'fabric'; // v6
import { fabric } from 'fabric'; // v5

export const FabricJSCanvas = () => {
  const canvasEl = useRef<HTMLCanvasElement>(null);
  useEffect(() => {
    const options = { ... };
    const canvas = new fabric.Canvas(canvasEl.current, options);
    // make the fabric.Canvas instance available to your app
    updateCanvasContext(canvas);
    return () => {
      updateCanvasContext(null);
      canvas.dispose();
    }
  }, []);

  return <canvas width="300" height="300" ref={canvasEl}/>;
};
Node.js
import http from 'http';
import * as fabric from 'fabric/node'; // v6
import { fabric } from 'fabric'; // v5

const port = 8080;

http
  .createServer((req, res) => {
    const canvas = new fabric.Canvas(null, { width: 100, height: 100 });
    const rect = new fabric.Rect({ width: 20, height: 50, fill: '#ff0000' });
    const text = new fabric.Text('fabric.js', { fill: 'blue', fontSize: 24 });
    canvas.add(rect, text);
    canvas.renderAll();
    if (req.url === '/download') {
      res.setHeader('Content-Type', 'image/png');
      res.setHeader('Content-Disposition', 'attachment; filename="fabric.png"');
      canvas.createPNGStream().pipe(res);
    } else if (req.url === '/view') {
      canvas.createPNGStream().pipe(res);
    } else {
      const imageData = canvas.toDataURL();
      res.writeHead(200, '', { 'Content-Type': 'text/html' });
      res.write(`<img src="${imageData}" />`);
      res.end();
    }
  })
  .listen(port, (err) => {
    if (err) throw err;
    console.log(
      `> Ready on http://localhost:${port}, http://localhost:${port}/view, http://localhost:${port}/download`
    );
  });

See our ready to use templates.


Other Solutions

Project Description Demo
Three.js 3D graphics
PixiJS WebGL renderer
Konva Similar features ❌
html-to-image HTML to image/canvas

More Resources

Credits Patreon

fabric.js's People

Contributors

asturur avatar davidjrice avatar garg avatar github-actions[bot] avatar gloriousjob avatar gordorank avatar gregtap avatar inssein avatar jafferhaider avatar jiayihu avatar kangax avatar kienz avatar kjtsanaktsidis avatar melchiar avatar melight avatar miracle2k avatar msievers avatar rockerboo avatar rodovich avatar rykerwilliams avatar sapics avatar shaman123 avatar sjpemberton avatar sorich87 avatar stefanhayden avatar timandres avatar twffy avatar xhmikosr avatar xxorax avatar zigotica avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fabric.js's Issues

Canvas element gets positioned 'absolute' and loses it predefined position.

I use this to create a new canvas element:
fabricCanvas = new fabric.Element('canvasHTMLElementId');

After initialization the canvas css style attribute 'position' is set to 'absolute' and its 'top' and 'left' attribute to 0. Why? The result is that my element is placed at the left-top corner of the document!

Further I'm confused about that you are wrapping the canvas element in an div container and adding TWO further identical elements. My code results in this:

<div class="canvas_container" style="width: 738px; height: 80px; -moz-user-select: none;">
     <canvas class="canvas-container" width="738" height="80" style="width: 738px; height: 80px; position: absolute; left: 0pt; top: 0pt; -moz-user-select: none;"></canvas>
     <canvas class="canvas-container" width="738" height="80" style="width: 738px; height: 80px; position: absolute; left: 0pt; top: 0pt; -moz-user-select: none;"></canvas>
     <canvas id="canvasHTMLElementId" width="738" height="80" style="position: absolute; width: 738px; height: 80px; left: 0pt; top: 0pt; cursor: default;"></canvas>
</div>

I've played around with firebug and found out that if you add a "position: relative;" to the style of the <div> container at least my canvas is positioned correctly and RELATIVE to the position of the <div>. It then is at the position I've defined in my CSS file.

Please fix this. I can't use fabric.js with this bug.
I'm using Ubuntu 10.10 and Firefox 4.0.

Thanks a lot!
Lufti

Background scaling bug with toDataURLWithMultiplier

Saving a fabric.js canvas with a background color as an image with the help of toDataURLWithMultiplier makes the background scale strange.

The problem can be reproduced in the kitchensink demo if you execute the following code:

canvas.backgroundColor = "#ff0000";
canvas.renderAll();
console.log(canvas.toDataURLWithMultiplier("jpeg", 0.3));  // Take the string and paste in in the address bar

The background only appears in the upper left corner and only covers about 1/9 of the whole canvas.

Using Google Chrome 15.0.865.1000 dev-m and Mozilla Firefox 3.6.13

bringForward and sendBackward problem

I have noticed that using bringForward or sendBackward fails when the objects we are trying to move have their bounding box limits contained into a bigger object. If I move the object so it's bounding box is partially contained only, then the object will move up or down he stack... Looked at the source, it looks like it coming from the fact that those two methods use the intersectsWithObject method which must fail when one objects boundaries covers totally the other... bug?

Remove Prototype.js as a dependency.

For DOM + events + XHR use (already included) APE library. For array, string and function helpers (e.g. Function#bind, Array#map, String#trim, etc.) β€” create small standalone module (possibly under Canvas.util).

text rendering isn't working

Hey,

we just spend a couple of hours trying to render text in a canvas, using cufon for the fonts. We have the assumption that the _render method in text.class.js is somehow not complete, as there is nothing happening that would render the text. Can you give us any hint how we can get it working?

The result we want is that we can specify font family and font color of the text, and make the text element resizable etc, like a normal canvas element. The rest of the library is awesome so far, so we'd rather not switch now.

Any hints very much appreciated!

Help with loadFromJSON & loadFromDatalessJSON

Hi kangax -- I am pulling my hair out trying to save a canvas state and reload it later. I am having zero success with either loadFromJSON and loadFromDatalessJSON (by the way, what is datalessJSON?). I have tried to put some elements on my canvas (they are loaded from svg), save the canvas as JSON (canvas.toJSON) into a variable. Clear the canvas, try to reload using one of the 2 methods mentioned above, and keep getting errors... I have tried from a JSON file, errors as well. My JSON was valid (I checked), but maybe not for what is expected by Canvas... it is not described in the doc, is it?

code example:

Myapp.mycanvas = Myapp.canvas.toJSON();
Myapp.canvas.loadFromJSON(Myapp.mycanvas);

The error:

JSON.parse: unexpected character
[Break On This Error] var Cufon=(function(){var k=function()....Image.fromElement.async=true})(this);

Down the line, do you think you could post an example of loading the result of a saved canvas back into a blank canvas? I have not seen anything like that in the examples, kitchensink etc...

undo & redo support

I saw a post about this topic written in april but still there is no module for undo & redo. I think it's an important for these kind of jobs. Is there any plan to do this?

toDatalessJSON -> loadFromDatalessJSON doesnt always keep the "z-index sorting"

When having a lot of objects in the canvas, then saving it with toDatalessJSON and then loading it back into the canvas at another time (could be after a simple page reload) with loadFromDatalessJSON doesn't always keep the sorting (z-index) of layers as when you saved it. It seems to happen kinda random, some layers are still in the correct z-index, but some isn't.

I would guess that it has something with the load function to do with since you can with the same JSON get different result on each load

Objects resize/scale controls to be always on top

Would it be possible to have the border with controls on an active object always on top (maybe in a new canvas above the one with objects)?

Say for example that you have a list of all the objects in the canvas in a sidebar where you can select objects to bring forward, delete, send backward etc. From this list, you select an object that gets activated in the canvas. The controls for resize, scale and rotate shows up around the object, but the object is behind another object and therefor the only thing that will happen is that you will select the object in front of the one you want to control.

Maybe it's already possible to have the controls above all objects in the canvas? I have missed stuff in the docs before, haha :)

Disable dragging of certain Objects

Is it possible to disable dragging of some Objects?
Would be nice to have this feature.

Couldn't find anything in the code. I wasn't able to figure out how your dragging is working. May you give us a short explaination?

canvas.backgroundColor

Using the canvas.backgroundColor on a canvas with rounded corners overlaps the corners (creating a rectangle)

canvas {

-moz-border-radius: 1em; 
-webkit-border-radius: 1em; 
border-radius: 1em;

}

Then in js: canvas.backgroundColor = 'rgba(....)' triggers this.

How do I draw a Polygon?

I've been trying draw Polygons but am getting the error: "array[i] is undefined fabric.js/all.js Line 1647".

Example of tries:
canvas.add(new fabric.Polygon({
points: [obj1, obj2, obj3, obj4] //obj has .x and .y
}));

canvas.add(new fabric.Polygon({ 
    points: [[thisPathRect[0][0],thisPathRect[0][1]], [thisPathRect[1][0],thisPathRect[1][1]], [thisPathRect[2][0],thisPathRect[2][1]], [thisPathRect[3][0],thisPathRect[3][1]]]
}));

Any ideas? (There don't seam to be any example on how to create a Polygon in fabric.js, I guess my best bet apart from asking here is understanding http://kangax.github.com/fabric.js/docs/symbols/src/src_polygon.class.js.html ).

How do I "scale"?

HTML Canvas support scaling by doing ctx.scale(x,y), how is that functionality exposed in fabric.js?

I tried doing..
var ctx = canvas.getContext();
ctx.scale(650, 650);
..but that doesn't seam to do anything.

Also, is this is the right place to be asking such questions?

drawBorders() problem with text-object

Do you have a solution for this problem (see screenshot)? The border lines are not set correctly for text-objects.
I used the latest version of all.js and the font delicous_500 from the project page.

With other fonts i have the same problem.

Thanks.

Array#indexOf and Function#bind shims don't follow ES5

The Array#indexOf fallback doesn't correctly handle negative fromIndex values so large negative values can cause the browser to lock up.

var array = ['a', 'b', 'c'];
array.indexOf('c', -1e9); // this will lock up the browser

While Function#bind is impossible to get 100% spec compliant (it may not have the correct length, and will have a prototype property), you can make the bound function work as spec'ed when called as a constructor.

function Alien(type) {
  this.type = type;
}

var thisArg = {};
var Tribble = Alien.bind(thisArg, 'Polygeminus grex');

// `thisArg` should **not** be used for the `this` binding when called as a constructor
var fuzzball = new Tribble;
console.log(fuzzball.type); // expected "Polygeminus grex"

removeActiveObject is misleading

  • removeActiveObject should actually remove object
  • discardActiveObject (new method) should do what removeActiveObject currently does β€” removes selection from an object.

add onerror in image loading functions

Hi,

When an image failed to load either the callback is never caller (fromURL) or the script crashed (fromObject).
Would it be possible to add an onerror event on the image?

For example, here's the work-around I did:
In fabric.Image.fromObject and fabric.Image.fromURL just below img.onload

    img.onerror = function() {
      if (callback) {
        callback(null);
      }
      img = img.onerror = null;
    };

This way the callback is still fired with a null value letting me handle this the way I want.

_enlivenObjects also needs a slight change in the switch case image:

fabric[capitalize(o.type)].fromObject(o, function (o) {
              //adding if to prevent failed image to crash
              if (o !== null) { 
                  _this.insertAt(o, index);
              }

Anyway, thanks for the awesome job !

Rect: Can't set rx and ry via constructor.

It's not possible to set the rx and ry values of a Rect with its constructor.

var background = new fabric.Rect({
    left: 0,
    top: 0,
    fill: '#FF0000',
    width: 100,
    height: 100,
    active: false,

    rx: 10,
    ry: 10
});

It's only working if I set it after initialization:

var background = new fabric.Rect({
    left: 0,
    top: 0,
    fill: '#FF0000',
    width: 100,
    height: 100,
    active: false
});
background.rx = 8;
background.ry = 8;

Or am I missing something? ;)
greetz Lufti

Underlays

It would be quite useful to have underlays (images that are permanently in background).

It's easy to implement them if you don't want (or need) them to show when you call canvas.toDataURL: just set the parent div css: background: #ffffff url(image.png) no-repeat right top.

@kangax, any tips as to how I could implement this? I could do it.

circle object radius is incorrect?

hi,
first off this is an awesome library. I'm using it for a pretty cool project which I will share soon.
The issue I'm running into is that on an object where obj.type="circle" (so, a circle object) the .radius property seems to be incorrect. Is that expected? Also, you would expect a 'getRadius()' method on a circle but I dont see it in the doc.
For now, getWidth()/2 will give the radius, but I feel that isnt the 'best' way. Just wanted to report this as an issue I ran into.
thanks

fabric.Canvas#loadFromJSON problem with various types of objects

If I load a JSON object that contains various objects (e.g. images, path-groups, triangles etc.) into fabric.Canvas the order of objects varies to the original order of the JSON object.
Is there a problem with loading images?

Examples:
1st times loaded => objects are placed incorrect

2nd times loaded => objects are placed correct

Objects:
cars => images
streets => images
rectangle, ellipse, triangle => rectangle, ellipse, triangle
street signs => svg
text => text

Thanks.

Support multiple sequences in bezier curves

For example, this does NOT work right now:

c 0,-53.25604 43.17254,-96.42858 96.42857,-96.42857 53.25603,0 96.42857,43.17254 96.42857,96.42857

but this does (note intermediate "c")

c 0,-53.25604 43.17254,-96.42858 96.42857,-96.42857 c 53.25603,0 96.42857,43.17254 96.42857,96.42857

Clicking on transparent pixel select element beneath

Clicking on a pixel selects the element using the bounding box in the demo. I'd like to test if it's a transparent pixel for that element, and if so select the element below it, recursively. I couldn't find a way in the docs to do this, but I'd be glad to help to implement if given a few pointers.

It seems that all that it would take is to add a test in Element::containsPoint() such as:

      // we iterate through each object. If target found, return it.
      var iLines = target._getImageLines(target.oCoords),
          xpoints = target._findCrossPoints(x, y, iLines);

      // check if pixel is transparent
      var color = target.getPixelColor(x, y);

      // if xcount is odd then we clicked inside the object
      // For the specific case of square images xcount === 1 in all true cases
      if (color.alpha > 0 && ((xpoints && xpoints % 2 === 1) || target._findTargetCorner(e, this._offset))) {
        return true;
      }

But I couldn't find a 'getPixelColor' method or similar....

Add support for disabling UI controls on objects

An option on fabric.Object to toggle controls; when turned off, fabric.Canvas β€” which manages change of cursor when mouse is within area of a control β€” would leave cursor alone. So cursor wouldn't change, controls wouldn't render, and clicking+dragging controls area would not have any effect. In that "controls-off" state, it would still be possible to move object (which can already be disabled); cursor would still change on mouseover (which could already be disabled as well); and it would still be possible to select an object, group it, etc.

Export as SVG?

I see in the demo that there is a "Rasterize canvas to image" option, but does fabric provide a way to export as SVG? If not, what would we need to do to implement that?

I see that it has been done in SVGCanvas: http://svgkit.sourceforge.net/tests/canvas_tests.html, but it looks like that is completely overriding the renderingcontext of the canvas. Without doing so, I could see it as not being possible to export the entire canvas, since you don't necessarily know what else has been added, but even if you were just able to export all of the fabric objects, that would be very nice.

Sprite based animations

Animations could be real animations, now they are more like transformations. There are two ways to achieve it - by CSS3 animations or by js background-position changing. CSS3 would require adding dom element for every animation, so I guess js animation would be a better choice.
I wanted to make a fork for that myself, but any comments before I start coding would be nice.

Make events consistent

Currently exposed events are:

object:scaled,
object:modified,
object:moved,
object:selected

group:selected_
before:group:destroyed,
after:group:destroyed

selection:cleared, path:created, after:render, mouse:up

The problem is that some of these are low level ("mouse:up"), others are high level ("group:selected", "object:moved", etc.). They are also inconsistent β€” there's "object:scaled" but no "group:scaled"; there's "mouse:up" but no "mouse:down".

Need to take care of all this.

Selecting selectable objects behind unselectable objects

If an object is unselectable, would it be possible to somehow select the first selectable object behind that object? Any functions I've missed in the documentation that already does this?

I made another issue a while ago (#22) that would probably work very well together with this (selecting selectable object behind unselectable objects).

Thanks!

Disable anti-alias?

It's currently not possible disable anti-aliasing right? I guess it should be done in the browsers implementation of canvas but while that's not here is it possible to work around it? What would be the optimal solution? At least for basic shapes.

This feature is desirable for people working with the "retro computer graphics style".

IE and SVG parsing

I’m trying to parse external SVG file using loadSVGFromURL() method and excanvas in IE, but nothing happens. I can’t even access callback values or alert simple message.
Everything works fine in other browsers.

I’ve tried with simple rectangle drawing and it works as it should, so I think it’s either invalid SVG file or I’m setting wrong some parameters.

Does excanvas (or fabric) have some limitations when trying to parse specific SVG files?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.