您的位置:首页 > 其它

canvas(一)--基本用法

2018-03-20 10:55 453 查看
本canvas专栏的内容极大部分参考外部资源,具体链接已给出,仅作为自己的学习笔记。

canvas属性

height pixels 设置 canvas 的高度。
width pixels 设置 canvas 的宽度。
如何使用 <canvas> 标记绘图<canvas> 标记和 SVG 以及 VML 之间的差异
<canvas> 标记和 SVG 以及 VML 之间的一个重要的不同是,<canvas> 有一个基于 JavaScript 的绘图 API,而 SVG 和 VML 使用一个 XML 文档来描述绘图。
这两种方式在功能上是等同的,任何一种都可以用另一种来模拟。从表面上看,它们很不相同,可是,每一种都有强项和弱点。例如,SVG 绘图很容易编辑,只要从其描述中移除元素就行。
要从同一图形的一个 <canvas> 标记中移除元素,往往需要擦掉绘图重新绘制它。

大多数 Canvas 绘图 API 都没有定义在 <canvas> 元素本身上,而是定义在通过画布的 getContext() 方法获得的一个“绘图环境”对象上。
Canvas API 也使用了路径的表示法。但是,路径由一系列的方法调用来定义,而不是描述为字母和数字的字符串,比如调用 beginPath() 和 arc() 方法。
一旦定义了路径,其他的方法,如 fill(),都是对此路径操作。绘图环境的各种属性,比如 fillStyle,说明了这些操作如何使用。

注释:Canvas API 非常紧凑的一个原因上它没有对绘制文本提供任何支持。要把文本加入到一个 <canvas> 图形,必须要么自己绘制它再用位图图像合并它,或者在 <canvas> 上方使用 CSS 定位来覆盖 HTML 文本。
PS:Internet Explorer 8 或更早的浏览器不支持 <canvas> 元素
摘抄自:http://www.w3school.com.cn/html5/html5_canvas.asp

一、画直线

1.简单的直线
首先先来理解几个概念:
①beginPath() 方法在一个画布中开始子路径的一个新的集合。当一个画布的环境第一次创建,beginPath() 方法会被显式地调用;
②closePath() 方法关闭一条打开的子路径,如果画布的子路径是打开的,closePath() 通过添加一条线条连接当前点和子路径起始点来关闭它。如果子路径已经闭合了,这个方法不做任何事情。一旦子路径闭合,就不能再为其添加更多的直线或曲线了。要继续向该路径添加,需要通过调用 moveTo() 开始一条新的子路径。
③stroke() 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
④fill() 方法填充路径。fill() 方法使用 fillStyle 属性所指定的颜色、渐变和模式来填充当前路径。这一路径的每一条子路径都单独填充。任何未闭合的子路径都被填充,就好像已经对他么调用了 closePath() 方法一样(但是,注意,实际上没有这么让子路径成为闭合的)。画布使用“非零匝数规则”来确定哪个点在路径的内部,而哪个点在路径的外部。这一规定的细节超出了本参考页的范围,但是,它们通常只和那些与自身相交的复杂路径相交。填充一条路径并不会清除该路径。你可以在调用 fill() 之后再次调用 stroke(),而不需要重新定义该路径。<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.moveTo(50, 50);
ctx.lineTo(150, 150);
ctx.stroke(); //stroke() 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
</script>效果:



2.给直线设置粗细和颜色
使用lineWidth、strokeStyle属性分别设置线条的宽度和颜色
<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
//线条宽度
ctx.lineWidth = 10;
//线条颜色(支持颜色编码与rgb()函数)
ctx.strokeStyle = "#cd2828";
//ctx.strokeStyle = "rgb(205,40,40)";效果一样
ctx.moveTo(50, 50);
ctx.lineTo(150, 150);
ctx.stroke();
</script>效果:



