When initialising I'm finding that my `Bitmap` sometimes is not displayed on `staging`. For that reason, I've set a small timeout for 100ms that seems to solve the problem. The project I'm working on, has a canvas on top of a video element: top layer and bottom layer. The video element is the webcam stream, where I capture a snapshot and place it on the canvas. The canvas also works as a mask, but when the snapshot is taken operated independent of the video layer.

On the `placeMask` method below, I tried to stick a `Bitmap` eventListener `added` (<http://createjs.com/docs/easeljs/classes/Bitmap.html>) to know when the image is on staging and only then request getUserMedia. This didn't work and this far only using the `timeout` seems to work at 100ms (working locally, tested remotely with 100/1000ms it fails). Locally, tried 0ms and 10ms without success.

I thought this could be related with the images being loaded, so added a preloader that happens before the `CanvasImageSnappe` is initialised, but without success.

Also, when I say first browser load, I mean that if the user refreshes or request the same url again, the image is displayed on staging. If the user opens a new window or tab, the image fails to load. The 100ms fixes this (working locally, remotely 1000ms did not work).

The code below is not complete, but has the methods related with the issue or context.

```
function CanvasImageSnapper() {

    this.init();

}

CanvasImageSnapper.prototype = {

    init: function () {

        this.setVars();
        this.setListeners();

        // this fix the issue but I'd like to know the reason why
        setTimeout(function () {
            this.placeMask(this.setWebcam.bind(this));
        }.bind(this), 100);

    },

    setVars: function () {

        this.myCanvas = document.querySelector('#myCanvas');
        this.myCanvas.style.width = window.innerWidth + 'px';
        this.myCanvas.style.height = window.innerWidth / (16/9) + 'px';
        this.moduleContainer = document.querySelector('.p-canvas-webcam-prototype');
        this.moduleContainer.style.width = window.innerWidth + 'px';
        this.moduleContainer.style.height = window.innerWidth / (16/9) + 'px';
        this.myCamera = document.querySelector('#my_camera');
        this.videoStream = this.myCamera.querySelector('video');
        this.stage = new createjs.Stage('myCanvas');
        this.stage.canvas.width = parseInt(this.myCanvas.style.width);
        this.stage.canvas.height = parseInt(this.myCanvas.style.height);
        this.ratio = this.stage.canvas.width / this.stage.canvas.height;
        createjs.Touch.enable(this.stage);

        this.el_my_result = document.getElementById('my_result');
        this.el_take_snapshot = document.querySelector('.take_snapshot');
        this.container = new createjs.Container();
        this.handler_container = new createjs.Container();

        this.dragBox = new createjs.Shape(new createjs.Graphics().beginFill("#FFFFFF").drawRect(0, 0, this.stage.canvas.width, this.stage.canvas.height))
        this.dragBox.alpha = 0.01; // hit area needs to be at least `0.01`, but leaving almost transparent to see through
        this.stage.addChild(this.dragBox);

        this.btnPrint = document.querySelector('.btn-print');

        this.snapshot = null;
        this.shape_size = { w: 10, h: 10 };
        this.maskImage;

        this.btnDownload = document.querySelector('.btn-download');

        this.shapes;

        this.webCamMaxWidth = 1280;
        this.webCamMaxHeight = 720;
        this.webCamSizeRatio = 16 / 9;

        this.snapshots = [];

        this.el_remove_snapshot = document.querySelector('.remove_snapshot');

        this.galleryThemes = document.querySelectorAll('.gallery-selector ul li');

        this.maskName = 'mask_01';

        // cache
        this.cached = {
            images: {
                'mask_01': new createjs.Bitmap('img/mask_01.png'),
                'mask_02': new createjs.Bitmap('img/mask_02.png'),
                'mask_03': new createjs.Bitmap('img/mask_03.png'),
            }
        };

        // mandrill api key
        this.mandrillApiKey = 'xxxxxxxxxxx';

    },

    setListeners: function () {

        // disable to improve performance
        //createjs.Ticker.addEventListener("tick", this.tickHandler.bind(this));

        this.el_take_snapshot.addEventListener('click', this.snapHandler.bind(this));

        this.dragBox.addEventListener("mousedown", function (event) {

            var offset = new createjs.Point();

            offset.x = this.stage.mouseX - this.container.x;
            offset.y = this.stage.mouseY - this.container.y;

            event.target.addEventListener("pressmove", function (event) {

                this.container.x = event.stageX - offset.x;
                this.container.y = event.stageY - offset.y;

                this.handler_container.x = this.container.x;
                this.handler_container.y = this.container.y;

                this.stage.update();

            }.bind(this));

        }.bind(this));

        this.btnPrint.addEventListener('click', function (e) {
            this.print();
        }.bind(this));

        window.addEventListener('resize', this.winResizeHandler.bind(this));

        this.btnDownload.addEventListener('click', function () {
            this.hideHandlers();
            this.downloadImg();
        }.bind(this));

        window.addEventListener('showHandlers', function () {

            this.handler_container.alpha = 1;

            this.stage.update();

        }.bind(this));

        Webcam.on('load', function () {

            this.camFitToScale();

        }.bind(this));

        this.el_remove_snapshot.addEventListener('click', function () {
            this.removeShapshotHandler.call(this);
        }.bind(this));

        var context = this;
        for (var i = 0; i < this.galleryThemes.length; i++) {
            this.galleryThemes[i].addEventListener('click', function () {

                // clear existing
                if (context.maskImage) {
                    context.stage.removeChild(context.maskImage);
                    context.stage.update();
                }

                context.maskName = this.getAttribute('data-mask-name');

                context.placeMask.call(context, false);

            });
        }

    },

    placeMask: function (callback) {

        this.maskImage = this.cached.images[this.maskName];

        this.maskImage.scaleX = parseInt(this.myCanvas.style.width) / this.maskImage.image.width;
        this.maskImage.scaleY = parseInt(this.myCanvas.style.height) / this.maskImage.image.height;

        this.stage.addChild(this.maskImage);

        this.stage.update();

        if (typeof callback === "function") {

            callback.call(this);

        }

    }

}

```

To be clear about the preloader, I've attached the code, so that my intention here is clear. I don't know if this helps, since maybe loading the image on the Bitmap constructor fetches the image again, ignoring any browser cache ?

```
var arrImgList = ['img/mask_01.png', 'img/mask_02.png', 'img/mask_03.png'];

imagesLoaded(arrImgList, function( instance ) {
    var canvasImageSnapper = new CanvasImageSnapper();
    window.canvasImageSnapper = canvasImageSnapper;
});

```

You can find the full code here: <http://pastie.org/private/371jvrb5i1vmtz0e28bnvw>