HTML Canvas笔记
1.
在Canvas上画线,我们使用以下两种方法:moveTo(x,y) 定义线条开始坐标;lineTo(x,y) 定义线条结束坐标
ctx.lineJoin="round";//圆角
ctx.lineJoin="miter";//尖角(默认)
ctx.lineJoin="bevel";//斜角
ctx.closePath();//这个相当于用线段画图,最后结尾可以用这个,它可以最后结尾和开头连起来
绘制线条必须使用到 "ink" 的方法,就像stroke()。
在canvas中绘制圆形, 我们使用以下方法:arc(x,y,r,start,stop)。
实际上我们在绘制圆形时使用了 "ink" 的方法, 比如 stroke() 或者 fill()。
stroke是HTML5canvas中的一个方法,stroke()方法可以用于绘制当前路径。
stroke()方法会实际地绘制出通过moveTo()和lineTo()方法定义的路径。默认颜色是黑色。
fill()具有填充的作用。
比如画圆时:
var c=document.getElementById("myCanvas");利用id来找canvas元素。
var ctx=c.getContext("2d");建立2d环境
ctx.beginPath();//beginPath就是一个断点,让上一个和下一个不受影响。每次写一个就要加这个
ctx.arc(95,50,40,0,2Math.PI);//95,50是X,Y,40是圆的半径,2Math.PI圆的公式
ctx.stroke();//这里不设颜色就是默认黑色。
使用 canvas 绘制文本,重要的属性和方法如下:font - 定义字体
fillText(text,x,y) - 在 canvas 上绘制实心的文本
strokeText(text,x,y) - 在 canvas 上绘制空心的文本
ctx.textAlign="center";//居中
ctx.textAlign="start";//左
ctx.textAlign="end";//右
ctx.textBaseline="top";//上
ctx.textBaseline="bottom";//下
ctx.textBaseline="middle";//中
渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。以下有两种不同的方式来设置Canvas渐变:
createLinearGradient(x,y,x1,y1) - 创建线条渐变
createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
当我们使用渐变对象,必须使用两种或两种以上的停止颜色。
addColorStop()方法指定颜色停止,参数使用坐标来描述,可以是0至1.
使用渐变,设置fillStyle或strokeStyle的值为 渐变,然后绘制形状,如矩形,文本,或一条线。
fillRect(x,y,width,height):绘制实心矩形
strokeRect(x,y,width,height):绘制空心矩形
clearRect(x,y,width,height):清空矩形
closePath() 方法创建从当前点到开始点的路径。闭合。
beginPath() 方法开始一条路径,或重置当前的路径。
clearRect() 方法清空给定矩形内的指定像素。
fillRect() 方法绘制“已填色”的矩形。默认的填充颜色是黑色。fillstyle()方法要在fillRect() 方法的前面。
var timer=setInterval(函数名,间隔时间)
if(条件)
clearinterval(timer)
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式。
setInterval() 方法会不停地调用函数,直到 clearInterval() 被调用或窗口被关闭。
由 setInterval() 返回的 ID 值可用作 clearInterval() 方法的参数。
arcTo() 方法在画布上创建介于两个切线之间的弧
ctx.arcTo(150,20,150,70,50); // 创建弧
//(150,20)是第一个点的坐标,(150,70)是第二个点的坐标。50是弧的半径。
绘制二次贝塞尔曲线:quadraticCurveTo(cp1x, cp1y, x, y);
ctx.moveTo(10, 200); //起始点
var cp1x = 40, cp1y = 100; //控制点
var x = 200, y = 200; // 结束点
2.
save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。
save是入栈,restore是出栈。
关于 save() :Canvas状态存储在栈中,每当save()方法被调用后,当前的状态就被推送到栈中保存。
栈:“先进后出”,即最先进栈的数据,最后出栈;
队列存储数据,讲究 "先进先出",即最先进队列的数据,也最先出队列。
可以调用任意多次 save方法(类似数组的 push())。
push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度。
restore():每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复(类似数组的 pop())。
例如:
var ctx;// 通过var弱类型定义:然后它的类型取决于等号后面值的类型
function draw(){ //定义函数
var canvas = document.getElementById('tutorial');//获取id
if (!canvas.getContext) return;//判断浏览器是否支持canvas的获取上下文的操作。
var ctx = canvas.getContext("2d");//获取2d环境
ctx.fillRect(0, 0, 150, 150); // 使用默认设置绘制一个矩形
ctx.save(); // 保存默认状态
ctx.fillStyle = 'red' // 在原有配置基础上对颜色做改变
ctx.fillRect(15, 15, 120, 120); // 使用新的设置绘制一个矩形
ctx.save(); // 保存当前状态
ctx.fillStyle = '#FFF' // 再次改变颜色配置
ctx.fillRect(30, 30, 90, 90); // 使用新的配置绘制一个矩形
ctx.restore(); // 重新加载之前的颜色状态
ctx.fillRect(45, 45, 60, 60); // 使用上一次的配置绘制一个矩形
ctx.restore(); // 加载默认颜色配置
ctx.fillRect(60, 60, 30, 30); // 使用加载的配置绘制一个矩形
}
draw();
translate(x,y):平移,将画布的坐标原点向左右方向移动x,向上下方向移动y。
例如:
var ctx;// 通过var弱类型定义:然后它的类型取决于等号后面值的类型
function draw(){ //定义函数
var canvas = document.getElementById('tutorial1');//获取id
if (!canvas.getContext) return;//判断浏览器是否支持canvas的获取上下文的操作。
var ctx = canvas.getContext("2d");//获取2d环境
ctx.save(); //保存坐原点平移之前的状态
ctx.translate(100, 100);//将坐标原点左右方向移动100,向上下方向移动100
ctx.strokeRect(0, 0, 100, 100);//绘制一个矩形的边框,矩形的左上角的坐标为(0, 0),矩形的宽和高为(100,100)
ctx.restore(); //恢复到最初状态
ctx.translate(220, 220);//将坐标原点左右方向移动220,向上下方向移动220
ctx.fillRect(0, 0, 100, 100);//绘制一个填充的矩形,矩形的左上角的坐标为(0, 0),矩形的宽和高为(100,100)
}
draw();
3.
rotate(angle);旋转坐标轴。
这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。旋转的中心是坐标原点。
例如:
var ctx; // 通过var弱类型定义:然后它的类型取决于等号后面值的类型
function draw(){ //定义函数
var canvas = document.getElementById('tutorial1'); //获取id
if (!canvas.getContext) return; //判断浏览器是否支持canvas的获取上下文的操作
var ctx = canvas.getContext("2d"); //获取2d环境
ctx.fillStyle = "red"; //填充矩形颜色为红色
ctx.save(); //保存状态
ctx.translate(100, 100); //将坐标原点左右方向移动100,向上下方向移动100
ctx.rotate(Math.PI / 180 * 45); //图形旋转45度角
ctx.fillStyle = "blue"; //填充矩形颜色为蓝色
ctx.fillRect(0, 0, 100, 100); //画一个左上角坐标为(0,0),长为100,宽为100的矩形
ctx.restore(); //恢复到最初状态
ctx.save(); //保存状态
ctx.translate(0, 0); //将坐标原点左右方向移动0,向上下方向移动0
ctx.fillRect(0, 0, 50, 50); //画一个左上角坐标为(0,0),长为50,宽为50的矩形
ctx.restore(); //恢复到最初状态
}
draw();//执行函数
scale(x, y);增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。
scale方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。值比 1.0 小表示缩 小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。
transform(a, b, c, d, e, f);//变形矩阵
a水平缩放绘图
b:水平倾斜绘图
c:垂直倾斜绘图
d:垂直缩放绘图
e:水平移动绘图
f:垂直移动绘图
<canvas id="triangle" height="500" width="500" style="border:1px solid #d3d3d3"></canvas>
<script>
var canvas=document.getElementById("triangle"); //获取id
var ctx = canvas.getContext("2d");//获取2d环境
var x=0,y=100,r=0;//定义变量x,y,r
setInterval( //定义计时器
function(){ //函数
ctx.clearRect(0,0,canvas.width,canvas.height);//清空给定矩形内的指定像素。
ctx.save(); //保存状态
ctx.translate(x,y);//平移,将画布的坐标原点向左右方向移动x,向上下方向移动y
ctx.rotate(r);//顺时针旋转r角度
ctx.fillRect(-20,-20,40,40);画一个左上角坐标为(-20,-20),长为40,宽为40的矩形
ctx.restore();//恢复到最初状态
x= x>400?0:x+6;//如果x大于400就输出0,否则x+6
r+=Math.PI/180*5;//定义r为5度
}
,20);//每隔20毫秒执行一次函数
</script>
<canvas id="mycanvas" height="600" width="600" style="border:#CF1013 solid"></canvas>//定义画布id="mycanvas",高为600,宽为600,格式边框为实线,颜色为#CF1013
<script type="text/javascript">
var canvas=document.getElementById("mycanvas");//获取id
var cobj=canvas.getContext("2d");//获取2d环境
var arr=[];//一个数组对象
setInterval( //定义计时器
function (){ //定义函数
cobj.clearRect(0,0,600,600);//清空给定矩形内的指定像素。
for(var i=0;i<arr.length;i++){ //for循环当i小于arr.length时i就递增
cobj.save();//保存状态
cobj.translate(300,300);平移,将画布的坐标原点向左右方向移动300,向上下方向移动300
cobj.scale(arr[i].scale,arr[i].scale);//缩放横纵轴
cobj.rotate(arr[i].angle*Math.PI/180); //旋转arr[i].angle角度
cobj.beginPath();//重新开始新路径,把之前路径清空
cobj.fillStyle=arr[i].color;填充颜色为arr[i].color
cobj.rect(arr[i].num,arr[i].num,30,30);绘制左上角坐标为(arr[i].num,arr[i].num),宽为30,高为30的矩形
cobj.fill();//执行函数fill()
cobj.restore();//恢复到之前状态
}
}
,60)
setInterval(function(){ //定义函数
for(var i=0;i<arr.length;i++) //for循环当i小于arr.length时i就递增
{
if(arr[i].num<0){arr.splice(i,1);continue;删掉第i位,删1个
}
arr[i].angle+=2;//arr[i].angle=arr[i].angle+2
arr[i].num-=0.2;//arr[i].num=arr[i].num-0.2
arr[i].scale-=0.002;//arr[i].scale=arr[i].scale-0.002
if(arr[i].scale<=0.2)arr[i].scale=0.2;//如果arr[i].scale<=0.2,输出arr[i].scale=0.2
}
},60);//每60毫秒执行一次函数
setInterval( //定义计时器
function(){ //定义函数
var rect={angle:0,num:150,scale:1,
color:"rgb("+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+","+parseInt(Math.random()*255)+")"};//定义矩形的角度为0,数目为150,缩放不变,颜色为随机取色
arr.push(rect);//向数组的末尾添加一个或多个元素,并返回新的长度
}
,1000)//每隔1秒执行一次函数
</script>
splice方法有删除、替换、添加三种功能
var arr = ['TM', '钟毅', '张森', '杜鹏', 'Leo'];
//删除
//arr.splice(0, 1); //删掉第0位,删1个。两个参数第一个是从第几位开始,第二个是删掉几个。splice删除的时候有返回值,返回的是被删除的内容
//替换
//arr.splice(0, 1, '莫涛'); //替换第0位,替换1个,替换为'莫涛'。返回的还是删除的东西
//添加
arr.splice(1, 0, '李贤'); //在第1位那里,删除0个,添加了一个'李贤'到了第1位,'钟毅'就变成了arr[2]了。后面也可以添加多个。如果splice删除了0个,那么就没有返回值。
4.
要创建一些像素,需要调用2D渲染上下文的createImageData 方法。通过传入宽度和高度,它会返回一个包含所有常规属性的ImageData对象:width、height和(最重要的)data。data属性所包含的CanvasPixelArray 将保存新的像素,此时它们是不可见的,因为它们都被设置为透明黑色。
例一:
<canvas id="s" height="300" width="300" style="border:1px solid #f00"></canvas>定义画布
id="s",高为300,宽为300,格式边框为实线,颜色为#f00
<script>
var canvas=document.getElementById("s");//获取id
var ctx = canvas.getContext("2d");//获取2d环境
var imgData = ctx.createImageData(250, 250); //创建一个包含250×250透明像素区域的ImgData 对象
var pixels = imgData.data;//变量pixels仅用作访问CanvasPixelArray中的像素的快捷方式
var numPixels=imgData.width*imgData.height;//变量numPixels保存了ImageData对象中的像素个数,它就是for循环的执行次数
for (var i = 0; i < numPixels; i++)//for循环
{
pixels[i*4] = 255; // 将红色颜色值设置为255(全色)
pixels[i*4+1] = 0; // 将绿色颜色值设置为0
pixels[i*4+2] = 0; // 将蓝色颜色值设置为0
pixels[i*4+3] = 255; // 阿尔法值设置为255
}
ctx.putImageData(imgData,0,0);//执行ImageData函数
</script>
例二:
<canvas id="kk" height="300" width="300" style="border:1px solid #f00"></canvas>定义画布id="kk",高为300,宽为300,格式边框为实线,颜色为#f00
<script>
var canvas=document.getElementById("kk");//获取id
context= canvas.getContext("2d");//获取2d环境
var imgData = context.createImageData(250, 250); //创建一个包含250×250透明像素区域的ImgData 对象
var pixels = imgData.data;//变量pixels仅用作访问CanvasPixelArray中的像素的快捷方式
var numPixels=imgData.width*imgData.height;//变量numPixels保存了ImageData对象中的像素个数,它就是for循环的执行次数
for (var i = 0; i < numPixels; i++)
{
pixels[i*4] = Math.floor(Math.random()*255); // 将红色颜色值设置为0到255之间的整数
pixels[i*4+1] = Math.floor(Math.random()*255); //将绿色颜色值设置为0到255之间的整数
pixels[i*4+2] = Math.floor(Math.random()*255); //将蓝色颜色值设置为0到255之间的整数
pixels[i*4+3] = 255; //阿尔法值设置为255
};
context.putImageData(imgData,10,10);//执行ImageData函数,左上角坐标为(10,10)
</script>
例三:
<canvas id="ll" height="500" width="500" style="border:1px solid #f00"></canvas>
<script>
setInterval(function(){//定义计时器
var canvas=document.getElementById("ll");
context= canvas.getContext("2d");
var imageData = context.createImageData(500, 500);//创建一个包含500×500透明像素区域的imageData 对象
var pixels = imageData.data;//变量pixels仅用作访问CanvasPixelArray中的像素的快捷方式
var numTileRows = 4;// 定义四行
var numTileCols = 4;// 定义四列
var tileWidth = imageData.width/numTileCols;//根据ImageData对象的尺寸和各行各列的块数计算出每个块的宽度
var tileHeight = imageData.height/numTileRows;//根据ImageData对象的尺寸和各行各列的块数计算出每个块的高度
for (var r = 0; r < numTileRows; r++)//遍历每一行的块
{
for (var c = 0; c < numTileCols; c++)//遍历当前行的每一列块
{
var red = Math.floor(Math.random()*255);//将红色颜色值设置为0到255之间的整数
var green = Math.floor(Math.random()*255);//将绿色颜色值设置为0到255之间的整数
var blue = Math.floor(Math.random()*255);//将蓝色颜色值设置为0到255之间的整数
for (var tr = 0; tr < tileHeight; tr++)//当前访问块的像素行(基于块的高度)
{
for (var tc = 0; tc < tileWidth; tc++){ //当前访问块的像素列(基于块的宽度)
var trueX = (c*tileWidth)+tc;//像素的真实x轴位置
var trueY = (r*tileHeight)+tr;//像素的真实y轴位置
var pos = (trueY*(imageData.width*4))+(trueX*4);//获取非本行的全部像素数+本行之前的所有像素数,就是在数组中的位置
pixels[pos] = red; //获取红色值
pixels[pos+1] = green;//获取绿色值
pixels[pos+2] = blue;//获取蓝色值
pixels[pos+3] = 255;//阿尔法值设置为255
};
};
};
};
context.putImageData(imageData, 0, 0); },1000);//将像素绘制到画布上
</script>