闲聊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);

效果:

shadow_font_pointsDraw_line_test_result.png

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

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,064评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,606评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,011评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,550评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,465评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,919评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,428评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,075评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,208评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,185评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,191评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,914评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,482评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,585评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,825评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,194评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,703评论 2 339

推荐阅读更多精彩内容