小白入门---HTML5标签canvas

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();
})();
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值