canvas二二十四日少年老成练,canvas

canvas一周一练,canvas

从上个星期开始,耳朵就一直在生病,里面长了个疙瘩,肿的一碰就疼,不能吃饭不能嗨 (┳_┳)……在此提醒各位小伙伴,最近天气炎热,一定要注意防暑上火,病来如山倒呀~
 

接下来我正在喝着5块一颗的药学习canvas……

canvas(画布)是html5新增的标签元素,用来定义图形,比如图表和其他图像。<canvas>标签只是图形容器,必须使用脚本(通常为javascript)来绘制图形。

canvas与svg的区别  

canvas是HTML5提供的新元素<canvas>,而svg存在的历史要比canvas久远,已经有十几年了。svg并不是html5专有的标签,最初svg是用xml技术(超文本扩展语言,可以自定义标签或属性)描述二维图形的语言。

首先,从它们的功能上来讲,canvas可以看做是一个画布。其绘制出来的图形为标量图,因此,可以在canvas中引入jpg或png这类格式的图片,在实际开发中,大型的网络游戏都是用canvas画布做出来的,并且canvas的技术现在已经相当的成熟。
另外,我们喜欢用canvas来做一些统计用的图表,如柱状图曲线图或饼状图等。而svg,所绘制的图形为矢量图,所以其用法上受到了限制。因为只能绘制矢量图,所以svg中不能引入普通的图片,因为矢量图的不会失真的效果,在项目中我们会用来做一些动态的小图标。
但是由于其本质为矢量图,可以被无限放大而不会失真,这很适合被用来做地图,而百度地图就是用svg技术做出来的。

另外从技术发面来讲canvas里面绘制的图形不能被引擎抓取,如我们要让canvas里面的一个图片跟随鼠标事件:canvas.onmouseover=function(){}。而svg里面的图形可以被引擎抓取,支持事件的绑定。
另外canvas中我们绘制图形通常是通过JavaScript来实现,svg更多的是通过标签来来实现,如在svg中绘制正矩形形就要用<rect>,这里我们不能用属性style="width:XXX;height:XXX;"来定义。
我再来介绍一个svg的js库:TWO.JS。其中包含two.js和three.js前者用于绘制二维图形,后者用于绘制三维图形。TWO.JS可以支持三种格式,svg(默认)、canvas、和WEBGL。当然也可以在普通div中引入。

要从同一图形的一个<canvas>标记中移除元素,需要擦掉重新绘制;而svg很容易编辑,只要从其描述中移除元素即可。

以上是之前在别人博客中看到的,所以先引用过来,待之后熟练掌握canvas,svg再写自己的心得体会。

具体请参考 http://blog.csdn.net/helloword_chen/article/details/49788309
1、基本语法

<canvas id="canvasMain" width="800" height="600" >
    您的浏览器不支持canvas
</canvas>

当没有设置宽度和高度的时候,canvas会初始化宽度为300px和高度为150px;当浏览器不支持canvas标签的时候,会显示其中的文字。

在canvas坐标体系中,以左上角为坐标原点,向右为x轴正方向,向下为y轴正方向,如下图:

图片 1

进行绘制需要获取canvas的上下文环境context,之后调用API进行图像绘制

var canvas = document.getElementById("canvasMain"),
    ctx = canvas.getContext("2d");

 替换内容是在不支持<canvas>标签的浏览器中展示的。也可以通过检测getContext()方法的存在来判断是否支持(有些浏览器会为html规范之外的元素创建默认的html元素对象)

var canvas = document.getElementById("canvasMain");
if(canvas.getContext("2d")) {
    var ctx = canvas.getContext("2d");
    // drawing code here
} else {
    // canvas-unsupported code here
}

导出在<canvas>元素上绘制的图像,接收一个参数,即图像的MIME类型格式。若绘制到画布上的图像来自不同域,该方法会报错

