Canvas基础知识

总结一些基础知识

1. 画一条直线

  • moveTo设置起点,lineTo设置下一坐标
<canvas id="canvas"></canvas>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");
        // 设置状态
        context.beginPath();
        context.moveTo(100, 100);// 起点
        context.lineTo(700, 700);// 下一点坐标
        context.closePath();
        context.lineWidth = 10;// 线宽
        context.strokeStyle = "#0f0";// 颜色
        
        // 绘制
        context.stroke();
    }
</script>
  • lineCap属性 - 设置线段起始位置的样式,取值如下
    butt:(default)默认值
    round:圆头
    square:方头
<canvas id="canvas"></canvas>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");

        context.lineWidth = 30;
        context.strokeStyle = "tomato";

        context.beginPath();
        context.moveTo(100, 100);
        context.lineTo(400, 100);
        context.lineCap = "butt";
        context.stroke();

        context.beginPath();
        context.moveTo(100, 200);
        context.lineTo(400, 200);
        context.lineCap = "round";
        context.stroke();

        context.beginPath();
        context.moveTo(100, 300);
        context.lineTo(400, 300);
        context.lineCap = "square";
        context.stroke();
        // 辅助线
        context.lineWidth = 1;
        context.beginPath();
        context.moveTo(100, 50);
        context.lineTo(100, 350);
        context.stroke();

        context.beginPath();
        context.moveTo(400, 50);
        context.lineTo(400, 350);
        context.stroke();
    }
</script>

结果如下:


lineCap
  • lineJoin属性- 两条直线相交处的样式,可取值如下:
    miter:(default),尖角,miterLimit 默认值10,控制尖角的长度,只有设置miter时生效。
    bevel:斜接
    round: 圆角
<canvas id="canvas"></canvas>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");

        context.lineWidth = 50;
        context.strokeStyle = "tomato";

        context.beginPath();
        context.moveTo(300, 300);
        context.lineTo(400, 100);
        context.lineTo(500, 300);
        context.lineJoin = "miter";
        context.miterLimit = 10;
        context.stroke();

        context.beginPath();
        context.moveTo(300, 500);
        context.lineTo(400, 300);
        context.lineTo(500, 500);
        context.lineJoin = "bevel";
        context.miterLimit = 10;
        context.stroke();

        context.beginPath();
        context.moveTo(300, 700);
        context.lineTo(400, 500);
        context.lineTo(500, 700);
        context.lineJoin = "round";
        context.miterLimit = 10;
        context.stroke();
    }
</script>

示意图如下:


lineJoin

2. 画一个矩形

(1).直接使用连线的方式画出矩形。

<canvas id="canvas"></canvas>
<script>

    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");
        context.beginPath();
        context.moveTo(100, 100);
        context.lineTo(600, 100);
        context.lineTo(600, 600);
        context.lineTo(100, 600);
        context.lineTo(100, 100);//可以省略,closePath()会自动封闭图形
        context.closePath();

        context.lineWidth = 10;
        context.strokeStyle = "#0f0";

        context.stroke();
    }
</script>

(2).使用context.rect(x, y, width, height)规划路径,这里只规划路径,不会绘制。
context.fillRect(x, y, width, height), context.strokeRect(x, y, width, height)不但规划路径,还将矩形直接绘制出来。

<canvas id="canvas"></canvas>
<script>

    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");

        drawRect(context, 100, 100, 300, 200, 5, "blue", "red");
        drawRect2(context, 250, 200, 300, 200, 5, "blue", "rgba(0, 255, 0, 0.5)");


    }

    function drawRect(cxt, x, y, width, height, borderWidth, borderColor, fillColor){
        cxt.beginPath();
        cxt.rect(x,y, width, height); // 规划路径
        cxt.closePath();

        cxt.lineWidth = borderWidth;
        cxt.fillStyle = fillColor;
        cxt.strokeStyle = borderColor;

        cxt.fill();
        cxt.stroke();
    }
    function drawRect2(cxt, x, y, width, height, borderWidth, borderColor, fillColor){
        cxt.lineWidth = borderWidth;
        cxt.fillStyle = fillColor;
        cxt.strokeStyle = borderColor;

        cxt.fillRect(x, y, width, height); // 填充
        cxt.strokeRect(x, y, width, height);
    }
