HTML5中canvas使用

1、Canvas基础

1)  canvas类似于img标签(行内块),但是不能在css里设置宽高。
    它使用自身的width和height属性。但可以用css写其它东西
2)  页面中引入Canvas的方法
    <canvas id="canvas" width="500" height="500">
        您的浏览器不支持canvas,请升级最新版
    </canvas>
3)  基本的canvas的操作方法
    1> 获取元素  var canvas = document.getElementById("canvas");
    2> 获取上下文对象(画笔) var ctx = canvas.getContext("2d");
        console.log(ctx);//CanvasRenderingContext2D对象
    3> 基本的绘制步骤
        1.开始绘制 ctx.beginPath();
        2.绘制起点 ,通常只写一次  ctx.moveTo(x,y);
        3.绘制后续的点 ,可写多次  ctx.lineTo(x,y);
        4.结束绘制/关闭路径,会把终点 和 起点 链接起来,进行绘制
          当需要终点 和 起点链接起来的时候才使用,需要才写
          ctx.closePath();
        5.画(填)  先设置 后画 填充  注意先后顺序
          绘制的线和填充的内容会发生覆盖的情况,没有优先级,
          由代码的书写顺序绝对(后面的会覆盖前面的设置)
          ctx.stroke();//画
          ctx.fill();//填  如果填的时候,没有ctx.closePath() 则会由起点填充到终点

2、Canvas画直线

1)填充
    ctx.beginPath();
    ctx.moveTo(100,100);
    ctx.lineTo(400,400);
    ctx.lineTo(100,400);
    ctx.closePath();
    ctx.fillStyle = "green";//换填充的颜色
    ctx.globalAlpha = 0.5; //全局透明度
    ctx.fill();
2)描边
    ctx.beginPath();
    ctx.moveTo(100,100);
    ctx.lineTo(400,400);
    ctx.closePath();
    ctx.strokeStyle = "red" //设置画线颜色
    ctx.lineWidth = 10; //设置线宽  里外同时扩散
    ctx.stroke();//画
3)其它属性
    ctx.lineWidth  线宽
    lineCap = "round"; 线末尾的形状 不需要ctx.closePath()
    lineJoin = "round"; 两条边交汇时,创建圆角边,需要ctx.closePath()

3、Canvas画矩形

1)画矩形:
        fillRect(x,y,width,height)  按照矩形填充
        strokeRect(x,y,width,height)  按照矩形画线

2)示例:
    //矩形
    // ctx.beginPath();
    // ctx.strokeStyle = "blue";
    // ctx.strokeRect(0,400,100,50);
    // ctx.stroke();

    //正方形
    // ctx.beginPath();
    // ctx.fillStyle = "pink";
    // ctx.fillRect(0,0,100,100);
    // ctx.fill();

    //画多个图形
    // for(var i = 0; i < 500; i+=10){
    //    var x = 10,y = 10,w=50,h=50;
    //    ctx.strokeStyle = randomColor();
    //    ctx.strokeRect(x+i,y+i,w,h);
    // }

4、Canvas画文字

1)画文字
    空心  ctx.strokeText(text,x,y,maxWidth?);
    实心  ctx.fillText(text,x,y,maxWidth?);
    参数1:要显示的文本信息
    参数2,3文字在画布上显示的位置
    参数4:可选参数,设置文本的最大显示宽度,文本不会超出该宽度

2)文字的对齐方式
    ctx.textAlign("left/center/right"); 水平方向
    ctx.textBaseline("top/middle/bottom/baseline"); 垂直方向

3)字体大小和样式
    ctx.font = "50px 宋体";

5、Canvas画圆

1)绘制圆形 ctx.arc(x,y,r,start,end,dir);
    //参数1:圆心的x
    //参数2:圆心的y
    //参数3:圆的半径
    //参数4:起始点的位置,根据右侧和设置的弧度找到起点
    //参数5:终点的位置,根据右侧和设置的弧度找到终点
    //参数6:绘制的方向 true代表逆时针,false代表顺时针

2)绘制同心圆  半径由大到小 让小得覆盖大的
    for(var i = 250; i > 20; i-=20){
        ctx.beginPath();
        ctx.strokeStyle = randomColor();
        // ctx.fillStyle = randomColor();
        ctx.arc(250,250,i,0,Math.PI*2,false);
        ctx.stroke();
        // ctx.fill();
    }

