canvas構建一個平面直角坐標系


功能:

  1:可設置只顯示某個象限(onlyQuadrant)

     2:可設置刻度大小(setCalibration)

     3:可設置放大比例(setProportion)

可調用的方法(包括上面3個):

  向坐標系打印一點 (printPoint)

  在坐標畫一條直線(printLine)

  設置下一畫筆的填充色(setFillColor)

  設置下一畫筆的邊框色(setStrokeColor)

  獲取某個坐標的真實x坐標(getx)

  獲取某個坐標的真實y坐標(gety)

例子:http://jun-lu.github.com/jun/canvas_sin_cos_tan.html

源碼:https://github.com/jun-lu/jun/blob/master/src/FlatSystem.js

/**
    平面直角坐標系類
    可以輕松在一塊畫布上畫出平面直角坐標系,可設置寬度,高度,繪制比例,以及單位刻度
    構造函數 : FlatSystem
                context: 畫布的2d上下文
                width:繪制的最大寬度
                height:繪制的最大高度
    屬性設置:
            this.calibration=30 //刻度 可通過 setCalibration(number) 設置 ,這個方法也是對外API之一
            this.proportion=2 //繪制比例  可通過 setProportion(number) 設置這個方法也是對外API之一
    api:
        setCalibration(number);// 設置坐標系刻度
        setProportion();// 設置坐標系繪制比例
        init();//在畫布上畫出坐標系,如果在init之前沒有設置刻度和繪制比例會使用默認的值
        clear(x,y,width,height)//清除畫布的某塊區域,如果不傳遞任何值會清空全部畫布 
        
        
*/
function FlatSystem(context, width, height){
            
    this.context = context;
    this.width = width;
    this.height = height;
    this.calibration = 20;//刻度
    this.proportion = 2;//繪制比例
    this.jx = this.width/2; //0坐標點的x位置
    this.jy = this.height/2; //0坐標點的y位置
        
    //this.init();
    
}
FlatSystem.prototype = {
    constructor:FlatSystem,
    init:function(){
        this.context.clearRect(0,0,this.width, this.height);
        //this.width *= this.proportion;
        //this.height *= this.proportion;
        this.context.moveTo(0,0);
        this.setFillColor("#000");
        this.setStrokeColor("#000");
        this.build();
    },
    clear:function(x, y, width, height){
        this.context.clearRect(x ||0,y || 0,width || this.width, height || this.height);
    },
    setProportion:function(proportion){//整數
        this.proportion = proportion;
    },
    setCalibration:function(calibration){
        this.calibration = calibration;//刻度
    },    
    onlyQuadrant:function(quadran){//顯示某一象限 1, 2, 3, 4
        if(quadran == 0){
            this.jx = this.width/2;
            this.jy = this.height/2;
        }
        
        if(quadran == 1){
            this.jx = 50;
            this.jy = this.height-50;
        }
        if(quadran == 2){
            this.jx = this.width - 50;
            this.jy = this.height - 50;
        }
        if(quadran == 3){
            this.jx = this.width -50;
            this.jy = 50;
        }
        if(quadran == 4){
            
            this.jx = 50;
            this.jy = 50;
        }
    },
    /**
        在坐標系統打印一個點
        x 軸坐標
        y 軸坐標
        width 點的寬度
        height 點的高度
    */
    printPoint:function(x,y,width,height){//默認點陣寬度2
    
        x = this.getx(x);
        y = this.gety(y);
        
        if(x < this.width &&  y < this.height){
            this.drawRect(x, y, width || 2, height || 2);
            return true;
        }
        return false;
    },
    /***
        在坐標系中畫一條直線(線段)
        x 線段結束點 x坐標
        y 線段結束點 y坐標
        
        sx 線段開始點 x坐標 可選 不傳遞將會使用上次畫筆結束點
        sy 線段開始點 y坐標 可選
        
    */
    printLine:function(x, y, sx, sy){
        this.drawLine(this.getx(x), this.gety(y), this.getx(sx),this.gety(sy));
    },
    /**
        設置填充色
    */
    setFillColor:function(color){
        this.context.fillStyle = color;
    },
    /**
        設置邊框色
    */
    setStrokeColor:function(color){
        this.context.strokeStyle = color;
    },
    /**
        非公開
    */
    drawRect:function(x,y,width, height){

        this.context.beginPath();
        this.context.fillRect(x-width/2, y-height/2, width, height);
        this.context.stroke();
    },
    /***
        非公開
        在畫布打印一個點,坐標為真實開始坐標和結束坐標
    */
    drawLine:function(x, y, sx, sy){//目標x y 開始sx sy
        this.context.beginPath();
        if(sx !== undefined && sy !== undefined ){
            this.context.moveTo(sx,sy);
        }
        //this.context.beginPath();
        this.context.lineTo(x, y);
        this.context.stroke();
    },
    fillText:function(text, x, y){
        this.context.fillText(text, this.getx(x), this.gety(y));
    },
    build:function(){//構建坐標系

        this.drawLine(this.jx, this.height, this.jx, 0);// y
        this.drawLine(0, this.jy, this.width,  this.jy);// x
        this.setFillColor('#d8d8d8');
        this.fillText("O", this.jx+5 , this.jy+10);//原點坐標 0
        this.buildCoordinate();// +x height/2
        
    },
    buildCoordinate:function(){//構建坐標系中的刻度和數字
        
        
        var calibration = this.calibration * this.proportion;//calibration 最小刻度
        var width = this.width;
        var height = this.height;
        
        // len = 中心點到4個最遠點的最大絕對值 / 最小間隔單位
        var len = Math.max(
                    Math.max( Math.abs(this.getx(0) - width), Math.abs(this.getx(0) - 0) ), //x軸絕對最大值
                    Math.max( Math.abs(this.gety(0) - height ), Math.abs(this.gety(0) - 0) ) //y軸絕對最大值
                )*this.proportion / calibration;


        //this.setFillColor('#d8d8d8');
        var fixed = this.proportion >= 1 ? function(x){//對於繪制比例小於1 處理小位數
            return x;
        } : function(x){ return (x).toFixed(1);};
        
        
        
        var j=0;//中間變量
        var d = 0;
        var sx=0;
        var sy=0; 

        this.context.textBaseline = "middle";
        this.setFillColor('#d8d8d8');
        for(var i=1; i<=len;i++){//注釋過的代碼都是適當優化過的 其實等於沒優化

            j = String(fixed(calibration*i));
            //console.log(typeof j);
            sx = this.getx(calibration*i);//第一象限
            sy = this.gety(0);
            
            this.drawLine(sx, sy, sx, sy-5);
            this.context.textAlign = "center";
            this.context.fillText(j, sx, sy+10);
            /***/
            
            sx = this.getx(-calibration*i);//第3象限
            //sy = this.gety(0);
            this.drawLine(sx, sy, sx, sy-5);
            this.context.fillText(j, sx, sy+10);
            /***/
            sx = this.getx(0);//第4象限
            sy = this.gety(-calibration*i);
            
            this.drawLine(sx, sy, sx-5, sy);
            this.context.textAlign = "left";
            this.context.fillText(j, sx+5, sy);
            /***/
            
            //sx = this.getx(0);//第2象限
            sy = this.gety(calibration*i);
            
            this.drawLine(sx, sy, sx-5, sy);
            this.context.fillText(j, sx+5, sy);
            /***/
        }


    },
    isIn:function(x, y){
        var x = this.getx(x);
        var y = this.gety(y);
        return x>=0 && x <= this.width && y>=0 && y<= this.height;
    },
    /**
        獲取真實x坐標
    */
    getx:function(x){
        return parseInt(this.jx+(x/this.proportion));
    },
     /**
        獲取真實x坐標
    */
    gety:function(y){
        return parseInt(this.jy-(y/this.proportion));
    }
};


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM