Canvas使用

百度

基础设置

1. 创建

HTML5 <canvas> 标签用于绘制图像(通过脚本,通常是 JavaScript),<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器)。

HTML: (canvas默认大小为300px*150px)
<canvas id="myCanvas" width="500" height="500"></canvas>

JavaScript:
var canvas = document.getElementById("myCanvas");
if (canvas == null || !canvas.getContext("2d")) return false;
var cd = canvas.getContext("2d");

getContext() 方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性,包括在画布上绘制文本、线条、矩形、圆形等等。

2. 阴影

shadowColor = color;   //设置或返回用于阴影的颜色,默认全透明的黑色
shadowBlur = float;    //设置或返回用于阴影的模糊级别,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0
shadowOffsetX = float; //设置或返回阴影距形状的 X 轴(水平)距离,不受变换矩阵所影响,负值表示阴影会往左延伸,正值则表示会往右延伸,默认为 0
shadowOffsetY = float; //设置或返回阴影距形状的 Y 轴(垂直)距离,不受变换矩阵所影响,负值表示阴影会往上延伸,正值则表示会往下延伸,默认为 0

3. 线型

可以通过一系列属性来设置线的样式。

lineWidth = value;       //设置或返回当前的线条宽度,默认值是1.0,属性值必须为正数
lineCap = butt | round | square; //设置或返回线条的结束端点样式,默认为butt
lineJoin = round | bevel | miter; //设置或返回两条线接合处(相交时创建的拐角)的样式,默认为miter
miterLimit = value;      //设置或返回最大斜接长度,斜接长度(交接处长度)是指线条交接处内角顶点到外角顶点的长度
getLineDash();           //返回一个包含当前虚线样式,长度为非负偶数的数组
setLineDash(segments);   //设置当前虚线样式
lineDashOffset = value;  //设置虚线样式的起始偏移量
详解:
lineWidth:线宽是指给定路径的中心到两边的粗细。换句话说就是在路径的两边各绘制线宽的一半。因为画布的坐标并不和像素直接对应,当需要获得精确的水平或垂直线的时候要特别注意。
lineCap:butt表示线段端点在自己的格子内;round表示端点处加上了半径为一半线宽的半圆; square 表示端点处加上了等宽且高度为一半线宽的方块。
lineJoin:round表示创建圆角,边角处磨圆,圆的半径等于线宽;bevel表示创建斜角,一个线段内边与另一个线段外边产生交点,两个交点相连,去掉外部尖角部分,保留内夹角部分;miter表示创建尖角,线段会在连接处外侧延伸直至交于一点,延伸效果受到miterLimit 属性的制约。
miterLimit:miter效果时,线段的外侧边缘会延伸交汇于一点上。线段直接夹角比较大的,交点不会太远,但当夹角减少时,交点距离会呈指数级增大。miterLimit 属性就是用来设定外延交点与连接点的最大距离,如果交点距离大于此值,连接效果会变成了 bevel。

4. 颜色

canvas有两种上色:图形填充fillStyle 和图形轮廓strokeStyle 。

fillStyle = color | gradient | pattern;   //css颜色值 | 渐变(线性或放射性)| 可重复的图片
strokeStyle = color | gradient | pattern; //css颜色值 | 渐变(线性或放射性)| 可重复的图片
其中:
默认值是 #000000。

color 详解:

点击查看

gradient 详解:

gradient = cd.createLinearGradient(x1, y1, x2, y2);         //创建渐变,从渐变的起点 (x1,y1) 到渐变的终点 (x2,y2)。
gradient = cd.createRadialGradient(x1, y1, r1, x2, y2, r2); //创建渐变,从以 (x1,y1) 为原点,半径为 r1 的圆,到另一个以 (x2,y2) 为原点,半径为 r2 的圆。
创建出 canvasGradient 对象后,用 addColorStop 方法上色。
gradient.addColorStop(position, color);                      //position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。color 参数必须是一个有效的 CSS 颜色值。给同一位置设置两种颜色,可以实现突变的效果。
示例:
var lingrad = cd.createLinearGradient(0,0,0,150);  //新建一个渐变
lingrad.addColorStop(0, 'red');                    //设置渐变起点为红色
lingrad.addColorStop(0.5, 'blue');                 //设置渐变中间点为蓝色
lingrad.addColorStop(0.5, '#fff');                 //设置渐变中间点突变为白色
lingrad.addColorStop(1, '#000');                   //设置渐变结束点为黑色
cd.fillStyle = lingrad;                            //设置填充样式为创建的渐变
cd.fillRect(0,0,100,100);                          //创建并填充矩形,矩形长宽各100,从上往下,顶点到75%处为红色变蓝色,75%处到底部为白色变黑色 
cd.fillRect(0,0,150,150);                          //创建并填充矩形,矩形长宽各150,从上往下,顶点到中间为红色变蓝色,中间到底部为白色变黑色 

pattern 详解:

pattern = cd.createPattern(image, type);  //image 可以是一个 Image 对象的引用,或者另一个 canvas 对象。type 必须是下面的字符串值之一:repeat,repeat-x,repeat-y 和 no-repeat。
注意: 
用 canvas 对象作为 image 参数在 Firefox 1.5 (Gecko 1.8) 中是无效的。
图案的应用跟渐变很类似的,创建出一个pattern之后,赋给 fillStyle 或 strokeStyle 属性即可。
示例:
var img = new Image();                         //新建一个Image对象
img.src = 'someimage.png';                     //设置Image对象的实际引用图片地址
var pattern = cd.createPattern(img,'repeat');  //创建pattern
cd.fillStyle = pattern;                        //赋值给fillStyle属性
cd.fillRect(0,0,100,100);                      //将图片填充矩形框
注意:
与drawImage不同,这里需要确认Image对象已经装载完毕,否则图案可能效果不对的。

5. 透明度

通过设置 globalAlpha 属性或者使用一个半透明颜色作为轮廓或填充的样式。

globalAlpha = value; //这个属性影响到 canvas 里所有图形的透明度,取值范围在 0.0(完全透明)和 1.0(完全不透明)之间。 默认值是1.0。 如果数值不在范围内,包括Infinity和NaN,无法赋值,并且globalAlpha会保持原有的数值。
注明:
少量颜色填充可以直接用rgba,不需要设置这个属性

6. 填充规则

当用到 fill(或者 clip和isPointinPath )时,可以选择一个填充规则,该填充规则根据某处在路径的外面或者里面来决定该处是否被填充,这对于自己与自己路径相交或者路径被嵌套的时候是有用的。

cd.fill();             //使用默认值直接填充
cd.fill("nonzero");   //非零环绕原则,是默认值
cd.fill("evenodd");    //奇偶原则

两个原则详解
非零环绕原则nonzero详解:

用来判断哪些区域属于路径内( 计算结果非0,即为路径内 )。
* 在路径包围的区域中,随便找一点,向外发射一条射线,
* 和所有围绕它的边相交,
* 然后开启一个计数器,从0计数,
* 如果这个射线遇到顺时针围绕,那么+1,
* 如果遇到逆时针围绕,那么-1,
* 如果最终值非0,则这块区域在路径内。

奇偶原则evenodd详解:

* 在路径包围的区域中,随便找一点,向外发射一条射线,
* 和所有围绕它的边相交,
* 查看相交线的个数,如果为奇数,就填充,如果是偶数,就不填充。

绘制

1. 绘制矩形

canvas只支持一种原生的图形绘制:矩形。所有其他的图形的绘制都至少需要生成一条路径。
矩形的绘制有三种方法:

fillRect( x , y , width , height )    //绘制一个填充的矩形
strokeRect( x , y , width , height )  //绘制一个矩形的边框
clearRect( x , y , width , height )   //清空指定的矩形区域,让去除部分完全透明
其中:
(x,y)起点  width宽  height高