</script>

fillStyle, strokeStyle 可取颜色值如下:
#ffffff 、#fff、
rgb(255, 255, 100)、rgba(100, 100, 100, 0.8)、
hsl(20, 62%, 28%)、 hsla(30, 82%, 45%, 0.6)、
red

3. 图形变换

  • 位移:translate(x, y)
  • 旋转:rotate(deg)
  • 缩放:scale(sx, sy) , sx - x方向缩放倍数,sy - y方向缩放倍数。
  • 变换矩阵
    a c e          a - 水平缩放(1) ;   b - 水平倾斜(0)
    b d f          c - 垂直倾斜(0) ;   d - 垂直缩放(1)
    0 0 1          e - 水平位移(0);   f - 垂直位移(0)
  • 设置变换矩阵:
    transform(a, b, c, d, e, f)
    setTransform(a, b, c, d, e, f) 设置变换后的默认值
  • canvas状态的保存与恢复
    context.save();
    context.restore();
<canvas id="canvas" style="border: 1px solid #000;"></canvas>
<script>

   window.onload = function () {
       var canvas = document.getElementById("canvas");

       canvas.width = 800;
       canvas.height = 800;

       var context = canvas.getContext("2d");

       context.save();
       context.fillStyle = "red";
       context.translate(100, 100);
       context.fillRect(0, 0, 400, 400);
       context.restore();

       context.save();
       context.fillStyle = "green";
       context.translate(300, 300);
       context.fillRect(0, 0, 400, 400);
       context.restore();
   };
<canvas id="canvas"></canvas>
<script>

    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");

        context.fillStyle = "#000";
        context.fillRect(0, 0, canvas.width, canvas.height);

        for(var i = 0; i < 200; i++){
            var r = Math.random()*10+10;
            var x = Math.random()*canvas.width;
            var y = Math.random()*canvas.height;
            var a = Math.random()*360;
            drawStar(context, x, y, r, a)
        }
    };

    function drawStar(cxt, x, y, R, rot){
        var rot = rot || 0;

        cxt.fillStyle = "#fb3";
        cxt.strokeStyle = "#fd5";
        cxt.lineWidth = 3;

        cxt.save();
        cxt.transform(R, 0, 0, R, x, y);
        // cxt.translate(x, y);
        cxt.rotate(rot/180*Math.PI);
        // cxt.scale(R, R);

        starPath(cxt);

        cxt.fill();
        cxt.stroke();

        cxt.restore();

    }
    function starPath(cxt){
        cxt.beginPath();

        for(var i = 0; i < 5; i ++){
            cxt.lineTo(Math.cos((18 + i*72 ) / 180 * Math.PI),
                -Math.sin((18 + i*72) / 180 * Math.PI) );
            cxt.lineTo(Math.cos((54 + i*72) / 180 * Math.PI) * 0.5,
                -Math.sin((54 + i*72 ) / 180 * Math.PI) * 0.5);
        }
        cxt.setTransform(1, 0, 0, 1, 0, 0);//清除上一次的影响
        cxt.closePath();
    }
</script>

4. fillStyle - 线性渐变&径向渐变

  • 线性渐变
    //step1
    var grd = context.createLinearGradient(xstart, ystart, xend, yend);
    //step2
    grd.addColorStop(stop, color);
<canvas id="canvas"></canvas>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 800;
        var context = canvas.getContext("2d");

        var linearGrad = context.createLinearGradient(0, 0, 800, 800);
        linearGrad.addColorStop(0.0, 'white');
        linearGrad.addColorStop(0.25, 'yellow');
        linearGrad.addColorStop(0.5, 'green');
        linearGrad.addColorStop(0.75, 'blue');
        linearGrad.addColorStop(1.0, 'black');

        context.fillStyle = linearGrad;
        context.fillRect(0, 0, 800, 800);
    }
</script>
  • 径向渐变
    //step1
    var grd = context.createRadialGradient(x0, y0, r0, x1, y1, r1);
    //step2
    grd.addColorStop(stop, color);