var canvas = document.getElementById("canvasMain");
if(canvas.getContext) {
    //取得图像的数据URI
    var imgURI = canvas.toDataURL('image/png');
    //显示图像
    var image =  document.createElement('img');
    image.src = imgURI;
    document.body.appendChild(image);        
}

2、2D上下文

  • 填充和描边

  填充:用指定的样式(颜色、渐变、图像)填充图形;描边:在图形的边缘画线
  两个属性分别是fillStyle
 strokeStyle,属性的值可以是字符串、渐变对象或模式对象

  • 绘制矩形

      
 图片 2  

  绘制矩形方法:fillRect()  strokeRect()   clearRect()
 参数依次为:矩形x坐标、y坐标、宽度、高度

var drawing = document.getElementById('drawing');
if(drawing.getContext) {
    var context = drawing.getContext('2d');
    context.strokeStyle = 'rgba(0, 0, 255, 0.5)';//描边属性
    context.fillStyle = 'pink';//填充属性

    context.lineWidth = 3; //描边线条宽度
    context.lineCap = 'square';//线条末端形状(butt平头、round圆头、square方头)
    context.lineJoin = 'round';//线条相交的方式(round圆交、bevel斜交、miter斜接)

    context.fillRect(10, 10, 50, 50);//填充矩形
    context.fillStyle = 'green';
    context.fillRect(30, 30, 50, 50);
    context.strokeRect(100, 10, 50, 50);//描边矩形
    context.clearRect(40, 40, 15, 15);//清除画布上的矩形区域             
}
  • 绘制路径

   图片 3

   closePath()绘制一条连接到路径起点的线条

   fill()填充路径    stroke()描边路径   clip()在路径上创建一个剪切区域

   isPointInPath(x,y)判断画布上的某一点是否位于路径上

var drawing = document.getElementById('drawing');
if(drawing.getContext) {
            /*绘制路径*/
            var context = drawing.getContext('2d');
            context.strokeStyle = 'pink';
            context.beginPath();//开始绘制新路径
            //绘制外圆
            context.arc(100, 100, 99, 0, 2*Math.PI, false);//参数依次为圆心坐标x、y、半径、起始角度(用弧度表示)、结束角度、起始角度是否按逆时针方向计算(flase为顺时针)
            context.moveTo(194, 100);//将绘图游标移动到(x,y),不画线
            //绘制内圆
            context.arc(100, 100, 94, 0, 2*Math.PI, false);
            //绘制分针
            context.moveTo(100, 100);
            context.lineTo(100, 25);//从上一点开始绘制一条直线,到(x,y)为止
            //绘制时针
            context.moveTo(100, 100);
            context.lineTo(35, 100);
            //绘制文本
            context.font = 'bold 14px Arial';//表示文本样式、大小、字体
            context.textAlign = 'center';//文本对齐方式(start、end、left、right、center),建议用start、end代替left、right
            context.textBaseline = 'middle';//文本的基线(top、hanging、middle、alphabetical、ideopgraphic、bottom)
            context.fillText('12', 100, 20);
            //描边路径
            context.stroke();
            //额外练习
            context.moveTo(230, 10);
            //arcTo(x1,y1,x2,y2,radius):从上一点开始绘制一条弧线,到(x2,y2)为止,并以给定的半径穿过(x1,y1)
            context.arcTo(280, 60, 330, 10, 50);
            //bezierCurveTo(c1x,c1y,c2x,c2y,x,y):从上一点开始绘制一条曲线,到(x,y)为止,并以(c1x,c1y)(c2x,c2y)为控制点
            context.bezierCurveTo(210, 70, 290, 90, 300, 100);
            context.moveTo(320, 10);
            //quadraticCurveTo(cx,cy,x,y):从上一点开始绘制一条二次曲线,到(x,y)为止,并以(cx,cy)为控制点
            context.quadraticCurveTo(420, 100, 400, 10);
            //rect(x,y,width,height):从点(x,y)开始绘制矩形,此方法绘制的是矩形路径而不是独立的形状
            context.rect(450, 10, 50, 50);
            context.stroke();
}
  • 绘制文本

  fillText()绘制文本    strokeText()为文本描边  
 参数:文本字符串、x坐标、y坐标、可选的最大像素宽度

  • 变换

  图片 4

