canvas学习笔记

最近看了一下canvas标签的使用,记下来,以免以后忘记却找不到。

个人理解 canvas算是定义了一个容器或者是标记,告诉浏览器这个区域我要用来画图,其本身没有实质性的作用,不像p标签可以将文本块化,但如果结合js会有一些实用、有意思的图画,下面就大概介绍一下一些用法(博主也是现学现卖,求大神板砖轻拍!)。

画图的第一步就是要在html中定义一个canvas标签(画布)

	<canvas id="test" height="200" width="200"></canvas>
上面就是定义一个id为test 高为200 宽为200的区域。

为了解决有一些浏览器不支持canvas(IE9+、Firefox 1.5+、Safari 2+、Opera 9+、Chrome、iOS 版Safari 以及Android 版WebKit)看不到信息是问题可以在canvas中写一些文本提示浏览器不支持canvas标签,如果浏览器不支持canvas时就会显示 提示信息,代码如下:

	<canvas id="test" height="200" width="200">该浏览器不支持canvas标签</canvas>
要想在画布(canvas)上面画图就要取得画布的上下文,获得画布上下文的方法是getContext()方法,获取2d图片的上下文就要给其传递一个2d的参数,但有一些浏览器不支持canvas变迁所以在获取上下文之前要先判断该浏览器是否支持canvas标签代码如下:

	var drawing = document.getElementById("test") ;
   //判断浏览器是否支持canvas标签
    if(drawing.getContext){
	//获取画布上下文
        var context = drawing.getContext("2d") ;
    }

接下来就可以在画布上画图了,以下代是在id为test上画了两个方框

var drawing = document.getElementById("test") ;
    if(drawing.getContext){
        var context = drawing.getContext("2d") ;

        //绘制一个绿色的框
        context.strokeStyle = "#00ff00" ;
        context.strokeRect(1,1,100,100) ;

        //绘制一个蓝色的框
        context.strokeStyle = "#0000ff" ;
        context.strokeRect(60,60,100,100) ;
    }
上面定义了两个框,一个绿色的框,一个蓝色的框 strokeStyle属相是设置框的颜色,支持上面的#00ff00的写法也支持rgb或者rgba的写法,strikeRect方法是定义了这个框,

前连个参数定义的是框的坐标起点,也就是canvas中的(1,1)这个点为框的左上角,后两个定义的是x轴以及y中的长度,一个起点和长宽就定义了一个框;画出来的图像如下:


定义方块和定义方框也是类似的,定义一个方块的的方法是

	context.fillRect(0,0,100,100) ;
同样是四个参数,参数的意义也是一样的,前两个是左上角的坐标,后两个是x轴和y轴的长度,定义两个方块的代码如下:

var drawing = document.getElementById("test") ;
    if(drawing.getContext){
        var context = drawing.getContext("2d") ;
        context.fillStyle = "rgba(0,0,255,0.5)" ;
        context.fillRect(0,0,100,100) ;

        context.fillStyle = "rgba(0,255,0,0.5)" ;
        context.fillRect(50,50,100,100) ;
    }
上面定义了两个方块,第一个颜色为蓝色,透明度为0.5,左上角是0,0坐标方块的长宽为100px;第二个方块的颜色绿色,透明度为0.5 ,起点为50,50,长宽分别是100px;图像如下:

下面介绍直线的画法

var drawing = document.getElementById("test") ;
    if(drawing.getContext){
        var context = drawing.getContext("2d") ;
        //起点移动到(100,100) ;
        context.moveTo(100,100) ;
        //直线的终点
        context.lineTo(150,150) ;
        //样式 线粗3px
        context.lineWidth = 3;
        //线的颜色
        context.strokeStyle = "#ff0000";
        //划线
        context.stroke() ;
    }
再画布上画了一条直线,直线的起点是画布的(100,100)坐标,直线的终点是画布的(150,150),直线的粗为3px,线的颜色为红色 stroke为划线,如果没有调这个方法就不会显现。

下面是画弧线

在画圆之前首先要开始路径,开始路径的方法是:beginPath() ;画圆用得方法是arc方法,其中前两个参数表示的圆心的坐标,中间两个参数是画弧线的起点坐标,第五个参数是画弧的角度(弧度单位表示),最后一个表示的是否逆时针画弧,下面为代码示例:

var draw = document.getElementById("test") ;
    if(draw.getContext){
        var context = draw.getContext("2d") ;
        context.beginPath() ;
        context.arc(100,100,90,90,0,2*Math.PI,false) ;
        context.stroke() ;
    }

	上面为画的圆,圆的圆心是(100,100)坐标,半径为90px,画出来的图像如下:
				
