H5之画布canvas小记,以及通过画布实现原子无规则运动

我们知道html在h5出之前就仅仅只是一个标签,一个标记,语义化并不强,后来新增的标签如video,audio都是语义化更强(让人一看就懂是什么东西,反正我是这么理解的,一个div不代表着什么),本身自带功能的标签(这个功能别问我怎么弄出来的,是浏览器自身内核渲染出来的),就一句话,这个标签就有这样的功能,当然需要定制化外观或功能也可以自己写。而画布其实也一样。简单的理解就是一张布,一张一尘不染的布,等待各位奋笔挥毫。

画布很简单就是一个标签<canvas></canvas>;

一、那首先画布能干什么呢?

       这里先说下自然界一切的图形外观其实都是由最最简单的点线矩形三角等等基本的东西组成的,很多看似很复杂的图形其实都是由这些基本图形通过平移、旋转、缩放等等实现的,h5也不例外。

h5的画布能做的东西其实你可以想象成一只笔,而且这只笔只能画几个基本图形,包括什么呢?

1、圆形,点,弧度

    一个基本例子:cxt.arc(x,y,r,0,Math.PI*2,true);  

    对应的是这个圆的圆形x,y坐标,r半径,起始角,结束角,顺或逆时针,true是逆时针,起始角0度在X轴正方向。(详细点可以看这个图)

写个简单的例子:(画一个最最简单的圆)

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");         //这部分后面说明,没什么,画布画东西都需要的,设置基础环境,跟我们基础设施一样,要打电话发短信得有基站,要坐地铁得有轨道等等     
cxt.fillStyle="#FF0000"; //填充的颜色 cxt.beginPath(); //开始画,开始路径
cxt.arc(70,18,15,0,Math.PI*2,true); //上面讲的核心,设置圆的各项属性,只有这里才是核心,其他都是没啥意思的
cxt.closePath(); //关闭路径,这些后面细说 cxt.fill(); //画完的填充方式:fill很明显就是充满填满,还有空心圆的cxt.strock();后面你会发现不少都会用到,这里就先说到这

2、矩形,填充

    基本的形式:

              空矩形:ctx.strokeRect(20,20,150,100);

              被填充的矩形:cxt.fillRect(0,0,150,75);

    没什么好说的,无非就是矩形原点(记住了是左上角的点)坐标,长跟宽而已。

    接下来重要的事情说三遍,核心、核心、核心。这里就仅仅是核心的那一句,其他的呵呵,我肯定不会告诉你上面有个很类似的了。

3、线条、路径

    基本的形式:

       cxt.moveTo(10,10);  //从哪个点移动

       cxt.lineTo(150,50);  //画线到哪个点

       cxt.lineTo(10,50);

       cxt.stroke(); //实际的把线给画出来,默认颜色是黑色,可以理解成一个play或是run,前面的只是定义,这个才是根据定义实实际际的画出来。

上面这些都只是画布核心,需要画的图形。

但是单独只是把画布选择出来然后直接写这些的话,是画不出任何东西的,为什么呢?首先你没有定义要在怎样的环境下画,即画布本身,接下来还下指令让画布开始画以及什么时候结束画。

具体如下:

同样以画线条为例:

var c=document.getElementById("myCanvas"); //常规的js选择,用jq也可以且更方便些,兼容性也好一些 var ctx=c.getContext("2d"); //把画布设置成一个二维的环境,这里你可能会问是不是可以设置成3d,很遗憾,目前canvas还不可以 ctx.beginPath(); //开始画了,这里虽然是开始路径的意思,但无论画弧画线画其他都是要的 ctx.moveTo(20,20); ctx.lineTo(20,100); //画第2根线 ctx.lineTo(70,100); //画第2根线,这里画多少根线看你需求,你构思中需要画几根、怎么画都在这。 ctx.strokeStyle="green"; //设置线条的颜色,这里设置属性的后面再说
ctx.stroke(); //线条实际画出来

 4、渐变   

首先渐变你可以理解成一个矩形,也可以理解成一个路径,它的意思是从某种颜色(或是透明度,主要是颜色吧)渐渐的过渡到另一种颜色。

基本的形式:   (一些是画布基本设置,为了方便我就不分开了)

var c=document.getElementById("myCanvas");  
var cxt=c.getContext("2d");//呐,这是公共的,画布要画东西都需要这个,即设置画布环境
cxt.createLinearGradient(0,0,175,50);   //设置线性渐变
grd.addColorStop(0,"#FF0000"); //颜色1
grd.addColorStop(1,"#00FF00"); //颜色2
cxt.fillStyle=grd; //告诉画布填充的类型

 

5、插入图片

这个没想到吧?呵呵,没错画布不止是我们自己画,也可以把别人已经画好的引用到我们的画里面,当然这个别人画好的不是画,是图片,照片也是OK的,只要html能解析的图片格式,都可以。

