您的位置:首页 > Web前端 > HTML5

html5学习canvas

2015-09-19 23:22 453 查看
在html5中新增了一个标签元素叫做canvas,顾名思义,canvas就是一个画布,我们可以通过canvas来在页面中绘制我们想要的元素,以及添加一些动画效果。

创建canvas

我们可以通过两种方式来创建一个canvas对象,分别使用html标签,和javascript来创建一个canvas对象。

使用html来创建canvas对象

<canvas id="canvas"></canvas>


使用javascript引入canvas

//首先获取canvas对象
var canvas = document.getElementById("canvas");
//获得绘制2d图形的上下文环境
var context = canvas.getContext("2d");


绘制简单图形

绘制直线

这里我们先绘制一条直线。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvas</title>
    <style type="text/css">
        canvas{
            margin: 0 auto;
            display: block;
            border: 1px #ff9875 solid;
        }
    </style>

    <script type="text/javascript">
        window.onload = function(e) {
            //得到canvas对象
            var canvas = document.getElementById("canvas");
            //设置当前canvas的宽和高
            canvas.width = 600;
            canvas.height = 600;
            //获取用于绘制2d图形的上下文
            var context = canvas.getContext("2d");
            //描述具体的绘制路径
            context.moveTo(100,100);//首先将画笔移动到100,100这个点,该点是相对于当前canvas对象的,即0,0点是当前canvas的左上角
            //从上一个点描述一条直线到500,500改点
            context.lineTo(500,500);
            //真正的绘制
            context.stroke();
        }
    </script>
</head>
<body>
    <canvas id="canvas"></canvas>
</body>
</html>


效果如下:



为画笔设置样式

//设置当前画笔的宽度
context.lineWidth = 10;
//设置当前画笔的样式,这里为颜色
context.strokeStyle = '#ff0000'


可以看到,这里我们设置属性都是通过context上下文环境来设置的,此时效果如下:



画三角形

//得到canvas对象
var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
//获取用于绘制2d图形的上下文
context.moveTo(150,75);
context.lineTo(225,225);
context.lineTo(75,225);
context.lineTo(150,75);
//真正的绘制
context.stroke();


此时效果如下:



beginPath改变画笔颜色

这里我已经绘制了一个三角形了,那么如果还需要在底部绘制一条直线,并且为该直线设置不同的颜色,应该怎么做呢??看下如下代码:

//得到canvas对象
var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
context.lineWidth = 10;//所有的线条宽度都是10,所以设置一次即可

//beginPath表示将要进行一段全新的路径绘制
context.beginPath();            
context.moveTo(150,75);
context.lineTo(225,225);
context.lineTo(75,225);
context.lineTo(150,75);
context.strokeStyle = "red";
context.stroke();

context.beginPath();
context.moveTo(20,280);
context.lineTo(280,280);
context.strokeStyle = "green";
context.stroke();


PS:这里在每次更换画笔属性,之前都必须调用context.beginPath()方法,新设置的属性才会生效。 此时效果如下:




但是这里有一个问题,就是由于三角形是封闭的图像,在结束的时候由于我们当前的宽度是10,所以会有5px的空隙流出来,解决该问题,只需要在描述需要绘制的所有的点,之后添加一个context.closePath()方法即可。

context.beginPath();
context.moveTo(150,75);
context.lineTo(225,225);
context.lineTo(75,225);
context.lineTo(150,75);
context.closePath()
context.strokeStyle = "red";
context.stroke();


此时效果如下:



为多边形设置填充

另外context中还有如下属性,可以用来设置多边形的填充颜色:

fillStyle :设置需要填充的颜色

fill() :填充

同样是上面的三角形:

context.beginPath();
context.moveTo(150,75);
context.lineTo(225,225);
context.lineTo(75,225);
context.closePath()
context.strokeStyle = "red";
context.fillStyle= "#876508"; //设置多边形填充颜色
context.fill(); //填充
context.stroke();


此时效果如下:



canvas常用API

绘制矩形

canvas为我们提供了如下方法,用来绘制矩形:

rect(x,y,widht,height) //绘制一个矩形的边

fillRect(x,y,widht,height) //绘制一个实心的具有fillstyle的矩形

strokeRect(x,y,widht,height) //绘制一个空心,具有strokeStyle的矩形

使用rect绘制矩形

