I can't use fabric.js canvas library in ionic 2 app


#1

I’m testing Fabric.js to create a canvas. I’ve made next steps to create the app and to include this library:

> ionic start canvas2 sidemenu --v2
> cd canvas2
> npm install fabric --save
> npm install @types/fabric --save

Whenever I try to create a canvas I get this error:

Page1 ionViewDidEnter error: __WEBPACK_IMPORTED_MODULE_2_fabric__.Canvas is not a constructor
The code that I've used is:

page1.ts

import fabric from 'fabric';
...
export class Page1 {
 canvas : fabric.Canvas;

 ionViewDidEnter() {

    this.canvas = new fabric.Canvas('c');
    .....
}
...

page1.html

....
<ion-content padding>
    <canvas id="c" style="border: 1px solid red"></canvas> 
</ion-content>

I don’t know how to fix this error. Any idea? Did I forget anything?

I’d be truly greatful if someone could help on this.


#2

Typically when using Webpack I’ve had better luck with

import * as fabric from 'fabric'

than with using the default import as you currently are. Not sure if it will make a difference with this particular library, but it has fixed similar problems I had with moment.


#3

I tried it but it didn’t work .

I also used:

 import { Canvas } from 'fabric';
    .....
    canvas : Canvas;
    ...
     this.canvas = new Canvas('c');

and I got the same error.

Any other idea?


#4

import ‘fabric’

declare let fabric: any;


#5

I’ve tried your suggestion but I got the following error:

Page1 ionViewDidEnter error: Cannot read property 'Canvas' of undefined

On the other hand, I think I’ve found the origin of the problem I mentioned in my first post (but I don’t know how to fix it).
I reviewed the source code and I noticed that all objects are generated without fabric namespace (like __WEBPACK_IMPORTED_MODULE_2_fabric___default.a.Canvas). I’ve run the app in Chrome while having enabled devTools and I checked that if .fabric is included, the object is created.

I don’t know how to properly setup my app, or if I have to make any change in the configuration or if I need to make some changes in the library to get the variables generated including “.fabric” just before the name of the class or any method.

Any idea will be truly appreciated.

Thanks in advance.


#6

import { Component } from ‘@angular/core’;

import { NavController } from ‘ionic-angular’;

import ‘fabric’

declare let fabric: any;

@Component({
selector: ‘page-page1’,
templateUrl: ‘page1.html’
})
export class Page1 {

private canvas;
private boundBox;
private shape;

constructor(public navCtrl: NavController) {

}

ionViewDidLoad(){
this.canvas = new fabric.Canvas(‘c’);

this.boundBox = new fabric.Rect({
  width:200,
  height:200,
  fill:'transparent',
  stroke: '#666',
  strokeDashArray:[5,5]
});
this.shape = new fabric.Rect({
  width:50,
  height:50,
  left: 10,
  top:10,
  fill:'red'
});
this.canvas.add(this.boundBox);
this.canvas.add(this.shape);
this.canvas.centerObject(this.boundBox);

}

}
<canvas width="300" height="300" id="c" style="border: 1px solid red"></canvas>

should be how it works, i have just created a working version using that so if your having issues i will create a repo and you can download it :slight_smile:


#7

Thanks Matthew! It works now!! :smile:
I don’t know what I did wrong before


#8

problem I think is the life cycle event difference ionViewDidLoad not ionViewDidEnter also no width set on the canvas would also not help you :slight_smile:


#9

I’ve had the same issue, and able to get the code works by following @matthewhw1989’s solution, but when I try to add image to the canvas, it fails with runtime error: Cannot read property ‘canvas’ of undefined again

    const url = 'https://images-na.ssl-images-amazon.com/images/I/51OZU4ySzOL.jpg';
    fabric.Image.fromURL(url, function(oImg) {
      this.canvas.add(oImg);
    });

any idea to solve this? or any recommendation on library as an alternative to fabric.js? My project will allow user to manipulate images (i.e. add, remove, drag, scale, rotate) in the canvas.

Thanks in advance


#10

Hi your problem is the use of “function” with use of “this” so in turn it references the function rather than the class.

fabric.Image.fromURL(url, (oImg) => {
      this.canvas.add(oImg);
});

notice the typescript function change. :slight_smile:


#11

Thanks, I always assume 1) function() {} and 2) () => {} , are all the same but only syntax difference…seems i need to go through arrow function basis first…


#12

hey someone solve this issue…I’ve been stuck this error more than three days…anyone help me to solve this error…

Thanks…