该直线宽度为10px;颜色酒红色,笔头是方头
3.给直线设置笔头
使用 lineCap 属性设置线条两端的形状(线头类型):
butt:方头(默认值)
round:圆头
square:加长方头(效果与butt类似,但会在线条的两头各增加一半线宽的长度)
<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
//线条宽度
ctx.lineWidth = 10;
//线条颜色
ctx.strokeStyle = "#cd2828";

//第一条直线,默认方头
ctx.moveTo(50, 50);
ctx.lineTo(250, 50);
ctx.stroke();

//第二条直线,使用圆头
ctx.beginPath();
ctx.moveTo(50, 100);
ctx.lineTo(250, 100);
ctx.lineCap = "round";
ctx.stroke();

//第三条直线,使用加长方头
ctx.beginPath();
ctx.moveTo(50, 150);
ctx.lineTo(250, 150);
ctx.lineCap = "square";
ctx.stroke();
</script>效果:



注:绘图上下文的beginPath()方法
beginPath()其实就是告诉画布:“我要开始画草稿了,请把之前的草稿都清除掉。”是的,beginPath()是重新开始新路径,而把之前的路径都清空掉。如果路径没有了,那么我们的stroke()和fill()就无法起作用,我们看到下面一个例子:
<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(50, 50);
ctx.lineTo(250, 50);
ctx.beginPath();
ctx.moveTo(50, 100);
ctx.lineTo(250, 100);
ctx.stroke();
</script>效果:



我们在代码中绘制了两条直线,但是在调用stroke()以后,只有第二条直线绘制了出来。原因就是我们第二次调用方法beginPath()时清除了第一条直线的路径,没有“草稿”我们无法描边。
转载链接:http://www.hangge.com/blog/cache/detail_1019.html
                http://blog.csdn.net/xuyjun/article/details/18099147

二、画圆形

1.一个简单的圆<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.arc(100,75,50,0,2*Math.PI);
ctx.stroke();
</script>效果:



arc() 方法创建弧/曲线(用于创建圆或部分圆)。

arc()语法:context.arc(x,y,r,sAngle,eAngle,counterclockwise);

x 圆的中心的 x 坐标。
y 圆的中心的 y 坐标。
r 圆的半径。
sAngle 起始角,以弧度计。(弧的圆形的三点钟位置是 0 度)。
eAngle 结束角,以弧度计。

counterclockwise 可选。规定应该逆时针还是顺时针绘图。False = 顺时针,true = 逆时针。



在上面画直线的时候,设置宽度,颜色和线头的方法都可以用的<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = "#cd2828";
ctx.lineCap = "round";
ctx.arc(100,75,50,0,1/2*Math.PI);
ctx.stroke();
</script>
效果:



2.一个被填充的圆<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.arc(200,100,50,0,360,false);
ctx.fillStyle="red";//填充颜色,默认是黑色
ctx.fill();//画实心圆
ctx.closePath();
</script>效果:



三、画三角形

1.空心等边三角形
我是这样实现的<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=200;
canvas.height=200;
var ctx=canvas.getContext('2d');
var height = 200*Math.sin(Math.PI/3);//计算等边三角形的高
ctx.beginPath();
ctx.lineWidth=2;//线的边框为2像素
ctx.moveTo(100,0); //从A(100,0)开始
ctx.lineTo(0,height);//从A(100,0)开始,画到B (0,173)结束
ctx.stroke();//绘制定义的图形
ctx.lineTo(200,height); //B(0,173)-C(200,173)
ctx.stroke();//绘制定义的图形
ctx.lineTo(100,0);
ctx.stroke();//绘制定义的图形
ctx.closePath();
</script>感觉比较容易理解一点,下面是别人的实现方法
<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=200;
canvas.height=200;
var ctx=canvas.getContext('2d');
var height = 200*Math.sin(Math.PI/3);//计算等边三角形的高
ctx.beginPath();
ctx.lineWidth=2;//线的边框为2像素
ctx.moveTo(100,0); //从A(100,0)开始
ctx.lineTo(0,height);//从A(100,0)开始,画到B (0,173)结束
ctx.lineTo(200,height); //B(0,173)-C(200,173)
ctx.closePath();
ctx.stroke();//绘制定义的图形
</script>
效果:



2.实心等边三角形<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=200;
canvas.height=200;
var ctx=canvas.getContext('2d');
//填充三角形(等边)
ctx.beginPath();
var height = 200*Math.sin(Math.PI/3);//计算等边三角形的高
ctx.moveTo(100,0); //从A(100,0)开始
ctx.lineTo(0,height);//从A(100,0)开始,画到B (0,173)结束
ctx.lineTo(200,height); //B(0,173)-C(200,173)
ctx.fillStyle="red"; //以上面定义的渐变填充
ctx.fill(); //闭合形状并且以填充方式绘制出来
</script>效果:



PS:画三角形其实确定三个点就好办多了
3.渐变颜色<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=200;
canvas.height=200;
var ctx=canvas.getContext('2d');
//填充三角形(等边)
ctx.beginPath();
var height = 200*Math.sin(Math.PI/3);//计算等边三角形的高
ctx.moveTo(100,0); //从A(100,0)开始
ctx.lineTo(0,height);//从A(100,0)开始,画到B (0,173)结束
ctx.lineTo(200,height); //B(0,173)-C(200,173)
//ctx.fillStyle='#00ff00';//以纯色绿色填充
var grd = ctx.createLinearGradient(0,0,200,0);//使用渐变颜色填充,从(0,0)到(200,0) (左到右)
grd.addColorStop(0,"#4CE8B2"); //起始颜色
grd.addColorStop(1,"#EFD458"); //终点颜色
ctx.fillStyle=grd; //以上面定义的渐变填充
ctx.fill(); //闭合形状并且以填充方式绘制出来
</script>效果:



PS:createLinearGradient() 方法创建线性的渐变对象。渐变可用于填充矩形、圆形、线条、文本等等。请使用该对象作为 strokeStyle 或 fillStyle 属性的值。请使用 addColorStop() 方法规定不同的颜色,以及在 gradient 对象中的何处定位颜色。
语法:context.createLinearGradient(x0,y0,x1,y1);
x0 渐变开始点的 x 坐标
y0 渐变开始点的 y 坐标
x1 渐变结束点的 x 坐标

y1 渐变结束点的 y 坐标
addColorStop() 方法规定 gradient 对象中的颜色和位置。

addColorStop() 方法与 createLinearGradient() 或 createRadialGradient() 一起使用。
语法:gradient.addColorStop(stop,color);
stop 介于 0.0 与 1.0 之间的值,表示渐变中开始与结束之间的位置。
color 在结束位置显示的 CSS 颜色值

参考链接:http://caibaojian.com/canvas-triangle.html

四、画矩形

1.空心矩形<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=1000;
canvas.height=1000;
var ctx=canvas.getContext('2d');
ctx.rect(20,20,150,100);
ctx.stroke();
</script>效果:



PS:rect() 方法创建矩形。请使用 stroke() 或 fill() 方法在画布上实际地绘制矩形。
语法:context.rect(x,y,width,height);
x 矩形左上角的 x 坐标
y 矩形左上角的 y 坐标
width 矩形的宽度,以像素计

height 矩形的高度,以像素计
2.实心矩形<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=1000;
canvas.height=1000;
var ctx=canvas.getContext('2d');
ctx.beginPath();
ctx.fillStyle='#00ff00';
ctx.rect(20,20,150,100);
ctx.fill();
</script>
效果:



五、画多边形

六边形和八边形,使用moveTo()与lineTo()方法,再结合一些简单的三角函数,就可以绘制出任意边数的多边形。

