DrawerJS unofficial documentation

In case you have bought https://www.drawerjs.com/ license, you might be wondering how to do couple special, yet very often needed, tricks that are not covered in documentation.

add new Text object into canvas

For example, in the documentation you’ll find how to add an image through code – https://www.drawerjs.com/try-standalone-api

drawer.api.setBackgroundImageByUrl(url)

But how to add a Text object and place it into canvas? You won’t find that in the official docs..
In order to do that, you need to create fabric.IText object, add default styling and place it into canvas. You can find complete example below.

On last 2 lines I’ve also changed the text – you can change any style, or position value like this.

// This is default Drawer initialization, 
// as can be found in documentation
var canvas = new DrawerJs.Drawer(null, {
    // I recommend to keep this at 'false', 
    // latest version of DrawerJS has a bug related to this
    exitOnOutsideClick: false,
    backgroundCss: 'transparent',
    // you can load as many plugins as you want, 
    // this for this example, we will only need 'Text'
    plugins: [ 'Text' ],
    pluginsConfig: {
        Text: {
            fonts: {
                'Arial': 'Arial, Helvetica, sans-serif',
            },
            defaultFont: 'Arial'
        }
    },
    basePath: '/',
    transparentBackground: true,
    align: 'center' // equivalent of margin: 0 auto
}, 582, 414);

$(document).ready(function () {
    $('#canvas-editor').append(canvas.getHtml());
    canvas.onInsert();
    canvas.api.startEditing();

    // Custom code - this is what you're looking for!
    var t = new fabric.IText('Lorem Ipsum');
    t.top = 50;
    t.left = 50;
    // be sure to pick font family defined in pluginsConfig->Text
    t.fontFamily = 'Arial, Helvetica, sans-serif';
    t.fontSize = 15;
    t.fill = '#000';
    t.fillRule = 'nonzero';
    t.fontWeight = 'normal';
    t.editable = true;
    canvas.fCanvas.add(t);
    // you can omit next line - it just highlights the newly 
    // added object and allows user to change the text right away 
    canvas.fCanvas.setActiveObject(t);

    // And this is how you can change anything 
    // later on - on 'click' event for example
    t.text = 'Different Text';
    canvas.fCanvas.renderAll();
});

Fire event after your changes have been rendered into canvas

Lets say you want to change background through code – you look at their documentation and find out this is the way to do it

drawer.api.setBackgroundImageByUrl(url)

but – if you use bigger image, it may take a while, 2-3 seconds to render. If you save the image before that, you end up with base64 without the new image.
Events are not covered in their documentation at all, so this is the trick:

// add event listener first
canvas.fCanvas.on('after:render', function(){ 
    console.log('Done, we can export the image now'); 
});

// make changes to canvas.. 
drawer.api.setBackgroundImageByUrl(url)

Remove focus – unhighlight object

If you are exporting image you don’t want the default blue border around highlighted object

if(temp = canvas.api.getSelectedObject()){
    temp.active = false;
}
canvas.fCanvas.renderAll();

Export canvas into base64

var base64Output = canvas.api.getCanvasAsImage();

.. and you can send this through $.post() to backend

Resize canvas and all DrawerJS objects in it

// Set up same base ground ..
var canvas = new DrawerJs.Drawer(null, {
    // I recommend to keep this at 'false', 
    // latest version of DrawerJS has a bug related to this
    exitOnOutsideClick: false,
    backgroundCss: 'transparent',
    // you can load as many plugins as you want, 
    // this for this example, we will only need 'Text'
    plugins: [ 'Text' ],
    pluginsConfig: {
        Text: {
            fonts: {
                'Arial': 'Arial, Helvetica, sans-serif',
            },
            defaultFont: 'Arial'
        }
    },
    basePath: '/',
    transparentBackground: true,
    align: 'center' // equivalent of margin: 0 auto
}, 500, 500);
// do what you have to do..
// ..
// now you want to resize everything?


// set up new canvas size - note that we are going to use
// canvas twice the original size, therefore we will
// need to resize all objects to twice their size
canvas.setSize(1000, 1000);
// check if there are any objects inserted 
// this could be text, images, lines, rectangles, triangles, pencil objects etc..
if(canvas.fCanvas._objects.length > 0) {
    // there are some, loop through them
    for (var i = 0; i < canvas.fCanvas._objects.length; i++) {
        var o = canvas.fCanvas._objects[i];
        o.setScaleX(o.scaleX * 2); // twice the original size
        o.setScaleY(o.scaleY * 2);
        o.setTop(o.top * 2);
        o.setLeft(o.left * 2);
    }
    // render our changes
    canvas.fCanvas._objects[0].canvas.renderAll();
}

How to center and scale image when adding it through API

You can use addImageFromUrl like this:

canvas.api.addImageFromUrl('/1.png', {'centerImage': true, 'scaleX': 2, 'scaleY': 2});

