HTML Canvas笔记

142 阅读8分钟

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>