//得到canvas对象
var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
//起点是20,20 宽度和高度都是260
context.rect(20,20,260,260); 
context.stroke();


效果如下:



使用fillRect绘制矩形

//得到canvas对象
var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
context.fillStyle = "#ab8975";
//直接使用fillRect方法绘制实心矩形
context.fillRect(20,20,260,260);


效果如下:



使用strokeRect绘制矩形

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
context.strokeStyle = "#ff0080";
context.strokeRect(20,20,260,260);


效果如下:



lineCap属性

首先看下常用的线条属性lineCap,该属性用来设置线条两端的形状,有如下三个值:

butt: 默认值

round :两端为圆形

square :两端为方形

这里我写了一段代码来区分这三个属性的不同之处:

//得到canvas对象
var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

//首先画两条竖线,用来方便观察不同的lineCap属性的区别
context.moveTo(50,0);
context.lineTo(50,300);
context.moveTo(250,0);
context.lineTo(250,300);
context.stroke();

context.lineWidth = 40;//为所有的线条设置相同的宽度
context.strokeStyle = "#ab0249"; //为所有的线条设置填充颜色

//默认的lineCap butt
context.beginPath();
context.moveTo(50,60);
context.lineTo(250,60);
context.stroke();

//lineCap设置为round
context.beginPath();
context.moveTo(50,140);
context.lineTo(250,140);
context.lineCap = "round";
context.stroke();

//lineCap设置为square
context.beginPath();
context.moveTo(50,220);
context.lineTo(250,220);
context.lineCap = "square";
context.stroke();


此时效果如下:



canvas图形变换

translate平移

这里我写了一个简单的demo来展示平移的效果:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
context.lineWidth = 5;

context.beginPath();
context.fillStyle = "#aaa"; 
//context.translate(50,50); //表示将当前图形的左上角x和y轴分别平移50px
context.fillRect(0,0,100,100);


可以看到,添加translate方法之后对比的效果如下:



translate的叠加效果

此时我再在当前画布上绘制一个红色的实心矩形,并且将其x和y轴分别平移100,100的像素。

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
context.lineWidth = 5;

context.beginPath();
context.fillStyle = "#aaa"; 
context.translate(50,50); //表示将当前图形的左上角x和y轴分别平移50px
context.fillRect(0,0,100,100);

context.beginPath();
context.fillStyle = "#ff0000";
//此时该rect的x和y轴,实际上移动了150px,这就说明了translate的叠加效果 
context.translate(100,100); 
context.fillRect(0,0,100,100);


效果如下:




可以看到translate平移默认是有叠加效果的,即后边的移动,会将前面的所有移动叠加,然后再次进行平移。

解决translate的叠加效果

使用translate(-x,-y)

为了防止这样的事情发生,我们可以在每次移动translate(x,y)指定距离之后,在使用translate(-x,-y)平移回到初始位置,这样,后边的平移就不会受到影响了。

context.beginPath();
context.fillStyle = "#aaa"; 
context.translate(50,50); //表示将当前图形的左上角x和y轴分别平移50px
context.fillRect(0,0,100,100);
context.translate(-50,-50); 

context.beginPath();
context.fillStyle = "#ff0000";
context.translate(100,100); 
context.fillRect(0,0,100,100);
context.translate(-100,-100);


此时效果如下:



使用save()和restore()

我们可以在每次绘制之前,先使用save()方法保存之前的图形,然后在绘制完成之后,在调用restore方法恢复到保存之前的图形。

context.save();
context.beginPath();
context.fillStyle = "#aaa"; 
context.translate(50,50); //表示将当前图形的左上角x和y轴分别平移50px
context.fillRect(0,0,100,100);
context.restore();

context.save();
context.beginPath();
context.fillStyle = "#ff0000";
context.translate(100,100); 
context.fillRect(0,0,100,100);
context.restore();


可以看到,在save和restore方法中间,可以随意的更改canvas的绘制,都不会影响到后边的绘制。

scale方大缩小

这里我绘制了三个正方形,来演示rotate方法:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 400;
canvas.height = 400;
var context = canvas.getContext("2d");
context.lineWidth = 5;

context.save();
context.beginPath();
context.scale(1,1); 
context.strokeRect(50,50,50,50);
context.restore();