This is just an example, you can use any other parameter - left, top, width, height, rotate, etc..

How to load older canvas when needed ( e.g. when going back in form )

The official documentation is buggy and will end in Uncaught ReferenceError: serializedCanvas is not defined(…)

Best way to get around it, is to use these 2 functions appropriately:
1st/ store canvas data when needed ( e.g. when you are navigating away from this page )

localStorage.setItem('ourdata', JSON.stringify(canvas.getCanvasData()));

2nd/ then you can bring it up next time you go back to that page by placing canvas.loadCanvas(localStorage.getItem('ourdata')); after append. See example:

$(document).ready(function () {
     $('#canvas-editor').append(canvas.getHtml());
    canvas.onInsert();
    canvas.api.startEditing();
    canvas.loadCanvas(localStorage.getItem('ourdata'));
});

Uncaught TypeError: Cannot read property 'find' of null(…)

If you are using backgroundImage plugin, make sure you use

exitOnOutsideClick: false

You can have it automatically turned on like this

$(document).ready(function () {
    $('#canvas-editor').append(canvas.getHtml());
    canvas.onInsert();
    canvas.api.startEditing();

.. and just keep it that way.

Change default drag&drop border color in canvas

canvas.fCanvas.on('after:render', function(){ 
    if(canvas.fCanvas._objects.length > 0){
        for(var i = 0, len = canvas.fCanvas._objects.length; i < len; i+=1){
            canvas.fCanvas._objects[i].borderColor = 'rgba(251,182,74,1)';
            canvas.fCanvas._objects[i].cornerColor = 'rgba(251,182,74,1)';
        }
    }
});

Where 255,181,74 is your new rgb color. Be sure to place this after $('#canvas-editor').append(canvas.getHtml());

Ubuntu 16 – how to increase maximum file open limit ( ulimit -n )

If you are setting up nginx,chances are you will discover your worker_connections is at some low number, such as 1024.
You can’t increase this number unless you increase kernel limit as well.
First of all run cat /proc/sys/fs/file-max to discover your maximum limit.

abc@ubuntu:~$ cat /proc/sys/fs/file-max
1048576
abc@ubuntu:~$ ulimit -n
1024

As you can see there’s plenty of space for improvement. Lets say I want my new ‘ulimit -n’ to read 131072.

abc@ubuntu:~$ sudo nano /etc/sysctl.conf

add

fs.file-max = 131072

run

sudo sysctl -p

edit

sudo nano /etc/security/limits.conf

add

* soft     nproc          131072    
* hard     nproc          131072   
* soft     nofile         131072   
* hard     nofile         131072
root soft     nproc          131072    
root hard     nproc          131072   
root soft     nofile         131072   
root hard     nofile         131072
sudo nano /etc/pam.d/common-session

add

session required pam_limits.so

And that’s it. Log out and in and try ulimit -n

abc@ubuntu:~$ ulimit -n 131072

Now you can edit nginx as well

events {
    worker_connections 131072;
    use epoll;
    multi_accept on;
}

mount point XYZ is itself on a OSXFUSE volume

If you use SSHFS on MacOS and the end point stops responding or crashes, you need to do new SSHFS connection – but to do that, you need to either restart your mac or umount the old connection first.

I use sshfs to access data on my vmware ( Ubuntu ) – if that restarts, or crashes – I end up with error message mount_osxfusefs: mount point /Users/jan/site-sshfs is itself on a OSXFUSE volume

sshfs root@vmware:/srv/www/site/public_html/ /Users/jan/site-sshfs -oauto_cache,reconnect,defer_permissions,noappledouble,negative_vncache,volname=Site_VMware
mount_osxfusefs: mount point /Users/jan/site-sshfs is itself on a OSXFUSE volume

To fix this, do mount:

jan:~ jan$ mount
/dev/disk1 on / (hfs, local, journaled)
devfs on /dev (devfs, local, nobrowse)
map -hosts on /net (autofs, nosuid, automounted, nobrowse)
map auto_home on /home (autofs, automounted, nobrowse)
root@vmware:/srv/www/site/public_html/ on /Users/jan/site-sshfs (osxfusefs, nodev, nosuid, synchronous, mounted by jan)

Look at the last line – that’s the connection we need to break.
Therefore, do:

jan:~ jan$ umount root@vmware:/srv/www/site/public_html/

That’s it! Now you can create new sshfs link.

Find out ‘open files’ limit for apache user

You need to find out under which user your apache deamon runs.
You can do this by

root@ljstudio:/# cat /etc/httpd/conf/httpd.conf | grep "User"

And then:

root@ljstudio:/# su - apache -c 'ulimit -aHS' -s '/bin/bash'
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 257402
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 1024
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

‘apache’ is usually used on CentOS, while on Ubuntu it’s expected to use www-data user instead.