3)绘制笑脸的几种方法
    1>一般常规画法
        ctx.arc(250,250,200,0,Math.PI*2,false);
        ctx.stroke();
        ctx.beginPath();
        ctx.arc(200,200,30,0,Math.PI*2,false);
        ctx.stroke();
        ctx.beginPath();
        ctx.arc(300,200,30,0,Math.PI*2,false);
        ctx.stroke();
        ctx.beginPath();
        ctx.arc(250,270,100,0,Math.PI,false);
        ctx.closePath();
        ctx.stroke();
    2>封装函数思想
        function draw(x,y,r,start,end,dir){
            ctx.beginPath();
            ctx.arc(x,y,r,start,end,dir);
            ctx.closePath();
            ctx.stroke();
        }
        //调用函数
        draw(250,250,200,0,Math.PI*2,false);
        draw(200,200,30,0,Math.PI*2,false);
        draw(300,200,30,0,Math.PI*2,false);
        draw(250,270,100,0,Math.PI,false);
    3>面向对象思想  初级 和封装函数没什么不同
        var smileArr = [
            {x:250,y:250,r:200,end:Math.PI*2},
            {x:200,y:200,r:30,end:Math.PI*2},
            {x:300,y:200,r:30,end:Math.PI*2},
            {x:250,y:270,r:100,end:Math.PI}
        ];
        for(var i = 0; i < smileArr.length; i++){
            ctx.beginPath();
            ctx.arc(smileArr[i].x,smileArr[i].y,smileArr[i].r,0,smileArr[i].end,false);
            ctx.closePath();
            ctx.stroke();
        }
    4>面向对象思想  中级
        function Area(x,y,r,start,end,dir){
            this.x=x;
            this.y=y;
            this.r=r;
            this.start=start;
            this.end=end;
            this.dir=dir;
        }
        //添加原型方法
        Area.prototype.draw = function(){
            ctx.beginPath();
            ctx.arc(this.x,this.y,this.r,this.start,this.end,this.dir);
            ctx.closePath();
            ctx.stroke();
        }
        //创建实例化对象
        var bigCircle = new Area(250,250,200,0,Math.PI*2,false);
        var leftEyes = new Area(200,200,30,0,Math.PI*2,false);
        var rightEyes = new Area(300,200,30,0,Math.PI*2,false);
        var mouth = new Area(250,270,100,0,Math.PI,false);
        //调用原型的方法
        bigCircle.draw();
        leftEyes.draw();
        rightEyes.draw();
        mouth.draw();
    5>面向对象思想  高级
        function Area(x,y,r,start,end,dir){
            this.x=x;
            this.y=y;
            this.r=r;
            this.start=start;
            this.end=end;
            this.dir=dir;
        }
        Area.prototype.draw = function(){
            ctx.beginPath();
            ctx.arc(this.x,this.y,this.r,this.start,this.end,this.dir);
            ctx.closePath();
            ctx.stroke();
        }
        // 数据
        var smileArr = [
            {x:250,y:250,r:200,end:Math.PI*2},
            {x:200,y:200,r:30,end:Math.PI*2},
            {x:300,y:200,r:30,end:Math.PI*2},
            {x:250,y:270,r:100,end:Math.PI}
        ];
        for(var item of smileArr){
            var obj = new Area(item.x,item.y,item.r,0,item.end,false);
            obj.draw();
        }

6、Canvas画曲线

1)画曲线
    ctx.quadraticCurveTo(x2,y2,x3,y3);//二次贝塞尔曲线   一对基准点  一对终点
    ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);//三次贝塞尔曲线 两对基准点 一对终点
2)示例
    1> 二次贝塞尔曲线
        ctx.moveTo(0,0);//绘制起点
        ctx.quadraticCurveTo(250,500,500,0);
        ctx.stroke();

        ctx.moveTo(0,0);//绘制起点
        ctx.quadraticCurveTo(500,250,0,500);
        ctx.stroke();

        ctx.moveTo(0,500);
        ctx.quadraticCurveTo(250,0,500,500);
        ctx.stroke();

        // ctx.beginPath();
        ctx.moveTo(500,0);
        ctx.quadraticCurveTo(0,250,500,500);
        ctx.stroke();
        // ctx.fill();

    2> 三次贝塞尔曲线
        ctx.beginPath();
        ctx.strokeStyle="orange";
        ctx.moveTo(0,0);//绘制起点
        ctx.bezierCurveTo(500,0,0,500,500,500);
        ctx.stroke();
        //这里上下两条线是重合的
        // ctx.beginPath();
        // ctx.strokeStyle="purple";
        // ctx.moveTo(500,500);//绘制起点
        // ctx.bezierCurveTo(0,500,500,0,0,0);
        // ctx.stroke();

        //----------------------------------------
        
        ctx.beginPath();
        ctx.strokeStyle="red";
        ctx.moveTo(500,0);//绘制起点
        ctx.bezierCurveTo(0,0,500,500,0,500);
        ctx.stroke();
        //这里上下两条线是重合的
        // ctx.beginPath();
        // ctx.strokeStyle="hotpink";
        // ctx.moveTo(0,500);//绘制起点
        // ctx.bezierCurveTo(500,500,0,0,500,0);
        // ctx.stroke();

        //--------------------------------

        ctx.beginPath();
        ctx.strokeStyle="green";
        ctx.moveTo(0,500);//绘制起点
        ctx.bezierCurveTo(0,0,500,500,500,0);
        ctx.stroke();
        //这里上下两条线是重合的
        // ctx.beginPath();
        // ctx.strokeStyle="pink";
        // ctx.moveTo(500,0);//绘制起点
        // ctx.bezierCurveTo(500,500,0,0,0,500);
        // ctx.stroke();

        //--------------------------------

        ctx.beginPath();
        ctx.strokeStyle="blue";
        ctx.moveTo(500,500);//绘制起点
        ctx.bezierCurveTo(500,0,0,500,0,0);
        ctx.stroke();
        //这里上下两条线是重合的
        // ctx.beginPath();
        // ctx.strokeStyle="red";
        // ctx.moveTo(0,0);//绘制起点
        // ctx.bezierCurveTo(0,500,500,0,500,500);
        // ctx.stroke();

