canvas(七)绘制网格和坐标轴

1.绘制网格

  • 传入dom和分割线间隔进行渲染,网格线分为水平方向和垂直方向
<script>
    //绘制网格
    function drwaGrid(dom = document.querySelector("canvas"),space = 50){
        //获取画笔
        var ctx = dom && dom.getContext("2d")
        //根据画布宽高计算分割线数量
        var row = Math.floor(dom.height/space)
        var col = Math.floor(dom.width/space)
        //设置虚线
        ctx.setLineDash([5,10])
        //绘制水平分割线
        for(var i=0;i<=row;i++){
            //开启新路径
            ctx.beginPath()
            //起点
            ctx.moveTo(0,i*space)
            //画直线
            ctx.lineTo(dom.width,i*space)
            //绘制
            ctx.stroke()
        }
        //绘制垂直分割线
        for(var i=0;i<=col;i++){
            //开启新路径
            ctx.beginPath()
            //起点
            ctx.moveTo(i*space,0)
            //画直线
            ctx.lineTo(i*space,dom.height)
            //绘制
            ctx.stroke()
        }
    }


    //获取容器
    var box = document.querySelector('canvas')
    //绘制网格
    drwaGrid(box)
</script>

2.绘制坐标轴

  • 分为3个部分:坐标轴,刻度线,坐标轴箭头

<script>
    //封装绘制坐标轴的类
    class DrawAxis{
        //构造器
        constructor(dom = document.querySelector('canvas'),padding = 20){
            //初始化
            this.init(dom,padding)
            //执行绘制
            this.render()
        }

        //初始化
        init(dom,padding){
            //获取画笔
            this.ctx = dom.getContext('2d')
            //间隔
            this.padding = padding
            //坐标原点
            this.x0 = this.padding + 0.5
            this.y0 = dom.height - this.padding + 0.5
            //坐标终点
            this.x_end = dom.width - this.padding + 0.5
            this.y_end = this.padding + 0.5
            //网格宽高
            this.grid_width = dom.width - this.padding * 2
            this.grid_height = dom.height - this.padding * 2
        }

        //执行渲染
        render(){
            //绘制坐标轴
            this.DrawLine()
            //绘制刻度线
            this.DrawMark()
            //绘制箭头
            this.DrawArrow()
        }

        //绘制坐标轴
        DrawLine(){
            //设置绘制宽度
            this.ctx.lineWidth = 1

            //横坐标线
            this.ctx.beginPath()
            //起点
            this.ctx.moveTo(this.x0,this.y0)
            //终点
            this.ctx.lineTo(this.x_end,this.y0)
            //绘制
            this.ctx.stroke()

            //纵坐标线
            this.ctx.beginPath()
            this.ctx.moveTo(this.x0,this.y0)
            this.ctx.lineTo(this.x0,this.y_end)
            this.ctx.stroke()
        }
        //绘制刻度线
        DrawMark(){
            //定义刻度间隔
            var space = 50
            //刻度线高度
            var mark_width = 3
            //计算刻度线数量
            var row = Math.floor(this.grid_height / space)
            var col = Math.floor(this.grid_width / space)

            //x轴刻度线
            for(var i=0;i<col;i++){
                //新路径
                this.ctx.beginPath()
                //当前x刻度坐标
                var x = (i+1) * space + this.x0
                //起点
                this.ctx.moveTo(x,this.y0)
                //终点
                this.ctx.lineTo(x,this.y0 - mark_width)
                //绘制
                this.ctx.stroke()
            }

            //y轴刻度线
            for(var i=0;i<row;i++){
                //新路径
                this.ctx.beginPath()
                //当前y刻度坐标
                var y = this.y0 - (i+1) * space
                //起点
                this.ctx.moveTo(this.x0,y)
                //终点
                this.ctx.lineTo(this.x0 + mark_width,y)
                //绘制
                this.ctx.stroke()
            }
        }
        //绘制箭头(以坐标轴终点为起点,填充一个三角形)
        DrawArrow(){
            //设置填充颜色
            this.ctx.fillStyle = 'black'

            //横坐标轴箭头
            //开启新路径
            this.ctx.beginPath()
            //移动到x轴终点附近
            this.ctx.moveTo(this.x_end + 8,this.y0)
            //绘制三角形
            this.ctx.lineTo(this.x_end - 4,this.y0 - 3)
            this.ctx.lineTo(this.x_end - 4,this.y0 + 3)
            this.ctx.lineTo(this.x_end + 8,this.y0)
            //填充
            this.ctx.fill()

            //纵坐标轴箭头
            //开启新路径
            this.ctx.beginPath()
            //移动到y轴终点附近
            this.ctx.moveTo(this.x0,this.y_end - 8)
            //绘制三角形
            this.ctx.lineTo(this.x0 - 3,this.y_end + 4)
            this.ctx.lineTo(this.x0 + 3,this.y_end + 4)
            this.ctx.lineTo(this.x0,this.y_end - 8)
            //填充
            this.ctx.fill()
        }
    }


    //获取容器
    var box = document.querySelector('canvas')
    //绘制坐标轴
    new DrawAxis(box)