2. 绘制路径

路径是通过不同颜色和宽度的线段或曲线相连接形成的不同形状的点的集合。
图形的基本元素是路径。一个路径,甚至一个子路径,都是闭合的。
使用路径绘制图形的步骤:
①创建路径起始点;
②使用画图命令去画出路径;
③把路径封闭;
④路径生成后,通过描边或填充路径区域来渲染图形。
使用路径绘制图形的函数:

beginPath()        //新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径
closePath()        //闭合路径之后图形绘制指令又重新指向到上下文中
stroke()           //通过线条来绘制图形轮廓,不会自动闭合没有闭合的形状
fill()             //通过填充路径的内容区域生成实心的图形,自动闭合所有没有闭合的形状,不需要调用closePath()函数
moveTo( x , y )    //移动笔触,将笔触移动到指定的坐标(x , y)上
lineTo( x , y )    //绘制一条从当前位置到指定的位置(x , y)的直线

弧线

arc( x , y , radius , startAngle , endAngle , anticlockwise)  //画一个以(x , y)为圆心,以radius为半径的圆弧(圆),从startAngle 开始到endAngle 结束,anticlockwise参数为一个布尔值,true表示逆时针,false表示顺时针。
注意:
arc()函数中的角度单位是弧度,不是度数。角度与弧度的js表达式:弧度= 角度 * Math.PI / 180,角度 = 弧度 * 180 / Math.PI

贝塞尔(bezier)以及二次贝塞尔

quadraticCurveTo( cp1x , cp1y , x , y )               //绘制二次贝塞尔曲线,(x , y)为结束点,(cp1x , cp1y)为控制点
bezierCurveTo( cp1x , cp1y , cp2x , cp2y , x , y )    //绘制三次贝塞尔曲线,(x , y)为结束点,(cp1x , cp1y)为控制点一 ,(cp2x , cp2y)为控制点二

矩形

rect( x , y , width , height )    //绘制一个左上角坐标为(x , y),宽为width高为height的矩形