context.save();
context.beginPath();
context.scale(2,2); //表示将x和y同时放大2倍
context.strokeRect(50,50,50,50);
context.restore();

context.save();
context.beginPath();
context.scale(3,3); //表示将x和y同时放大3倍
context.strokeRect(50,50,50,50);
context.restore();


此时效果如下:




奇怪:可以看到,左上角的偏移量也跟着放大了,而且边框也跟着放大了。

渐变

线性渐变

渐变可以填充在矩形, 圆形, 线条, 文本等等, 各种形状可以自己定义不同的颜色。创建一个线性渐变:

createLinearGradient(x,y,x1,y1)


当我们使用渐变对象,必须使用两种或两种以上的停止颜色。

addColorStop()方法指定颜色停止,参数使用坐标来描述,可以是0至1.

线性渐变demo

这里我创建一个简单的从白色到黑色的渐变:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

var linear = context.createLinearGradient(0,0,300,300);
linear.addColorStop(0.0,'#fff');
linear.addColorStop(1.0,'#000');
context.fillStyle = linear;
context.fillRect(0,0,300,300);


可以看到,这里我的渐变是和canvas的大小相同的,此时效果如下:



添加多个addColorStop

另外,在上面的demo中,我们也可以添加多个colorStop,来设定不同时候渐变的颜色。

linear.addColorStop(0.0,'#fff');
linear.addColorStop(0.35,'#ff0');
linear.addColorStop(0.7,'#0ff');
linear.addColorStop(1.0,'#000');


此时效果入下:



设置渐变方向

同时我们还可以设置渐变的方向:

//表示水平渐变,从0,0渐变到300,0
var linear = context.createLinearGradient(0,0,300,0);




//表示竖直渐变,从0,0渐变到0,300
var linear = context.createLinearGradient(0,0,0,300);




径向渐变

径向渐变是以一个同心圆为中心进行的渐变,创建径向渐变:

createRadialGradient(x,y,r,x1,y1,r1) //创建一个径向/圆渐变


其中x,y,r表示第一个圆的圆心和半径

x1,y1,r1表示第二个圆的圆心和半径

径向渐变的效果就发生在这两个圆之间。

径向渐变demo

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

var radial = context.createRadialGradient(150,150,0,150,150,100);
radial.addColorStop(0.0,'#fff');
radial.addColorStop(0.35,'#ff0');
radial.addColorStop(0.7,'#0ff');
radial.addColorStop(1.0,'#000');
context.fillStyle = radial;
context.fillRect(0,0,300,300);


可以看到我在createRadialGradient指定渐变是从当前canvas的中心到半径为100的圆之间发生渐变的。效果如下:



使用createPattern绘制图片

同样,我们可以使用createPattern来绘制图片到canvas中。创建createPattern如下:

createPattern(canvas,repeat-style)
//canvas 这里表示需要绘制的图片
//repeat-style 表示重复的样式,取值和css中的background是一样的


createPattern简单demo

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

var backImage = new Image();
backImage.src = "car.jpg";
backImage.onload = function() {
    var pattern = context.createPattern(backImage,"no-repeat");
    context.fillStyle = pattern;
    context.fillRect(0,0,300,300);
}


这里我们new了一个image,并且在该image被加载进dom中时候,执行

context.fillStyle = pattern;

context.fillRect(0,0,300,300);

这样的填充和绘画代码,效果如下:



绘制曲线

使用arc函数绘制圆形

先看下arc函数的定义:

arc(x,y,r,start,stop,anticlockwise)


x,y表示绘制圆弧的中心

r 表示绘制圆弧的半径

start ,stop 表示绘制圆弧的起始和结束角度

anticlockwise 表示是否逆时针绘制

绘制圆形代码:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

context.beginPath();
context.lineWidth = 5;
context.arc(150,150,100,0,2 * Math.PI,false);
context.strokeStyle = "#ec7654";
context.fillStyle= "#092376"; //设置多边形填充颜色
context.fill(); //填充
context.stroke();


可以看到,这里我选取当前canvas的中心点作为圆心,100位半径,从0到2pi,效果如下:



绘制文本

canvas同时为我们提供了绘制文本的方法:

font字体设置

fillText(text,x,y) - 在 canvas 上绘制实心的文本

strokeText(text,x,y) - 在 canvas 上绘制空心的文本

