闲聊js9: 创建一个演示用的渲染库7(渲染状态及点集绘制)

本篇的目的是要了解:

  1. 封装渲染状态
  2. 提供一个通用的点集绘制函数,可以绘制点线面,封闭与否,及填充与否

1. 提供渲染状态进栈/出栈操作:

    pushStates() {
        this.context.save();
    }

    popStates() {
        this.context.restore();
    }

2. 设置Line相关渲染状态:(lineWidth,lineCap,lineJoin,miterLimit,default值见代码注释)

    /*
    ctx.lineWidth = value;  canvas2d default 1.0

    ctx.lineCap = "butt";   canvas2d default
    ctx.lineCap = "round";
    ctx.lineCap = "square";

    ctx.lineJoin = "bevel";
    ctx.lineJoin = "round";
    ctx.lineJoin = "miter";  canvas2d defaule

    ctx.miterLimit = value;  canvas2d default 10.0
    */

    setLineState(lineWidth = 2.0, lineCap = 'butt', lineJoin = 'round', miterLimit = 10.0) {
        let ctx = this.context;
        ctx.lineWidth = lineWidth;
        ctx.lineCap = lineCap;
        ctx.lineJoin = lineJoin;
        ctx.miterLimit = miterLimit;
    }

3. 设置shadow相关渲染状态:(shadowColor,shadowOffsetX/Y,shadowBlur,default值见代码注释)

   /*
    ctx.shadowColor = color;      canvas2d default rgba(0,0,0,0)
    ctx.shadowOffsetX = offset;   canvas2d default 0.0
    ctx.shadowOffsetY = offset;   canvas2d default 0.0
    ctx.shadowBlur = level;       canvas2d default 0.0
    */
    setShadowState(shadowColor = 'rgba(0,0,0,0.5)', shadowOffsetX = 2, shadowOffsetY = 2, shadowBlur = 2) {
        let ctx = this.context;
        ctx.shadowColor = shadowColor;
        ctx.shadowOffsetX = shadowOffsetX;
        ctx.shadowOffsetY = shadowOffsetY;
        ctx.shadowBlur = shadowBlur;
    }

4. 设置文本相关渲染状态:(textAlign,textBaseLine,font,default值见代码注释)

    /*
    ctx.textAlign = "left" || "right" ||
                    "center" || "start" ||
                     "end";             
                     canvas2d default start

    ctx.textBaseline = "top" || "hanging" ||
                       "middle" || "alphabetic" ||
                       "ideographic" || "bottom";
                       canvas2d default alphabetic
                       
    ctx.font = value;  canvas2d default 10px sans-serif 
    */

    setTextState(textAlign = 'center', textBaseLine = 'middle', font = '14px sans-serif') {
        let ctx = this.context;
        ctx.textAlign = textAlign;
        ctx.textBaseLine = textBaseLine;
        ctx.font = font;
    }

5. 点集绘制函数:

//通用函数,可以绘制点线面,是否封闭,是否填充
    //其他绘制函数,都是该函数的特殊形式
    drawPoints(points = [], style = 'red', isClosed = true, isFill = true) {

        //必须要大与等于2个点
        if (points.length < 2)
            return;

        let ctx = this.context;

        ctx.save();

        ctx.beginPath();

        //移动到第一个点位置
        ctx.moveTo(points[0].x, points[0].y);

        //从1-(n-1)循环绘制线段
        for (let i = 1; i < points.length; i++) {
            ctx.lineTo(points[i].x, points[i].y);
        }

        //如果需要,封闭路径
        if (isClosed == true) {
            ctx.closePath();
        }

        //填充还是描边绘制
        if (isFill == true) {
            ctx.fillStyle = style;
            ctx.fill();
        } else {
            ctx.strokeStyle = style;
            ctx.stroke();
        }

        ctx.restore();
    }

6. 测试:

        let canvas = document.getElementById("myCanvas");
        let context = canvas.getContext('2d');
        let render = new BLFRender(context);

        render.clear();

        render.drawGrid('white', 'black', 20, 20);

        //设置全局的shadow和line,以及文本渲染状态
        //影响所有下面的绘制
        render.setShadowState();
        render.setLineState();
        render.setTextState();

        render.drawRect(new Rect(10, 10, 80, 40));
        render.drawRect(new Rect(110, 10, 80, 40), 'blue', false);

        render.drawCircle(new Circle(310, 60, 50));
        render.drawCircle(new Circle(410, 60, 50), 'blue', false);
     
        /*
        下面两个函数共同点:
          1. 圆心都为【600,60】,半径都为50px
          2. 起始角都为30度,结束角都为180度
          3. isClosed都设置为false,不封闭arc路径
        下面两个函数不同点:
          1. 上面函数isCCW(是否逆时针) = false,style = red
          2. 下面函数isCCW(是否逆时针) = true, style = blue
           
        */
        render.drawArc(new Arc(600, 60, 50, 30, 180, false), 'red', false);
        render.drawArc(new Arc(600, 60, 50, 30, 180, false, true), 'blue', false);

        let pts = [new Point(700, 50), new Point(790, 50), new Point(790, 200)];
        render.drawPoints(pts, 'blue', false, false);
        render.drawText(100, 100);

效果:

闲聊js9: 创建一个演示用的渲染库7(渲染状态及点集绘制)_第1张图片
shadow_font_pointsDraw_line_test_result.png

可以看到阴影出现了,文字变化了,关于线段相关属性,大家可以调整一下lineWidth到例如25,再设置其他属性,就可以明显看到各种变化。具体就自己测试一下吧!

htmlpreview.github.io/?https://github.com/jackyblf/BLF_JS_Demos/blob/master/drawShape.html

你可能感兴趣的:(闲聊js9: 创建一个演示用的渲染库7(渲染状态及点集绘制))