Question

I've organized my jCanvas code into a render method which fires on window.resize:

<script type="text/javascript">
    var middleX;
    var middleY;
    var canvas;
    var ctx;

    var isLoaded = false;

    $(document).ready
    (
        function ()
        {
            init();
            isLoaded = true;

            render();

            $("canvas").fadeIn(2000);
        }
    );

    function scaleToWindowDimensions()
    {
        ctx.canvas.width = window.innerWidth;
        ctx.canvas.height = window.innerHeight;

        middleX = $canvas.width() / 2;
        middleY = $canvas.height() / 2;
    }

    function init()
    {
        $canvas = $('canvas');
        ctx = document.getElementById("canvas").getContext("2d");

        scaleToWindowDimensions();
    }

    $(window).resize
    (
        function ()
        {
            scaleToWindowDimensions();

            render();
        }
    );

    function render()
    {
        if (!isLoaded)
        {
            return;
        }

        $canvas.clearCanvas();

        // ctx.clearRect(0, 0, $canvas.width(), $canvas.height());

        $canvas.addLayer({
            method: 'drawArc',
            strokeStyle: "#000",
            strokeWidth: 1,
            fillStyle: '#c33',
            x: middleX,
            y: middleY,
            closed: true,
            radius: 50,
            // Event bindings
            mousedown: function (target)
            {
                alert('You pushed RED!');
            },
            mouseup: function (target)
            {
                target.fillStyle = '#c33';
            },
            mouseover: function (target)
            {
                target.fillStyle = "#888";
            },
            mouseout: function (target)
            {
                target.fillStyle = "#c33";
            }
        });

        $canvas.addLayer({
            method: "drawText",
            strokeStyle: "#000",
            fromCenter: true,
            strokeWidth: 1,
            fillStyle: "#333",
            fontSize: "18pt",
            fontFamily: "Verdana",
            x: middleX,
            y: middleY,
            text: "Man",
            data: { "id": 1, "word": "Man" },
            mousedown: function (target)
            {
                alert($(this).id);
            }
        });

        $canvas.addLayer({
            method: 'drawArc',
            strokeStyle: "#000",
            strokeWidth: 1,
            fillStyle: '#d88',
            x: 500,
            y: 100,
            closed: true,
            radius: 40,
            // Event bindings
            mousedown: function (target)
            {
                alert('You pushed RED!');
                target.fillStyle = '#333';
            },
            mouseup: function (target)
            {
                target.fillStyle = '#d88';
            },
            mouseover: function (target)
            {
                target.fillStyle = "#888";
            },
            mouseout: function (target)
            {
                target.fillStyle = "#d88";
            }
        });

        $canvas.addLayer({
            method: "drawText",
            strokeStyle: "#000",
            fromCenter: true,
            strokeWidth: 1,
            fillStyle: "#333",
            fontSize: "16pt",
            fontFamily: "Verdana",
            x: 500,
            y: 100,
            text: "Men",
            data: { "id": 2, "word": "Men" },
            mousedown: function (target)
            {
                alert($(this).id);
            }
        });

        $canvas.addLayer({
            method: 'drawLine',
            strokeStyle: "#222",
            strokeWidth: 1,
            x1: middleX,
            y1: middleY,
            x2: 500,
            y2: 100,
            radius: 40,
        });

        $canvas.drawLayers();
    }
</script>

This draws this image:

Output

The intent is for the first step when render is called to clear the entire canvas:

$canvas.clearCanvas();

// ctx.clearRect(0, 0, $canvas.width(), $canvas.height());

These are two separate attempts to clear the canvas, neither of which works. Without the canvas being cleared, the result is this:

enter image description here

I have a general idea that this has something to do with the layers rather than drawing directly, but I'm baffled why the canvas is not being cleared...

TIA.

Was it helpful?

Solution

clearCanvas is working as intended, the issue here is that you are adding five layers to $canvas on each call to render. So, when drawLayers is called, all the layers added to $canvas are drawn; the five updated ones along with all those layers which were added in previous render calls.

One way to solve this issue would be to only alter the layers in the render method with setLayer, and add them in a method which is called only once, possibly init.

So, init becomes:

function init() {
    $canvas = $('canvas');
    ctx = document.getElementById("canvas").getContext("2d");

    scaleToWindowDimensions();

    console.log($canvas);

    //Adding layers in init
    //and defining all the 
    //static properties which
    //won't change on each render
    $canvas.addLayer({
        name: "l0",                  //Unique name for access
        visible: true,
        method: 'drawArc',
        strokeStyle: "#000",
        strokeWidth: 1,
        fillStyle: '#c33',
        x: middleX,
        y: middleY,
        closed: true,
        radius: 50,
        // Event bindings
        mousedown: function (target) {
            alert('You pushed RED!');
        },
        mouseup: function (target) {
            target.fillStyle = '#c33';
        },
        mouseover: function (target) {
            target.fillStyle = "#888";
        },
        mouseout: function (target) {
            target.fillStyle = "#c33";
        }
    })
        .addLayer({
        name: "l1",                  //Unique name for access               
        visible: true,
        method: "drawText",
        strokeStyle: "#000",
        fromCenter: true,
        strokeWidth: 1,
        fillStyle: "#333",
        fontSize: "18pt",
        fontFamily: "Verdana",
        x: middleX,
        y: middleY,
        text: "Man",
        data: {
            "id": 1,
            "word": "Man"
        },
        mousedown: function (target) {
            alert($(this).id);
        }
    })
        .addLayer({
        name: "l2",                  //Unique name for access
        visible: true,
        method: 'drawArc',
        strokeStyle: "#000",
        strokeWidth: 1,
        fillStyle: '#d88',
        x: 500,
        y: 100,
        closed: true,
        radius: 40,
        // Event bindings
        mousedown: function (target) {
            alert('You pushed RED!');
            target.fillStyle = '#333';
        },
        mouseup: function (target) {
            target.fillStyle = '#d88';
        },
        mouseover: function (target) {
            target.fillStyle = "#888";
        },
        mouseout: function (target) {
            target.fillStyle = "#d88";
        }
    })
        .addLayer({
        name: "l3",                  //Unique name for access
        visible: true,
        method: "drawText",
        strokeStyle: "#000",
        fromCenter: true,
        strokeWidth: 1,
        fillStyle: "#333",
        fontSize: "16pt",
        fontFamily: "Verdana",
        x: 500,
        y: 100,
        text: "Men",
        data: {
            "id": 2,
            "word": "Men"
        },
        mousedown: function (target) {
            alert($(this).id);
        }
    })
        .addLayer({
        name: "l4",                  //Unique name for access
        visible: true,
        method: 'drawLine',
        strokeStyle: "#222",
        strokeWidth: 1,
        x1: middleX,
        y1: middleY,
        x2: 500,
        y2: 100,
        radius: 40,
    });
}

And render becomes:

function render() {
    if (!isLoaded) {
        return;
    }

    $canvas.clearCanvas();

    // ctx.clearRect(0, 0, $canvas.width(), $canvas.height());

    //Here, use setLayer to change
    //properties which are supposed to change
    //with render

    //We use the unique name of each layer
    //set in init to access them.
    $canvas.setLayer("l0", {
        x: middleX,
        y: middleY,
    });

    $canvas.setLayer("l1", {
        x: middleX,
        y: middleY
    });

    //Layer l2 and l3 don't
    //change anything, so they are
    //not changed with render.

    $canvas.setLayer("l4", {
        x1: middleX,
        y1: middleY
    });

    $canvas.drawLayers();
}

Working Example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top