Search code examples
javascripthtmlcanvascreatejseaseljs

How to address a shape drawn on a HTML5 canvas and change its properties?


I am beginning to explore the HTML5 canvas, and I apologize in advance for the naivety of my question. Using Flash CC, I have generated a canvas with a rectangle on it:

(function (lib, img, cjs, ss) {
var p; // shortcut to reference prototypes
// library properties:
lib.properties = {
    width: 550,
    height: 400,
    fps: 24,
    color: "#FFFFFF",
    manifest: []
};
// symbols:
// stage content:
(lib.canvas_test = function() {
    this.initialize();
    // Layer 1
    this.shape = new cjs.Shape();
    this.shape.graphics.beginFill().beginStroke("#669966")
    .setStrokeStyle(1,1,1).moveTo(-94,-62).lineTo(94,-62).lineTo(94,62).lineTo(-94,62).closePath();
    this.shape.setTransform(198,136);
    this.shape_1 = new cjs.Shape();
    this.shape_1.graphics.beginFill("#FF933C")
    .beginStroke().moveTo(-94,62).lineTo(-94,-62).lineTo(94,-62).lineTo(94,62).closePath();
    this.shape_1.setTransform(198,136);
    this.addChild(this.shape_1,this.shape);
}).prototype = p = new cjs.Container();
p.nominalBounds = new cjs.Rectangle(378,273,190,126);
})(lib = lib||{}, images = images||{}, createjs = createjs||{}, ss = ss||{});
var lib, images, createjs, ss;

Now I am stuck. How can I retrieve (and change) the color of the rectangle using a Javascript function? I had hoped that the shapes would simply be children of the canvas, but this does not seem to be the case.


Solution

  • The earlier answers are correct about Canvas being basically a bitmap, but EaselJS gives you a retained graphics mode, so you can change properties and update the stage/canvas to reflect them.

    You are using Flash export to generate your content, so you should be able to access your elements via the exportRoot, which is created in the HTML. This is essentially the Flash "stage", represented by an EaselJS container that is defined by canvas_test in your exported library.

    exportRoot = new lib.canvas_test();
    

    You can see in the canvas_test code, each "child" is defined. Any graphics are wrapped in EaselJS Shape instances. There are also classes for handling groups (Containers), Bitmaps, Text, and animations (MovieClips).

    Here is your exported code above put added to the stage: http://jsfiddle.net/lannymcnie/b5me4xa2/

    It is easy to modify shapes once they are created, but you have to define them with that in mind. The Flash export doesn't really provide you this capability, since it just exports everything as a single, chained graphics instructions list. You can however introspect it fairly easily to find the commands you want to modify. Warning: This requires EaselJS 0.7.0+ in order to work. Earlier versions will not work with this approach

    The demo you provided has a single Rectangle. Unfortunately there is a bug in the current version of Flash that exports it as 2 shapes, one for the stroke, and another for the fill. This example will modify the stroke.

    var shape = exportRoot.shape; // Access the shape instance that has the stroke
    var stroke = shape.graphics._stroke;
    stroke.style = "#ff0000"; // Set to red.
    

    To do the fill, you can do the same thing on shape_1, but affect the _fill instead. Here is an updated sample

    You can also access any of the instructions, and affect their properties. You can see a full command list in the Graphics docs (see the sidebar for the full list). Here is a quick sample modifying the first moveTo command on the stroke:

    var shape = exportRoot.shape;
    shape.graphics._activeInstructions[0].x = -110;
    

    You can see a sample of that code here: http://jsfiddle.net/lannymcnie/b5me4xa2/2/ -- You will have to modify both fill and stroke to move them both :)