<canvas id="canvas"></canvas>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");
        canvas.width = 800;
        canvas.height = 800;
        var context = canvas.getContext("2d");

        var linearGrad = context.createRadialGradient(400, 400, 100, 400, 400, 400);
        linearGrad.addColorStop(0.0, 'white');
        linearGrad.addColorStop(0.25, 'yellow');
        linearGrad.addColorStop(0.5, 'green');
        linearGrad.addColorStop(0.75, 'blue');
        linearGrad.addColorStop(1.0, 'black');

        context.fillStyle = linearGrad;
        context.fillRect(0, 0, 800, 800);
    }
</script>

5. createPattern

  • createPattern(img, repeat-style)
    repeat-style:no-repeat; repeat-x; repeat-y; repeat
  • createPattern(canvas, repeat-style)
  • createPattern(video, repeat-style)

6.曲线绘制

  • 圆或圆弧

context.arc(context, center, radius, startingAngle, endingAngle, anticlockwiae)
anticlockwiae = false 顺时针

<canvas id="canvas"></canvas>
<script>
    window.onload = function(){
        var canvas = document.getElementById("canvas");

        canvas.width = 1024;
        canvas.height = 768;

        var context = canvas.getContext("2d");

        context.lineWidth = 2;
        context.strokeStyle = "#058";

        for(var i = 0; i < 10; i ++){
            context.beginPath();
            context.arc(50 + i*100, 60, 40, 0,2*Math.PI*(i+1)/10);
            context.closePath();//会自动闭合

            context.stroke()
        }

        for(var i = 0; i < 10; i ++){
            context.beginPath();
            context.arc(50 + i*100, 180, 40, 0,2*Math.PI*(i+1)/10);

            context.stroke()
        }

        for(var i = 0; i < 10; i ++){
            context.beginPath();
            context.arc(50 + i*100, 300, 40, 0,2*Math.PI*(i+1)/10, true);
            context.closePath();//会自动闭合

            context.stroke()
        }

        for(var i = 0; i < 10; i ++){
            context.beginPath();
            context.arc(50 + i*100, 420, 40, 0,2*Math.PI*(i+1)/10, true);

            context.stroke()
        }

        context.fillStyle = "#0f0";

        for(var i = 0; i < 10; i ++){
            context.beginPath();
            context.arc(50 + i*100, 540, 40, 0,2*Math.PI*(i+1)/10, true);
            context.closePath();//会自动闭合

            context.fill()
        }

        for(var i = 0; i < 10; i ++){
            context.beginPath();
            context.arc(50 + i*100, 660, 40, 0,2*Math.PI*(i+1)/10, true);

            context.fill()
        }
    }
</script>
  • arcTo

context.arcTo(x1, y1, x2, y2, radius)

<canvas id="canvas"></canvas>
<script>
    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 1800;
        canvas.height = 1800;

        var context = canvas.getContext("2d");
        context.moveTo(400,100)
        context.arcTo(1200,400,400,700,400);
        context.strokeStyle= "red"
        context.stroke()
    }
</script>
  • 贝赛尔曲线 Bezier

(1)QuadraticCurveTo(二次)
context.moveTo(x0, y0); //初始点
contextquadraticCurveTo(x1, y1, x2, y2)//控制点、结束点
(2)BezierCurveTo(三次)
context.moveTo(x0, y0);
context.bezierCurveTo(x1, y1, x2, y2, x3, y3);

    function drawLand(cxt){
        cxt.save();

        cxt.beginPath();
        cxt.moveTo(0, 600);
        cxt.bezierCurveTo(540, 400, 660, 800, 1200, 600);
        cxt.lineTo(1200, 800);
        cxt.lineTo(0, 800);
        cxt.closePath();

        var lanStyle = cxt.createLinearGradient(0, 800, 0, 0);
        lanStyle.addColorStop(0.0, "#030");
        lanStyle.addColorStop(1.0, "#580");
        cxt.fillStyle = lanStyle;

        cxt.fill();

        cxt.restore();
    }

7.文字渲染基础

context.font = "bold 40px Arial";
context.fillText(String, x, y, [maxlen]);
context.StrokeText(String, x, y, [maclen])