3)用二次贝塞尔曲线可以大致实现三次贝塞尔曲线的效果
    例如:
        //三次
        ctx.beginPath();
        ctx.strokeStyle="pink";
        ctx.moveTo(500,0);//绘制起点
        ctx.bezierCurveTo(500,500,0,0,0,500);
        ctx.stroke();

        //二次
        ctx.moveTo(500,0);
        ctx.quadraticCurveTo(500,250,250,250);
        ctx.stroke();

        ctx.beginPath();
        ctx.moveTo(250,250);
        ctx.quadraticCurveTo(0,250,0,500);
        ctx.stroke();

4)利用Canvas曲线的画法,可以画出肯定不合常规的图形
    例如:心、不规则三角形、太极等
        //画心
            ctx.fillStyle="red";
            ctx.moveTo(250,200);
            ctx.quadraticCurveTo(0,50,250,450);
            ctx.fill();

            ctx.beginPath();
            ctx.moveTo(250,200);
            ctx.quadraticCurveTo(500,50,250,450);
            ctx.fill();

7、Canvas画图片

1)画图片  ctx.drawImage(img,x,y,w,h,dx,dy,dw,dh);
        img为要画的图片
        img后紧邻的四个值是在canvas中的位置,以及显示图片的宽高
        最后面四个值是寻找的图片中具体想显示的区域
        
2)示例
    如果想把图片画到canvas中,需要先创建image对象
    var img  = new Image();
    img.src = "。。。。。";
    img.onload = function(){
        //必须等图片加载完成再去绘制
        ctx.drawImage(img,100,100,200,200,100,100,100,100);
        //清除画布  四个参数:x,y,w,h
        ctx.clearRect(250,250,200,200);//用户清除画布中已有的内容
        // ctx.clearRect(0,0,500,500); //清除整个画布的内容
    }

8、Canvas形变

1)平移 ctx.translate(x,y); 改变的是坐标系,不改变已经绘制好了的内容
2)缩放 ctx.scale(0.5,0.5); 位置以及原图大小都会改变,缩放时密度变大,缝隙变小
3)旋转 ctx.rotate(deg); 围绕画轴起点旋转,是整个画布的旋转

4)示例:
    //绘制表盘
    ctx.translate(250,250);
    for(var i = 0; i < 12; i++){
        ctx.rotate(Math.PI/6);
        ctx.beginPath();
        ctx.moveTo(0,-200);
        ctx.lineTo(0,-150);
        ctx.closePath();
        ctx.lineWidth = 10;
        ctx.stroke();
    }

9、Canvas阴影
ctx.shadowColor = "red"; 阴影颜色
ctx.shadowOffsetX = 10; 阴影X轴偏移量
ctx.shadowOffsetY = 10; 阴影y轴偏移量
ctx.shadowBlur = 10; 阴影的模糊程度

10、Canvas动画
原理: 搽除-绘制-搽除-绘制-搽除-绘制-。。。
使用setInterval();
setTimeout()实现setInterval()
requestAnimationFrame(); 帧动画

11、注意:
1)多个图形之间有连线时,是因为画笔没有抬起,解决方法是写上ctx.beginPath();
2)fill和stroke同时使用时会有覆盖效果,注意先后顺序
而且每个相对应的设置,都有先设置,再进行描边或者填充,
不然

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • 啥是canvas? HTML5 标签用于绘制图像(通过脚本,通常是 JavaScript)。不过, 元素本身...
    kiaizi阅读 761评论 0 4
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,674评论 2 32
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥ios动画全貌。在这里你可以看...
    每天刷两次牙阅读 8,471评论 6 30
  • 神奇且强大的canvas 一.Canvas的基本介绍 1.什么是Canvas 定义:是HTML5提供的一种新标签,...
    Ainy尘世繁花终凋落阅读 10,738评论 1 18
  • 在iOS中随处都可以看到绚丽的动画效果,实现这些动画的过程并不复杂,今天将带大家一窥iOS动画全貌。在这里你可以看...
    F麦子阅读 5,104评论 5 13