Search code examples
javascriptimagecanvaskineticjs

Understanding placing images in Kinetic.JS?


Below I have some code for an assignment I'm working on. Having been placed in a 2nd year course without taking foundations of JavaScript, I'm kind of in a rut.

I'm trying to place three images, and be able to call on them later with functions to change their opacity.

When I have the images placed, only one seems to want to appear at a time, and when I call to them, I'm told that they don't exist.

// Create the canvas based on the existing div for it in the HTML file

var stage = new Kinetic.Stage
({
    container: 'canvasContainer',
    width: 600,
    height: 600
});

  /* /////////////////////////////////////////////////////
    C O D E   F O R   L O A D I N G   U P   I M A G E S
  ///////////////////////////////////////////////////// */

    var characters = new Kinetic.Layer();
    stage.add(characters);

    window.onload = function()
    {

        var majoraCharacter = new Image();

        majoraCharacter.src ="https://upload.wikimedia.org/wikipedia/commons/3/34/Red_star.svg"

        majoraCharacter.onload = function()
        {
        character1= new Kinetic.Image({ x: 400, y: 300, width: 150, height: 150, offset: {x: 75, y: 75}, image: majoraCharacter});
        characters.add(character1);
        characters.draw();
        }

    }

    window.onload = function()
    {

        var amaterasuCharacter = new Image();

        amaterasuCharacter.src ="https://upload.wikimedia.org/wikipedia/commons/3/34/Red_star.svg"

        amaterasuCharacter.onload = function()
        {
        character2= new Kinetic.Image({ x: 400, y: 200, width: 150, height: 150, offset: {x: 75, y: 75}, opacity:0.5, image: amaterasuCharacter});
        characters.add(character2);
        characters.draw();
        }

    }

    window.onload = function()
    {

        var toothlessCharacter = new Image();

        toothlessCharacter.src ="https://upload.wikimedia.org/wikipedia/commons/3/34/Red_star.svg"

        toothlessCharacter.onload = function()
        {
        character3= new Kinetic.Image({ x: 400, y: 100, width: 150, height: 150, offset: {x: 75, y: 75}, image: toothlessCharacter});
        characters.add(character3);
        characters.draw();
        }

    }



  /* /////////////////////////////////////////////////////
          C A N V A S   F U N C T I O N A L I T Y
  ///////////////////////////////////////////////////// */

      // Create new layer for background images

      // Create layer for character images

      var character = new Kinetic.Layer();

      var rect = new Kinetic.Rect({
        x: 100,
        y: 100,
        width: 150,
        height: 150,
        fill: 'grey',
        strokeWidth: 4,
        offset: {x: 75, y: 75},
      });

      // add the shape to the layer
      character.add(rect);

      // add the layer to the stage
      stage.add(character);

Is there a way I can better add images to canvas?

And what is preventing them from co-existing, and being editable outside of their loading functions?

Any and all answers are greatly appreciated!


Solution

  • A Demo: http://jsfiddle.net/m1erickson/Bf88D/

    Some KineticJS basics:

    • KineticJS starts with a stage.
    • The stage is a container for one or more layers which are added to the stage
    • Each layer is actually a canvas
    • Shapes (including images) are added to a layer.

    Since you're new to javascript, here's an outline of how to structure your project

    • just use one window.onload and put all your javascript in that one window.onload
    • load all images in advance so they are available to draw on your canvas
    • When all the images are loaded, then create Kinetic.Image objects from them.

    Here's an image loader that loads all your images in advance and then calls the start function when your images are fully loaded.

    // image loader
    
    var imageURLs=[];  // put the paths to your images here
    var imagesOK=0;
    var imgs=[];
    imageURLs.push("");
    loadAllImages(start);
    
    function loadAllImages(callback){
        for (var i=0; i<imageURLs.length; i++) {
            var img = new Image();
            imgs.push(img);
            img.onload = function(){ 
                imagesOK++; 
                if (imagesOK>=imageURLs.length ) {
                    callback();
                }
            };
            img.onerror=function(){alert("image load failed");} 
            img.crossOrigin="anonymous";
            img.src = imageURLs[i];
        }      
    }
    
    function start(){
        // the imgs[] array holds fully loaded images
        // the imgs[] are in the same order as imageURLs[]
        // use the images now!
    }
    

    After you have all your images loaded, you can use this reusable function to add Kinetic Images on the layer.

    • You send in one image that you've loaded in advance.
    • You also send in the x,y position where you want the image located.
    • You also send in the width,height that you want the image resized to.

    This function adds one new image to the layer

    function addKineticImage(image,x,y,w,h){
        var image = new Kinetic.Image({
            x:x,
            y:y,
            width:w,
            height:h,
            image:image,
            draggable: true
        });
        layer.add(image);
        layer.draw();
    }