</script>

3.封装成插件

将绘制坐标轴,绘制网格,坐标转换的方法封装到插件中
使用方法,传入canvas元素和padding

class DrawCoordinateSystem{
    constructor(canvas,padding){
        this.canvas = canvas || document.querySelector("canvas")
        this.padding = padding
        this.ctx = this.canvas.getContext("2d")
        //根据padding计算原点
        this.x0 = 0+padding
        this.y0 = this.canvas.height-padding

        //定义箭头的长度和高度
        this.arrowWidth = 30
        this.arrowHeight = 5

        //定义刻度间隔
        this.space = 50
        //定义刻度长度
        this.markWidth = 5

        //绘制坐标轴
        this.drawAxis()
        //绘制网格
        this.drawDrid()
    }
    // 绘制坐标轴的方法
    drawAxis(){
        var {ctx,canvas,x0,y0,arrowWidth,arrowHeight,markWidth,space} = this
        //绘制x轴
        ctx.beginPath()
        ctx.moveTo(x0,y0)
        ctx.lineTo(canvas.width,y0)
        ctx.stroke()
        //绘制箭头
        ctx.beginPath()
        ctx.moveTo(canvas.width,y0)
        ctx.lineTo(canvas.width-arrowWidth,y0-arrowHeight)
        ctx.lineTo(canvas.width-arrowWidth,y0+arrowHeight)
        ctx.closePath()
        ctx.fill()
        //绘制x轴的刻度
        for(var x=x0+space;x<canvas.width-arrowWidth;x+=space){
            ctx.beginPath()
            ctx.moveTo(x,y0)
            ctx.lineTo(x,y0-markWidth)
            ctx.stroke()
        }

        //绘制y轴
        ctx.beginPath()
        ctx.moveTo(x0,y0)
        ctx.lineTo(x0,0)
        ctx.stroke()
        //绘制箭头
        ctx.beginPath()
        ctx.moveTo(x0,0)
        ctx.lineTo(x0-arrowHeight,arrowWidth)
        ctx.lineTo(x0+arrowHeight,arrowWidth)
        ctx.closePath()
        ctx.fill()
        //绘制x轴的刻度
        for(var y=y0-space;y>arrowWidth;y-=space){
            ctx.beginPath()
            ctx.moveTo(x0,y)
            ctx.lineTo(x0+markWidth,y)
            ctx.stroke()
        }

        //绘制原点标题
        ctx.textBaseline ="top"
        ctx.font = "15px 微软雅黑"
        ctx.textAlign = "center"
        ctx.fillText("(0,0)",x0,y0+2)
    }

    //绘制网格的方法
    drawDrid(){
        var {canvas,space,x0,y0} = this
        // 定义当前坐标
        var x = x0,y = y0
        // 设置虚线
        ctx.setLineDash([5,10])
        //绘制水平方向的网格线
        for(y=y0+space;y>0;y-=space){
            //开启路径
            ctx.beginPath()
            
            ctx.moveTo(x0,y)
            ctx.lineTo(canvas.width,y)
            ctx.stroke()
        }
        //绘制垂直方向的网格线
        for(x=x0+space;x<canvas.width;x+=space){
            //开启路径
            ctx.beginPath()
            
            ctx.moveTo(x,0)
            ctx.lineTo(x,y0)
            ctx.stroke()
        }
        ctx.beginPath()
    }

    //坐标转换工具
    transform(x=0,y=0){
        var {padding,y0} = this
        x = x+padding
        y = y0- y
        return [x,y]
    }
}

使用插件

<script>
    var canvas = document.querySelector("canvas")
    var ctx = canvas.getContext("2d")

    //绘制坐标轴
    var draw = new DrawCoordinateSystem(canvas,20)
    //在此坐标轴绘制一个圆(转换坐标)
    ctx.arc(...draw.transform(100,100),80,0,Math.PI*2)
    ctx.fillStyle="yellow";
	ctx.fill();
</script>

posted @ 2019-10-10 14:21  ---空白---  阅读(2960)  评论(0编辑  收藏  举报