那具体是怎样的格式呢?(跟上面的一样,我把基本格式先贴一下)

var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");
var img=new Image()            
img.src="flower.png"     
cxt.drawImage(img,0,0);  //这里说下,插入的图片,放的x坐标,y坐标

这个呢?其实跟我们写html引入网页原理是一样的,都只是引入一个链接,这个链接直指数据库里某一张图片。相信各位看到src都有种亲切感吧= =

二、好了,画布能干什么,基本都在上面了,接下来先做个小总结,我把各个核心属性稍微总结一下:

cxt=c.getContext("2d"); 设置画布为2d环境,目前还没有3d,当然你也可以教教我3d的画要怎么画,美术不好= =

画线:
moveTo(0,0):从什么开始移动,开始画线条
lineTo(x,y):把线条要画到哪里,这两个基本都是成对出现的,但lineTo也有moveTo的属性,就是当你用lineTo画到终点时,这个终点也可以当成下个lineTo的起点,所以一个moveTo可以对应一个lineTo

画圆:cxt.arc(x,y,r,0,Math.PI*2,true);  不细说了,触类旁通

画矩形:

              空矩形:ctx.strokeRect(20,20,150,100);

              被填充的矩形:cxt.fillRect(0,0,150,75);

   画渐变:

createLinearGradient(x,y,l,h): 定义线性渐变
grd.addColorStop(0,"#FF0000"); 渐变色
grd.addColorStop(1,"#00FF00");
插入图:
var img=new Image();            
img.src="flower.png";
drawImage(img,0,0):画布插入图片

其他:

fillstyle:填充类型  可以是颜色也可以是渐变

填充方式:

ctx.stroke(); 空心填充,无论圆,矩形等等填充的都是空心的

ctx.fill(); 实心填充

画布基础环境:

var cxt=c.getContext("2d");设置画布基础环境为二维的。

三、啰嗦了这么多,没有实干怎么行呢?嘿嘿,自己捣鼓了一个程序,叫做自由自在的小球球,具体代码如下:最后啰嗦下,画布各项属性都是靠js代码来设置的,主体就一个canvas标签。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>canvasDemo1</title>
    <style>
        html,body,canvas{margin:0;padding:0}
        body{overflow:hidden}
    </style>
    <script>
        window.onload=function(){

            (function canvas1(){

                var oCanvas=document.getElementsByTagName('canvas')[0];
                var ctx=oCanvas.getContext('2d');
                var colorArr=["#E08031","#199475","#99CC99","#09C","#096"];
                var x,y,r,xr,yr,d;
                var loveArr=[];
                var w=window.innerWidth;
                var h=window.innerHeight;
                oCanvas.width=w;
                oCanvas.height=h;
                function random(min,max){
                    return Math.random()*(max-min)+min;   //数学上的random()是返回一个比例值
                }
                function Love(){}
                Love.prototype={
                    init:function(){
                        //这4个是基础定义,设置球初始坐标,初始大小及颜色
                        this.r=random(10,15);
                        this.x=random(this.r,w-this.r);
                        this.y=random(this.r,h-this.r);
                        this.color=colorArr[Math.floor(random(0,5))];
                        //设置球移动的速率
                        this.xr=random(-5,5);
                        this.yr=random(-5,5);
                    },
                    draw:function(){ //画布基本操作,这里是画一个小球
                        ctx.beginPath();
                        ctx.arc(this.x,this.y,this.r,0,Math.PI*2);
                        ctx.fillStyle=this.color;
                        ctx.fill();
                    },
                    move:function(){   //小球移动
                        this.x+=this.xr;
                        this.y+=this.yr;
                        (this.x+this.r>=w||this.x-this.r<=0)?this.xr=-this.xr:null; //边缘碰撞判定
                        (this.y+this.r>=h||this.y-this.r<=0)?this.yr=-this.yr:null;
                        this.draw();
                    }
                };
                function create(){   //画小球
                    var bubble=new Love();
                    bubble.init();
                    bubble.draw();
                    loveArr.push(bubble);//把每个小球对象存进数组里面
                }

                for(var i=0;i<50;i++){  //一次性画50个,修改画布上的小球数目也从这里效果修改
                        create();
                    }

                var time=setInterval(function(){
                    ctx.clearRect(0,0,w,h); //清空画布
                    for(var i=0;i<loveArr.length;i++){
                        loveArr[i].move();
                        //把之前存进数组的小球对象数据一个个拿出了(遍历),并做了一个预先设计好的位移
                    }
                },1000/60);
                oCanvas.onclick=function(){
                    clearInterval(time);
                }

            })();

        }
    </script>
</head>
<body>
<canvas></canvas>
</body>
</html>
原文地址:https://www.cnblogs.com/dorseych/p/8634175.html