<canvas id="canvas"></canvas>
<script>

    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");

        context.font = "bold 40px Arial";
        context.fillStyle = "#058";
        context.fillText("欢迎学习Canvas!欢迎学习Canvas!", 40, 100);
        context.lineWidth = 1;

        context.strokeStyle = "#058";
        context.strokeText("欢迎学习Canvas!欢迎学习Canvas!", 40, 200);

        context.fillText("欢迎学习Canvas!欢迎学习Canvas!", 40, 300, 400);
        context.strokeText("欢迎学习Canvas!欢迎学习Canvas!", 40, 400, 400);
    }
</script>
  • font

默认值"20px sans-serif"
(1)font-style:
normal(default);
italic(斜体字);
oblique(倾斜字体)
(2)font-variant:
normal;
small-caps(以小型形式显示大写字母)
(3)font-weight:
lighter;
normal;
bold;
bolder;
100,200,300,400(normal),500,600,700(bold),800,900
(4)font-size:
20px;
2em;
150%;
(5)font-family:
设置多种字体备选;
支持@font-face
web安全字体

<canvas id="canvas"></canvas>
<script>

    window.onload = function () {
        var canvas = document.getElementById("canvas");

        canvas.width = 800;
        canvas.height = 800;

        var context = canvas.getContext("2d");

        context.font = "bold 40px Arial";

        var linearGrad = context.createLinearGradient(0, 0, 700, 0);
        linearGrad.addColorStop(0.0, 'tomato');
        linearGrad.addColorStop(0.25, 'yellow');
        linearGrad.addColorStop(0.5, 'green');
        linearGrad.addColorStop(0.75, 'pink');
        linearGrad.addColorStop(1.0, 'red');

        context.fillStyle = linearGrad;
        // context.fillStyle = "#058";
        context.fillText("欢迎学习Canvas!欢迎学习Canvas!", 40, 100);
        context.lineWidth = 1;

        context.strokeStyle = "#058";
        context.strokeText("欢迎学习Canvas!欢迎学习Canvas!", 40, 200);

        context.fillText("欢迎学习Canvas!欢迎学习Canvas!", 40, 300, 400);
        context.strokeText("欢迎学习Canvas!欢迎学习Canvas!", 40, 400, 400);
    }
</script>
  • 文本对齐

context.textAlign = left/center/right
cotext.textBaseline = top/middle/bottom (alphabetic拉丁/ideographic汉,日/hanging印)

  • 文本度量

context.measureText(String).width

8. 阴影

context.shadowColor;
context.shadowOffsetX;//x位移值
context.shadowOffsetY;//y位移值
xontext.shadowBlur; //模糊值

9. global

  • globalAlpha = 1(default) //使全局具有透明度
  • glibalCompositeOperation//绘制的图像在重叠时产生的效果
    "sourece-over" - 后绘制的图像在先绘制的图形上面
    "destination-over" - 先绘制的图形在后悔值的上面
    ···········································································································································································
    source-over
    source-atop
    source-in
    source-out
    ···········································································································································································
    destination-over
    destination-atop
    destination-in
    destination-out
    ···········································································································································································
    lighter
    copy
    xor

10. 剪辑区域

context.clip();

11. 剪纸效果

非零环绕原则

其他

  • clearRect
    context.clearRect(x, y, width, height)
  • isPointInPath
    context.isPointInPath(x, y)
    var x = event.clientX - canvas.getBoundingClientRect().left
    var y = event.clientY - canvas.getBoundingClientRect().Right

兼容性

explorecanvas https://code.google.con/p/explorecanvas/
canvas 图形库:canvasplus/ArtisanJS/Rgraph

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

推荐阅读更多精彩内容

  • 一、基础介绍和画直线 大多数现代浏览器都是支持Canvas的,比如 Firefox, safari, chrome...
    空谷悠阅读 814评论 0 1
  • 1 Canvas接口元素定义 1.1 getContext()方法 为了在canvas上绘制,你必须先得到一个画布...
    Kevin_Junbaozi阅读 1,281评论 1 2
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,658评论 2 32
  • title: Canvas基础date: 2016-11-09tags: HTML5 0x00 Canvas 使用...
    曼路x_x阅读 300评论 0 2
  • 最近笔者在学习HTML5的新元素 ,会分享一些基础知识以及小例子,最终使用 实现一个绘制简单图表(条形图、线图或者...
    Sue1024阅读 1,482评论 0 1