• 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));
        }
    };
  • 相关阅读:
    jQuery中的观察者模式(Observer Pattern)
    jQuery异步获取json数据的2种方式
    jQuery制作水平多级下拉菜单
    简单说明CGI和动态请求是什么
    五种IO模型透彻分析
    不可不知的socket和TCP连接过程
    零复制(zero copy)技术
    编译httpd细节
    ansible编译httpd playbook示例
    翻译:CREATE DATABASE语句
  • 原文地址:https://www.cnblogs.com/idche/p/2473943.html
Copyright © 2020-2023  润新知