2017-04-25 canvas 学习笔记

canvas 绘制线条

  • 嵌入式不建议使用,会导致内部图片拉伸
<canvas id="canvas" width="900" height="600" style="border:1px solid #000;">xxxxx</canvas>
//获取 canvas 上下文
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//2.绘制
    //绘制第一条直线
    //ctx.beginPath();

    //起点
    ctx.moveTo(100, 100);

    //终点
    ctx.lineTo(300, 100);
    //注意点:之前的操作,都是描述路径,不没有进行绘制

    //线宽
    ctx.lineWidth = 10;
    //颜色
    ctx.strokeStyle = 'red';

    //描边
    ctx.stroke();

    //3.画竖线
    //开启路径
    //作用:beginPath() 将当前路径和上一条路径隔离, 方便进行样式的设置和管理
    ctx.beginPath();

    //起点
    ctx.moveTo(200, 50);
    //终点
    ctx.lineTo(200, 350);

    //画斜线
    ctx.lineTo(350, 450);

    //闭合路径
    //作用:将路径线头和线尾连接,闭合
    ctx.closePath();

    ctx.lineWidth = 4;
    ctx.strokeStyle = 'green';

    //描边
    ctx.stroke();

绘制表格背景

 //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.绘制背景
    //常量
    var margin = 10;//间距
    //行数
    var row = canvas.height / margin;
    //列数
    var col = canvas.width / margin;
    //遍历
    //横线
    for(var i = 0;i<row;i++) {
        //起点
        ctx.moveTo(0, i * margin);
        //终点
        ctx.lineTo(canvas.width, i * margin);
    }

    //竖线
    for(var i = 0;i<col;i++) {
        //起点
        ctx.moveTo(i * margin, 0);
        //终点
        ctx.lineTo(i * margin, canvas.height);
    }

    //线宽
    ctx.lineWidth = 0.5;
    //颜色
    ctx.strokeStyle = 'red';

    //描边
    ctx.stroke();

绘制表格

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.绘制背景

    //常量
    var margin = 10;//间距
    //行数
    var row = canvas.height / margin;
    //列数
    var col = canvas.width / margin;
    //遍历
    //横线
    for(var i = 0;i<row;i++) {
        //起点
        ctx.moveTo(0, i * margin);
        //终点
        ctx.lineTo(canvas.width, i * margin);
    }

    //竖线
    for(var i = 0;i<col;i++) {
        //起点
        ctx.moveTo(i * margin, 0);
        //终点
        ctx.lineTo(i * margin, canvas.height);
    }

    //线宽
    ctx.lineWidth = 0.5;
    //颜色
    ctx.strokeStyle = 'red';

    //描边
    ctx.stroke();

    //3.坐标轴
    //坐标轴的原点
    var x0 = 100;
    var y0 = 500;
    var maxWidth = 500;
    var maxHeight = 400;

    //开启路径
    ctx.beginPath();
    //横坐标
    //起点
    ctx.moveTo(x0, y0);
    //终点
    ctx.lineTo(x0 + maxWidth, y0);
    ctx.lineTo(x0 + maxWidth - margin, y0 - margin);
    //moveTo 作用:相当于将当前的画笔移动到指定点上
    ctx.moveTo(x0 + maxWidth, y0);
    ctx.lineTo(x0 + maxWidth - margin, y0 + margin);

    //纵坐标
    ctx.moveTo(x0, y0);
    ctx.lineTo(x0, y0 - maxHeight);

    ctx.lineTo(x0 - margin, y0 - maxHeight + margin);

    ctx.moveTo(x0, y0 - maxHeight);
    ctx.lineTo(x0 + margin, y0 - maxHeight + margin);

    //注意:第一条路径设置完样式后, 如果第二条路径不设置样式,会沿用第一条的样式
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'blue';

    //描边
    ctx.stroke();

    //4.折现
    //数据
    var data = [10, 30, 20, 60, 5, 40, 70];
    //比例
    var w = maxWidth / data.length; //根据数组等分
    var h = maxHeight /100;// 1:100

    //生成点
    var pointArr = [];
    for(var i = 0;i<data.length;i++)
    {
        pointArr.push({
            x:x0 + w * (i + 1),
            y:y0 - h * data[i]
        })
    }
    console.log(pointArr);

    //画折线
    ctx.beginPath();

    ctx.moveTo(x0, y0);
    for(var i = 0;i<pointArr.length;i++)
    {
        //确定终点
        ctx.lineTo(pointArr[i].x, pointArr[i].y);
    }

    ctx.lineWidth = 4;
    ctx.strokeStyle = 'green';

    ctx.stroke();