var drawing = document.getElementById('drawing');
if(drawing.getContext) {
            //变换
            var context = drawing.getContext('2d');
            context.strokeStyle = 'rgba(0, 0, 255, 0.5)';
            context.beginPath();
            context.arc(100, 100, 99, 0, 2*Math.PI, false);
            context.moveTo(194, 100);
            context.arc(100, 100, 94, 0, 2*Math.PI, false);
            //变换原点
            context.translate(100, 100);//将坐标原点移动到该点
            //旋转表针
            context.rotate(1);//围绕原点旋转图像angle弧度
            //绘制分针
            context.moveTo(0, 0);
            context.lineTo(0, -80);
            //绘制时针
            context.moveTo(0, 0);
            context.lineTo(-65, 0);
            context.stroke();

            context.rotate(-1);
            context.fillStyle = 'rgba(0, 0, 255, 0.5)';
            context.save();//保存上下文状态,只保存绘图上下文的设置和变换,不会保存绘图上下文的内容
            context.fillStyle = 'pink';
            context.translate(-100, -100);
            context.save();
            context.fillStyle = 'green';
            context.fillRect(220, 10, 50, 50);

            context.restore();//返回之前保存的设置
            context.fillRect(280, 10, 50, 50);

            context.restore();
            context.fillRect(340, 10, 50, 50);
}
  • 绘制图像

  图片 5 

  drawImage()还可传入<canvas>元素作为第一个参数,表示把另一个画布内容绘制到当前画布上。

  可能遇到的问题:drawImage()图片不显示在画布上,原因可能是你取图片的时候,此时图片还没有加载出来

window.onload = function(){
        var drawing = document.getElementById('drawing');
        if(drawing.getContext) {
            //图像
            var context = drawing.getContext('2d');
            var image = document.images[0];
            //参数依次表示为:图像元素、源图像x坐标、y坐标、目标的宽度、高度
            context.drawImage(image, 0, 0, 150, 250);
            //参数依次表示为:图像元素、源图像x坐标、y坐标、源图像宽度、高度、目标图像x坐标、y坐标、目标图像宽度、高度
            context.drawImage(image, 100, 300, 500, 600, 0, 0, 70, 80);
        }
};
  • 阴影、渐变、模式

  图片 6

   模式与渐变一样,都是从画布原点(0,0)开始的,将填充样式设置为模式对象,只表示在某个特定区域内显示重复的图像,而不是从某个位置开始绘制重复的图像。

   createPattern()第一个参数也可以是<video>元素,或者是另一个<canvas>元素

