线的样式
线宽 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 为图片渲染时的左上角坐标
调整亮度(变亮变暗)
实现算法:
将红、绿、蓝三个通道值,分别同时加上一个正值或负值。
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = imgData.data;
//遍历每个像素
for (var i = 0; i < data.length; i += 4) {
var a = 50;
data[i + 0] += a;
data[i + 1] += a;
data[i + 2] += a;
}
//在指定位置输出图片
cxt.putImageData(imgData, 140, 10);
}
a = 50 变亮的效果:
a = -50 变暗的效果:
调整透明度
cxt.globalAlpha用于调整整个Canvas的透明度,这里只是希望将图片透明化
实现算法:
将每一个像素的透明度乘以n,n的取值范围为0.0~1.0
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = imgData.data;
//遍历每个像素
for (var i = 0; i < data.length; i += 4) {
data[i + 3] = data[i + 3] * 0.3;
}
//在指定位置输出图片
cxt.putImageData(imgData, 140, 10);
}
颜色反转(底片)
即图片颜色颠倒,效果类似相机的底片。
实现算法:
红、绿、蓝这三个通道的像素取各自的相反值,也就是(255-原值)
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = 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(imgData, 140, 10);
}
黑白效果(灰度图)
指将彩色图片转换成黑白图片。
实现算法:
首先取红、绿、蓝三个通道的平均值,也就是(data[i+0]+data[i+1]+data[i+2])/3。然后data[i+0]、data[i+1]和data[i+2]全部保存为这个平均值。
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = imgData.data;
//遍历每个像素
for (var i = 0; i < data.length; i += 4) {
var average = (data[i + 0] + data[i + 1] + data[i + 2] + data[i + 3]) / 3;
data[i + 0] = average; //红
data[i + 1] = average; //绿
data[i + 2] = average; //蓝
}
//在指定位置输出图片
cxt.putImageData(imgData, 140, 10);
}
效果优化——加权平均
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = imgData.data;
//遍历每个像素
for (var i = 0; i < data.length; i += 4) {
var grayscale = data[i] * 0.3 + data[i + 1] * 0.6 + data[i + 2] * 0.1;
data[i + 0] = grayscale; //红
data[i + 1] = grayscale; //绿
data[i + 2] = grayscale; //蓝
}
//在指定位置输出图片
cxt.putImageData(imgData, 140, 10);
}
复古
使得图片有一种古旧效果。
实现算法:
将红、绿、蓝三个通道,分别取这三个值的某种加权平均值。
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = imgData.data;
//遍历每个像素
for (var i = 0; i < data.length; i += 4) {
var r = data[i + 0];
var g = data[i + 1];
var b = data[i + 2];
data[i + 0] = r * 0.39 + g * 0.76 + b * 0.18;
data[i + 1] = r * 0.35 + g * 0.68 + b * 0.16;
data[i + 2] = r * 0.27 + g * 0.53 + b * 0.13;
}
//在指定位置输出图片
cxt.putImageData(imgData, 140, 10);
}
红色蒙版
让图片呈现一种偏红的效果
实现算法:
将红通道(r)赋值为红、绿、蓝这三个的平均值,并且将绿通道、蓝通道都赋值为0。
同样的方式可以实现类似效果的绿色蒙版、蓝色蒙版等。
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 10, 10);
var imgData = cxt.getImageData(10, 10, 120, 120);
var data = imgData.data;
//遍历每个像素
for (var i = 0; i < data.length; i += 4) {
var r = data[i + 0];
var g = data[i + 1];
var b = data[i + 2];
var average = (r + g + b) / 3;
data[i + 0] = average;
data[i + 1] = 0;
data[i + 2] = 0;
}
//在指定位置输出图片
cxt.putImageData(imgData, 140, 10);
}
创建像素区域 createImageData()
cxt.createImageData(sw,sh); //第1种格式
sw,sh 为像素区域的宽和高
cxt.createImageData(imageData); //第2种格式
imageData为一个像素对象,最终像素区域的宽高和这个像素对象相同
createImageData()和putImageData()配合使用是对一个区域进行像素操作的。只有使用createImageData()创建了一个区域,才可以对该区域进行相应的像素操作。
var imgData = cxt.createImageData(100, 100);
var data = imgData.data;
for (var i = 0; i < 100 * 100 * 4; i += 4) {
data[i + 0] = 0;
data[i + 1] = 0;
data[i + 2] = 255;
data[i + 3] = 255;
}
cxt.putImageData(imgData, 20, 20);
var image = new Image();
image.src = "images/princess.png";
image.onload = function () {
cxt.drawImage(image, 0, 0, 60, 60);
//获取一个图片的imgData
var imgData1 = cxt.getImageData(0, 0, 60, 60);
//利用这个图片的imgData作为参数
var imgData2 = cxt.createImageData(imgData1);
var data = imgData2.data;
for (var i = 0; i < imgData2.width * imgData2.height * 4; i += 4) {
data[i + 0] = 0;
data[i + 1] = 0;
data[i + 2] = 255;
data[i + 3] = 255;
}
cxt.putImageData(imgData2, 80, 0);
}
变换元素
变换可用于图形,也可以用于图片和文字。
变换的本质都是通过“变换矩阵transform()”实现的,涉及到线性代数,平时并不会用,不必深究,简单了解即可:
- translate(e,f)等价于transform(1,0,0,1,e,f)。
- scale(a,d)等价于transform(a,0,0,d,0,0)。
- rotate(θ)等价于transform(cosθ,sinθ,-sinθ,cosθ,0,0)。
setTransform() 与 transform() 用法相同,只是transform() 是在变换后的基础上继续变换,而setTransform() 会重置图形的状态,再进行变换。
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
cxt.fillStyle = "yellow";
cxt.fillRect(0, 0, 100, 50)
cxt.setTransform(1, 0.5, -0.5, 1, 30, 10);
cxt.fillStyle = "red";
cxt.fillRect(0, 0, 100, 50);
cxt.setTransform(1, 0.5, -0.5, 1, 30, 10);
cxt.fillStyle = "blue";
cxt.fillRect(0, 0, 100, 50);
将 setTransform 改为 transform 后效果为
平移 translate()
本质是移动了整个坐标轴
cxt.translate(x,y);
- x 为x轴方向的移动距离,单位px,为正,则是向右移动,为负,则向左移动
- y 为y轴方向的移动距离,单位px,为正,则是向下移动,为负,则向上移动
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script type="text/javascript">
function $$(id) {
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
//绘制初始图形
cxt.fillStyle = "HotPink";
cxt.fillRect(30, 30, 50, 50);
$$("btn").onclick = function () {
// 清空canvas
cxt.clearRect(0, 0, cnv.width, cnv.height);
cxt.translate(10, 10);
cxt.fillStyle = "HotPink";
// 重绘
cxt.fillRect(30, 30, 50, 50);
}
}
</script>
</head>
<body>
<canvas id="canvas" width="200" height="150" style="border:1px dashed gray;"></canvas><br />
<input id="btn" type="button" value="移动"/>
</body>
</html>
缩放 scale ()
cxt.scale(x,y);
- x 为x轴方向的缩放倍数
- y 为y轴方向的缩放倍数
x,y 的值为0~1时为缩小,大于1时为放大,也可以为负,但基本不用。
使用 scale 缩放时,图形的左上角坐标、宽度和高度、线条宽度都会同步缩放,若不是预期效果,记得进行相应的处理!
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<meta charset="utf-8" />
<script type="text/javascript">
function $$(id) {
return document.getElementById(id);
}
window.onload = function () {
var cnv = $$("canvas");
var cxt = cnv.getContext("2d");
//绘制初始图形
cxt.fillStyle = "HotPink";
cxt.fillRect(30, 30, 50, 50);
//图形放大
$$("btn-big").onclick = function () {
// 清空canvas
cxt.clearRect(0, 0, cnv.width, cnv.height);
cxt.scale(1.5, 1.5);
cxt.fillStyle = "HotPink";
// 添加平移,抵消左上角坐标的放大
cxt.translate(-10, -10);
cxt.fillRect(30, 30, 50, 50);
};
//图形缩小
$$("btn-small").onclick = function () {
// 清空canvas
cxt.clearRect(0, 0, cnv.width, cnv.height);
cxt.scale(0.5, 0.5);
cxt.fillStyle = "HotPink";
// 反向平移,抵消左上角坐标的縮小
cxt.translate(30, 30);
cxt.fillRect(30, 30, 50, 50);
};
};
</script>
</head>
<body>
<canvas
id="canvas"
width="200"
height="150"
style="border: 1px dashed gray"
></canvas
><br />
<input id="btn-big" type="button" value="放大" />
<input id="btn-small" type="button" value="缩小" />
</body>
</html>
旋转 rotate()
cxt.rotate(angle);
- angle 为图形旋转的角度,取值为-Math.PI2~Math.PI2。当angle>0时,图形顺时针旋转;当angel<0时,图形逆时针旋转。
120*Math.PI/180 //120°
150*Math.PI/180 //150°
默认情况下,rotate()方法的旋转中心就是原点坐标(0,0)
cxt.fillStyle = "HotPink";
cxt.fillRect(30, 30, 50, 50);
$$("btn").onclick = function () {
cxt.rotate(-30 * Math.PI / 180); //逆时针旋转30°
cxt.fillStyle = "LightSkyBlue ";
cxt.fillRect(30, 30, 50, 50); //注意,这里仍然是fillRect(30, 30, 50, 50)
}
改变旋转中心
先使用translate(x,y),然后再使用rotate()方法
var i = 0;
var rectWidth = 100;
var rectHeight = 50;
setInterval(function () {
i++;
cxt.clearRect(0, 0, cnv.width, cnv.height);
cxt.save();
cxt.translate(cnv.width / 2, cnv.height / 2); //将坐标移动到中心
cxt.rotate(Math.PI * (i / 100)); //累进旋转
cxt.fillStyle = "HotPink";
cxt.fillRect(-rectWidth / 2, -rectHeight / 2, rectWidth, rectHeight); //填充矩形
cxt.restore();
}, 10);
使用translate()方法结合图形的长宽将旋转中心移动到图形中心上。
本例中,将矩形的中心与画布的中心重合,是为了方便操作。
实战范例 1 —— 内卷花纹
cxt.translate(150, 0);
cxt.fillStyle = "rgba(255,0,0,0.25)";
for (var i = 0; i < 50; i++) {
cxt.translate(25, 25); //图形平移
cxt.scale(0.95, 0.95); //图形缩放
cxt.rotate(Math.PI / 10); //图形旋转
cxt.fillRect(0, 0, 100, 50);
}
实战范例 2 —— 彩虹
//定义数组,存储7种颜色
var colors = ["red", "orange", "yellow", "green", "blue", "navy", "purple"];
cxt.lineWidth = 12;
cxt.translate(50,0);
//循环绘制圆弧
for (var i = 0; i < colors.length; i++) {
//每次向下移动10px
cxt. translate(0,10);
//定义颜色
cxt.strokeStyle = colors[i];
//绘制圆弧
cxt.beginPath();
cxt.arc(50, 100, 100, 0, 180 * Math.PI / 180, true);
cxt.stroke();
}
```![在这里插入图片描述](https://img-blog.csdnimg.cn/00258c688cd24e07be5544a4429c24be.png)