绘制矩形

   //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.绘制矩形一
 /*   ctx.rect(100, 100, 200, 100);

    //线宽
    ctx.lineWidth = 4;
    //颜色
    ctx.strokeStyle = 'red';

    //描边
    ctx.stroke();

    //填充色
    ctx.fillStyle = 'blue';

    //填充
    ctx.fill();*/


    //3.绘制矩形二
    //快速创建无填充矩形
    //作用: 快速的描述路径, 之后立即绘制
    //注意:一定要在绘制之前设置样式和线宽
   /* ctx.strokeStyle = 'red';
    ctx.lineWidth = 4;

    ctx.strokeRect(200, 200, 200, 100);*/

   //快速创建填充矩形
    ctx.fillStyle = 'blue';
    ctx.fillRect(200, 200, 200, 100);

绘制画板

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.监听鼠标点击
    canvas.onmousedown = function (e) {

        //画布清空
        //canvas.width = 900;
        //清除一块矩形区域
        ctx.clearRect(0,0, canvas.width,canvas.height);

        //开启路径
        ctx.beginPath();

        //起点
        ctx.moveTo(e.offsetX, e.offsetY);
        //3.监听鼠标移动
        canvas.onmousemove = function (e) {
            //终点
            ctx.lineTo(e.offsetX, e.offsetY);

            ctx.strokeStyle = 'orange';
            ctx.lineWidth = 4;

            //描边
            ctx.stroke();
        };

        //4.监听鼠标抬起
        canvas.onmouseup = function () {
            //取消事件
            canvas.onmousemove = null;
            canvas.onmouseup = null;
        }


    }

绘制弧线

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.画弧
    /*ctx.arc(200, 200, 100, 0, 90 *Math.PI/180);

    ctx.strokeStyle = 'red';
    ctx.lineWidth = 4;*/

    //逆时针画弧
    //counterclockwise:是否是逆时针。true是逆时针,false:顺时针(默认)
    ctx.arc(200, 200, 100, 0, 90 *Math.PI/180, true);
    ctx.strokeStyle = 'blue';
    ctx.lineWidth = 6;

    //描边
    ctx.stroke();

    //填充颜色
    ctx.fillStyle = 'green';
    ctx.fill();

非零正交原则

  • 填充时候判断,当正交数值为0时不绘制,与逆时针边线相交,正交数值-1,与顺时针边线相交,正交数值+1,非0时填充,为0时不填充

绘制奥运五环

 //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.第一个五环
    var colorArr = ['red', 'green','blue', 'black', 'yellow'];
    for(var i = 0;i< colorArr.length;i++)
    {
        //开启路径
        ctx.beginPath();
        ctx.arc((i +1) * 100, 100, 80, 0, 2*Math.PI);
        ctx.strokeStyle = colorArr[i];
        ctx.lineWidth = 4;
        ctx.stroke();
    }

    //第二个五环
    for(var i = 0;i<colorArr.length;i++)
    {
        //开启路径
        ctx.beginPath();
        if (i < 3){// 0, 1, 2
            ctx.arc((i +1) * 100, 300, 80, 0, 2*Math.PI);
        }else { //3, 4
            ctx.arc((i - 2) * 100 + 40, 300 + 80, 80, 0, 2*Math.PI)
        }


        ctx.strokeStyle = colorArr[i];
        ctx.lineWidth = 4;
        ctx.stroke();

    }

绘制饼状图

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.数据
    var data = [
        {name:'北京', color:'yellow', value:0.3},
        {name:'上海', color:'red', value:0.2},
        {name:'杭州', color:'green', value:0.1},
        {name:'深圳', color:'blue', value:0.15},
        {name:'广州', color:'pink', value:0.25}
    ];

    //3.常量
    //圆心
    var x0 = canvas.width * 0.5;
    var y0 = canvas.height * 0.5;
    //半径
    var radius = 150;
    //开始角度
    var beginAngle = -90 *Math.PI/180;

    //4.绘制饼状图
    for(var i = 0;i<data.length;i++)
    {
        //4.1开启路径
        ctx.beginPath();
        //4.2确定起点
        ctx.moveTo(x0,  y0);

        //4.3计算扇形角度
        var tempAngle = data[i].value *360 *Math.PI/180;
        //4.4计算每个扇形结束角度
        var endAngle = beginAngle + tempAngle;
        //4.5 画弧
        ctx.arc(x0,y0, radius, beginAngle,endAngle);
        //4.6设置扇形颜色
        ctx.fillStyle = data[i].color;
        //4.7填充
        ctx.fill();

        //根据结束角度更新起始角度,作为下一个扇形的起始角度
        beginAngle = endAngle;
    }

绘制文字

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');


    //2.绘制文字
    ctx.font = "100px '微软雅黑'";
    ctx.strokeStyle = 'blue';

    //绘制无填充文字
    ctx.strokeText('SeeMyGo', 200, 200);

    //填充文字颜色
    ctx.fillStyle = 'purple';
    //绘制填充的文字
    ctx.fillText('SeeMyGo', 200, 200);

    //3.文字对齐
    //注意:默认系统会给文字添加一条看不见的基线,只有对文字对齐方式修改,就是根据基线设置
    //开启路径
    ctx.beginPath();

    ctx.strokeStyle = 'red';
    ctx.lineWidth = 4;

    //3.1 垂直对齐方式
//    ctx.textAlign = 'center';

    //3.2 水平方向的对齐方式
//    ctx.textBaseline = 'top';

    //4.文字阴影
    //阴影模糊范围
    ctx.shadowBlur = 15;

    //阴影的颜色
    ctx.shadowColor = 'blue';
    //偏移
    ctx.shadowOffsetX = 15;
    ctx.shadowOffsetY = 15;

    //绘制第二个文字
    ctx.strokeText('Html5', 200, 350);
    ctx.fillText('Html5', 200, 350);

给饼状图添加文字

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.数据
    var data = [
        {name:'北京', color:'yellow', value:0.3},
        {name:'上海', color:'red', value:0.2},
        {name:'杭州', color:'green', value:0.1},
        {name:'深圳', color:'blue', value:0.15},
        {name:'广州', color:'pink', value:0.25}
    ];

    //3.常量
    //圆心
    var x0 = canvas.width * 0.5;
    var y0 = canvas.height * 0.5;
    //半径
    var radius = 150;
    //开始角度
    var beginAngle = -90 *Math.PI/180;

    //4.绘制饼状图
    for(var i = 0;i<data.length;i++)
    {
        //4.1开启路径
        ctx.beginPath();
        //4.2确定起点
        ctx.moveTo(x0,  y0);

        //4.3计算扇形角度
        var tempAngle = data[i].value *360 *Math.PI/180;
        //4.4计算每个扇形结束角度
        var endAngle = beginAngle + tempAngle;
        //4.5 画弧
        ctx.arc(x0,y0, radius, beginAngle,endAngle);
        //4.6设置扇形颜色
        ctx.fillStyle = data[i].color;
        //4.7填充
        ctx.fill();

        //5.绘制文字
        //文字角度
        var textAngle = beginAngle + tempAngle * 0.5;
        //计算文字左上角坐标
        var textX = x0 + (radius + 30) * Math.cos(textAngle);
        var textY = y0 + (radius + 30) * Math.sin(textAngle);
        //文字内容
        var text = data[i].name + data[i].value * 100 + '%';

        //文字字号调整
        ctx.font = "15px '微软雅黑'";

        //左边文字处理
        if ((textAngle > 90 *Math.PI/180) && (textAngle < 270 * Math.PI/180)){
            ctx.textAlign = 'end';
        }

        //绘制文字
        ctx.fillText(text, textX, textY);

        //根据结束角度更新起始角度,作为下一个扇形的起始角度
        beginAngle = endAngle;
    }