window.onload = function(){
        var drawing = document.getElementById('drawing');
        if(drawing.getContext) {
            //阴影
            var context = drawing.getContext('2d');
            context.shadowColor = 'rgba(0, 0, 0, 0.5)';//阴影颜色,默认黑色
            context.shadowOffsetX = 5;//x轴方向的阴影偏移量,默认0
            context.shadowOffsetY = 5;//y轴方向的阴影偏移量,默认0
            context.shadowBlur = 4;//模糊的像素数,默认0

            context.fillStyle = 'rgba(0, 0, 255, 0.5)';
            context.fillRect(10, 10, 50, 50);
            context.fillStyle = 'pink';
            context.fillRect(30, 30, 50, 50);

            //渐变
            var gradient = context.createLinearGradient(100, 10, 130, 130);//创建线性渐变,返回CanvasGradient对象的实例。参数:起点x坐标、y坐标、终点x坐标、y坐标
            gradient.addColorStop(0, 'white');//指定色标,参数:色标位置(0到1之间的数字,0表示开始的颜色,1为结束的颜色)、css颜色值
            gradient.addColorStop(1, 'black');

            context.fillStyle = gradient;
            context.fillRect(100, 10, 50, 50);

            var createLinearGradient = function(context, x, y, width, height) {
                return context.createLinearGradient(x, y, x+width, y+height);
            };

            var gradientNew = createLinearGradient(context, 180, 10, 50, 50);
            gradientNew.addColorStop(0, 'red');
            gradientNew.addColorStop(1, 'green');
            context.fillStyle = gradientNew;
            context.fillRect(180, 10, 50, 50);

            var gradientRound = context.createRadialGradient(275, 35, 10, 275, 35, 30);//径向渐变,参数:起点圆的圆心、半径,终点圆的圆心、半径
            gradientRound.addColorStop(0, 'pink');
            gradientRound.addColorStop(1, 'blue');
            context.fillStyle = gradientRound;
            context.fillRect(250, 10, 50, 50);

            //模式,即重复的图像,可以用来填充或描边图形
            var image = document.images[0],
                pattern = context.createPattern(image, 'repeat-x');//创建新模式,参数:图像元素、是否重复(repeat、repeat-x、repeat-y、no-repeat)
            context.fillStyle = pattern;
            context.fillRect(350, 10, 350, 350);
        }
}    
  • 使用图像数据

  getImageData()可取得原始图像数据,参数:要取得数据的画面区域的x坐标、y坐标、宽度、高度。返回的对象是ImageData的实例,该对象有3个属性:width、height和data。其中data为数组,保存着图像中

每一个像素的数据,每一个像素用4个元素来表示,分别表示红、绿、蓝和透明度值。因此,第一个像素的数据保存在数组的第0到第3个元素中。

  注意:只有在画布“干净”的情况下(即图像并非来自其他域),才可以取得图像数据。

  • 合成

  globalAlpha:介于0和1之间的值(包括0和1),用于指定透明度,默认为0。

  globalComositionOperation:表示后绘制的图形怎样与先绘制的图形结合。

  图片 7

   图片 8

3、WebGL

  WebGL是针对canvas的3D上下文,并不是由W3C制定的标准。

 

本文持续更新中~

 

 

从上个星期开始,耳朵就一直在生病,里面长了个疙瘩,肿的一碰就疼,不能吃饭不能嗨(┳_┳)在此提醒各位小伙伴…

<canvas>元素是HTML5中的绘图元素,通过定义一个画布区域,然后使用javascript动态地在这个区域里面绘制图形,对于2D和3D图形都可以绘制,我们将其分成2D上下文和WebGL两大块内容来一起来学习,但是WebGL觉得比较少用到,而且难,所以不讲了!
一、了解canvas
<canvas id=‘draw’ width=‘200’ height=‘200′ > nothing
</canvas>,这是便是一个基本canvas元素的写法了,但是我们必须通过javascript来动态获得,那么需要这样:

图片 9图片 10

 1 var draw = document.getElementById(‘draw’);
 2 //确定是否支持canvas
 3 if(draw.getContext){
 4 //这样就取得绘图上下文对象的引用,画图便可以开始了!
 5 var context = draw.getContext(‘2d’);
 6 //取得图像的数据uri,显示图像
 7 var imageuri = draw.toDataURL(‘image/png’);
 8 var img = document.createElement(‘img’);
 9 img.src= imageuri;
10 document.body.appendChild(img);
11 }

View Code

二、2D上下文
对于2D上下文的坐标是开始于canvas元素的左上角的,原点的坐标为(0,0),x轴越往右越大,y轴越往下越大就算但画布的原坐标发生translate也不例外,如下图:

填充(使用指定样式[颜色、渐变、图像、模式等]填充图形)和描边(图形的边缘画线)分别为fillStyle和strokeStyle,需要注意一点,fillStyle和strokeStyle会被延用至重新设置这两个值!

图片 11图片 12

1 var draw = document.getElementById(‘draw’);
2 if(draw.getContext){
3 var context = draw.getContext(‘2d’);
4 context.strokeStyle = “#000”;
5 context.fillStyle = ‘#0000ff’;
6 }

View Code

绘制矩形,有以下方法fillRect()、strokeRect()、clearRect()的方法,都是一样的,传入四个参数,矩形的x坐标、矩形的y坐标、矩形的宽度width、矩形的高度height,

图片 13图片 14

 1 var draw = document.getElementById(‘draw’);
 2 if(draw.getContext){
 3 
 4 var context = draw.getContext(‘2d’);
 5 //绘制黑色矩形
 6 context.strokeStyle = “#000”;
 7 context.strokeRect(10,10,50,50);
 8 //绘制黑色矩形
 9 context.strokeStyle = “#000”;
10 context.fillRect(30,30,50,50);
11 
12 //在两个填充矩形重叠的地方清除一个小矩形
13 context.clearRect(40,40,10,10);
14 
15 //绘制描边矩形
16 context.fillStyle = ‘#0000ff’;
17 context.fillRect(30,30,50,50);
18 
19 }

View Code

绘制路径,2d上下文有很多在画布上绘制路径的方法,可以创造出复杂的形状和线条。要绘制路径,首先需要调用beginPath()方法,
arc(x,y,radius,startAngle,endAngle,counterclockwise),意思是以(x,y)为圆心,radius为半径,counterclockwise的值为false的时候顺时针画圆(或圆弧),开始角度startAngle,结束角度endAngle,用弧度表示;
arcTo(x1,y1,x,y,radius),意思是从(x1,y1)到(x,y),以radius为半径,画一条弧线;
lineTo(x,y),意思是从上一个点画一条直线至(x,y);
moveTo(x,y),意思是将绘图的游标移至(x,y),也就是从此点开始绘制;
rect(x,y,width,height),这是画个矩形,就不多说了;
bezierCurveTo(x1,y1,x2,y2,x,y),意思从上一个点开始,是以(x1,y1)、(x2,y2)为控制点,(x,y)为终点的三次贝尔塞曲线;

quadraticCurveTo(cx,cy,x,y),意思是从上一个点开始,是以(cx,cy)为控制点,(x,y)为终点的二次贝尔塞曲线。

那么接下来,创建路径之后,我们可以又怎么这几种选择:

使用closePath(),关闭路径,绘制一条连接至起点的线条;

使用fill()、stroke(),对路径进行填充或是描边,前提是设置了(fillStyle、strokeStyle)

使用clip(),创建一个剪切区域

如果我们想在路径关闭之前,判断某个点是否在路径上,可以这样来做

if(context.isPointInPath(100,100)){ 
    alert("点击这里http://t.cn/RUbL4rP,就可以跳转,快来看看阿!");      
}

 绘制文本,有图,就有文本,主要有两个方法,fillText()和strokeText(),传入四个参数,str(字符串)、x坐标、y坐标、最大像素宽度(超过此值,将会自动收缩),当然这两个方法是以以下三个属性(font、textAlign、textBaseline)为基础的,当然要注意,这两个方法也是使用fillStyle和strokeStyle来做填充和描边滴,之后也有demo更新到github上面去!

图片 15图片 16

context.font="blod 14px Arial";
context.textAlign = "center";//"start" "end" "left" "right"
context.textBaseline = "middle";//"top" "bottom" "hanging" "alphabetic"  "ideographic"

context.fillText("工资低,被迫下海,还望大家多多支持,多多棒槌,宣传一下下",100,20);

View Code

有时候,我们需要将我们的文本控制在某一个区域中的时候,那么会用到measureText()方法,传入一个参数(我们需要显示的字符串),得到的对象里面有个width属性,返回最佳的width,假如说我们现在想在width=150px的画布上显示合适的字体的话,可以这样

图片 17图片 18

发表评论

电子邮件地址不会被公开。 必填项已用*标注