zoukankan      html  css  js  c++  java
  • HTML5☞canvas

     <canvas>便签用于绘制图像,图表。不过,<canvas> 元素本身并没有绘制能力(它仅仅是图形的容器) - 您必须使用脚本JavaScript来完成实际的绘图任务。既然你要画出你想要的图案,你给有画布啊,总不能在空气中画画啊,所以第一步你要创建一个画布,给画布一个宽高能装下你的画。<canvas width="500" height="500" id="canvas"></canvas>。

    canvas开始标签和结束便签可以填充内容,填充的内容是后备信息, 如果浏览器不支持canvas元素,就会显示这个后备信息。因为是js控制,所以在脚本语言获取这个元素。var Canvas = document.getElementById('canvas');画布创建好了,要在这个画布上绘图,就须取得绘图上下文。而取得绘图上下文的对象引用,需调用getContext()方法并传入上下文的名字,传入‘2d’,就可以取得2D上下文对象。在使用canvas之前,首先要检测getContext()方法是否存在。这一步非常重要。

    if(canvas.getContext ){
    
      var  context = canvas.getContext("2d");
    
      context . strokeStyle = "red";
    
      context . fillStyle = "blue"
    
      ......
    
    }

    使用2D绘图上下文提供的方法,可以简单绘制2D图形,比如矩形,弧线,和路径 。2D上下文的坐标开始于canvas元素的左上角,原始坐标是(0,0)。所有坐标值都是基于这个原点计算。         

    填充和描边 :填充就是用指定的样式(颜色 渐变或图像)填充图形,描边,就是只在图形的边缘划线。填充和描边取决于两个属性fillStylestrokeStyle  这两个属值可以是字符串渐变对象,模式对象。             
    绘制矩形:方法包括fillRect(),strokeRect() clearRect();这三个方法都接受4个参数,矩形x坐标,y坐标,矩形宽度,矩形高度。
     
    var canvas = document.getElementById('canvas');
    if (canvas.getContext) {
      var context = canvas.getContext('2d');
      context.fillStyle = 'red';               //绘制红色矩形
      context.fillRect(100, 100, 100, 100);
      context.fillStyle = 'rgba(0,0,255,0.5)'; //绘制半透明蓝色矩形
      context.fillRect(150, 150, 100, 100);
    }

    clearRect()方法用于清除画布上的矩形区域,本质上,这个方法可以把绘制上下文中的某一矩形区域变透明。

    canvas  线段样式 

    context.lineCap='butt | round | square';
    链接的线段是不会带有圆或者方块的
     
    当两条线条交汇时,创建边角样式
    context.lineJoin='miter | bevel | round';

     miterLimit = 10;(默认值)只有当lineJoin为miter时有效

     斜街长度:内角与外角的距离,当lineJoin是miter时,用于控制斜接部分的长度  miterLimit。如果斜街长度超过miterLimit的值,就会自动变成bevel   实际运算时大于limit * lineWidth / 2的值。

     绘制路径
     
    绘制路径可以创造出复杂的形状和线条。要绘制路径,首先必须调用beginPath()方法,表示要开始绘制新路径。然后在调用下列方法绘制实际路径。
    moveTo(x,y) 将游标移动到(x,y),不划线。
    lineTo(x,y)    从上一点开始绘制一条直线,到(x,y)
    pen.lineWidth=15;
    pen.moveTo(100,100);
    pen.lineTo(300,100);             //图片中最粗的那条线
    pen.strokeStyle = 'red';
    pen.stroke();
     
    pen.lineWidth=5;                 //画笔由15改成5
    pen.strokeStyle = 'yellow';      //颜色变黄色
    pen.lineTo(200,200);        //接着上面的点画。最末端点垂直坐高垂直于红色的那条
    pen.moveTo(300,100)         //改变起点
    pen.lineTo(100,150);                        
    pen.stroke();
    
    pen.strokeStyle = 'black';
     
    pen.lineWidth=1;
    pen.lineTo(50,150);
    pen.lineTo(50,450);
    pen.stroke();

    我们发现他们是一个路径的(就想是一个集合),也就是你改变笔的粗细和颜色会整体改变,原因就是canvas是根据状态进行绘制的,当改变颜色时会把当前状态下所有的颜色进行绘制。而先前绘制的不会消失的。

    那要怎么让他们不是同一个路径呢?用这个就可以了pen.beginPath(); 开始子路径一个新的集合 就可以设置颜色 和 粗细了 。

    pen.closePath()的作用是关闭路径,如果当前的图形不是封闭的,会封闭图形。pen.beginPath()和pen.closePath()不用同时存在。

     
    canvas画弧
     
    pen.arc(圆心坐标,圆心坐标,起始弧度,结束弧度,弧形方向);
     
    也就是说无论是顺时针画弧还是逆时针画弧,规定的pi的位置都是固定的。
     
    pen.moveTo(100,100);   
    pen.arc(100, 100, 30, Math.PI * 0 , Math.PI / 0.5, 0);此时的顺时针就是1/4圆,逆时针就是3/4圆。 
    注意起始弧度和结束弧度都是用PI的形式表示。 0顺时针  1逆时针
    pen.closePath();
    pen.stroke();
    画出来

    pen.aracTo(x1,y1,x2,y2,r); 从上一点开始绘制一条弧线(圆角)

    绘制的弧线与当前点的x1,y1连线,x1,y1和x2,y2连线相切

    画一个圆角矩形

    pen.moveTo(120, 100);
    pen.arcTo(200, 100, 200, 200, 20);
    pen.arcTo(200, 200, 100, 200, 20);
    pen.arcTo(100, 200, 100, 100, 20);
    pen.arcTo(100, 100, 200, 100, 20);
    pen.stroke();

    canvas画贝塞尔曲线

    pen.quadraticCurveTo(x1, y1, ex, ey);    二次贝塞尔曲线

    x1 y1 控制点         ex  ey结束点

    pen.moveTo(100, 100);
    pen.quadraticCurveTo(200, 200, 300, 100);
    pen.stroke();
    pen.bezierCurveTo(x1, y1, x2, y2, ex, ey); 三次贝塞尔曲线
    两个控制点   一个结束点
    pen.moveTo(100, 100);
    pen.bezierCurveTo(200, 50, 300, 200, 400, 50);
    pen.stroke();

    创建路径后,接下来有几种可能的选择,如果绘制一条连接到路径的起点线条,可以使用closePath();
    如果路径以完成,你想用fillStyle填充他,可以调用fill()方法。另外,还可以调用stroke()方法对路径描边,最后还可以调用clip(),这个方法可以在路径上创建一个剪裁区域。
     

    canvas 绘制文本

    绘制文本主要有两个方法,fillText()strokeText(),这两个方法都接收4个参数 fillText(“文本字符串” ,文字x坐标,Y坐标,可选的最大像素),

    fillText() 用 fillStyle()属性绘制文本,strokeText() 用 strokeStyle()属性为文本描边

    而且这两个方法都已下列3个属性为基础。

    • font(“font-style  font-variant  font-weight  font-size  font-family”)其中默认值是:20px sans-serif也就是说这两个值是必须设定的
    • textAlign=“ left ” | “ center ” | “ right | start | end ”    文本对齐方式
    • textBaseline="  "   可选值见下面,文本的基线

    文字基线对齐方式 textBaseline

    属性

    由于绘制文本比较复杂,特别是需要把文本控制在某一区域中的时候,2D上下文提供了辅助确定文本大小的方法measureText(),这个方法接收一个参数,及要绘制的文本。返回一个TextMetrics对象,对象目前只有一个属性width属性。measureText()利用font, textAlign 和textBaseline的当前值计算指定的文本大小。

    假设你想在一个140像素宽的矩形区域绘制文本,下面的代码从100像素的字体开始递减,最终会找到合适的字体大小。

    var fontsize = 100;
    context.font = fontsize + 'px Arial';
    
    while (context.measureText("hellow World").width > 140) {
      fontsize--;
      context.font = fontsize + 'px Arial';
    }
    context.fillRect(100, 100, 140, 140);
    context.fillText("hellow World", 100, 100);
    context.fillText("fontseizeis"+fontsize, 30, 30);
    canvas坐标轴旋转(跟css3的转换差不多)
     
    1.translate(dx,dy)位置重新映射画布上的(0,0)
    pen.translate(100, 100);
    pen.strokeRect(0, 0, 100, 100);
    2.scale(sx,sy)  缩放当前的绘图
    3.rotate(Math.PI)旋转当前的绘图
    4.save() restore ()
    保存当前图像状态的一份拷贝(保存画布状态)压如栈中
    从栈中弹出存储的图形状态并恢复
    5.setTransform(  a  ,  b  ,  c  ,  d  ,  e  ,  f  )先重置,在变换
    参数:水平缩放 水平倾斜 垂直倾斜 垂直缩放 水平移动 垂直移动
    transform(a,b,c,d,e,f)在之前的状态基础上变换
     
    canvas 在水平和垂直方向重复图像:
    1.createPattern(image,“repeat | repeat-x | repeat-y | no-repeat”);
    img元素(Image对象),canvas元素 ,video元素(有图形的)
    var img = new Image();
    img.src = "hat.png";      //异步加载图片所以用onload保证加载完成
    img.onload = function(){
      var bg = pen.createPattern(img, "repeat");
      pen.fillStyle=bg;
      pen.fillRect(0,0,100,100);
     
    }

    重复canvas元素

    canvas绘制图像 

    drawImage() 方法在画布上绘制图像、画布或视频。

    drawImage() 方法也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸。

    context.drawImage(img,x,y); 在canvas的位置

    context.drawImage(img,x,y,width,height); 在画布上定位图像,并规定图像的宽度和高度:

    context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height); 前四个设定目标元素的位置和宽高,后四个设定canvas元素定位位置宽和高

    canvas渐变

    线性渐变

    createLinearGradient(x1,y1,x2,y2);线性渐变必须在填充渐变区域里定义渐变,否则没有效果。

    把线性渐变保存在一个变量bg里,bg.addColorStop(numbe(小数),颜色);  把变量填充fillStyle.

    径向渐变

    createRadialGradient(x1, y1, r1, x2, y2, r2);   起始点的坐标和半径    结束点的坐标和半径
     

     canvas 阴影

    shadowColor   shadowOffsetX     shadowOffsetY       shadowBlur

    canvas剪切

    clip() 方法从原始画布中剪切任意形状和尺寸。

    提示:一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。您也可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。

    整个画布都设置透明度globalAlpha = 1(默认值)

    canvas 合成(新像素和旧像素的合并方式)

    默认source-over  常用source-over   destination-over  copy

    将canvas内容导出  (注意:受同源策略限制,需开启服务器,否则会报错)canvas.toDataURL();是canvas自身的方法不是上下文对象。将canvas的内容抽取成一张图片以base64的编码格式,将canvas的内容放入ing元素里

    获取canvas像素信息

    getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。

    对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

    • R - 红色 (0-255)
    • G - 绿色 (0-255)
    • B - 蓝色 (0-255)
    • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的

    getImageData(x,y,dx,dy);//受同源策略

    您也可以使用 getImageData() 方法来反转画布上某个图像的每个像素的颜色。

    var imgData=ctx.getImageData(10,10,50,50);
    ctx.putImageData(imgData,10,70);

    putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);

    canvas命中检测    isPointPath(x,y)检测是否在区域内    isPointStroke(x,y)检测是否在直线上   返回 true 或  false

    还可以检测当前的的像素值,如果为透明,则该点不在路径上

    Canvas的fill方法之“非零环绕原则nonzero”与“奇偶原则evenodd”https://www.jianshu.com/p/d4b8b5d931df

  • 相关阅读:
    Oracle数据库死锁和MySQL死锁构造和比较
    shell单引号中输出参数值
    视频流媒体服务器
    使用syncthing进行双机文件同步
    状态(State)模式--设计模式
    中介者(调停者)模式--设计模式
    链表的中间节点
    删除链表中的倒数第N个节点
    Logos讲解--逆向开发
    MonkeyDev安装--逆向开发
  • 原文地址:https://www.cnblogs.com/jiaobaba/p/10473194.html
Copyright © 2011-2022 走看看