线的样式
线宽 lineWidth
lineWidth 是context对象的属性,用于描述线条的宽度,属性值为整数,默认值为1px。
- strokeRect()方法绘制的矩形实际宽度是(width+lineWidth),实际高度是(height+lineWidth)
- arc()方法绘制的圆形实际半径为(radius+lineWidth)。
//lineWidth值为5 cxt.lineWidth = 5; cxt.moveTo(20, 20); cxt.lineTo(180, 20); cxt.stroke(); //lineWidth值为10 cxt.beginPath(); cxt.lineWidth = 10; cxt.moveTo(20, 70); cxt.lineTo(180, 70); cxt.stroke(); //lineWidth值为15 cxt.beginPath(); cxt.lineWidth = 15; cxt.moveTo(20, 120); cxt.lineTo(180, 120); cxt.stroke();
必须使用beginPath()方法来开始新的路径,才可以绘制一个新的lineWidth属性
cxt.lineWidth = 5; cxt.arc(70, 70, 50, 0, -90 * Math.PI / 180, false); cxt.stroke();
线帽 lineCap
lineCap 是context对象的属性,用于描述线条开始处和结尾处的线帽样式,取值如下:
- butt (默认值) 无线帽
- round 圆形线帽
- square 正方形线帽
cxt.lineWidth = 16; //lineCap值为默认值(butt) cxt.moveTo(20, 20); cxt.lineTo(180, 20); cxt.stroke(); //lineCap值改为round cxt.beginPath(); cxt.lineCap = "round"; cxt.moveTo(20, 70); cxt.lineTo(180, 70); cxt.stroke(); //lineCap值改为square cxt.beginPath(); cxt.lineCap = "square"; cxt.moveTo(20, 120); cxt.lineTo(180, 120); cxt.stroke();
必须使用beginPath()方法来开始新的路径,才可以绘制一个新的 lineCap 属性
round和square值会使线条稍微变长一点,因为它们给线条增加了线帽部分。
- 取值为round:每条线的头和尾都增加一个半圆,半圆的直径为线宽长度。
- 取值为square:每条线的头和尾都增加一个长方形,长方形的长度为线宽的一半,高度保持为线宽长度。
cxt.moveTo(50, 50); cxt.lineTo(100, 50); cxt.lineTo(50, 100); cxt.lineTo(100, 100); cxt.lineWidth = 12; cxt.lineCap = "round"; cxt.stroke();
lineCap属性只对线条的开始处和结尾处这两个地方起作用,而线段与线段交接的地方依然是“尖角”。
线的交点 lineJoin
lineJoin 是context对象的属性,用于描述两个线条交接处的样式,取值如下:
- miter(默认值)尖角,线段在交接处延伸直至交于一点
- round 圆角,圆角所在圆的直径等于线宽长度。
- bevel 斜角,斜角所在正方形的对角线长等于线宽长度。
cxt.moveTo(50, 50); cxt.lineTo(100, 50); cxt.lineTo(50, 100); cxt.lineTo(100, 100); cxt.lineWidth = 12; cxt.lineJoin = "miter"; cxt.stroke();
cxt.lineJoin = "round";
cxt.lineJoin = "bevel";
虚线 setLineDash()
IE不支持
cxt.setLineDash(array);
array 是一个数组,如[10,5]表示的是“10px实线”和“5px空白”重复拼凑组合而成的线型。数组[10,5,5,5]表示的是“10px实线、5px空白、5px实线、5px空白”重复拼凑组合而成的线型。
cxt.strokeStyle = "red"; cxt.setLineDash([10,5]); cxt.strokeRect(50, 50, 80, 80);
绘制文本
文本属性:
- font 文本样式(含大小,粗细,字体等),和css用法一样。默认值为
10px sans-serif。
context.font = "font-style font-weight font-size/line-height font-family";
cxt.font = "bold 30px 微软雅黑";
- fillStyle 填充样式
- strokeStyle 描边样式
文本方法:
- strokeText() 绘制描边文字
- fillText() 绘制填充文字
- measureText() 获取文本长度,单位为px(实际是占据空间矩形的长度)
// text 为目标文本 var length = cxt.measureText(text).width;
描边文本(空心文本)
strokeText(text , x , y , maxWidth)
- text 文本内容
- x 文本最左侧的坐标
- y 文本最下方的坐标
- maxWidth (可选) 文本最大宽度,若文本超出最大宽度,会强制压缩
var text = "绿叶学习网"; cxt.font = "bold 30px 微软雅黑"; cxt.strokeStyle = "purple"; cxt.strokeText(text, 30, 60);
cxt.strokeText(text,30,60)改为cxt.strokeText(text,30,60,100)后,文本会压缩
填充文本
fillText(text , x , y , maxWidth)
- text 文本内容
- x 文本最左侧的坐标
- y 文本最下方的坐标
- maxWidth (可选) 文本最大宽度,若文本超出最大宽度,会强制压缩
var text = "绿叶学习网"; cxt.font = "bold 30px 微软雅黑"; cxt.fillStyle = "purple"; cxt.fillText(text,30,60);
cxt.fillText(text,30,60) 改为cxt.fillText(text,30,60,100) 会压缩文字
文本水平居中
var text = "绿叶学习网"; cxt.font = "20px bold"; var textWidth = cxt.measureText(text).width; var canvasWidth = cnv.width; var xPosition = canvasWidth / 2 - textWidth / 2; cxt.fillStyle = "purple"; cxt.fillText(text, xPosition, 50);
文本水平对齐方式 textAlign (用得少)
—— left 左对齐-在指定的横坐标的左侧开始
—— right 右对齐-在指定的横坐标的右侧结束
—— start 与阅读方向开始位置对齐(左到右阅读环境中,表现为左对齐)
—— end 与阅读方向结束位置对齐(左到右阅读环境中,表现为右对齐)
—— center 文本的中心被放置在指定的横坐标
//在横坐标150处绘制一条竖线 cxt.strokeStyle = "purple"; cxt.moveTo(150, 0); cxt.lineTo(150, 200); cxt.stroke(); cxt.font = "15px Arial"; cxt.textAlign = "start"; cxt.fillText("textAlign取值为start", 150, 30); cxt.textAlign = "left"; cxt.fillText("textAlign取值为left", 150, 60); cxt.textAlign = "end"; cxt.fillText("textAlign取值为end", 150, 90); cxt.textAlign = "right"; cxt.fillText("textAlign取值为right", 150, 120); cxt.textAlign = "center"; cxt.fillText("textAlign取值为center", 150, 150);
文本垂直对齐方式 textBaseline (用得少)
- alphabetic 文本基线是普通英文字母的基线
- top 文本基线是em方框的顶端
- middle 文本基线是em方框的中心
- bottom 文本基线是em方框的底端
//在纵坐标100处绘制一条横线 cxt.strokeStyle = "purple"; cxt.moveTo(0, 100); cxt.lineTo(300, 100); cxt.stroke(); cxt.font = "20px Arial"; cxt.textBaseline = "alphabetic"; cxt.fillText("alphabetic", 10, 100); cxt.textBaseline = "top"; cxt.fillText("top", 110, 100); cxt.textBaseline = "middle"; cxt.fillText("middle", 160, 100); cxt.textBaseline = "bottom"; cxt.fillText("bottom", 230, 100);
操作图片
图片渲染
cxt.drawImage(image ,dx , dy);
- image 为页面中的img元素,或js创建的image对象
- dx,dy 为图片左上角的坐标
//创建image对象 var image = new Image(); image.src = "images/princess.png"; // 必须等图片加载完后,再进行渲染 image.onload = function () { cxt.drawImage(image, 40, 20); }
<img id="pic" src="images/princess.png" alt=""/>
/*隐藏HTML中的img元素*/ #pic{display:none;}
var image = $$("pic"); cxt.drawImage(image, 40, 20);
图片取自页面中的img元素时,图片已完成了加载,所以无需添加 image.onload 等待加载。此时一般会用CSS隐藏图片,避免图片在页面中显示多次图片。
图片缩放
常用于Canvas游戏开发
cxt.drawImage(image , dx , dy ,dw , dh)
- image 为页面中的img元素,或js创建的image对象
- dx, dy 为图片左上角的坐标
- dw , dh 为图片的宽度和高度
var image = new Image(); image.src = "images/princess.png"; image.onload = function () { cxt.drawImage(image, 40, 20, 60, 60); }
图片裁剪(矩形裁剪)
此方法可以将部分图像复制到画布,类似于CSSSprite技术,从而使得图片只需要加载一次即可,这样极大地提高了速度(常用于Canvas游戏开发)。
cxt.drawImage(image , sx , sy , sw, sh , dx , dy , dw , dh)
- image 为页面中的img元素,或js创建的image对象
- sx, sy 为源图片截取部分的左上角坐标
- sw , sh 为源图片截取部分的宽度和高度
- dx, dy 为canvas中图片左上角的坐标
- dw , dh 为canvas中图片的宽度和高度
var image = new Image(); image.src = "images/princess.png"; image.onload = function () { cxt.drawImage(image, 0, 0, 80, 80, 40, 20, 80, 80); }
图片切割 clip()(自定义形状的裁剪)
//第1步,绘制基本图形,用来切割 cxt.beginPath(); cxt.arc(70, 70, 50, 0, 360 * Math.PI / 180, true); cxt.closePath(); cxt.stroke(); //第2步,使用clip()方法,使得切割区域为上面绘制的基本图形 cxt.clip(); //第3步,绘制一张图片 var image = new Image(); image.src = "images/princess.png"; image.onload = function () { cxt.drawImage(image, 10, 20); }
图片平铺
var pattern = cxt.createPattern(image , type); cxt.fillStyle = pattern; cxt.fillRect();
- type 来指定平铺方式
—— repeat (默认值) 在水平方向和垂直方向同时平铺
—— repeat-x 只在水平方向平铺
—— repeat-y 只在垂直方向平铺
—— no-repeat 只显示一次
createPattern()方法不仅可以用于平铺图片,还可以用于平铺其他canvas元素或者平铺video元素(即视频),使用图片会有一定的加载时间,因此在实际开发中,对于一些基本的背景图案,会使用Canvas来绘制。
var myImg = new Image(); myImg.src = "images/flower.png"; myImg.onload = function () { var pattern = cxt.createPattern(myImg, "repeat"); cxt.fillStyle = pattern; cxt.fillRect(0, 0, cnv.width, cnv.height); }
var pattern = cxt.createPattern(myImg, "repeat-x");
var pattern = cxt.createPattern(myImg, "repeat-y");
- 平铺 canvas
//创建canvas元素 var bgCanvas = document.createElement("canvas"); bgCanvas.width = 20; bgCanvas.height = 20; //在新创建的canvas中画一个圆 var bgCxt = bgCanvas.getContext("2d"); bgCxt.beginPath(); bgCxt.arc(10, 10, 10, 0, 360 * Math.PI / 180, true); bgCxt.closePath(); bgCxt.fillStyle = "HotPink"; bgCxt.fill(); //平铺canvas var pattern = cxt.createPattern(bgCanvas, "repeat-x"); cxt.fillStyle = pattern; cxt.fillRect(0, 0, 200, 200);
用图片填充文字(用得少)
//创建image对象 var image = new Image(); image.src = "images/princess.png"; image.onload = function () { var text = "绿叶学习网"; cxt.font = "bold 22px 微软雅黑"; var pattern = cxt.createPattern(image, "no-repeat"); cxt.fillStyle = pattern; cxt.fillText(text, 10, 50); }
用图片填充图形
//创建image对象 var image = new Image(); image.src = "images/princess.png"; image.onload = function () { cxt.beginPath(); cxt.arc(50, 50, 50, 0, 360 * Math.PI / 180, false); cxt.closePath(); var pattern = cxt.createPattern(image, "no-repeat"); cxt.fillStyle = pattern; cxt.fill(); }
图片特效
更高级的图片处理,如调整图片亮度、变黑白图片等需要对图片进行像素级处理,基本流程为:
- 获取图片的像素信息
var imgData = cxt.getImageData(x , y , width , height); var data = imgData.data;
—— x,y 为目标图片区域左上角的坐标
—— widht ,height 为图片区域的宽和高
此处的 imgData 是一个canvasPixelArray对象,其有属性 data,属性值为[r1,g1,b1,a1,r2,g2,b2,a2,……] 格式的描述一张图片像素数据的数组。imgData.data 数组中每四个数存储着1个像素的rgba颜色值,这四个数分别是该像素的红(r)、绿(g)、蓝(b)、透明度(a)。
imgData.data.length 即图片像素的总量。
修改图片的像素信息
即对 imgData.data 数组进行遍历处理,如颜色反转:
for (var i = 0; i < data.length; i += 4) { data[i + 0] = 255 - data[i + 0]; data[i + 1] = 255 - data[i + 1]; data[i + 2] = 255 - data[i + 2]; }
通过新像素信息渲染图片
cxt.putImageData(image , x , y);
—— image 为 canvasPixelArray对象(修改后的图片像素信息)
—— x,y 为图片渲染时的左上角坐标
canvas系列教程03 —— 线的样式、绘制文本、操作图片(图片的渲染、缩放、裁剪、切割、平铺、特效)、变换元素(平移、缩放、旋转)(二): https://developer.aliyun.com/article/1558613