Search code examples
javascripteaseljs

Using EaselJS, how can I set a framerate for painting while not redrawing the existing bitmap elements?


I'm new to EaselJS and I have a stage with bitmaps and I need to add painting functionality so shapes can be drawn on top of bitmaps.

The paint function needs stage.autoClear = false to create the shape. This code forces ALL the elements on the stage (including bitmaps) to be redrawn. But the existing bitmaps on the stage should not be redrawn.

The bitmaps are in container which is a child of stage. This is what I have (much of it from https://github.com/CreateJS/EaselJS/blob/master/examples/CurveTo.html):


    function init() {
    
        canvas = document.getElementById("theCanvas");
        stage = new createjs.Stage(canvas);
        createjs.Touch.enable(stage);
        stage.enableMouseOver(10);
        stage.mouseMoveOutside = true;
        stage.addChild(container);
    };
    
    function initPaint() {
    
        var oldPt;
        var oldMidPt;
        var color;
        var stroke;
        
        stage.autoClear = false;
        stage.enableDOMEvents(true);
        createjs.Ticker.framerate = 24;
    
    
        stage.addEventListener("stagemousedown", handleMouseDown);
        stage.addEventListener("stagemouseup", handleMouseUp);
    
        stage.addChild(drawingCanvas);
        stage.update();
    
    };
    
    function handleMouseDown(event) {
        if(!event.primary) {return; }
        stage.autoClear = false;
    
        color = "#000000";
        stroke = 20;
        oldPt = new createjs.Point(stage.mouseX, stage.mouseY);
        oldMidPt = oldPt.clone();
        stage.addEventListener("stagemousemove", handleMouseMove);
    }
    
    function handleMouseMove(event) {
        if (!event.primary) { return; }
        var midPt = new createjs.Point(oldPt.x + stage.mouseX >> 1, oldPt.y + stage.mouseY >> 1);
    
        drawingCanvas.graphics.clear().setStrokeStyle(stroke, 'round', 'round').beginStroke(color).moveTo(midPt.x, midPt.y).curveTo(oldPt.x, oldPt.y, oldMidPt.x, oldMidPt.y);
    
        oldPt.x = stage.mouseX;
        oldPt.y = stage.mouseY;
    
        oldMidPt.x = midPt.x;
        oldMidPt.y = midPt.y;
    
        stage.update();
    }
    
    function handleMouseUp(event) {
    
        if (!event.primary) { return; }
        stage.removeEventListener("stagemousemove", handleMouseMove);
    }

Bitmap elements have already been added to the stage. When initPaint is called with stage.autoclear = false, the bitmaps get redrawn, one on top of the other (this is evident because I have a shadow effect on the bitmaps and the shadow keeps getting darker). How do I stop the bitmap elements from getting redrawn?


Solution

  • You can't conditionally choose what gets redrawn to a stage.

    The best option you have is to have a separate canvas/cache that you continuously draw to, and then add it as the source of a bitmap that is on your main stage. Caching basically does this for you.

    An easy approach is to put your auto-draw content into a Container, and cache() it:

    var c = new createjs.Container();
    c.addChild(bg, txt); // Add your content
    c.cache(0,0,400,800);
    

    Then you don't need to use autoClear on your stage, and everything else draws as normal. You just need to update your cache when the content changes. Using source-over as the draw mode will add the current contents to the cache, instead of clearing it first.

    c.updateCache("source-over");
    

    For example, here is a fiddle where I animate some text over a transparent box. The additive effect looks great, but it also makes the circle shape do the same thing: https://jsfiddle.net/lannymcnie/yfqne2or/

    enter image description here

    By simply putting the bg and text in a container, and caching that, I can control what parts get the effect, leaving the rest of the stage unaffected. Note that this does result in a double-draw of your content, but there is really no better way to accomplish it using one canvas. https://jsfiddle.net/lannymcnie/yfqne2or/2

    enter image description here