1.等边实心多边形<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=1000;
canvas.height=1000;
var ctx=canvas.getContext('2d');
function drawPath(x, y, n, r)
     {
    var i,ang;
    ang = Math.PI*2/n //旋转的角度
     ctx.save();//保存状态
    ctx.fillStyle ='rgba(255,0,0,.3)';//填充红色,半透明
     ctx.strokeStyle ='hsl(120,50%,50%)';//填充绿色
     ctx.lineWidth = 1;//设置线宽
     ctx.translate(x, y);//原点移到x,y处,即要画的多边形中心
     ctx.moveTo(0, -r);//据中心r距离处画点
     ctx.beginPath();
     for(i = 0;i < n; i ++)
     {
     ctx.rotate(ang)//旋转
     ctx.lineTo(0, -r);//据中心r距离处连线
     }
     ctx.closePath();
     ctx.stroke();
     ctx.fill();
     ctx.restore();//返回原始状态
    }
    drawPath(100, 100, 5, 40)//在100,100处画一个半径为40的五边形
     drawPath(200, 100, 3, 40)//在200,100处画一个半径为40的三角形
     drawPath(300, 100, 7, 40)//在300,100处画一个半径为40的七边形
     drawPath(100, 200, 15, 40)//在100,200处画一个半径为40的十五边形
     drawPath(200, 200, 4, 40)//在100,200处画一个半径为40的四边形
</script>效果:



摘抄自:https://www.cnblogs.com/anxiaoyu/p/6694090.html
PS:
save():用来保存Canvas的状态。save之后,可以调用Canvas的平移、放缩、旋转、错切、裁剪等操作。 
restore():用来恢复Canvas之前保存的状态。防止save后对Canvas执行的操作对后续的绘制有影响。
对canvas中特定元素的旋转平移等操作实际上是对整个画布进行了操作,所以如果不对canvas进行save以及restore,那么每一次绘图都会在上一次的基础上进行操作,最后导致错位。比如说你相对于起始点每次30度递增旋转,30,60,90.如果不使用save 以及 restore 就会变成30, 90, 150,每一次在前一次基础上进行了旋转。save是入栈,restore是出栈。
rotate() 方法旋转当前的绘图。

angle
旋转角度,以弧度计。
如需将角度转换为弧度,请使用 degrees*Math.PI/180 公式进行计算。
举例:如需旋转 5 度,可规定下面的公式:5*Math.PI/180。

translate():translate() 方法重新映射画布上的 (0,0) 位置。

语法:context.translate(x,y);
x 添加到水平坐标(x)上的值
y 添加到垂直坐标(y)上的值

参考链接:http://blog.csdn.net/u014788227/article/details/52250208
2.等边空心多边形<body>
<canvas id="myCanvas"></canvas>
</body>
<script type="text/javascript">
var canvas=document.getElementById('myCanvas');
canvas.width=1000;
canvas.height=1000;
var ctx=canvas.getContext('2d');
function drawPath(x, y, n, r)
{
var i,ang;
ang = Math.PI*2/n //旋转的角度
ctx.save();//保存状态
ctx.strokeStyle ='hsl(120,50%,50%)';//填充绿色
ctx.lineWidth = 1;//设置线宽
ctx.translate(x, y);//原点移到x,y处,即要画的多边形中心
ctx.moveTo(0, -r);//据中心r距离处画点
ctx.beginPath();
for(i = 0;i < n; i ++)
{
ctx.rotate(ang)//旋转
ctx.lineTo(0, -r);//据中心r距离处连线
}
ctx.closePath();
ctx.stroke();
ctx.restore();//返回原始状态
}
drawPath(100, 100, 5, 40)//在100,100处画一个半径为40的五边形
drawPath(200, 100, 3, 40)//在200,100处画一个半径为40的三角形
drawPath(300, 100, 7, 40)//在300,100处画一个半径为40的七边形
drawPath(100, 200, 15, 40)//在100,200处画一个半径为40的十五边形
drawPath(200, 200, 4, 40)//在100,200处画一个半径为40的四边形
</script>效果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: