Canvas画图基础

画矩形

Canvas画矩形还是比较方便的,可以用fillrect,clearrect,strokerect,rect几种方法,各自间有点区别,先上代码:

// html
<canvas id="canvas" width="500" height="500" ></canvas>

var canvas1 = document.getElementById("canvas");
var ctx = canvas1.getContext('2d');
ctx.strokeStyle = '#ff4444'; 
ctx.fillStyle = '#000';                         
ctx.fillRect(100,100,100,100);
ctx.clearRect(120,120,60,60);
ctx.strokeRect(80,80,140,140);

ctx.beginPath();
ctx.rect(80, 250, 100, 100);
ctx.stroke();

绘制效果如下:

使用fillrect,clearrect,strokerect方法不用绘制路径,也不需要另外调用fill或者stroke方法来『上色』就可以绘制出图形,而rect方法仅仅是绘制出一个矩形的路径,还需要额外通过stroke或者fill方法才能绘制出矩形。

fillRectstrokeRect的区别就是画的是实心还是空心,而clearRect就是清空一个矩形区域,上图就是通过clearRect和fillrect配合画出的那个比较粗的矩形,实际上完全可以使用ctx.lineWidth来控制strokeRect的绘制宽度。

另外,矩形是Canvas里面唯一一种可以不通过路径就可以绘制的图形,其它的图形都需要生成一条路径才能绘制出来。

绘制路径

画了矩形再画个圆呗,

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');

ctx.beginPath();
ctx.lineWidth = 7;

ctx.strokeStyle = '#ff4444';
ctx.arc(80, 80, 50, 0 ,Math.PI*2);
ctx.stroke();

绘制效果如下:

arc(x, y, radius, startAngle, endAngle, counterclockwise)

  • x,y: 描述弧的圆形的圆心的坐标。
  • radius: 描述弧的圆形的半径。
  • startAngle, endAngle: 沿着圆指定弧的开始点和结束点的一个角度。这个角度用弧度来衡量。
  • counterclockwise 弧沿着圆周的逆时针方向(TRUE)还是顺时针方向(FALSE)遍历。

画了一个我们再画一个

ctx.moveTo(170, 120);

ctx.strokeStyle = '#000';
ctx.arc(120, 120, 50, 0 ,Math.PI*2);
ctx.stroke(); // 再画圆

会发现,两个园都变成了黑色,而不是我们预期的一个红色一个黑色。

这里就要说到路径了,在画第二个圆的时候,我们把strokeStyle改了颜色,但是绘制的时候把所有已经有的路径,不管是否绘制过,都重新绘制了一遍,这里有两个圆的路径,所以两个都被涂上了黑色。

这里在绘制第二个圆之前我们需要使用beginPath方法来重新开一条『新路』,如果画的是非闭合路径,可能还需要使用closePath方法来从当前点绘制一条到开始点的直线来闭合路径。

顺时针和逆时针的区别

counterclockwise是arc方法的最后一个参数,表示顺时针画还是逆时针画,看字面比较容易理解,但是实际用起来却有点不一样。

分别通过顺时针和逆时针画两个圆:

var canvas = document.getElementById("canvas1");
var ctx1 = canvas.getContext('2d');
ctx1.lineWidth = 7;

function draw(ctx, x) {
        ctx.clearRect(0, 0, 500, 500);
        ctx.beginPath();
        ctx.strokeStyle = '#ff4444';
        if (x < Math.PI*2) {
            x += 0.05;
        } else {
            x = 0;
        }
        ctx.arc(80, 80, 50, 0, x, false); // 顺时针
        ctx.stroke();
        ctx.beginPath();
        ctx.strokeStyle = '#000';
        ctx.arc(200, 80, 50, 0, x, true); // 逆时针
        ctx.stroke();
        requestAnimationFrame(function () {
            draw(ctx, x);
        });
}

requestAnimationFrame(function () {
        draw(ctx1, 0);
});

效果如下:

代码上看,就是不断增加endAngle,顺时针还好理解,但是逆时针就有点不一样了,可以看到逆时针的画法一开始就把圆整个形状画好了,然后却是慢慢的减小绘画区域。

这里我们首先要明白startAngle为0的时候是在圆的右侧经过圆心的水平线和圆的交点处。也就是3点钟那个地方。然后不管顺时针还是逆时针,endAngle都是同一个地方(有种说废话的赶脚),所以,顺时针就是按顺时针方向从startAngle走到endAngle,而逆时针是从逆时针方向走,所以才有一开始逆时针就画完了整个圆,然后才慢慢退回去。

另外,这种通过requestAnimationFrame来不不停画东东的方法,就是Canvas动画的基本实现原理了。

moveTo

还有个需要注意的就是moveTo这个方法,这个方法是将画笔移动到某个坐标处,move的过程中不会产生路径,所以可以用来画一些不连续的路径,比如之前我们画的两个圆,用了ctx.moveTo(170, 120);。为什么一定是这个坐标呢,这个坐标是圆的起始点,我们可以尝试换一下,会发现从moveTo之后的位置到下次起笔的位置会多一条连接线。

比如上面例子中使用ctx.moveTo(170, 170)就会如下图:

可以得出,当moveTo之后的点和下一次开始绘制的点不重合时,就会出现一条直线连接这两点,为了避免这种情况,moveTo移动的点最好跟下一次绘制的开始点重合。

总结

Canvas的内容比较多,涉及到画矩形,圆形,各种图形,线条,画图片,动画,像素点处理,粒子动画,贝塞尔曲线甚至包含构建三维空间,VR视频等等,上文只是简单介绍了Canvas画图基础的几个小点,更多的内容以后慢慢写。现就上面的内容简单做个总结:

  1. Canvas可以画各种东西,但除了矩形,其它的都是要依靠路径来画的。
  2. 画新的路径之前最好使用beginPath方法,这样不容易影响之前的路径。
  3. 画圆是从startAngle开始到endAngle结束,走的方向有顺时针和逆时针的差别。
  4. moveTo的点最好和下次开始绘画的点重合,这样避免不必要的线条。

源码地址:https://github.com/bob-chen/canvas-demo/tree/master/basic

参考

http://www.w3school.com.cn/html5/html_5_canvas.asp

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏深度学习之tensorflow实战篇

R语言高级绘图命令(标题-颜色等)

plot(x)          以x的元素值为纵坐标、以序号为横坐标绘图 plot(x,y)        x(在x-轴上)与y(在y-轴上)的二元作图 ...

5856
来自专栏深度学习之tensorflow实战篇

Python生成词云图,TIIDF方法文本挖掘: 词频统计,词云图

python中使用wordcloud包生成的词云图。 下面来介绍一下wordcloud包的基本用法。 class wordcloud.WordCloud(fon...

5026
来自专栏编程

你不知道的前端算法之热力图的实现

作者:TalkingData 李凤禄 本文为TalkingData原创,未经授权禁止转载。申请授权请在评论中留言联系! inMap 是一款基于 canvas 的...

7528
来自专栏为数不多的Android技巧

Xfermode in android

Xfermode有三个实现类:AvoidXfermode, PixelXorXfermode以及PorterDuffXfermode。 前两个类因为不支持硬件加...

1834
来自专栏Modeng的专栏

canvas学习总结三:绘制路径-线段

版权声明:本文为原创文章发布于公众号:Modeng , 你可以随意转载但请务必注明出处!!! https://blog.csdn.net/qq_32135...

771
来自专栏儿童编程

Processing雁群实验(续)

(1)旋转复杂不规则图形; (2)运用二维数组定义图形; (3)鼠标左右移动控制物体沿 Y 轴旋转; (4)点击鼠标线条变色。

1412
来自专栏前端桃园

Grid布局简介

没错,这其实就是我们小时候写的小格子本本,其实它跟我们今天要讲的主题Grid布局非常类似,其实Grid布局就是它的升级加强版。

9657
来自专栏编程

你不知道的前端算法之热力图的实现

本文作者:TalkingData 可视化工程师李凤禄 编辑:Aresn inMap 是一款基于 canvas 的大数据可视化库,专注于大数据方向点线面的可视化效...

2579
来自专栏葬爱家族

Android高德之旅(8)绘制线废话简单的api总结

绘制线会比绘制点稍微复杂点,抛开一些复杂的属性不谈,主要分为三类:实线、虚线、纹理。绘制线在自定义地图中是非常重要的一个环节。

3015
来自专栏Android先生

Android自定义View——从零开始实现书籍翻页效果

前言:在上篇Android自定义View——从零开始实现书籍翻页效果(二)博客中,我们 补全了翻页效果以及增加了 取消翻页的动画,这期要教大家如何 向View填...

4642

扫码关注云+社区

领取腾讯云代金券