下面代码原本是打算画一个钟表,但尚未完成但是基本的东西都有所体现
	
 var drawing = document.getElementById("test") ;
    if(drawing.getContext){
        var context = drawing.getContext("2d");
//开始路径
        context.beginPath();
//绘制外圆
        context.arc(100, 100, 99, 0, 2 * Math.PI, false);
//绘制内圆
        context.moveTo(194, 100);
        context.arc(100, 100, 94, 0, 2 * Math.PI, false);
//绘制分针
     /*   context.moveTo(100, 100);
        context.lineTo(100, 15);
//绘制时针
        context.moveTo(100, 100);
        context.lineTo(35, 100);*/

        //变换原点
        context.translate(100, 100);
//绘制分针
        context.moveTo(0,0);
        context.lineTo(0, -85);
//绘制时针
        context.moveTo(0, 0);
        context.lineTo(-65, 0);

        //写字
        //设置字体的样式
        context.font = "bold 14px Arial";
        //文本的水平对其方式,如果是start表示的是文本的开始部分对应的是(100,,10)坐标。同理如果是end 表示的是文本的结束部分对应(100,10)的坐标
        context.textAlign = "center";
        //文本的垂直对齐方式,如果是top则表示文本的上部是坐标(100,10);
        context.textBaseline = "middle";
        //填写文本,第一个参数是文本的内容,后两个参数是文本的坐标值
        context.fillText("12", 0, -90);
//描边路径
        context.stroke();
    }
图像生成如下:
						
 
下面为写文本:
var draw = document.getElementById("juxing") ;
    if(draw.getContext){
        var context = draw.getContext("2d") ;
        var fontSize = 100;
        context.font = fontSize + "px Arial";
        context.textAlign = "start"  ;
        context.textBaseline = "top" ;
        while (context.measureText("HelloWorld").width>140){
            fontSize-- ;
            context.font = fontSize + "px Arial";
        }
        context.fillText("HelloWorld",10,10) ;

        context.fillText("Font size is " + fontSize + "px", 10, 50);
        context.stroke() ;
    }
context.drawImage(image,10,10,200,200) ;



上面是在canvas标签中显示字体并测试140px的长度最多能装多大的“HelloWorld”的字符串,并把最大像素的字符串画到canvas中,font属性定义的是字体的上样式,textAlign表示的是坐标点是文本的开始点还是结束点等等,其有五个属性值:"start"、"end"、"left"、"right"和"center" ,在j《javas高级程序》中建议使用的是start和end,不太建议使用left和right 。textBaseline使用基本和textAlign作用是相似的,只不过textBaseline定义的是水平的左右,而textAlign定义的是上下,top表示的是坐标点在文本的上边。

context.measureText("HelloWorld").width表示的是以context中的font来测量它所占的宽度。while循环的作用就是测量给定的font下画出“HelloWoorld”宽度是否会超出140个像素,如果超出就讲字体大小调小一点;最后context.fillText("Helloworld",10,10);就是将“Helloworld”装进context上下文中,其中的后两个参数表示的就是上面提到的坐标点(或者叫参考系)。

用canvas复制图片

绘制图片的方法是:context.drawImage() ;方法,当该方法传入三个参数的时候,第一参数是要处理的图片对象,后两个参数表示的是图片的起点要从画布的哪一个点开始如下面代码:

var draw = document.getElementById("imgTest") ;
    if(draw.getContext){
        var context = draw.getContext("2d") ;
        //获取图片
        var image = document.images[0] ;
        //将图片按照原大小绘制
       // context.drawImage(image,10,10) ;
    }
上面代码中首先获取了一个图片对象,然后从id为“imgTest”的坐标(10,10)处开始绘制图片。

图像缩放

context.drawImage()  除了能传三个参数还可以传五个参数,前三个参数的意思不变,后两个参数表示的要将图片缩放到的大小,代码如下:

	context.drawImage(image,10,10,200,200) ;
上面代码表示的是将图片缩放成200*200 ;

对图像像素进行处理

利用canvas不仅可以缩放图片还可以对图片的像素进行调整,利用getImageData()可以获得图像的数据对象,其有四个参数前两个是要取得图像的左上角的点,后两个表示

的是要取得宽度和高度,在数据对象中有一个属性名为“data”的属性,该属性是一个数组,它的每四个值都表示的是一个像素点的信息,这四个值分别表示的一个像素的红、绿

、蓝、透明度(rgba) ,可以对着四个值进行操作实现对图像的变换,下面一段代码实现的是将图像变灰,也就是类似于黑白照的效果:

var draw = document.getElementById("bianhui") ;
    if(draw.getContext){
        context = draw.getContext("2d") ;
        var image = document.images[0] ;
        context.drawImage(image,0,0) ;
        var imageData = context.getImageData(0,0,image.width,image.height) ;
        var datas = imageData.data ;
        var avg ;

        var length = datas.length ;
        for (var i=0; i<length; i+=4){
            var avg = Math.round((datas[i] + datas[i+1] + datas[i+2]) / 3 );
            datas[i] = avg ;
            datas[i+1] = avg ;
            datas[i+2] = avg ;
           /* var temp1 = datas[i+2] ;
            var temp2 = datas[i] ;

            datas[i] = datas[i] ;
            datas[i+1] = datas[i] ;
            datas[i+2] =  datas[i] ;*/
        }

        imageData.data = datas ;
        context.putImageData(imageData, 0, 0);
    }

下面一段代码是将图像的颜色取反,
var draw = document.getElementById("fanse") ;
        if(draw.getContext){
            context = draw.getContext("2d") ;
            var image = document.images[0] ;
            context.drawImage(image,0,0) ;
            var imageData = context.getImageData(0,0,image.width,image.height) ;
            var datas = imageData.data ;
            var avg ;

            var length = datas.length ;
            for (var i=0; i<length; i+=4){
                datas[i] = 255 - datas[i] ;
                datas[i+1] = 255 - datas[i+1] ;
                datas[i+2] = 255 - datas[i+2] ;
            }

            imageData.data = datas ;
            context.putImageData(imageData, 0, 0);
        }

下面一段代码是将每一个像素点的rgb三个值交换

var draw = document.getElementById("xiangsuzhiwei") ;
        if(draw.getContext){
            context = draw.getContext("2d") ;
            var image = document.images[0] ;
            context.drawImage(image,0,0) ;
            var imageData = context.getImageData(0,0,image.width,image.height) ;
            var datas = imageData.data ;
            var avg ;

            var length = datas.length ;
            for (var i=0; i<length; i+=4){

                var temp1 = datas[i+1] ;
                var temp2 = datas[i+2] ;


                datas[i+2] = datas[i] ;
                datas[i] = temp1 ;
                datas[i+1] = temp2 ;
            }

            imageData.data = datas ;
            context.putImageData(imageData, 0, 0);
        }

  下面一段代码是将图片根据某一个阀值变成黑白两色(二值化)

        var draw = document.getElementById("erzhi");
        if (draw.getContext) {
            context = draw.getContext("2d");
            var image = document.images[0];
            context.drawImage(image, 0, 0);
            var imageData = context.getImageData(0, 0, image.width, image.height);
            var datas = imageData.data;
            var avg;

            var length = datas.length;
            for (var i = 0; i < length; i += 4) {
                if (datas[i]<100 && datas[i + 1]<100 && datas[i + 2] < 100) {
                    datas[i + 2] = 0;
                    datas[i] = 0;
                    datas[i + 1] = 0;
                }else{
                    datas[i + 2] = 255;
                    datas[i] = 255;
                    datas[i + 1] = 255;
                }
            }
            imageData.data = datas;
            context.putImageData(imageData, 0, 0);
        }

下面第一张图为原图,第二张是变灰图,第三张是颜色换位图,第四张二值化图


阴影与渐变
	canvas还可以绘制出阴影和渐变的效果下面第一段代码为阴影,第二段为渐变
 var draw = document.getElementById("yingYingTest") ;
    if(draw.getContext){
        var context = draw.getContext("2d") ;
        context.shadowOffsetX = 5 ;
        context.shadowOffsetY = 5 ;
        context.shadowColor = "rgba(0, 0, 0, 0.5)";
        context.shadowBlur = 4 ;

        context.fillStyle = "rgba(255,240,10)" ;
        context.fillRect(10,10,100,100) ;

        //绘制蓝色矩形
        context.fillStyle = "rgba(0,0,255,1)";
        context.fillRect(70, 70, 100, 100);

var draw = document.getElementById("jianbian") ;
    if(draw.getContext){
        var context = draw.getContext("2d") ;
        var gradient = context.createLinearGradient(80,80,180,180) ;
        gradient.addColorStop(0,"red") ;
        gradient.addColorStop(1,"yellow") ;


        //绘制一个蓝色方块
        context.fillStyle = "#0000ff";
        context.fillRect(10,10,100,100) ;

        //绘制一个渐变方块
        context.fillStyle = gradient ;
        context.fillRect(80,80,100,100) ;

    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值