Path2D对象(详情

new Path2D()        //空的Path对象
new Path2D(path)    //克隆Path对象
new Path2D(d)       //从SVG建立Path对象
说明:
Path2D对象用来缓存或记录绘画命令,用以快速回顾路径
例子:
var path = new Path2D();
path.rect(50,50,50,50);
cd.stroke(path);

3. 绘制文本

属性设置:
font = value          //设置或返回文本内容的当前字体属性。 使用和 CSS font 属性相同的语法,默认的字体是 10px sans-serif。
textAlign = value     // 设置或返回文本内容的当前对齐方式。可选的值包括:start, end, left, right or center。 默认值是 start。
textBaseline = value  //设置或返回在绘制文本时使用的当前文本基线。 可选的值包括:top, hanging, middle, alphabetic, ideographic, bottom。默认值是 alphabetic。
direction = value     //文本方向。可能的值包括:ltr, rtl, inherit。默认值是 inherit。

渲染文本:
fillText(text, x, y [, maxWidth])    //在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的。
strokeText(text, x, y [, maxWidth])  //在指定的(x,y)位置绘制文本边框,绘制的最大宽度是可选的。

测量文本:
measureText()   //返回包含指定文本宽度的TextMetrics对象,详解见备注。

注:
measureText()使用
TextMetrics对象详解

4. 绘制图像

canvas可以用于动态的图像合成或者作为图形的背景。浏览器支持的任意格式的外部图片都可以使用,比如PNG、GIF或者JPEG,也可以将同一个页面中其他canvas元素生成的图片作为图片源。

引入图像到canvas的基本操作:
获得一个指向HTMLImageElement的对象或者另一个canvas元素的引用作为源,也可以通过提供一个URL的方式来使用图片,使用drawImage()函数将图片绘制到画布上。

canvas的API可以使用下面这些类型中的一种作为图片的源:

HTMLImageElement    //由Image()函数构造出来的图片,或者任何的<img>元素
HTMLVideoElement    //用一个HTML的 <video>元素作为图片源,可以从视频中抓取当前帧作为一个图像
HTMLCanvasElement   //用另一个 <canvas> 元素作为图片源。
ImageBitmap         //一个高性能的位图,可以低延迟地绘制,它可以从上述的所有源以及其它几种源中生成。
注:这些源统一由 CanvasImageSource类型来引用。

①使用相同页面内的图片
通过下列方法的一种来获得与canvas相同页面内的图片的引用:

document.images集合
document.getElementsByTagName()方法
document.getElementById()获得指定图片

②使用其它域名下的图片
在 HTMLImageElement上使用crossOrigin属性,可以请求加载其它域名上的图片。如果图片的服务器允许跨域访问这个图片,那么你可以使用这个图片而不污染canvas,否则,使用这个图片将会污染canvas。
注:污染canvas详解
③使用其它 canvas 元素
和引用页面内的图片类似地,用 document.getElementsByTagName 或 document.getElementById 方法来获取其它 canvas 元素。但你引入的应该是已经准备好的 canvas。
④由零开始创建图像
用脚本创建一个新的 HTMLImageElement 对象。使用Image()构造函数。

var img = new Image();   // 创建一个<img>元素
img.src = 'myImage.png'; // 设置图片源地址
当脚本执行后,图片开始装载。

若调用 drawImage 时,图片没装载完,那什么都不会发生(在一些旧的浏览器中可能会抛出异常)。因此应该用load事件来保证不会在加载完毕之前使用这个图片:

var img = new Image();   // 创建img元素
img.onload = function(){
  // 执行drawImage语句
}
img.src = 'myImage.png'; // 设置图片源地址
注:如果只用到一张图片,如上操作。如果需要不止一张图片,则应使用图片预加载策略。

⑤通过 data: url 方式嵌入图像
可以通过 data:url 方式来引用图像。Data urls 允许用一串 Base64 编码的字符串的方式来定义一个图片。

img.src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==';
优点是图片内容即时可用,无须再到服务器兜一圈,可以将 CSS、JavaScript、HTML 和 图片全部封装在一起,迁移方便。
缺点就是图像没法缓存,图片较大时,内嵌的 url 数据会相当长:

⑥使用视频帧
可以使用<video> 中的视频帧(即便视频是不可见的)。HTMLVideoElement对象可以作为canvas图片源。
获得源图对象后,可以使用 drawImage 方法将它渲染到 canvas 里。drawImage 方法有下面三种形态:

drawImage(image, x, y)                                              //其中image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。SVG图像必须在 <svg> 根指定元素的宽度和高度。
drawImage(image, x, y, width, height)                               //这个方法多了2个参数:width 和 height,这两个参数用来控制 当向canvas画入时应该缩放的大小
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)  //第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。其它8个参数,前4个是定义图像源的切片位置和大小,后4个则是定义切片的目标显示位置和大小。

变形合成

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

推荐阅读更多精彩内容

  • 标签:canvas 简单示例 入门知识作者: 张耀国 ( IgorZhang )E-mail: igorzhang...
    IgorZhang阅读 2,756评论 4 7
  • 请各位读者添加一下作者的微信公众号,以后有新的文章,将在微信公众号直接推送给各位,非常感谢。 0. 前言 相信各位...
    MR_LIXP阅读 5,146评论 17 56
  • 一、基础介绍和画直线 大多数现代浏览器都是支持Canvas的,比如 Firefox, safari, chrome...
    空谷悠阅读 806评论 0 1
  • 仅仅片刻,那名青衣看守便已经赶来,连道:“飞雪师傅,这典籍原本已经找到。”说着递给了东伯雪鹰。 东伯雪鹰接过低头看...
    im喵小姐阅读 338评论 0 0
  • 在所有的关系中,总会有一方付出的多,伤心的次数多,这样的关系,才可能长久,才可能有羡慕的眼光,才可能有因感动而泛红...
    有点慢阅读 127评论 0 0