4
\$\begingroup\$

I am doing some tests with html5 Canvas object. At the same time I am trying to make my javascript code more modular. In the following code, where/how should I declare canvas and context, so that it can be shared with other objects? Please provide general comments/improvements?

Output:

enter image description here

Code:

$( document ).ready(function() {

    var axis = {
        LEFT_INDENT : 100,  
        START_WORK_HOUR : 8,
        END_WORK_HOUR : 17,
        HOURS_IN_WORKDAY : 0,
        CANVAS_WIDTH : 0,
        CANVAS_HEIGHT : 0,
        AXIS_SIDE_MARGIN : 20,
        AXIS_TOP_MARGIN : 40,
        AXIS_ORIGIN : new Array(),  
        AXIS_RIGHT : 0,
        TICK_INCREMENT :  0,

        setup: function(){

            // assumes that I have <canvas id="myCanvas" width="800" height="300"></canvas>  in the HTML
            this.canvas = document.getElementById('myCanvas');
            this.context = this.canvas.getContext('2d');

            this.HOURS_IN_WORKDAY = this.END_WORK_HOUR - this.START_WORK_HOUR;
            this.CANVAS_WIDTH = this.canvas.width;
            this.CANVAS_HEIGHT = this.canvas.height;

            this.AXIS_ORIGIN = { x: this.AXIS_SIDE_MARGIN,
                            y: this.AXIS_TOP_MARGIN };

            this.AXIS_RIGHT = this.canvas.width-this.AXIS_SIDE_MARGIN;

            this.TICK_INCREMENT = (this.CANVAS_WIDTH-this.LEFT_INDENT-(2*this.AXIS_SIDE_MARGIN))/this.HOURS_IN_WORKDAY; 
            this.AXIS_RIGHT = this.canvas.width-this.AXIS_SIDE_MARGIN;
        },

        draw_lines: function(){
            this.context.beginPath();
            this.context.moveTo(this.LEFT_INDENT, this.AXIS_ORIGIN.y);
            this.context.lineTo(this.AXIS_RIGHT,  this.AXIS_ORIGIN.y)
            this.context.stroke();
            this.counter = this.START_WORK_HOUR;

            for(x=this.AXIS_SIDE_MARGIN+this.LEFT_INDENT ; x < this.AXIS_RIGHT ; x = x + this.TICK_INCREMENT){
                // grid lines
                this.context.beginPath();
                this.context.moveTo(x,30);
                this.context.lineTo(x,50)
                this.context.stroke();

                // background line - top to bottom
                this.context.save();   
                this.context.fillStyle = "#F0F8FF";
                this.context.beginPath();
                this.context.lineWidth = .1;
                this.context.moveTo(x,30);
                this.context.lineTo(x,this.CANVAS_HEIGHT-20)
                this.context.stroke();
                this.context.restore();   

                // text     
                this.context.font = "14px Arial";
                this.context.fillStyle = "#011f5b";     
                this.counter++;
                this.context.fillText(this.counter+":00",x-7,20);       
            }   
        }
    }
    axis.setup();
    axis.draw_lines();
});
\$\endgroup\$

migrated from stackoverflow.com Jul 7 '13 at 1:25

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ I'm not sure this will be helpful, but I created a github project called brushes.js which somewhat tries to encapsulate brushes to draw on a canvas. There are unit tests and examples. \$\endgroup\$ – Jim Schubert Jul 5 '13 at 6:33
2
\$\begingroup\$

You can wrap the functionality in an object. You instantiate it with a canvas element and some configuration options.

(function($) {

// config defaults    
var defaults = {
    LEFT_INDENT: 100,
    START_WORK_HOUR: 8,
    END_WORK_HOUR: 17,
    AXIS_SIDE_MARGIN: 20,
    AXIS_TOP_MARGIN: 40
};

// constructor
axis = function(canvas, config)
{
    this.config = $.extend({}, defaults, config);
    this.canvas = canvas;

    this.setup();
}

// define prototype functions
axis.prototype.setup = function() {
    this.context = this.canvas.getContext('2d');

    this.HOURS_IN_WORKDAY = this.config.END_WORK_HOUR - this.config.START_WORK_HOUR;
    this.CANVAS_WIDTH = this.canvas.width;
    this.CANVAS_HEIGHT = this.canvas.height;

    this.AXIS_ORIGIN = {
        x: this.config.AXIS_SIDE_MARGIN,
        y: this.config.AXIS_TOP_MARGIN
    };

    this.AXIS_RIGHT = this.canvas.width - this.config.AXIS_SIDE_MARGIN;

    this.TICK_INCREMENT = (this.CANVAS_WIDTH - this.config.LEFT_INDENT - 2*this.config.AXIS_SIDE_MARGIN)) / this.HOURS_IN_WORKDAY;
}

axis.prototype.draw_lines = function() {
    this.context.beginPath();
    this.context.moveTo(this.LEFT_INDENT, this.AXIS_ORIGIN.y);
    this.context.lineTo(this.AXIS_RIGHT,  this.AXIS_ORIGIN.y)
    this.context.stroke();
    this.counter = this.config.START_WORK_HOUR;

    for(x = this.config.AXIS_SIDE_MARGIN + this.config.LEFT_INDENT ; x < this.AXIS_RIGHT ; x = x + this.TICK_INCREMENT) {
        // grid lines
        this.context.beginPath();
        this.context.moveTo(x,30);
        this.context.lineTo(x,50)
        this.context.stroke();

        // background line - top to bottom
        this.context.save();   
        this.context.fillStyle = "#F0F8FF";
        this.context.beginPath();
        this.context.lineWidth = .1;
        this.context.moveTo(x,30);
        this.context.lineTo(x, this.CANVAS_HEIGHT - 20)
        this.context.stroke();
        this.context.restore();   

        // text     
        this.context.font = "14px Arial";
        this.context.fillStyle = "#011f5b";     
        this.counter++;
        this.context.fillText(this.counter+":00",x-7,20);       
    }   
}

}(jQuery));

To use it:

var a = new axis(document.getElementById('myCanvas'), {
     // whatever you want to override
});
a.draw_lines();
\$\endgroup\$
  • \$\begingroup\$ my god, there are so many ways of doing things in javascript! If I understand you group variables in its own array. The "axis" methods and properties do not have to be wrapped and grouped together. You are instantiating the axis object with the "new" verb then run the constructor within the object. Code is a bit neater, and setup is done within the class. What other advantages does this way offer? \$\endgroup\$ – Abe Jul 5 '13 at 3:30
  • \$\begingroup\$ @Abe With the encapsulation, it also allows to have multiple axis objects which are tied to canvas objects. \$\endgroup\$ – Jack Jul 5 '13 at 6:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy