第157天:canvas基础知识详解

目录

一、canvas简介 

1.1 什么是canvas?(了解) 

1.2 canvas主要应用的领域(了解) 

二、canvas绘图基础 

2.0 sublime配置canvas插件(推荐) 

2.1 Canvas标签 

2.1.1 canvas标签语法和属性 (重点) 

2.1.2 浏览器不兼容处理(重点) 

2.2 canvas绘图上下文context 6

2.2.1 ContextCanvas的上下文、绘制环境。(重点掌握) 

2.3 基本的绘制路径(重点) 

2.3.1 canvas坐标系 

2.3.2 设置绘制起点(moveTo) 

2.3.3 绘制直线(lineTo) 

2.3.4 路径开始和闭合 

2.3.5 描边(stroke) 

2.3.7 填充(fill) 

2.3.8 快速创建矩形rect()方法 

2.3.9 快速创建描边矩形和填充矩形 

2.3.10 清除矩形(clearRect) 

2.4 绘制圆形(arc) 

2.5 绘制文字(会使用就可以了) 

2.5.1 绘制上下文的文字属性 (有印象就行了) 

2.5.2 上下文绘制文字方法 

2.5.3 案例07文字绘制.html 

2.6 绘制图片(drawImage (重点) 

2.6.1 基本绘制图片的方式 

2.6.2 在画布上绘制图像,并规定图像的宽度和高度 

2.6.3 图片裁剪,并在画布上定位被剪切的部分 

2.6.4 JavaScript创建img对象 

2.6.5 面向对象基础复习补充: 

2.6.6 补充 sublime制作代码段(推荐--已结讲过了) 

三、 canvas进阶 

3.1 Canvas颜色样式和阴影 

3.1.1 设置填充和描边的颜色(掌握) 

3.1.2 设置阴影(了解,少用,性能差) 

3.2 复杂样式(了解) 

3.2.1 创建线性渐变的样式(了解) 

3.2.2 设置圆形渐变(径向渐变) (了解 )

3.2.3 绘制背景图(了解) 

3.3 变换(重点) 

3.3.1 缩放(重点) 

3.3.2 位移画布(重点) 

3.3.3 旋转(重点) 

3.3 绘制环境保存和还原(重要) 

3.4 设置绘制环境的透明度(了解) 

3.5 画布限定区域绘制(了解) 

3.6 画布保存base64编码内容(重要) 

3.7 画布渲染画布(重要) 

3.8 了解:线条样式(了解) 

3.9 了解贝塞尔曲线(知道有) 

3.9.1 绘制一条二次方曲线。 

3.9.2 绘制贝塞尔曲线(知道有) 

3.10了解创建两条切线的弧(知道有) 

3.11了解判断点是否在路径中(知道有) 

3.12了解文本宽度计算(知道有) 

3.13 如果以后做canvas游戏方向开发深入学习可以扩展内以下容: 

四、 Canvas开发库封装 

4.1封装常用的绘制函数 

4.1.1封装一个矩形 

4.2 第三方库使用 

五、Konva的使用快速上手 

5.1 Konva的整体理念 

5.2 Konva矩形案例 

5.2.1 创建一个矩形: Konva.Rect(option); 

5.3 Konva的动画系统 

5.3.1 tween对象(重点

5.3.2 动画to的使用 

5.3.3 Animate的应用 

5.3.4 循环播放动画的实现 

5.3.5 回放且循环播放动画 

5.3.6 进度条案例 

5.3.7 传智官网案例 

5.4 Konva的事件(重要) 

5.5 Konva的选择器 

5.6 饼状图案例 

5.7 柱状图案例 

六、Canvas项目实战 

七、Canvas优化 

 

一、canvas简介

1.1 什么是canvas?(了解)

  • HTML5提供的一种新标签

<canvas></canvas>

  • Canvas是一个矩形区域的画布,可以用JavaScript在上面绘画。控制其每一个像素。
  • canvas 标签使用 JavaScript 在网页上绘制图像,本身不具备绘图功能。
  • canvas 拥有多种绘制路径矩形圆形字符以及添加图像的方法。
  • HTML5之前的web页面只能用一些固定样式的标签:比如pdivh1但有了canvas Web页面可以可以丰富多彩。

1.2 canvas主要应用的领域(了解)

  1. 游戏:canvas在基于Web的图像显示方面比Flash更加立体、更加精巧,canvas游戏在流畅度和跨平台方面更牛。 
  2. 可视化数据.数据图表
  3. banner广告Flash曾经辉煌的时代,智能手机还未曾出现。现在以及未来的智能机时代,HTML5技术能够在banner广告上发挥巨大作用,用Canvas实现动态的广告效果再合适不过。
  4. 未来=> 模拟器:无论从视觉效果还是核心功能方面来说,模拟器产品可以完全由JavaScript来实现。
  5. 未来=> 远程计算机控制:Canvas可以让开发者更好地实现基于Web的数据传输,构建一个完美的可视化控制界面。
  6. 未来=> 图形编辑器:Photoshop图形编辑器将能够100%基于Web实现。
  7. 其他可嵌入网站的内容(多用于活动页面、特效):类似图表、音频、视频,还有许多元素能够更好地与Web融合,并且不需要任何插件。
  8. 完整的canvas移动化应用
  9. 我们课程的目标
  • 我们不是主要做游戏开发的
  • 要求必须会做基本的用canvas绘制的特效页面:比如,传智前端官网。
  • 会用canvas做一些简单的广告、活动页面
  1. canvas的标准:
  • 最新标准:http://www.w3.org/TR/2dcontext/
  • 稳定版本的标准:http://www.w3.org/TR/2013/CR-2dcontext-20130806/
  • 目前来说,标准还在完善中。先用早期的api足够完成所有的应用

二、canvas绘图基础

2.0 sublime配置canvas插件(推荐)

推荐:

    安装插件:AndyJS2

    github地址: https://github.com/malun666/AndyJS2

    直接下载到:X:\Users\用户名\AppData\Roaming\Sublime Text 3\Packages

2.1 Canvas标签

2.1.1 canvas标签语法和属性 (重点)

  • canvas:画布油布的意思 ==['kænvəs] ['kænvəs] ==
  • 标签名canvas,需要进行闭合。就是一普通的html标签。
  • 可以设置widthheight属性,但是属性值单位必须是px,否则忽略。
  • widthhegiht:默认300*150像素
  • 注意:
    • 不要用CSS控制它的宽和高,会走出图片拉伸,
    • 重新设置canvas标签的宽高属性会让画布擦除所有的内容。
    • 可以给canvas画布设置背景色
  • ie9以上才支持canvas, 其他chromeff、苹果浏览器等都支持
  • 只要浏览器兼容canvas,那么就会支持绝大部分api(个别最新api除外)
  • 移动端的兼容情况非常理想,基本上随便使用
  • 2d的支持的都非常好,3dwebglie11才支持,其他都支持
  • 如果浏览器不兼容,最好进行友好提示

2.1.2 浏览器不兼容处理(重点)

    例如:                     

    <canvas id="cavsElem">

        你的浏览器不支持canvas,请升级浏览器.浏览器不支持,显示此行文本

    </canvas>

    • 浏览器不兼容,可以使用flash等手段进行优雅降级

2.2 canvas绘图上下文context

2.2.1 ContextCanvas的上下文、绘制环境。(重点掌握)

  • 上下文:上知天文,下知地理。是所有的绘制操作api的入口或者集合。
  • Canvas自身无法绘制任何内容。Canvas的绘图是使用JavaScript操作的。
  • Context对象就是JavaScript操作Canvas的接口。 *使用[CanvasElement].getContext(‘2d’)来获取2D绘图上下文。

 

1 var canvas  = document.getElementById( 'cavsElem' ); //获得画布
2 var ctx = canvas.getContext( '2d' );//注意:2d小写, 3d:webgl

 

2.3 基本的绘制路径(重点)

2.3.1 canvas坐标系

canvas坐标系,从最左上角0,0开始。x向右增大 y向下增大

 

2.3.2 设置绘制起点(moveTo)

* 语法:ctx.moveTo(x, y);

* 解释:设置上下文绘制路径的起点。相当于移动画笔到某个位置

* 参数:x,y 都是相对于 canvas盒子的最左上角。

* 注意:**绘制线段前必须先设置起点,不然绘制无效**

2.3.3 绘制直线(lineTo)

* 语法:ctx.lineTo(x, y);

* 解释:从x,y的位置绘制一条直线到起点或者上一个线头点。

* 参数:x,y 线头点坐标。

2.3.4 路径开始和闭合

* 开始路径:ctx.beginPath();

* 闭合路径:ctx.closePath();

* 解释:如果复杂路径绘制,必须使用路径开始和结束。闭合路径会自动把最后的线头和开始的线头连在一起。

* beginPath: 核心的作用是将 不同绘制的形状进行隔离,

  每次执行此方法,表示重新绘制一个路径,跟之前的绘制的墨迹可以进行分开样式设置和管理。

2.3.5 描边(stroke)

* 语法:ctx.stroke();

* 解释:根据路径绘制线。路径只是草稿,真正绘制线必须执行stroke

* stroke: (用笔等)画;轻抚;轻挪;敲击;划尾桨;划掉;(打字时)击打键盘

  [strəʊk]   [strok]

  • canvas绘制的基本步骤:
    • 第一步:获得上下文 =>canvasElem.getContext('2d');
    • 第二步:开始路径规划 =>ctx.beginPath()
    • 第三步:移动起始点 =>ctx.moveTo(x, y)
    • 第四步:绘制线(矩形、圆形、图片...) =>ctx.lineTo(x, y)
    • 第五步:闭合路径 =>ctx.closePath();
    • 第六步:绘制描边 =>ctx.stroke();

  html部分:

<canvas id="cavsElem">
            你的浏览器不支持canvas,请升级浏览器
        </canvas>

  javascript部分:

 1   //===============基本绘制api====================
 2     //获得画布
 3     var canvas = document.querySelector('#cavsElem');
 4     var ctx = canvas.getContext('2d');  //获得上下文
 5 
 6     canvas.width = 900;     //设置标签的属性宽高
 7     canvas.height = 600;    //千万不要用 canvas.style.height
 8     canvas.style.border = "1px solid #000";
 9 
10     //绘制三角形
11     ctx.beginPath();        //开始路径
12     ctx.moveTo(100,100);    //三角形,左顶点
13     ctx.lineTo(300, 100);   //右顶点
14     ctx.lineTo(300, 300);   //底部的点
15     ctx.closePath();        //结束路径
16     ctx.stroke();           //描边路径

 

2.3.7 填充(fill)

* 语法:ctx.fill();

* 解释:填充,是将闭合的路径的内容填充具体的颜色。默认黑色。

* 注意:交叉路径的填充问题,非零环绕原则,顺逆时针穿插次数决定是否填充。

    以下是非0环绕原则的原理:(了解即可,非常少会用到复杂的路径)

    “非零环绕规则是这么来判断有自我交叉情况的路径的:对于路径中的任意给定区域,从该区域内部画一条足够长的线段,

    使此线段的终点完全落在路径范围之外。

    2-14中的那三个箭头所描述的就是上面这个步骤。

    接下来,将计数器初始化为0

    然后,每当这条线段与路径上的直线或曲线相交时,

    就改变计数器的值。如果是与路径的顺时针部分相交,则加1

    如果是与路径的逆时针部分相交,则减1。若计数器的最终值不是0,那么此区域就在路径里面,在调用fill()方法时,

    浏览器就会对其进行填充。

    如果最终值是0,那么此区域就不在路径内部,浏览器也就不会对其进行填充了

* 案例: 04填充矩形.html

 

 

2.3.8 快速创建矩形rect()方法

* 语法:ctx.rect(x, y, width, height);

* 解释:x, y是矩形左上角坐标, widthheight都是以像素计

* rect方法只是规划了矩形的路径,并没有填充和描边。

* 改造案例:04填充矩形.html

*rect: abbr. 矩形(rectangular);收据(receipt

2.3.9 快速创建描边矩形和填充矩形

* 语法: ctx.strokeRect(x, y, width, height);

    - 参数跟2.3.8相同,注意此方法绘制完路径后立即进行stroke绘制

* 语法:ctx.fillRect(x, y, width, height);

    - 参数跟2.3.8相同, 此方法执行完成后。立即对当前矩形进行fill填充。

2.3.10 清除矩形(clearRect)

* 语法:ctx.clearRect(x, y, width, hegiht);

* 解释:清除某个矩形内的绘制的内容,相当于橡皮擦。

2.4 绘制圆形(arc)

  • 概述:arc()方法创建弧/曲线(用于创建圆或部分圆)。
    • 语法:ctx.arc(x,y,r,sAngle,eAngle,counterclockwise);
    • arc: 弧(度)弧形物;天穹 英 [ɑːk] [ɑrk]
    • counter 反击,还击;反向移动,对着干;反驳,回答 ['kaʊntə] ['kaʊntɚ]
    • 解释:
      • x,y:圆心坐标。
      • r:半径大小。
      • sAngle:绘制开始的角度。 圆心到最右边点是0度,顺时针方向弧度增大。
      • eAngel:结束的角度,注意是弧度。π
      • counterclockwise:是否是逆时针。true是逆时针,false:顺时针
      • 弧度和角度的转换公式: rad = deg*Math.PI/180;
      • Math提供的方法中sincos等都使用的弧度
  • font 设置或返回文本内容的当前字体属性
    • font 属性使用的语法与 CSS font 属性相同。

 

2.5 绘制文字(会使用就可以了)

2.5.1 绘制上下文的文字属性 (有印象就行了)

例如:ctx.font = "18px '微软雅黑'";

  • textAlign 设置或返回文本内容的当前对齐方式
    • start : 默认。文本在指定的位置开始。
    • end : 文本在指定的位置结束。
    • center: 文本的中心被放置在指定的位置。
    • left : 文本左对齐。
    • right : 文本右对齐。

    * 例如:ctx.textAlign = 'left';         

 

 

  • textBaseline 设置或返回在绘制文本时使用的当前文本基线
    • alphabetic 默认。文本基线是普通的字母基线。
    • top 文本基线是 em 方框的顶端。。
    • hanging 文本基线是悬挂基线。
    • middle 文本基线是 em 方框的正中。
    • ideographic 文本基线是em基线。
    • bottom 文本基线是 em 方框的底端。

    例如: ctx.textBaseline = 'top';

    单词:

     alphabetic: 字母的;照字母次序的   [,ælfə'bɛtɪk]

     ideographic:表意的;表意字构成的    [,ɪdɪəʊ'ɡræfɪk]   [,ɪdɪə'græfɪk]

 

 

2.5.2 上下文绘制文字方法

* ctx.fillText()      在画布上绘制被填充的文本

* ctx.strokeText()    在画布上绘制文本(无填充)

* ctx.measureText()   返回包含指定文本宽度的对象

* 单词:measure 测量;估量;权衡   英 ['meʒə]   ['mɛʒɚ]

    //综合案例代码:

 

1  ctx.moveTo( 300, 300 );
2     ctx.fillStyle = "purple";               //设置填充颜色为紫色
3     ctx.font = '20px "微软雅黑"';           //设置字体
4     ctx.textBaseline = "bottom";            //设置字体底线对齐绘制基线
5     ctx.textAlign = "left";                 //设置字体对齐的方式
6     //ctx.strokeText( "left", 450, 400 );
7     ctx.fillText( "Top-g", 100, 300 );        //填充文字

2.6 绘制图片(drawImage) (重点)

2.6.1 基本绘制图片的方式

context.drawImage(img,x,y);

参数说明: x,y 绘制图片左上角的坐标, img是绘制图片的dom对象。

2.6.2 在画布上绘制图像,并规定图像的宽度和高度

context.drawImage(img,x,y,width,height);   

参数说明:width 绘制图片的宽度,  height:绘制图片的高度

如果指定宽高,最好成比例,不然图片会被拉伸</em>

    等比公式:  toH = Height * toW   /  Width;  //等比

             设置高 = 原高度 * 设置宽/ 原宽度;

2.6.3 图片裁剪,并在画布上定位被剪切的部分

context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

参数说明:

    sx,sy 裁剪的左上角坐标,

    swidth:裁剪图片的高度。 sheight:裁剪的高度

    其他同上

2.6.4 JavaScript创建img对象

第一种方式:

var img = document.getElementById("imgId");

第二种方式:

1 var img = new Image();//这个就是 img标签的dom对象
2     img.src = "imgs/arc.gif";
3     img.alt = "文本信息";
4     img.onload = function() {
5         //图片加载完成后,执行此方法
6     }

2.6.5 面向对象基础复习补充:

  • 创建对象的方式:
1   * var o = { name: '123', age: 18 }; //json方式创建
2     * var o = new Object();  //通过new的方式创建
3     * var o = new Persion(); //通过类的构造函数创建

JS中对象的属性创建方式

 

json的方式: var o = { age: 19 };

 

 * 直接添加属性:var o = {};  o.age = 19;//太分散了,不利于管理

    * 由于js动态语言的特性,如果属性不存在的时候,直接添加属性。

    * 构造函数添加属性

    * 原型添加公共的属性

JS的构造函数的原型 构造函数的原型就是:构造对象的模板,构造函数原型里面的所有的属性和方法都会共享给所有的 构造函数构造出来的所有实例。 

2.6.6 补充 sublime制作代码段(推荐)

第一步:sublime菜单栏工具 制作代码段

第二步:修改输出的sublime代码段文本

 

 1 <snippet>
 2     <content><![CDATA[
 3 1、这里放要tab键 输出的内容
 4 2、 ${1:this} 占位符,tab可以进行切换,数字是切换的索引。
 5     :后面的是默认的文本。
 6 ]]></content>
 7     <!-- Optional: Set a tabTrigger to define how to trigger the snippet -->
 8     <tabTrigger>简写的字母</tabTrigger>
 9     <!-- Optional: Set a scope to limit where the snippet will trigger -->
10     <!-- <scope>source.python</scope> -->
11 </snippet>

 

第三步:保存到插件的文件夹中,后缀名为:.sublime-snippet 比如我存放的位置: 
C:\Users\malunmac\AppData\Roaming\Sublime Text 3\Packages\User\snippets 
snippets是我自己新建的文件夹。

三、 canvas进阶

3.1 Canvas颜色样式和阴影

3.1.1 设置填充和描边的颜色(掌握)

  • fillStyle : 设置或返回用于填充绘画的颜色
  • strokeStyle: 设置或返回用于笔触的颜色

以上两个值都可以接受颜色名,16进制数据,rgb值,甚至rgba. 一般先进行设置样式然后进行绘制。

例如:

1 ctx.strokeStyle = "red";      
2 ctx.strokeStyle = "#ccc";      
3 ctx.strokeStyle = "rgb(255,0,0)";      
4 ctx.strokeStyle = "rgba(255,0,0,6)";

3.1.2 设置阴影(了解,少用,性能差)

  • 类比于CSS3的阴影。
  • shadowColor 设置或返回用于阴影的颜色
  • shadowBlur 设置或返回用于阴影的模糊级别,大于1的正整数,数值越高,模糊程度越大
  • shadowOffsetX 设置或返回阴影距形状的水平距离
  • shadowOffsetY 设置或返回阴影距形状的垂直距离
1   ctx.fillStyle = "rgba(255,0,0, .9)"
2     ctx.shadowColor = "teal";
3     ctx.shadowBlur = 10;
4     ctx.shadowOffsetX = 10;
5     ctx.shadowOffsetY = 10;
6     ctx.fillRect(100, 100, 100, 100);

3.2 复杂样式(了解)

3.2.1 创建线性渐变的样式(了解)

  • 一般不用,都是用图片代替,canvas绘制图片效率更高。
  • 线性渐变可以用于 矩形、圆形、文字等颜色样式
  • 线性渐变是一个对象
  • 语法:ctx.createLinearGradient(x0,y0,x1,y1); //参数:x0,y0起始坐标,x1,y1结束坐标

    例如:

1  //创建线性渐变的对象,
2     var grd=ctx.createLinearGradient(0,0,170,0);
3     grd.addColorStop(0,"black");  //添加一个渐变颜色,第一个参数介于 0.0 与 1.0 之间的值,表示渐变中开始与结束之间的位置。
4     grd.addColorStop(1,"white");  //添加一个渐变颜色
5     ctx.fillStyle =grd;           //关键点,把渐变设置到 填充的样式

3.2.2 设置圆形渐变(径向渐变) 了解

  • 创建放射状/圆形渐变对象。可以填充文本、形状等
  • context.createRadialGradient(x0,y0,r0,x1,y1,r1);
  • radial 半径的;放射状的;光线的;光线状的 英 ['reɪdɪəl] ['redɪəl]
  • 参数详解:
    • x0: 渐变的开始圆的 x 坐标
    • y0: 渐变的开始圆的 y 坐标
    • r0: 开始圆的半径
    • x1: 渐变的结束圆的 x 坐标
    • y1: 渐变的结束圆的 y 坐标
    • r1: 结束圆的半径
1 var rlg = ctx.createRadialGradient(300,300,10,300,300,200);
2 rlg.addColorStop(0, 'teal');    //添加一个渐变颜色
3 rlg.addColorStop(.4, 'navy');
4 rlg.addColorStop(1, 'purple');
5 ctx.fillStyle = rlg;//设置 填充样式为延续渐变的样式
6 ctx.fillRect(100, 100, 500, 500);

3.2.3 绘制背景图(了解)

  • ctx.createPattern(img,repeat)方法在指定的方向内重复指定的元素了解
  • patternn. 模式;图案;样品 英 ['pæt(ə)n] ['pætɚn]
  • 第一参数:设置平铺背景的图片,第二个背景平铺的方式。
    • image 规定要使用的图片、画布或视频元素。
    • repeat 默认。该模式在水平和垂直方向重复。
    • repeat-x 该模式只在水平方向重复。
    • repeat-y 该模式只在垂直方向重复。
    • no-repeat 该模式只显示一次(不重复)。
1   var ctx=c.getContext("2d");
2     var img=document.getElementById("lamp");
3     var pat=ctx.createPattern(img,"repeat");
4     ctx.rect(0,0,150,100);
5     ctx.fillStyle=pat;//  把背景图设置给填充的样式
6     ctx.fill();

3.3 变换(重点)

3.3.1 缩放(重点)

  • scale()方法缩放当前绘图,更大或更小
  • 语法:context.scale(scalewidth,scaleheight)
    • scalewidth : 缩放当前绘图的宽度 (1=100%, 0.5=50%, 2=200%, 依次类推)
    • scaleheight : 缩放当前绘图的高度 (1=100%, 0.5=50%, 2=200%, etc.) +注意:缩放的是整个画布,缩放后,继续绘制的图形会被放大或缩小。

3.3.2 位移画布(重点)

  • ctx.translate(x,y) 方法重新映射画布上的 (0,0) 位置
  • 参数说明:
  • x: 添加到水平坐标(x)上的值
  • y: 添加到垂直坐标(y)上的值
  • 发生位移后,相当于把画布的0,0坐标 更换到新的x,y的位置,所有绘制的新元素都被影响。
  • 位移画布一般配合缩放和旋转等。

3.3.3 旋转(重点)

  • context.rotate(angle); 方法旋转当前的绘图
  • 注意参数是弧度(PI
  • 如需将角度转换为弧度,请使用 degrees*Math.PI/180 公式进行计算。
  • ctx.save() 保存当前环境的状态
    • 可以把当前绘制环境进行保存到缓存中。
  • ctx.restore() 返回之前保存过的路径状态和属性
    • 获取最近缓存的ctx
  • 一般配合位移画布使用。

3.3 绘制环境保存和还原(重要)

  • ctx.save() 保存当前环境的状态
    • 可以把当前绘制环境进行保存到缓存中。
  • ctx.restore() 返回之前保存过的路径状态和属性
    • 获取最近缓存的ctx
  • 一般配合位移画布使用。

3.4 设置绘制环境的透明度(了解)

  • context.globalAlpha=number;
  • number:透明值。必须介于 0.0(完全透明) 与 1.0(不透明) 之间。
  • 设置透明度是全局的透明度的样式。注意是全局的。

3.5 画布限定区域绘制(了解)

  • ctx.clip(); 方法从原始画布中剪切任意形状和尺寸
  • 一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)
  • 一般配合绘制环境的保存和还原。

3.6 画布保存base64编码内容(重要)

  • canvas绘制的内容输出成base64内容。
  • 语法:canvas.toDataURL(type, encoderOptions);
  • 例如:canvas.toDataURL("image/jpg",1);
  • 参数说明:
    • type,设置输出的类型,比如 image/png image/jpeg
    • encoderOptions 0-1之间的数字,用于标识输出图片的质量,1表示无损压缩,类型为: image/jpeg 或者image/webp才起作用。

 

    案例1

 

1  var canvas = document.getElementById("canvas");
2     var dataURL = canvas.toDataURL();
3     console.log(dataURL);
4     // "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNby
5     // blAAAADElEQVQImWNgoBMAAABpAAFEI8ARAAAAAElFTkSuQmCC"
6 
7     var img = document.querySelector("#img-demo");//拿到图片的dom对象
8     img.src = canvas.toDataURL("image/png");      //将画布的内容给图片标签显示

 

3.7 画布渲染画布(重要)

1 context.drawImage(img,x,y);
2 img参数也可以是画布,也就是把一个画布整体的渲染到另外一个画布上。
3     var canvas1 = document.querySelector('#cavsElem1');
4     var canvas2 = document.querySelector('#cavsElem2');
5     var ctx1 = canvas1.getContext('2d');
6     var ctx2 = canvas2.getContext('2d');
7     ctx1.fillRect(20, 20, 40, 40);      //在第一个画布上绘制矩形
8     ctx2.drawImage(canvas1, 10, 10);    //将第一个画布整体绘制到第二个画布上

3.8 了解:线条样式(了解)

  • lineCap 设置或返回线条的结束端点(线头、线冒)样式
    • butt 默认。向线条的每个末端添加平直的边缘。
      • 翻译.:屁股;烟头;笑柄;靶垛;粗大的一端 英 [bʌt] [bʌt]
    • round 向线条的每个末端添加圆形线帽。

square 向线条的每个末端添加正方形线帽。 

 

 

  • lineJoin 设置或返回两条线相交时,所创建的拐角类型
    • bevel: 创建斜角
      • 翻译. 斜角;斜面;[] 斜角规 英 ['bev(ə)l] ['bɛvl]
    • round: 创建圆角

      miter: 默认。创建尖角 

  • lineWidth 设置或返回当前的线条宽度
  • miterLimit 设置或返回最大斜接长度
    • 意思: 斜接 英 ['maɪtə]
    • 斜接长度指的是在两条线交汇处内角和外角之间的距离。

一般用默认值:10就可以了。除非需要特别长的尖角时,使用此属

 

3.9 了解贝塞尔曲线(知道有)

3.9.1 绘制一条二次方曲线。

  • 微软的画图板中的曲线的颜色。
  • quadratic:二次方的意思, [kwɒ'drætɪk] [kwɑ'drætɪk]
  • Curve:曲线的意思, [kɜːv] [kɝv]
  • 语法: context.quadraticCurveTo(cpx,cpy,x,y);
  • 参数:
    • cpx 贝塞尔控制点的 x 坐标
    • cpy 贝塞尔控制点的 y 坐标
    • x  结束点的 x 坐标
    • y 结束点的 y 坐标 

1  ctx.beginPath();
2     ctx.moveTo(20,20);
3     //绘制2次方曲线,贝赛尔曲线
4     ctx.quadraticCurveTo(20,100,200,20);
5     ctx.stroke();

3.9.2 绘制贝塞尔曲线(知道有)

  • 绘制一条三次贝塞尔曲线
  • 语法:context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
  • 提示:三次贝塞尔曲线需要三个点。前两个点是用于三次贝塞尔计算中的控制点,第三个点是曲线的结束点。曲线的开始点是当前路径中最后一个点。如果路径不存在,那么请使用beginPath()  moveTo()方法来定义开始点。
  • 参数说明:
    • cp1x 第一个贝塞尔控制点的 x 坐标
    • cp1y 第一个贝塞尔控制点的 y 坐标
    • cp2x 第二个贝塞尔控制点的 x 坐标
    • cp2y 第二个贝塞尔控制点的 y 坐标
    • x: 结束点的 x 坐标
    • y: 结束点的 y 坐标

 

 1 //绘制复杂的贝塞尔曲线
 2 ctx.beginPath();
 3 ctx.moveTo(400,400);
 4 //参数说明:context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
 5 // cp1x: 第一个贝塞尔控制点的 x 坐标
 6 // cp1y: 第一个贝塞尔控制点的 y 坐标
 7 // cp2x: 第二个贝塞尔控制点的 x 坐标
 8 // cp2y: 第二个贝塞尔控制点的 y 坐标
 9 // x: 结束点的 x 坐标
10 // y: 结束点的 y 坐标
11 ctx.bezierCurveTo(500, 200, 600, 600, 700, 300);
12 ctx.stroke();  

 

3.10了解创建两条切线的弧(知道有)

  • 在画布上创建介于当前起点和两个点形成的夹角的切线之间的弧
  • 语法: context.arcTo(x1,y1,x2,y2,r); //类比:css3中的圆角。
  • 例如: ctx.arcTo(240, 100, 240, 110, 40);
  • 参数:
    • x1: 弧的端点1x 坐标
    • y1: 弧的端点1y 坐标
    • x2: 弧的端点2(终点)x 坐标
    • y2: 弧的端点2(终点)y 坐标
    • r : 弧的半径

 

1 //代码demo:
2 ctx.beginPath();
3 ctx.moveTo(100,100);
4 ctx.lineTo(200,100);
5 //context.arcTo(x1,y1,x2,y2,r); //类比:css3中的圆角。
6 ctx.arcTo(240, 100, 240, 110, 40);
7 ctx.lineTo(240, 300);
8 ctx.stroke();   

 

3.11了解判断点是否在路径中(知道有)

context.isPointInPath(x,y);

//isPointInPath() 方法返回 true,如果指定的点位于当前路径中;否则返回 false

//判断x,y坐标的点是否在当前的路径中。

3.12了解文本宽度计算(知道有)

context.measureText(text).width;

3.13 如果以后做canvas游戏方向开发深入学习可以扩展内以下容:

  • setTransform() 将当前转换重置为单位矩阵。然后运行 transform()
  • transform() 替换绘图的当前转换矩阵
  • globalCompositeOperation 设置或返回新图像如何绘制到已有的图像上
  • 像素操作

 

四、 Canvas开发库封装

4.1封装常用的绘制函数

4.1.1封装一个矩形

//思考:我们用到的矩形需要哪些绘制的东西呢?

1、矩形的 xy坐标

2、矩形的宽高

3、矩形的边框的线条样式、线条宽度

4、矩形填充的样式

5、矩形的旋转角度

6、矩形的缩小放大

//下面是把上面所有的功能进行封装的代码:

 1 function ItcastRect( option ) {//矩形构造函数
 2     this._init(option);
 3 }
 4 ItcastRect.prototype = {  //矩形的原型对象
 5     _init: function( option ) {  //初始化方法
 6         option = option || {};
 7         this.x = option.x === 0 ? 0 : option.x || 100;
 8         this.y = option.y === 0 ? 0 : option.y || 100;
 9         this.w = option.w || 100;
10         this.h = option.h || 100;
11         this.angle = option.angle === 0 ? 0 : option.angle || 0;
12         this.fillStyle = option.fillStyle || 'silver';
13         this.strokeStyle = option.strokeStyle || 'red';
14         this.strokeWidth = option.strokeWidth || 4;
15         this.scaleX = option.scaleX || 1;
16         this.scaleY = option.Y || 1;
17     },
18     render: function( ctx ) {//把矩形渲染到canvas中
19         ctx.save();
20         ctx.translate( this.x, this.y );//位移画布
21         ctx.rotate( this.angle * Math.PI / 180 );//旋转角度
22         ctx.scale( this.scaleX, this.scaleY );//缩放
23         ctx.fillStyle = this.fillStyle;
24         ctx.fillRect( 0, 0, this.w, this.h ); //填充矩形
25         ctx.lineWidth = this.strokeWidth;     //线宽
26         ctx.strokeStyle = this.strokeStyle;   //填充样式
27         ctx.strokeRect( 0,0,this.w,this.h );  //描边样式
28         ctx.restore();
29     },
30     constructor: ItcastRect
31 };

4.1.2 封装圆形代码

 封装圆形的代码如下:

 1 function ItcastCircle( option ) {
 2     this._init( option );
 3 }
 4 ItcastCircle.prototype = {
 5     _init: function( option ) {
 6         option = option || {};
 7         this.x = option.x === 0 ? 0 : option.x || 100;
 8         this.y = option.y === 0 ? 0 : option.y || 100;
 9         this.w = option.w || 100;
10         this.h = option.h || 100;
11         this.angle = option.angle === 0 ? 0 : option.angle || 0;
12         this.fillStyle = option.fillStyle || 'silver';
13         this.strokeStyle = option.strokeStyle || 'red';
14         this.strokeWidth = option.strokeWidth || 4;
15         this.scaleX = option.scaleX || 1;
16         this.scaleY = option.Y || 1;
17         this.opactity = option.opactity || 1;
18         this.counterclockwise = 
19             option.counterclockwise === true ? true : option.counterclockwise || false;
20         this.startAngle = option.startAngle == 0 ? 0 : option.startAngle || 0;
21         this.endAngle = option.endAngle == 0 ? 0 : option.endAngle || 0;
22         this.startAngle = this.startAngle * Math.PI/180;
23         this.endAngle = this.endAngle * Math.PI / 180;
24         this.r = option.r || 100;
25     },
26     render: function( ctx ) {
27         ctx.save();
28         ctx.translate( this.x, this.y);
29         ctx.scale( this.scaleX, this.scaleY );
30         ctx.rotate( this.agnle * Math.PI / 180 );
31         ctx.globalAlpha = this.opacity;
32         ctx.fillStyle = this.fillStyle;
33         ctx.strokeStyle = this.strokeStyle;
34         ctx.moveTo(0, 0);
35         ctx.arc( 0, 0, this.r, this.startAngle, this.endAngle, this.counterclockwise);
36         ctx.fill();
37         ctx.stroke();
38         ctx.restore();
39     },
40     constructor: ItcastCircle
41 };

 

 

 

 

 

 

 

 

 

posted @ 2018-01-26 22:01  半指温柔乐  阅读(1439)  评论(1编辑  收藏  举报