绘制图片

  //1.获取canvas和上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //2.标签绘制-方式一
    /*var img = document.getElementById('icon');
    //注意:图片的绘制,一定要在加载完后绘制
    img.onload = function () {
        ctx.drawImage(img, 200, 200);
    }*/

    //3.对象绘制-方式二
    /*var img = new Image();
    img.src = 'images/img_01.jpg';
    //加载完后绘制图片
    img.onload = function () {
        ctx.drawImage(this, 200, 200);
    }*/

    //4.等比例绘制图片-方式三
  /*  var img = new Image();
    img.src = 'images/img_02.jpg';
    //加载完后绘制图片
    //等比公式
    // 设定高/ 设定宽 = 图片高度 / 图片宽度;
    // 设定高  = 图片高度 / 图片宽度 * 设定宽;
    var w = 200;
    img.onload = function () {
        //计算高度
        var h = img.height /img.width * w;
        ctx.drawImage(this, 200, 200, w, h);
    };*/

    //5.截取图片-方式四
    var img = new Image();
    img.src = 'images/img_01.jpg';

    img.addEventListener('load', function () {
        //img: 截取图片
        //50,50,120,120  截取的图片的x,y 和宽高
        //200, 200, 120,120 在画布上的x,y 和画布上显示的宽高
        ctx.drawImage(img, 50,50,120,120, 200, 200, 200,200);
    })

绘制帧动画

   //1.获取上下文
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');

    //常量
    var duration = 200;//定时器时间
    var imgClipWH = 256;//截取宽高
    var index = 0; //图片角标, x
    var dir = 0;//方向 , 默认为0,代表往左

    //2.图片对象
    var image = new Image();
    image.src = 'images/girl.png';
    //图片加载完后绘制
    image.addEventListener('load', function () {

        //备份指针
        var self = this;

        //开启定时器
        setInterval(function () {
            //清空
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            //截图
            ctx.drawImage(self, index * imgClipWH, dir * imgClipWH, imgClipWH, imgClipWH, 200,200,imgClipWH,imgClipWH);

            index++;
            //取模, 无限循环
            index %= 8;
        }, duration);

        //3.监听按钮点击
        var buttonList = document.querySelectorAll('button');
        console.log(buttonList);
        //遍历,添加事件
        for(var i = 0;i<buttonList.length;i++)
        {
            buttonList[i].addEventListener('click', function () {
                //获取方向属性的值
                dir = this.getAttribute('dir');
            })
        }


    })

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

推荐阅读更多精彩内容

  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    Looog阅读 3,941评论 3 40
  • 一:canvas简介 1.1什么是canvas? ①:canvas是HTML5提供的一种新标签 ②:HTML5 ...
    GreenHand1阅读 4,679评论 2 32
  • 神奇且强大的canvas 一.Canvas的基本介绍 1.什么是Canvas 定义:是HTML5提供的一种新标签,...
    Ainy尘世繁花终凋落阅读 10,746评论 1 18
  • 一、canvas简介 1.1 什么是canvas?(了解) 是HTML5提供的一种新标签 Canvas是一个矩形区...
    J_L_L阅读 1,516评论 0 4
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,092评论 4 62