功能:
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)); } };