你想知道的canvas在这里(小白看过来)

初识canvas


前段时间重新看了一下canvas,觉得很有意思,现在总结一下,只限于基础的,中间有一些小的案例,说的有一些啰嗦,建议初学者参考,欢迎批评指正,共同进步!

首先,我们来认识一下,什么是canvas

一、Canvas定义:

通常用于绘制图表、动画,通过脚本(javascript)来完成, <canvas> 元素本身并没有绘制能力(它仅仅是图形的容器)

不支持canvas的浏览器页面为空不显示 (ie9以下)

可在canvas标签内写p标签

<p>您的浏览器不支持canvas</p>

支持cnavas的浏览器将不识别此标签

二、Canvas使用方法:

创建一个画布,在页面中引入canvas标签, 默认宽300px  高 150px

<canvas  id="can" ></canvas>//默认宽300px  高 150px

设置画布大小的方法:

1、属性width  height 设置宽高,画布上每个点都是一个像素

<canvas  id="can" width="800" height="800"></canvas>

那么问题来了

是否可以在style里面修改画布大小?

不可以 ,画布里面的内容也会被缩放

获取canvas画布:

var oC = document.getElementById('can');

绘制绘图环境

var cte = oC.getContext('2d');

设置绘制环境 :getContext(默认的是2d的场景) ------方法可返回一个对象,该对象提供了用于在画布上绘图的方法和属性。

绘制图形

一 、绘制方块

fillRect(X,Y,W,H): 默认填充颜色是黑色

参数:

X/Y:距离画布的坐标

W/H:矩形的宽高

var can = document.getElementById('can');//获取画布

var canT = can.getContext('2d');//绘制绘图环境

canT.fillRect(10,10,100,100);//画矩形

效果图:

设置绘图样式    (绘制填充矩形要先设置样式,再绘制)

fillStyle: 填充绘画的颜色、渐变或模式

填充的矩形要设置lineJoin样式(设置一个同坐标的描边矩形,设置描边矩形的lineJoin样式

var can = document.getElementById('can');

var canT = can.getContext('2d');

canT.fillStyle='#f40';//绘制填充矩形要先设置样式,再绘制

canT.fillRect(10,10,100,100);

效果图:

二,设置描边矩形

strokeRect(X,Y,W,H): 带边框的方块,默认一像素黑色边框

参数:

X/Y:距离画布的坐标

W/H:矩形的宽高

var can = document.getElementById('can');

var canT = can.getContext('2d');

canT.fillStyle='#f40';

canT.fillRect(10,10,100,100);

canT.strokeRect(150,10,100,100);

效果图:


设置绘图样式  ( 绘制填充矩形要先设置样式,再绘制)

a 绘图环境.strokeStyle='颜色'

b 绘图环境.lineWidth ='数值'

a绘图环境.strokeStyle='颜色'

var can = document.getElementById('can');

var canT = can.getContext('2d');//画图的方法和属性放在了这里

canT.fillStyle='#f40';

canT.fillRect(10,10,100,100);

canT.strokeStyle='#f40';绘制填充矩形要先设置样式,再绘制

canT.strokeRect(150,10,100,100);

效果图:


b 绘图环境.lineWidth ='数值'

var can = document.getElementById('can');

var canT = can.getContext('2d');

canT.fillStyle='#f40';

canT.fillRect(10,10,100,100);

canT.lineWidth = '30';//线条宽度,设置在绘图前

canT.strokeStyle='#f40';//线条颜色,设置在绘图前

canT.strokeRect(150,10,100,100);

三、边界绘制

lineJoin: 边界连接点样式  设置在绘图前

----miter  [ˈmaɪtər]  [ˈmaɪtə(r)] 默认,round(圆角),bevel [ˈbevl]  [ˈbevl](斜角)

  canT.lineWidth = '30';//线条宽度,设置在绘图前

  canT.strokeStyle='#f40';

  canT.lineJoin='round';//圆角,设置在绘图前

  canT.strokeRect(150,10,100,100);

效果图:


canT.lineWidth = '30';//线条宽度,设置在绘图前

canT.strokeStyle='#f40';

canT.lineJoin='bevel';//斜角角设置在绘图前

canT.strokeRect(150,10,100,100);

效果图:


四、绘制路径

beginPath(): 开启一条新路径

closePath(): 闭合当前路径

moveTo(x,y): 定义线条开始坐标

lineTo(x,y): 定义线条结束坐标

stroke(): 画线,默认黑色

  canT.beginPath();//开启一条新路径

  canT.lineWidth = '30';//线条宽度,设置在绘图前

  canT.moveTo(300,100);//定义线条开始坐标

  canT.lineTo(400,200);//定义线条结束坐标

  canT.stroke();// 画线,默认黑色

效果图:


lineCap: 端点样式

----butt(默认), round(圆角),square

fill(): 填充,默认黑色

rect(): 矩形区域(x,y,w,h)

clearRect(x,y,width,height) 方法清空给定矩形内的指定像素。

lineCap: 端点样式

----butt(默认), round(圆角),square

  canT.beginPath();//开启一条新路径

  canT.lineWidth = '30';//线条宽度,设置在绘图前

  canT.moveTo(300,100);//定义线条开始坐标

  canT.lineTo(400,200);//定义线条结束坐标

  canT.lineCap = 'round';//端点圆角

  canT.stroke();// 画线,默认黑色


canT.beginPath();//开启一条新路径

canT.lineWidth = '30';//线条宽度,设置在绘图前

canT.moveTo(300,100);//定义线条开始坐标

canT.lineTo(400,200);//定义线条结束坐标

canT.lineCap = 'square';//增加原长度的1/2分到两端

canT.stroke();// 画线,默认黑色

效果图:


canT.beginPath();//开启一条新路径

canT.lineWidth = '30';//线条宽度,设置在绘图前     

canT.moveTo(300,100);//定义线条开始坐标

canT.lineTo(400,200);//定义线条结束坐标

canT.lineCap = 'square';//增加元长度的1/2分到两端

canT.strokeStyle = 'red';//设置颜色

canT.fill();//填充颜色

canT.stroke();// 画线,默认黑色

效果图:


fill() 填充颜色

在用moveTo() lineTo()方法画矩形时填充颜色使用,必须先设置颜色,fillStyle='颜色',再用fill()填充

    canT.beginPath();//开启一条新路径

    canT.lineWidth = '30';//线条宽度,设置在绘图前     

    canT.moveTo(100,100);//定义线条开始坐标

    canT.lineTo(200,100);//定义线条结束坐标

    canT.lineTo(200,200);

    canT.lineTo(100,200);

    canT.closePath();

    canT.lineCap = 'square';

    canT.fillStyle = 'red';//设置要填充的颜色

  canT.fill();//填充 

  canT.stroke();// 画线,默认黑色

效果图:


rect(): 矩形区域(x,y,w,h)

clearRect(x,y,width,height) 方法清空给定矩形内的指

定像素。


canT.clearRect(0,0,150,160);

x: 要清除的矩形左上角的 x 坐标

y:要清除的矩形左上角的 y 坐标

width: 要清除的矩形的宽度

height: 要清除的矩形的高度


      // 画矩形方法三:

        // cxt.beginPath();

        // cxt.rect(50,50,100,100);

        // cxt.fillStyle = 'red';

        // cxt.fill();

五.画圆

arc(x,y,r,起始弧度,终止弧度,方向)

x/y: 圆心的坐标 定义圆的位置

r:圆的半径 定义圆的大小

弧度:Math.PI/180(一角度的弧度)

角度与弧度的转换关系: 角度*Math.PI/180

方向:顺时针(false 默认值),逆时针(true)

canvas中画圆起始位置为三点钟方向 六点钟方向为90度,九点钟方向是+-180度,12点钟方向为-90度

示意图:


案例一:

cxt.arc(100,100,100 ,0,360*Math.PI/180,true);

cxt.stroke();

效果图:


案例二:

90度扇形

        cxt.moveTo(100,100);

        cxt.arc(100,100,100 ,0,90*Math.PI/180,false);

        cxt.closePath();

        cxt.stroke();

效果图


        cxt.moveTo(100,100);

        cxt.arc(100,100,100 ,0,90*Math.PI/180,true);

        cxt.closePath();

        cxt.stroke();


案例三

移动的方块

    num = 0;

  style = 100;

  setInterval(function(){

  cxt.clearRect(0,0,oc.width,oc.height);

  num ++; //改变位置

  style ++; //改变大小

  cxt.fillRect(num,num,style,style);

},100)



案例四:

画扇形

120度  设置描边样式,填充颜色样式

cxt.moveTo(15,15,);

cxt.arc(150,150,150,0,120*Math.PI/180,false);

cxt.strokeStyle = '#f40';//设置描边样式

cxt.fillStyle = 'red';//填充颜色样式

cxt.fill();//填充 填充颜色样式

cxt.closePath();

cxt.stroke();


案例五:

canvasOnload

    var oc = document.getElementById('c1');

    var cxt = oc.getContext('2d');

    var num = 0;//定义变量

    var timer = setInterval(function(){

    cxt.clearRect(0,0,oc.width,oc.height);

    num+=10;//定义变化的角度 步频

    cxt.beginPath();//开始新路径

    cxt.lineWidth = '6';//线宽

    cxt.strokeStyle ='#ccc';

                        //起始弧度            //终止弧度

    cxt.arc(100,100,50,-90*Math.PI/180,(num+-90)*Math.PI/180,false);

    cxt.stroke();

    if(num>360){

        //当圆环闭合时,清除定时器

        clearInterval(timer);

    }

    },50)

效果图:


变换(平移 旋转 缩放)

translate(x,y):

平移 可以重新定义画布的(0,0)位置

默认画布(0,0)位置在画布左上角

参数:

x/y:x/y轴的偏移量

  ctx.fillRect(0,0,200,150);//未平移前

  ctx.translate(200,150);

  ctx.fillRect(0,0,200,150);


rotate(rad);

旋转当前图形 

旋转的参考角度为画布的(0,0)位置

角度:angle

弧度:radian

参数:

deg:旋转角度 弧度计

弧度= 角度*Math.PI/180

ctx.rotate(45*Math.PI/180);//旋转 写在绘制图形前面

ctx.fillRect(0,0,100,50);


  ctx.fillRect(0,0,100,50);

  ctx.translate(200,150);//图形的起始位置平移至(200,150)位置

  ctx.fillRect(0,0,100,50);


ctx.rotate(45*Math.PI/180);

ctx.fillRect(0,0,100,50);

ctx.translate(200,150);//图形的起始位置平移至(200,150)位置

ctx.fillRect(0,0,100,50);


以物体中心旋转

ctx.translate(50,25);//设位移量为宽高一半

ctx.rotate(45*Math.PI/180);

ctx.fillRect(-50,-25,100,50);//设填充点为宽高的-(1/2)


案例:

方块旋转

save(): 保存路径

restore(): 恢复路径

save()和restore(): 两个配对使用,save方法用于临时保存画布的坐标系统的状态;restore方法用来恢复save之后保存的状态。可以简单的理解为,save之后的一系列的操作,比如translate和rotate等,在restore后,都会被释放恢复到原来的状态。

var num =0;

ctx.translate(200,200);//定义画布的起始(0,0)位置

var timer = setInterval(function(){

ctx.clearRect(-160,-160,oc.width,oc.height);//注意清除区域值

ctx.save();//保存路径

num+=10;

ctx.rotate(num*Math.PI/180);

ctx.fillRect(-100,-100,200,200);

ctx.restore();//恢复路径

},1000)


scale(x,y)放大

参数:

x:代表水平放大的倍数

y:代表垂直放大的倍数

scale(1,1),默认

scale(2,2)放大一倍

scale(0.5,0.5)缩小一半

案例

画钟表

第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

function toDrow(){

// 第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

// cxt.moveTo(200,200);

// cxt.arc(200,200,150,0,6*Math.PI/180,false);

// 整个钟表一共360度,需要进行60次,用循环

    for(var i = 0; i < 60; i ++){

    cxt.moveTo(200,200);

    cxt.arc(200,200,150,i*6*Math.PI/180,(i+1)*6*Math.PI/180,false);

    cxt.stroke();

    //此时 将出现一个圆盘上出现60个闭合的扇形角度为6度

        }

        }

toDrow();

效果图


function toDrow(){

// 第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

  // cxt.moveTo(200,200);

  // cxt.arc(200,200,150,0,6*Math.PI/180,false);

  // 整个钟表一共360度,需要进行60次,用循环

    cxt.beginPath();

    for(var i = 0; i < 60; i ++){

      cxt.moveTo(200,200);

    cxt.arc(200,200,150,i*6*Math.PI/180,(i+1)*6*Math.PI/180,false);

    cxt.stroke();

    cxt.closePath();

//此时 将出现一个圆盘上出现60个闭合的扇形角度为6度

    }

//第二步:画遮罩层

  // 用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,

//半径小于原刻盘,制造出时中刻度的假象

      cxt.beginPath();

      cxt.fillStyle = '#fff';

      cxt.arc(200,200,140,0,360*Math.PI/180,false);

      cxt.fill();

      cxt.closePath();

}

效果图:


function toDrow(){

// 第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

  // cxt.moveTo(200,200);

  // cxt.arc(200,200,150,0,6*Math.PI/180,false);

  // 整个钟表一共360度,需要进行60次,用循环

    cxt.beginPath();

    for(var i = 0; i < 60; i ++){

      cxt.moveTo(200,200);

      cxt.arc(200,200,150,i*6*Math.PI/180,(i+1)*6*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现60个闭合的扇形角度为6度

    }

    cxt.beginPath();

//第二步:画遮罩层

  // 用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,半径小于原刻盘,

//制造出时中刻度的假象

      cxt.beginPath();

      cxt.fillStyle = '#fff';

      cxt.arc(200,200,140,0,360*Math.PI/180,false);

      cxt.fill();

      cxt.closePath();

//    第三步:画时针刻度

    // 同分钟,整个表盘的分钟刻度也是360度,分12个,每个刻度为30

    // 一共有12个30度

    cxt.beginPath();

    for(var i = 0; i  < 12; i ++){

      cxt.moveTo(200,200);

      cxt.lineWidth = 3;

      cxt.arc(200,200,150,i*30*Math.PI/180,(i+1)*30*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现12个闭合的扇形角度为30度  线宽为3

        }

        cxt.closePath();

        }

toDrow();


function toDrow(){

// 第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

  // cxt.moveTo(200,200);

  // cxt.arc(200,200,150,0,6*Math.PI/180,false);

  // 整个钟表一共360度,需要进行60次,用循环

    cxt.beginPath();

    for(var i = 0; i < 60; i ++){

      cxt.moveTo(200,200);

      cxt.arc(200,200,150,i*6*Math.PI/180,(i+1)*6*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现60个闭合的扇形角度为6度

    }

    cxt.beginPath();

//第二步:画遮罩层

  // 用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,半径小于原刻盘,

//制造出时中刻度的假象

      cxt.beginPath();

      cxt.fillStyle = '#fff';

      cxt.arc(200,200,140,0,360*Math.PI/180,false);

      cxt.fill();

      cxt.closePath();

//    第三步:画时针刻度

    // 同分钟,整个表盘的分钟刻度也是360度,分12个,每个刻度为30

    // 一共有12个30度

    cxt.beginPath();

    for(var i = 0; i  < 12; i ++){

      cxt.moveTo(200,200);

      cxt.lineWidth = 3;

      cxt.arc(200,200,150,i*30*Math.PI/180,(i+1)*30*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现12个闭合的扇形角度为30度  线宽为3

        }

        cxt.closePath();

        }

// 第四步:画遮罩层

    //  用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,

    //  半径小于分钟/秒钟(原)遮罩层,制造出时中刻度的假象


            cxt.beginPath();

            cxt.fillStyle = '#fff';

            cxt.arc(200,200,130,0,360*Math.PI/180,false);

            cxt.fill();

            cxt.closePath();

        }

        toDrow();

效果图:


  第五步:画时针分针秒针(行动轨迹)

  圆心相同 半径不同 ,起始弧度和终止弧度相等

起始弧度与终止弧度的值有时间轴来决定

function toDrow(){

// 第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

  // cxt.moveTo(200,200);

  // cxt.arc(200,200,150,0,6*Math.PI/180,false);

  // 整个钟表一共360度,需要进行60次,用循环

    cxt.beginPath();

    for(var i = 0; i < 60; i ++){

      cxt.moveTo(200,200);

      cxt.arc(200,200,150,i*6*Math.PI/180,(i+1)*6*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现60个闭合的扇形角度为6度

    }

    cxt.beginPath();

//第二步:画遮罩层

  // 用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,半径小于原刻盘,

//制造出时中刻度的假象

      cxt.beginPath();

      cxt.fillStyle = '#fff';

      cxt.arc(200,200,140,0,360*Math.PI/180,false);

      cxt.fill();

      cxt.closePath();

//    第三步:画时针刻度

    // 同分钟,整个表盘的分钟刻度也是360度,分12个,每个刻度为30

    // 一共有12个30度

    cxt.beginPath();

    for(var i = 0; i  < 12; i ++){

      cxt.moveTo(200,200);

      cxt.lineWidth = 3;

      cxt.arc(200,200,150,i*30*Math.PI/180,(i+1)*30*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现12个闭合的扇形角度为30度  线宽为3

        }

        cxt.closePath();

        }

// 第四步:画遮罩层

    //  用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,

    //  半径小于分钟/秒钟(原)遮罩层,制造出时中刻度的假象


            cxt.beginPath();

            cxt.fillStyle = '#fff';

            cxt.arc(200,200,130,0,360*Math.PI/180,false);

            cxt.fill();

            cxt.closePath();

            // 第五步:画时针分针秒针(行动轨迹)

        // 圆心相同 半径不同 ,起始弧度和终止弧度相等

        // 起始弧度与终止弧度的值有时间轴来决定

            // cxt.moveTo(200,200);

            // cxt.arc(200,200,150*0.5,起始弧度,终止弧度,false);

            // cxt.stroke();

            // 时针:最短最粗,

        cxt.beginPath();

        cxt.moveTo(200,200);

        cxt.lineWidth =4;

        cxt.arc(200,200,150*0.5,1,1,false);

        cxt.stroke();

        cxt.closePath();

        //    画分针

    cxt.beginPath();

    cxt.moveTo(200,200);

    cxt.lineWidth =3;

    cxt.arc(200,200,150*0.7,3,3,false);

    cxt.stroke();

    cxt.closePath();

        }

        toDrow();

效果图:


// 第六步:

设置在前边

// 想要让时分秒的显示和真实时间一致

// a:分别时间的时分秒

// B:让时分秒针的位置同一

// c:将函数放入定时器,每1000ms执行一次

// 当时间不为整点时,时针在两个数之间,此时需要将时针的位置加上偏移量

var timer = new Date();

ar tH = timer.getHours();//获取小时

var tM = timer.getMinutes();//获取分钟

var tS = timer.getSeconds();//获取秒

// 时针转弧度

// a: 每一个格代表30度,时钟和canvas的起始弧度相差90度,

// b: 当时间不为整点时需将偏移量加上

// eg:10:30分,时针在10-11正中间,一个格式2,判断分钟里有几个2

var tHVal = (30*tH-90+tM/2)*Math.PI/180;

// 分针转弧度

// 每一个格代表6度,时钟和canvas的起始弧度相差90度,

var tMVal =(6*tM-90)*Math.PI/180;

// 秒针转弧度

//  每一个格代表6度,时钟和canvas的起始弧度相差90度,

var tSVal =(6*tS-90)*Math.PI/180;

//  第七步:

// 将时分秒的弧度值替换

function toDrow(){

// 第六步:

// 想要让时分秒的显示和真实时间一致

// a:分别时间的时分秒

// B:让时分秒针的位置同一

// c:将函数放入定时器,每1000ms执行一次

// 当时间不为整点时,时针在两个数之间,此时需要将时针的位置加上偏移量

  var timer = new Date();

  var tH = timer.getHours();//获取小时

  var tM = timer.getMinutes();//获取分钟

  var tS = timer.getSeconds();//获取秒

// 将时分秒转换为弧度

// 时针转弧度

// a: 每一个格代表30度,时钟和canvas的起始弧度相差90度,

// b: 当时间不为整点时需将偏移量加上

// eg:10:30分,时针在10-11正中间,一个格式2,判断分钟里有几个2

  var tHVal = (30*tH-90+tM/2)*Math.PI/180;

// 分针转弧度

  // 每一个格代表6度,时钟和canvas的起始弧度相差90度,

    var tMVal =(6*tM-90)*Math.PI/180;

// 秒针转弧度

//  每一个格代表6度,时钟和canvas的起始弧度相差90度,

    var tSVal =(6*tS-90)*Math.PI/180;

//  第七步:

  // 将时分秒的弧度值替换

// 第一步:画出60个小格子代表分针/秒针刻度,每个刻度之间是6度

  // cxt.moveTo(200,200);

  // cxt.arc(200,200,150,0,6*Math.PI/180,false);

  // 整个钟表一共360度,需要进行60次,用循环

    cxt.beginPath();

    for(var i = 0; i < 60; i ++){

      cxt.moveTo(200,200);

      cxt.arc(200,200,150,i*6*Math.PI/180,(i+1)*6*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现60个闭合的扇形角度为6度

    }

    cxt.beginPath();

//第二步:画遮罩层

  // 用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,半径小于原刻盘,

//制造出时中刻度的假象

      cxt.beginPath();

      cxt.fillStyle = '#fff';

      cxt.arc(200,200,140,0,360*Math.PI/180,false);

      cxt.fill();

      cxt.closePath();

//    第三步:画时针刻度

    // 同分钟,整个表盘的分钟刻度也是360度,分12个,每个刻度为30

    // 一共有12个30度

    cxt.beginPath();

    for(var i = 0; i  < 12; i ++){

      cxt.moveTo(200,200);

      cxt.lineWidth = 3;

      cxt.arc(200,200,150,i*30*Math.PI/180,(i+1)*30*Math.PI/180,false);

      cxt.stroke();

//此时 将出现一个圆盘上出现12个闭合的扇形角度为30度  线宽为3

        }

        cxt.closePath();

        }

// 第四步:画遮罩层

    //  用一个圆覆盖到之前画出分钟/秒钟刻度盘上,圆心相同,

    //  半径小于分钟/秒钟(原)遮罩层,制造出时中刻度的假象


            cxt.beginPath();

            cxt.fillStyle = '#fff';

            cxt.arc(200,200,130,0,360*Math.PI/180,false);

            cxt.fill();

            cxt.closePath();

            // 第五步:画时针分针秒针(行动轨迹)

        // 圆心相同 半径不同 ,起始弧度和终止弧度相等

        // 起始弧度与终止弧度的值有时间轴来决定

            // cxt.moveTo(200,200);

            // cxt.arc(200,200,150*0.5,起始弧度,终止弧度,false);

            // cxt.stroke();

            // 时针:最短最粗,

        cxt.beginPath();

        cxt.moveTo(200,200);

        cxt.lineWidth =4;

        cxt.arc(200,200,150*0.5,tHVal,tHVal,false);

        cxt.stroke();

        cxt.closePath();

        //    画分针

    cxt.beginPath();

    cxt.moveTo(200,200);

    cxt.lineWidth =3;

    cxt.arc(200,200,150*0.7,tMVal,tMVal,false);

    cxt.stroke();

    cxt.closePath();

    //    画秒针

    cxt.beginPath();

    cxt.moveTo(200,200);

    cxt.lineWidth =2;

    cxt.arc(200,200,150*0.7,tSVal,tSVal,false);

    cxt.stroke();

    cxt.closePath();

        }

        toDrow();

        //定时器

etInterval(toDrow,1000);

插入图片

cxt.drawImage(obj,x,y)

参数:

三个参数

1.obj:要插入的图片对象

2.x/y:代表插入图片在画布上的位置(x,y)

语法:

cxt.drawImage(obj,x,y)

五个参数的是时候

cxt.drawImage(obj,x,y,w,h)

w/h:代表在画布上定位图片并设置照片的大小

不设置宽高,默认为图片自身宽高

九个参数代表

      cxt.drawImage(obj,sx,sy,sw,sh,x,y,w,h)

sx/sy: 要剪切图片的位置

sw/sh:剪切的大小

x/y:在画布的位置

w/h:图片的大小

createPattern(obj,是否重复):设置背景

  repeat:默认重复

  repeat-x:x轴重复

  repeat-y:y轴重复

  no-repeat:不重复

window.onload = function(){

            var oC = document.getElementById('c1');

            var cxt = oC.getContext('2d');

            //创建图片对象

            var oImg = new Image();

            //图片路径

            oImg .src = 'img/life.jpg';

            //当图片加载完成以后执行操作

            oImg.onload = function(){

                //图片插入canvas画布中

                cxt.drawImage(oImg,50,80)

            }

        }

效果


平铺:

window.onload = function(){

            var oC = document.getElementById('c1');

            var cxt = oC.getContext('2d');

            //创建图片对象

            var oImg = new Image();

            //图片路径

            oImg .src = 'img/life.jpg';

            //当图片加载完成以后执行操作

            oImg.onload = function(){

                //图片插入canvas画布中

                cxt.drawImage(oImg,0,0);

                var bg = cxt.createPattern(oImg,'repeat');

                //createPattern(obj,是否重复):设置背景

                  //repeat:默认重复

                  //repeat-x:x轴重复

                  // repeat-y:y轴重复

                  // no-repeat:不重复

              cxt.fillStyle = bg;

              cxt.fillRect(0,0,oC.width,oC.height);

            }

        }

效果:


剪裁:(剪裁图片不能设置平铺效果

window.onload = function(){

            var oC = document.getElementById('c1');

            var cxt = oC.getContext('2d');

            //创建图片对象

            var oImg = new Image();

            //图片路径

            oImg .src = 'img/life.jpg';

            //当图片加载完成以后执行操作

            oImg.onload = function(){

                //图片插入canvas画布中

                //cxt.drawImage(obj,sx,sy,sw,sh,x,y,w,h)

                //sx/sy: 要剪切图片的位置

                //sw/sh:剪切的大小,这个区域的图片舍弃

                //x/y:在画布的位置

                // w/h:图片的大小

                cxt.drawImage(oImg,30,50,100,200,200,100,200,200);


            }

        }

效果:


案例:

图片旋转:

分析:

第一步:

向画布插入图片

var oImg = new Image();//调用方法

oImg.src = "img/life.jpg";//图片路径

//设置canvas画布与图片大小一致

  oImg.onload = function() {//图片预加载,当图片加载完成再执行canvas

            cxt.drawImage(oImg,0,0,500,300);

        }

第二步:

设置旋转角度

window.onload = function(){

        var aInput = document.getElementsByTagName

        ("input");

        var oC = document.getElementById("c1");

        var cxt = oC.getContext("2d");

        var  i = 0;

        var iNow = 0;

        // 向画布插入图片

        var oImg = new Image();

        oImg.src = "img/life.jpg";

        oImg.onload = function() {

            cxt.drawImage(oImg,0,0,500,300);

        }

        // switch  语句开始

        aInput[0].onclick = function() {

            if(iNow==0) {

                iNow = 3;

            }

            else {

                iNow--;

            }

          toRotate();

        }

        aInput[1].onclick = function() {

            // 执行顺时针旋转图片

            // 当i= 1 第一次旋转 旋转90度

            if(iNow==3) {

                iNow = 0;

            }

            else {

                iNow++;

            }

          toRotate();

        }

        function toRotate() {

            switch(iNow) {

                case 1:

                    oC.width = oImg.height;

                    oC.height = oImg.width;

                    cxt.rotate(90*Math.PI/180);

                    cxt.drawImage(oImg,0,-oImg.height);

                break;

                case 2:

                    oC.width = oImg.width;

                    oC.height = oImg.height;

                    cxt.rotate(180*Math.PI/180);

                    cxt.drawImage(oImg,-oImg.width,-oImg.height);

                break;

                case 3:

                    oC.width = oImg.height;

                    oC.height = oImg.width;

                    cxt.rotate(270*Math.PI/180);

                    cxt.drawImage(oImg,-oImg.width,0);

                break;

                case 0:

                    oC.width = oImg.width;

                    oC.height = oImg.height;

                    cxt.rotate(0*Math.PI/180);

                    cxt.drawImage(oImg,0,0);

                break;

            }


        }

渐变

A: 创建线性渐变

creatLinearGradient(x1,y1,x2,y2)

  参数

  x1:起始坐标x轴

  y1:起始坐标y轴

  x2: 终止坐标x轴

  y2:终止坐标y轴

  给渐变对象添加颜色 addColorStop()

    接收两个参数

    第一个参数 规定渐变的位置

    第二个参数 渐变的颜色

    语法: addColorStop(0,'red');

// A实例

        //创建渐变对象

        var grad = cxt.createLinearGradient(100,100,300,300);

        // 给渐变对象添加颜色

        grad.addColorStop(0,'#f00');

        grad.addColorStop(0.3,'#e12');

        grad.addColorStop(1,'#f1e');

        // 将渐变对象赋值给fillStyle并创建一图形

        cxt.fillStyle = grad;

        cxt.fillRect(0,0,oC.width,oC.height);

效果:


B:创建径向渐变  createRadialGradient(x1,y1,r1,x2,y2,r2) x1/y1:起始位置坐标

x2/y2:结束位置坐标

r1/r2: 开始结束的半径

    // 创建一个径向渐变

    var  grad = cxt.createRadialGradient(200,200,50,200,200,100) ;

    // 给径向渐变对象添加颜色

    grad.addColorStop(0,'purple');

    grad.addColorStop(1,'blue');

    // 把样式赋值给fillStyle

    cxt.fillStyle = grad;

    // 创建一个图形

    cxt.fillRect(0,0,oC.width,oC.height);


文本

cxt.strokeText('文本内容',x,y);

参数:

x,y:文本位置坐标

cxt.fillText('明天',200,300);

var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.fillText('明天',200,300);

效果;


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.fillStyle ='yellow';//字体颜色

cxt.fillText('明天',200,300);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.fillStyle ='yellow';

cxt.font = 'italic bold 100px  impact';//字体 倾斜加粗字号100px

cxt.fillText('明天',200,300);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.strokeText('你好',200,300);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.strokeStyle=‘orange';

cxt.strokeText('你好',200,300);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.strokeStyle=‘orange';

cxt.font = 'italic bold 100px  impact';//字体 倾斜加粗字号100px

cxt.strokeText('你好',200,300);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.strokeStyle='orange';

cxt.font = 'italic bold 100px  impact';//字体 倾斜加粗字号100px

cxt.strokeText('你好',100,100);

cxt.fillStyle ='yellow';

cxt.fillText('明天',200,300);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

var  grad = cxt.createLinearGradient(250,300,400,500);

grad.addColorStop(0,'#fc3');

            grad.addColorStop(0.3,'#12fc');

            grad.addColorStop(1,'#10fc');

            cxt.font = 'italic bold 100px  impact';

            cxt.fillStyle = grad;

            cxt.fillText('明天',200,300)

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.strokeStyle='orange';

cxt.font = 'italic bold 100px  impact';//字体 倾斜加粗字号100px

var  grad = cxt.createRadialGradient(100,100,100,150,150,200);

// 给径向渐变对象添加颜色

grad.addColorStop(0,'#fc3');

grad.addColorStop(0.3,'#12fc');

grad.addColorStop(1,'#10fc');

cxt.strokeText('你好',100,100);

cxt.fillText('明天',200,300);

var  grad = cxt.createRadialGradient(100,100,100,150,150,200);

// 给径向渐变对象添加颜色

grad.addColorStop(0,'#fc3');

grad.addColorStop(0.3,'#12fc');

grad.addColorStop(1,'#10fc');

// 把样式赋值给fillStyle

cxt.strokeStyle = grad;

cxt.strokeText('你好',100,100);

效果:


阴影

创建阴影

cxt.shadowOffsetX:阴影x轴偏移量 ,

可以为负值,正值向右,负值向左偏移

cxt.shadowOffsetY:阴影x轴偏移量 ,

可以为负值,正值向下,负值向上偏移

cxt.shadowBlur:阴影的模糊值,值越大,

模糊度越强

cxt.shadowColor:阴影的颜色

var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

cxt.shadowOffsetX ='20';//阴影x轴偏移量

cxt.shadowOffsetY = '10'//阴影x轴偏移量

cxt.shadowBlur = '10';//阴影的模糊值

cxt.shadowColor ='red';//阴影的颜色

cxt.fillRect(100,100,100,100);

效果:


var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

var  grad = cxt.createRadialGradient(100,100,100,150,150,200);

// 给径向渐变对象添加颜色

grad.addColorStop(0,'#fc3');

grad.addColorStop(0.3,'#12fc');

grad.addColorStop(1,'#10fc');

cxt.shadowOffsetX ='20';

cxt.shadowOffsetY = '10'

cxt.shadowBlur = '10';

cxt.shadowColor ='red'

// 把样式赋值给fillStyle

cxt.strokeStyle = grad;

cxt.strokeText('你好',100,100);


像素:

oCxt.getImageData(x,y,w,h);

返回一个图像对象,这个对象包含了这个图像的像素信息

参数:

x/y:获取像素点的坐标位置

w/h:获取图像的宽高

createImageData(w,h)创建图像

参数:

w:创建图像的宽

h:创建图像的高 

putImageData(imgData,x,y,w,h)将像素放入画布中、

参数:创建的像素

x/y:像素坐标

w/h:像素大小

练习:创建一个100*100的图像 ,红色,255,0,,0,255

  var oC = document.getElementById('c1');

  var oCxt = oC.getContext('2d');

  var imgData = oCxt.createImageData(100,100);

  for(var  i =0; i<imgData.data.length;i++){

// 把每个像素的四个值都要赋值成红色对应的rgba

        //rgba  红绿蓝透明度 每4个值代表一个像素

        imgData.data[4*i]='255';

        imgData.data[4*i+1]='0';

        imgData.data[4*i+2]='0';

        imgData.data[4*i+3]='255';


        }

        //放入画布

  oCxt.putImageData(imgData,200,200)

效果:


measure:

  measureText();

  语法:mearsureText('测量的文本').wdith;

        测量文本的宽度/密度

        把文字水平居中的方式

        x轴坐标(画布的宽- 字体的宽)/2

练习:将‘往后余生’水平居中

var oC = document.getElementById('c1');

var cxt = oC.getContext('2d');

var str  = '往后余生';

cxt.font ='bold 100px impact';

var cX = (oC.width - cxt.measureText(str).width)/2;

cxt.fillText(str,cX,100);

效果:


至此,canvas的一些知识也介绍的差不多了,中间有一些案例供大家参考,说的有些啰嗦,适合初学者,希望对大家有一些帮助吧!

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

推荐阅读更多精彩内容

  • 【Python基础】条件语句 Python条件语句是通过一条或多条语句的执行结果(True或者False)来决定执...
    开发者学习指南阅读 145评论 0 0
  • 辩:买了百万医疗保险,就可以不买重大疾病保险? 近两年,随着百万医疗类保险的盛行,市场上开始出现这样一种声音,很多...
    侃爷说保险阅读 174评论 0 1
  • 【日精进打卡967天】 姓名:孙玉生 沈阳盛和商学院 六项精进第177期学员(队长),271期284期288期29...
    _玉_生_阅读 277评论 0 2
  • 曾经天人合一,知道万物相依,何时失去天真,凡事总讲道理。 原创作品 (Original Article)
    一诗一境界阅读 269评论 0 0
  • 周星驰捧红了一大批的女星,可以说香港的半个娱乐圈,都是周星驰撑起来的,像张柏芝、朱茵等,都是著名的“星女郎”。 周...
    漫娱小简阅读 329评论 0 0