Skip to content Skip to sidebar Skip to footer

JavaScript Prototype Inheritance And Html Canvas

I'm a Ruby developer who finally decided to learn JavaScript seriously. So I purchased some books and I started to dive in, but I got stuck quickly when I tried to understand proto

Solution 1:

The core of the problem is the context - your shapes are sharing the single context of the canvas, and therefore it is not straight-forward to flip back and forth between objects. Instead, think of your order-of-operations as handling a single shape at a time and only moving on to the next one when you are done with the former.

Note the order of calls in the make_me_crazy function:

function Point(x, y) {
    this.x = x;
    this.y = y;
  }

  function Shape() {
    this.points = [];
    this.init();
  }

  Shape.prototype = {
    constructor: Shape,
    init: function(){
      if (this.context === undefined) {
        Shape.prototype.context = document.getElementById('canvas').getContext('2d');
      };
      if(this.name === undefined){
        Shape.prototype.name = 'generic shape'
      }
    },
    draw: function(){
      var i, ctx = this.context;
      ctx.strokeStyle = 'rgb(0,0,255)';
      ctx.beginPath();
      ctx.moveTo(this.points[0].x, this.points[0].y);
      for (i = 1; i<this.points.length; i++) {
        ctx.lineTo(this.points[i].x, this.points[i].y);
      }
      ctx.closePath();
      ctx.stroke();
    },
    fill: function(color){
      var ctx = this.context;
      ctx.fillStyle = color;
      ctx.fill();
    },
    say_name: function(){console.log('Hello my name is '+ this.name)}
  };

  function Triangle(a,b,c){
    this.points = [a, b, c];
    this.name = 'Triangle'
    this.context = document.getElementById('canvas').getContext('2d');
  }

  function Rectangle(side_a, side_b){
    var p = new Point(200, 200);
    this.points = [
      p,
      new Point(p.x + side_a, p.y),// top right
      new Point(p.x + side_a, p.y + side_b), // bottom right
      new Point(p.x, p.y + side_b)// bottom left
    ];
    this.name = 'Rectangle'
    this.context = document.getElementById('canvas').getContext('2d');
  }

  (function(){
    var s = new Shape();
    Triangle.prototype = s;
    Rectangle.prototype = s;
  })();

  function testTriangle(){
    var p1 = new Point(100, 100);
    var p2 = new Point(300, 100);
    var p3 = new Point(200, 0);
    return new Triangle(p1, p2, p3);
  }

  function testRectangle(){
    return new Rectangle(100, 100);
  }

  function make_me_crazy(){
    var t = testTriangle();
    t.say_name();
    t.draw();
    t.fill('red');
    
    var r = testRectangle();
    r.draw();
    r.say_name();
  }
  make_me_crazy();
<canvas height='600' width='800' id='canvas'></canvas>

Solution 2:

About the points of your question.

For the first one: the key is this line of code

if(this.name === undefined){
    Shape.prototype.name = 'generic shape'
}

When you instantiate Rectangle and Triangle, both of them set name. In the other hand, the render method is only available in the Shape prototype.

About the second point (and the third one): Maybe are you painting the Rectangle over the Triangle. Try to switch the order of the draw calls to check it.


Post a Comment for "JavaScript Prototype Inheritance And Html Canvas"