小白入门---HTML5标签canvas

来源:互联网 发布:直播视频美颜软件 编辑:程序博客网 时间:2024/06/05 09:02

HTML5标签canvas

1、canvas简介

1、canvas:
* >做游戏:白鹭引擎、trees…;
* >做动画;做动态图表,频谱;画图…
* HTML5不是单纯的html
* canvas本身是一个标签,是一个空白的画布,默认是300*150的宽高
* 本身有宽高的属性,不需要使用CSS去设置,如果非要设置,一定要和canvas的宽高设置相同,不然绘制出来的内容就是变形的
* 如果希望画布上有内容,需要通过JS来绘制->是通过画布的上下文(相当于舞台,舞台上面可以有各种移动,展示出来)进行绘制的

2、使用步骤:
* >1.创建一个空白画布
* >2.获得画布的上下文
* >3.绘制准备:设置要绘制的一些样式和内容(画笔的宽,颜色,所需的资源)
* >4.开始绘制

3、HTMLCanvasElement的2个属性:
* >width:宽;
* >height:高
* >lineWidth:设置笔画宽度

4、HTMLCanvasElement的方法:
* >getContext(inDOMString contextId),可以传2d或者experimental-webgl(图形图像处理)
* >toDataURL():把canvas对象转成url->生成带有绘制内容的一个资源链接地址
* >moveTo(x,y):抬起笔来要落到哪一个位置
* >lineTo(x,y):画线到某个点
* >stroke(不传||path):把画的内容绘制出来:path是2d类型的
* >beginPath():标识,要开始一个路径
* >closePath():标识,要闭合一个路径
* >clearRect():是 Canvas 2D API 设置指定矩形区域内(以 点 (x, y) 为起点,范围是(width, height) )所有像素变成透明,并擦除之前绘制的所有内容的方法。
* >canvas:获得画布的DOM元素;
* >lineCap:设置画笔结束位置的形状(butt:方形,round:圆形,square:线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域。)
* >CanvasRenderingContext2D.createLinearGradient()Canvas 2D API 的方法沿着由参数表示的坐标给出的线创建一个梯度。
* >CanvasRenderingContext2D.createRadialGradient()Canvas 2D API 的方法创建由参数表示的两个圆的坐标给出的径向渐变。此方法返回a CanvasGradient。
* >CanvasRenderingContext2D.arc(x<原点x坐标>,y<原点y坐标>,radius<半径>,startAngle<起始角度>,endAngle<结束角度>,anticlockwise<是否逆时针>):其在中心的路径(X,Y)与半径位置[R开始于由startAngle和在结束endAngle通过在给定的方向上行进逆时针(默认顺时针)。
* >CanvasRenderingContext2D.createLinearGradient()//创建一个渐变对象
* >CanvasRenderingContext2D.strokeText(text,x,y [,maxWidth]);Canvas 2D API 的方法在给定的(x,y)位置上触发给定的文本。如果提供了最大宽度的可选第四个参数,文本将被缩放以适应该宽度。
* >Scale(x,y):放大缩小,不会影响到画布本身,所放的是画布里面的内容(让画布里面的单位进行缩放)
* >Save():保存画布上面之前的样式,即在写save之前的样式,包括(笔画宽度,颜色,变形)
* >Restore():还原的是上一次保存的状态,多次retore也是返回上次保存的内容[1]->1.[1,2]->2,1
* >Translate():平移,以画布的原点为参考。也相当于重新设置原点。
* >Rotate(anglePI/180*角度):旋转,旋转中心点一直是 canvas 的起始点。并没有旋转canvas,旋转的是后续绘制在canvas上的图形。 如果想改变中心点,我们可以通过 translate() 方法移动 canvas 。

5、 CanvasGradient :设置canvas里免颜色渐变的类,可以通过设置颜色的方式(fillStyl/strokeStyle)去设置渐变对象
* 方法:
* >addColorStop(offset(0-1),color):这个方法可以多次调用添加渐变的颜色值

6、canvas里面的动画:
* >1.通过不断刷新canvas里面的内容,实现动画
* >2.清除上一次canvas里面的内容

2、基本方法使用方法

(function(){    var rectX=0;    var rectY=0;    var timer;    function init(){        //dom操作  HTMLElement        //canvas:HTMLCanvasElement        var canvasEle=document.querySelector("#box");        canvasEle.width=innerWidth;        canvasEle.height=innerHeight;           /*获得画布的上下文          * 返回一个 CanvasRenderingContext2D对象:提供了绘制,设置绘制内容的方法属性         * >fillStyle:设置填充的样式(充满)         * >storkeStyle:设置绘制内容轮廓的样式         * >fillRect(x,y,w,h):绘制矩形的方法,以填充的方式绘制,原点是画布的左上角         */        var context=canvasEle.getContext("2d");         //设置要绘制的参数//      context.fillStyle="red";        //设置绘制内容轮廓的样式//      context.strokeStyle="yellow";        //距离原点左上角100,边长为5050()的画布        //context.fillRect(100,100,50,50);        context.lineWidth=2;        /*context.moveTo(200,100);        context.lineTo(400,100);        context.moveTo(400,100);        context.lineTo(400,200);        context.moveTo(400,200);        context.lineTo(200,200);        context.moveTo(200,200);        context.lineTo(200,100);        context.stroke();*/        rectX=50;        rectY=30;        drawRect({            context:context,            strokeColor:"white",            fillColor:"orange",            x:50,            y:30,            width:100,            height:100          });        /*setTimeout(function(){            context.clearRect(0,0,innerWidth,innerHeight);        },3000);        rectControl(context);*/    }    //封装一个画矩形的方法    function drawRect(info){        if(!info){            console.log("必须传参数");            return;        }        info.context.strokeStyle=info.strokeColor;        info.context.fillStyle=info.fillColor;        info.context.beginPath();//是 Canvas 2D API 通过清空子路径列表开始一个新路径的方法。 当你想创建一个新的路径时,调用此方法。        info.context.moveTo(info.x,info.y);        info.context.lineTo(info.x+info.width,info.y);        info.context.lineTo(info.x+info.width,info.y+info.height);        info.context.lineTo(info.x,info.y+info.height);//      info.context.lineTo(info.x,info.y);        info.context.closePath();//是 Canvas 2D API 将笔点返回到当前子路径起始点的方法        info.context.fill();//是 Canvas 2D API 根据当前的填充样式,填充当前或已存在的路径的方法        info.context.stroke();           }       function rectControl(context){        document.onkeydown=function(event){//当按下wasd的时候执行不同的动画            var dis="";//          console.log(event);            switch(event.keyCode){                case 87:                    dis="top";                    break;                case 65:                    dis="left";                    break;                case 83:                    dis="bottom";                    break;                case 68:                    dis="right";                    break;                default:                    break;            }            move(context,dis);        };        document.onkeyup=function(){            clearInterval(timer);            timer=null;        }    }       function move(context,direction){        context.clearRect(1,1,innerWidth,innerHeight);//清除上一帧        var distance=5;        switch(direction){            case "left":                rectX-=distance;                break;            case "right":                rectX+=distance;                break;            case "top":                         rectY-=distance;                console.log(rectY)                break;            case "bottom":                rectY+=distance;                break;        }               drawRect({            context:context,            strokeColor:"white",            fillColor:"orange",            x:rectX,            y:rectY,            width:100,            height:100                      });          if(timer){return}//自己调用自己,如果有timer,就不要去创建,如果不写,每次都创建,定时器效果会叠加        timer=setInterval(function(){            move(context,direction);        },30)    }    init(); })();
(function(){    function init(){        /*var canvasEle=document.querySelector("#box");        canvasEle.width=innerWidth;        canvasEle.height=innerHeight;        window.onresize=function(){            cavnasEle.width=innerWidth;            canvasEle.height=innerHeight;        };        var context=canvasEle.getContext("2d");        var linearGradient=context.createLinearGradient(0,0,innerWidth,innerHeight);//创建线性渐变的方法->CanvasGradient类型的对象        linearGradient.addColorStop(0,"blue");        linearGradient.addColorStop(0.5,"white");        linearGradient.addColorStop(1,"green");        context.fillStyle=linearGradient;//添加颜色渐变        context.strokeStyle=linearGradient;        context.font="40px 华文楷体";        context.strokeText("你好",100,100);        context.fillText("你好",200,200);//      context.fillRect(0,0,innerWidth,innerHeight);*/    }    init();})();
(function(){    var context=document.getElementById("container").getContext("2d");    function scale(){        context.save();//保存上一次canvas里面的状态        context.scale(0.5,1);//先放大缩小才行,放大缩小的是画布里面的内容的像素点,画布本身没有变化        context.fillStyle="red";        context.fillRect(100,100,100,100);        context.restore();//还原上次保存的状态        context.save();        context.fillStyle="yellow";        context.fillRect(100,100,50,50)        context.restore();        context.fillRect(0,0,50,50)    }    function test(){        context.save();        context.strokeStyle="green";        context.lineWidth=5;        context.moveTo(0,0);        context.lineTo(300,50);        context.stroke();        context.restore();        context.moveTo(0,100);        context.lineTo(300,100);        context.stroke();}    function move(){        context.save();        context.translate(200,-100);//沿着x向右移动200px,沿着y向上一定100px,移动的时候是以原点为中心去移动的        context.fillRect(300,300,100,100);        context.restore();        context.fillStyle="yellow";        context.fillRect(300,300,50,50);    }    function rotation(){            context.rotate(2*Math.PI/360*45);//旋转45度        context.fillText("nhao",300,300)        context.fillRect(300,300,50,50);    }    function init(){        scale();        test();        move();        rotation();    }    init();})();

3、canvas具体实例

1.自制画板
》HTML部分

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title>painter</title>        <style type="text/css">            *{margin: 0;padding: 0;}                    html{overflow: hidden;}            #box{background-color: #242424;}            .toolMenu{position: absolute;}            .openButton{width: 50px;height: 50px;background-color: #ff3c1a;border-radius: 50%;}            .tool{background-color: yellow;}            .tool li{margin-top: 5px;}            a{text-decoration: none;background-color: #bebebe;width: 60px;text-align: center;display: block;}        </style>    </head>    <body>        <div class="toolMenu">            <div class="openButton"></div>            <ul class="tool">                <li>宽度<input type="range"/></li>                <li>颜色<input type="color"/></li>                <li><a class="download" download="photo">下载</a></li>                <li><a class="clear" herf="#">清屏</a></li>                <li><a class="eraser" herf="#">橡皮擦</a></li>            </ul>        </div>        <canvas id="box"></canvas>    <script src="js/painter.js" type="text/javascript" charset="utf-8"></script>    <script src="js/main.js" type="text/javascript" charset="utf-8"></script>    </body></html>

》painter.js:面向对象写法

(function(){    function Painter(id){        var canvasEle=document.getElementById(id);        canvasEle.width=innerWidth;        canvasEle.height=innerHeight;        this.context=canvasEle.getContext("2d");//      this.context.strokeStyle="white";        this.drawLine();        this.bgcolor=document.defaultView.getComputedStyle(canvasEle, null).backgroundColor;    }    Painter.prototype.drawLine=function(){        var self=this;        self.context.canvas.addEventListener("mousedown",startAction);        self.context.canvas.addEventListener("mouseup",endAction);        function startAction(event){            if(!self.isClear){//如果没有使用橡皮擦就是划线的功能                self.context.beginPath();                self.context.moveTo(event.pageX,event.pageY);                self.context.stroke();            }                   self.context.canvas.addEventListener("mousemove",moveAction);        }        function endAction(){            self.isClear=false;//不再使用橡皮擦的功能            self.context.canvas.removeEventListener("mousemove",moveAction);        }        function moveAction(event){            if(self.isClear){//移动的时候清除,-8的原因是要让他移动到中间                self.context.clearRect(event.pageX-8,event.pageY-8,16,16);                return;            }            self.context.lineTo(event.pageX,event.pageY);            self.context.stroke();        }    }    Painter.prototype.setLineWidth=function(width){        this.context.lineWidth=width;    }    Painter.prototype.isRoundLineCap=function(isRound){        this.context.lineCap=isRound?"round":"butt";    }    Painter.prototype.setLineColor=function(color){        this.context.strokeStyle=color;    }    Painter.prototype.save=function(){        return this.context.canvas.toDataURL();//吧绘制的内容保存成一个图片地址    }    Painter.prototype.clear=function(){        this.context.clearRect(0,0,innerWidth,innerHeight);    }/*  Painter.prototype.eraser=function(){        this.setLineColor(this.bgcolor);        this.drawLine();            }*/    Painter.prototype.rubber=function(){        this.isClear=true;          }    window.Painter=Painter;})();

》main.js调用过程:

(function(){    function init(){        var painter=new Painter("box");        painter.setLineWidth(5);        painter.isRoundLineCap(true);        painter.setLineColor("red");        var toolView=document.querySelector(".tool")        document.querySelector(".openButton").onclick=function(){           toolView.style.display=toolView.style.display==="block"?"none":"block";        };      document.querySelector("input[type=range]").value=painter.context.lineWidth*2;        document.querySelector("input[type=range]").onchange=function(){            painter.setLineWidth(this.value/4);        };      document.querySelector("input[type=color]").value=painter.context.strokeStyle;        document.querySelector("input[type=color]").onchange=function(){            painter.setLineColor(this.value);        };        var download=document.querySelector(".download");        download.onclick=function(){            download.setAttribute("href",painter.save());        };        document.querySelector(".clear").onclick=function(){            painter.clear();        };        var eraser=document.querySelector(".eraser");        /*eraser.onclick=function(){                eraser.innerHTML=eraser.innerHTML==="橡皮擦"?"停止":"橡皮擦";            if(eraser.innerHTML=="停止"){                document.body.style.cursor="url(img/eraser.png),pointer";                painter.eraser();            }else{                document.body.style.cursor="";              painter.setLineColor(document.querySelector("input[type=color]").value)                painter.drawLine()            }                   };*/        eraser.onclick=function(){            painter.rubber();        }    }    init();})();

2、制作动态柱状图
》使用面向对象直接创建表格

(function(){    /*1.封装表格的背景     *2.绘制带文字小方块     * datas是传过来的需要可视化的数据     */    function Table(superEle,datas){        this.canvasContext=document.createElement("canvas").getContext("2d");//创建canvas对象        superEle.appendChild(this.canvasContext.canvas);//添加到父元素中        this.width=this.canvasContext.canvas.width=innerWidth;//设置宽        this.height=this.canvasContext.canvas.height=innerHeight;//设置高        this.datas=datas||[];        this.background();        this.addRect();    }    Table.prototype.background=function(){        this.canvasContext.beginPath();        this.canvasContext.strokeStyle="black";        var space=10;        this.canvasContext.strokeRect(space,space,this.width-space*2,this.height-space*2);//绘制矩形,边距留白        var lineHeight=(this.height-space*2)/10;        for(var i=1;i<10;i++){//绘制背景的9根线            this.canvasContext.moveTo(space,space+lineHeight*i);            this.canvasContext.lineTo(this.width-space,space+lineHeight*i);            this.canvasContext.stroke();        }    }    Table.prototype.addRect=function(){        var gradient=this.canvasContext.createLinearGradient(0,0,0,this.height);        gradient.addColorStop(0,"red");        gradient.addColorStop(1,"green");        this.canvasContext.fillStyle=gradient;        //宽度间距        var rectWidth=this.width-10*2;//总宽度        var rectHeight=this.height-10*2;//总高度        var space=rectWidth/this.datas.length/5;        var width=(rectWidth-space*(this.datas.length+1))/this.datas.length;        var max=1000;        var heightScale=rectHeight/max;//计算比例        for (var i=0;i<this.datas.length;i++) {            var height=this.datas[i]*heightScale;            var y=this.height-10-height;//总宽度-边距-小方块宽度            this.canvasContext.fillRect(space+(space+width)*i+10,y,width,height);        }    }    Table.prototype.setDatas=function(datas){        this.datas=datas;        this.canvasContext.clearRect(0,0,innerWidth,innerHeight);//清除上一次的内容然后再新建        this.background();        this.addRect();    }    window.Table=Table;})();

》调用创建的表格

var table=new Table(document.body,[33,200,500,90,100,800,770,1000,560]);                setInterval(function(){            var datas=[];            for (var i=0;i<10;i++) {                datas.push(Math.random()*1000);//随机创建数组            }            table.setDatas(datas);//将新的数据传入到table中        },1000*Math.random()*4);

3、绘制太极图和调试贝塞尔曲线
》HTML部分

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title></title>        <style type="text/css">            html{overflow: hidden;}            *{margin: 0;padding: 0;}            #box{background-color: #242424;}            div{                width: 20px;                height: 20px;                background-color: white;                border-radius: 50%;                 position: absolute;                left: 100px;                top: 200px;                text-align: center;                line-height: 20px;            }        </style>    </head>    <body>        <canvas id="box"></canvas>        <div class="startPoint">b</div>        <div class="endPoint">e</div>        <div class="Point1">1</div>        <div class="Point2">2</div>        <script src="js/circle.js" type="text/javascript" charset="utf-8"></script>    </body></html>

》具体的js代码:

(function(){    var curEle=null;    var startPoint=document.querySelector(".startPoint");    var endPoint=document.querySelector(".endPoint");    var Point1=document.querySelector(".Point1");    var Point2=document.querySelector(".Point2");    var context=null;    function init(){        var canvasEle=document.querySelector("#box");        canvasEle.width=innerWidth;        canvasEle.height=innerHeight;        window.onresize=function(){            canvasEle.width=innerWidth;            canvasEle.height=innerHeight;        };        context=canvasEle.getContext("2d");        context.strokeStyle="white";        context.lineWidth=10;        //x,y,radius,startAngle,endAngle,anticlockwise(默认逆时针)        /*context.beginPath();        context.arc(500,300,200,0,Math.PI*2,true);        context.stroke();        context.beginPath();        context.arc(600,300,100,0,Math.PI,true);        context.stroke();        context.beginPath();        context.arc(400,300,100,0,Math.PI,false);        context.stroke();        context.beginPath();        context.moveTo(300,300);        context.bezierCurveTo(500,400,200,400,600,600);        context.stroke();*/             for(var i=0;i<4;i++){//循环给每个元素添加事件            addEvent([startPoint,endPoint,Point1,Point2][i]);        }        document.ondblclick=function(){            document.removeEventListener("mousemove",move)        };          }    function addEvent(ele){            ele.onmousedown=function(){                curEle=this;                document.addEventListener("mousemove",move)            };        }    function move(event){            curEle.style.left=event.pageX+"px";            curEle.style.top=event.pageY+"px";            context.clearRect(0,0,innerWidth,innerWidth);            context.beginPath();            context.moveTo(getLeft(startPoint),getTop(startPoint));            context.bezierCurveTo(getLeft(Point1),getTop(Point1),getLeft(Point2),getTop(Point2),getLeft(endPoint),getTop(endPoint));            context.stroke();       }    function getLeft(ele){        return parseInt(ele.style.left)    }    function getTop(ele){        return parseInt(ele.style.top)    }       init();})();