Tuesday, February 7, 2012

Day 1 : InputCanvas 2.0

May Allah`s peace , mercy and blessing be upon you

Today I'll start redesigning InputCanvas , the old version wasn't clear and customisable. There was only 2 objects FormCanvas and InputCanvas , and only text input.
In this new version I'll try to create so match more objects that we can use separately. Also I'm going to use one of the most important feature in OOP which is inheritance , the most important object is BasicShape it's the parent object of all types of inputs with basic proprieties and methods.

First of all , I'll define a very useful function setNumArr(arg, max) , this function will be used to set some proprieties with the form of a 4x array like border, padding ... etc
Code speaks louder than words :
 
function setNumArr(arg,max)
{
    if(typeof arg === 'number')
    {
        var tmp = parseInt(arg);
        if(max && tmp > max) tmp = max;
        return [tmp, tmp, tmp, tmp];
    }
    else if(typeof arg === 'object' && arg.length == 4)
    {
        for(i=0;i<4;i++) {
            if(max && arg[i] > max) arg[i] = max;
        }
        return arg;
    }
    else return [0, 0, 0, 0];
}
Now the BasicShape definition :

// The basic shape element

function BasicShape(canvas,x,y,width,height)
{
    // Main proprieties
    this.canvas  = canvas;                                        // HTML canvas element
    this.context = canvas.getContext("2d");                       // Context of canvas
    this.x        = x || 0;                                       // Top left corner X
    this.y        = y || 0;                                       // Top left corner Y
    this.id       = '';                                           // Identifier
    this.mousein  = false;                                        // Mouse Status
    this.mouseinp = false;                                        // Mouse Previous Status
    this.focus    = false;                                        // Focus status
    this.view     = true;                                         // Visibility

    // Others
    this.width    = width;                                        // Width
    this.height   = height;                                       // Height
    this.padding  = [1, 1, 1, 1];                                 // Padding
    this.border   = {color:'#000000',size:2,radius:[1, 1, 1, 1]}; // Border
    this.shadow   = {color:'',blur:0,x:0,y:0};                    // Shadow
    this.bg       = '#FFFFFF';                                    // Background color
    
    // Event hundlers.
    this.onMouseMove = function (){};
    this.onMouseOver = function (){};
    this.onMouseOut  = function (){};
    this.onMouseDown = function (){};
    this.onMouseUp   = function (){};
    this.onKeyDown   = function (){};
    this.onKeyUp     = function (){};
    this.onKeyPress  = function (){};
    this.onBlur      = function (){};
    this.onFocus     = function (){};
    this.onClick     = function (){};
    this.onHover     = function (){};
}
Now we have to define some methods :

1- Setters :
 
/**
    * Set border proprieties.
    *
    * @param int size      : Size of border in pixel.
    * @param string color : Color of border (Hex).
    * @param int radius, array radius : Border radius [top,right,bottom,left].
    * @return void
*/
BasicShape.prototype.Border = function (size, color, radius) {
    this.border.size   = size  || 2;
    this.border.color  = color || '#000000';
    this.border.radius = setNumArr(radius,Math.min(this.width/2,this.height/2));
};

/**
    * Set padding.
    *
    * @param int padding, array padding : [top,right,bottom,left].
    * @return void
*/
BasicShape.prototype.Padding = function (padding) {
    this.padding = setNumArr(padding);
};

/**
    * Set shadow/light proprieties.
    *
    * @param string color : Color of border (Hex).
    * @param int x          : Offset x in pixel.
    * @param int y          : Offset y in pixel.
    * @param int blur     : Blur.
    * @return void
*/
BasicShape.prototype.Shadow = function (color, x, y, blur) {
    this.shadow.color  = color || '#000000';
    this.shadow.x      = x || 0;
    this.shadow.y      = y || 0;
    this.shadow.blur   = blur || 0;
};
2- Correcting X, Y, Width, Height :

Canvas's lineTo() defines a line , stroke() draws a stroke on the current sub-path using the current stroke style , which is not the desired result. The effect that we are looking for is similar to CSS's borders , so we have to translate the border by a (border's size / 2 ) offset.




 
/**
    * Get top left corner X.
    *
    * @return int
*/
BasicShape.prototype.X = function () {
    return this.x-this.border.size/2;
};

/**
    * Get top left corner Y.
    *
    * @return int
*/
BasicShape.prototype.Y = function () {
    return this.y-this.border.size/2;
};

/**
    * Get top right corner X.
    *
    * @return int
*/
BasicShape.prototype.WidthX = function () {
    return this.x+this.border.size/2+this.width;
};

/**
    * Get top right corner Y.
    *
    * @return int
*/
BasicShape.prototype.HeightY = function () {
    return this.y+this.border.size/2+this.height;
};


3- Lines coordinates ( To create the border radius effect ):
 
/**
    * Get lines start.
    *
    * @return array
*/
BasicShape.prototype.LineStart = function () {
    var linestart = [];
    linestart[0]  = {x : this.X() + this.border.radius[0] , y : this.Y()};
    linestart[1]  = {x : this.WidthX() , y : this.Y() + this.border.radius[1]};
    linestart[2]  = {x : this.X() - this.border.radius[2], y : this.HeightY()};
    linestart[3]  = {x : this.X(), y : this.HeightY() - this.border.radius[3]};
    return linestart;
};

/**
    * Get lines end.
    *
    * @return array
*/
BasicShape.prototype.LineEnd = function () {
    var lineend   = [];
    lineend[0]    = {x : this.WidthX() - this.border.radius[1] , y : this.Y()};
    lineend[1]    = {x : this.WidthX() , y : this.HeightY() - this.border.radius[2]};
    lineend[2]    = {x : this.X() + this.border.radius[3], y : this.HeightY()};
    lineend[3]    = {x : this.X() , y : this.Y() + this.border.radius[0]};
    return lineend;
};
4- Draw :
 
/**
    * Draw input's shape.
    *
    * @return array
*/
BasicShape.prototype.Draw = function () {
    var linestart = this.LineStart();
    var lineend   = this.LineEnd();
    var controls  = this.Controls();
    
    this.context.beginPath();
    this.context.moveTo(linestart[0].x, linestart[0].y);
    this.context.lineTo(lineend[0].x, lineend[0].y);
    this.context.arcTo(controls[1].x,controls[1].y,linestart[1].x, linestart[1].y,this.border.radius[1]);
    this.context.lineTo(lineend[1].x, lineend[1].y);
    this.context.arcTo(controls[2].x,controls[2].y,linestart[2].x, linestart[2].y,this.border.radius[2]);
    this.context.lineTo(lineend[2].x, lineend[2].y);
    this.context.arcTo(controls[3].x,controls[3].y,linestart[3].x, linestart[3].y,this.border.radius[3]);
    this.context.lineTo(lineend[3].x, lineend[3].y);
    this.context.arcTo(controls[0].x,controls[0].y,linestart[0].x, linestart[0].y,this.border.radius[0]);
    this.context.shadowColor   = this.shadow.color;
    this.context.shadowBlur    = this.shadow.blur;
    this.context.shadowOffsetX = this.shadow.x;
    this.context.shadowOffsetY = this.shadow.y;
    this.context.fillStyle     = this.bg;
    this.context.fill();
    this.context.lineWidth     = this.border.size;
    this.context.strokeStyle   = this.border.color;
    this.context.stroke();
    this.context.closePath();
};

That's all for today , next time we will create the FormCanvas object .

No comments:

Post a Comment


Zoli Issam's blog proudly powered by Blogger | All rights reserved Jaw,B 2010-2013