这里text表示需要绘制的文本,x,y表示绘制文本的左上角坐标。

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

context.font = "30px Arial"; //设置字体类型和大小
//context.fillStyle = "#ef9087"; //设置字体填充色
context.fillText("hello canvas",50,100); //绘制字体




阴影的绘制

canvas中并没有提供绘制阴影的方法,而是给我们提供了下面几个属性,当我们为context(绘制的上下文)设置了这样的属性以后就会有阴影效果了。

context.shadowColor //阴影的颜色

context.shadowOffsetX //x方向阴影的偏移量

context.shadowOffsetY //y方向阴影的偏移量

context.shadowBlur //阴影的模糊程度,值越大,越模糊

这里,我写了一个简单的带阴影的矩形:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

context.shadowColor = "#ff9087";
context.shadowOffsetX = 10;
context.shadowOffsetY = 10;
context.shadowBlur = 20;

context.fillStyle = "red";
context.fillRect(100,100,100,100);




globalAlpha属性

globalAlpha用来设置当前整个画布的透明度,之前我们绘制的所有的图形的透明度都是globalAlpha的默认值1,也就是不透明。为了展示globalAlpha属性的作用,这里我先随机绘制很多圆。

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 600;
canvas.height = 600;
var context = canvas.getContext("2d");
var R;
var G;
var B;
for (var i = 0; i < 80; i++) {
    R = Math.floor(Math.random()*255);
    G = Math.floor(Math.random()*255);
    B = Math.floor(Math.random()*255);
    context.fillStyle = "rgb("+R+","+G+","+B+")";

    context.beginPath();
    context.arc(Math.random()*canvas.width,Math.random()*canvas.height,Math.random()*80,0,2 * Math.PI,false);
    context.fill();
};


可以看到这类绘制的所有的圆的:圆心,半径,以及填充色都是随机生成的,此时效果如下:




此时是没有透明度的,后绘制的圆会将先绘制的遮盖住,此时只需要为context增加globalAlpha属性,并设置相应的透明度值即可。

context.globalAlpha = 0.7;


此时效果如下:



globalCompositeOperation属性

globalCompositeOperation属性,表示绘制的图形在重叠时候的显示方式。默认值如下:

globalCompositeOperation = “source-over”

这里,source表示后绘制的图形,source-over表示后绘制的遮挡住先绘制的图形。

该属性有如下一些值可以设置:




举个例子:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");
context.globalCompositeOperation = "source-over";

context.beginPath();
context.fillStyle = "#fe9876";
context.fillRect(50,100,200,100);

context.beginPath();
context.fillStyle = "#f58798";
context.arc(150,150,70,0,2 * Math.PI,false);
context.fill();


效果如下:




可以看到这里设置globalCompositeOperation 属性为默认值,也就是后绘制的圆会遮盖住先绘制的矩形重叠的部分。

其他属性值的效果如下:




具体可以参考http://www.w3school.com.cn/tags/canvas_globalcompositeoperation.asp

clip()方法

clip()方法的功能是在当前的canvas中剪切出来一块区域,后边的绘制都是在该区域内进行的,而不是默认的整个canvas。举个栗子:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;
var context = canvas.getContext("2d");

context.beginPath();
context.fillStyle = "#000";
context.fillRect(0,0,300,300);

context.beginPath();
context.fillStyle = "#fff";
context.arc(150,150,80,0,2 * Math.PI,false);
context.fill();
//剪切出当前圆的区域,后边的绘制都在改区域内进行,超出部分不显示
context.clip();

context.font = "40px Arial";
context.fillStyle = "#ef9087";
context.textAlign = "center"; //水平居中
context.textBaseline = "middle"; //竖直居中
context.fillText("hello world",canvas.width/2,canvas.height/2);


此时效果如下:



获取鼠标点击位置相对canvas

我们可以获取鼠标的点击位置相对于canvas的位置,通过如下代码获得:

var canvas = document.getElementById("canvas");
//设置当前canvas的宽和高
canvas.width = 300;
canvas.height = 300;

canvas .addEventListener('click', function(e){
    var x = event.clientX - canvas.getBoundingClientRect().left;
    var y = event.clientY - canvas.getBoundingClientRect().top;
    alert(x + "  === " +y)
}, false);


ok,今天关于html5的canvas学习就到这里了,希望大家喜欢。

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