JavaScript  使用Canvas绘图

<canvas>元素负责在页面中设定一个区域,可以通过JavaScript动态地在这区域中绘制图形。

一、基本用法

1、先设置width和height来指定绘图区域大小,默认是透明的。需用getContext()方法获得绘图上下文。

if(drawing.getcontext){    //检测浏览器是否支持canvas元素var context=drawing.getContext("2d");    //获取2D上下文对象
}

2、使用toDataURL()方法可获取绘制的图像,参数为图像的MIME类型各式。

var imgURL=drawing.toDataURL("image/png");

二、2D上下文

1、填充和描边

填充使用fillStyle属性,描边使用strokeStyle属性,属性的值(默认为"#000000")可以是字符串、渐变对象或模式对象。

context.strokeStyle="red";     //红色描边
context.fillStyle="#0000ff";   //蓝色填充

2、绘制矩形

fillRect()方法——有填充的矩形,颜色通过fillStyle属性设置,通过rgba()格式可设置填充透明度,

strokeRect()方法——有边框的矩形,颜色通过fillStyle属性设置,

clearRect()方法用于清除画布上的矩形区域,

常用这三个方法绘制矩形,且他们都有4个参数(x,y,width,height)。

描边线宽由lineWidth属性控制(值为整数)

线条末端形状由lineCap属性控制(值:butt平头、round圆头、square方头)

线条相交的方式由lineJoin属性控制(值:round圆交、bevel斜交、miter斜接)

context.fillStyle="ff0000";      //矩形填充为红色
context.fillRect(10,10,50,50);   //在(10,10)坐标,添加以宽50,高50,颜色填充的矩形
context.fillStyle="rgba(0,0,255,0.5)";    //设置矩形为蓝色,50%透明度
context.clearRect(40,40,10,10);    //在(40,40)坐标设置宽高为10的透明矩形

3、绘制路径

2D绘制可通过路径创造出复杂的形状和线条。首先调用beginPath()方法开始绘制新路径。然后,再通过调用下列方法创建路径:

arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)为圆心,半径radius,起始和结束角度,counterclockwise按逆时针旋转为true。

arcTo(x1, y1, x2, y2, radius):从上一点开始绘制一条弧线,到(x2, y2)为止,并且以给定的半径radius穿过(x1, y1)。

bezierCurveTo(c1x, c1y, c2x, c2y, x, y):从上一点开始绘制一条曲线,到(x, y)为止,并且以(c1x, c1y)和(c2x, c2y)为控制点。

lineTo(x, y):从上一点开始绘制一条直线,到(x, y)为止。

moveTo(x, y):将绘图游标移动到(x, y),不画线。

quadraticCurveTo(cx, cy, x, y):从上一点开始绘制一条二次曲线,到(x, y)为 止,并且以(cx, cy)作为控制点。

rect(x, y, width, height):从点(x, y)开始,设置矩形宽高,这个方法绘制的是矩形路径。

调用closePath()可以绘制一条连接到路径起点的线条。

可以调用fill()方法,使用用 fillStyle填充它。

可以调用stroke()方法对路径描边,描边使用的是strokeStyle。

可以调用clip()方法在路径上创建一个剪切区域。

context.arc(100,100,99,0,2*Math.PI,false);  //以(100,100)为圆心,半径99,画一个圆
context.moveTo(100,100);     //将坐标移动到(100,100)
context.lineTo(100,15);      //画一条从(100,100)到(100,15)的直线
context.stroke();     //描边路径

isPointInPath()可以在路径被关闭之前确定画布上的某一点是否位于路径上。

4、绘制文本

fillText()方法使用fillStyle属性绘制文本,strokeText()方法使用strokeStyle属性描边文本,他们接收4个参数:文本字符串、x,y坐标和最大像素宽度。且都有以下列3个属性,基本与CSS相同

font:文本样式、大小及字体,同CSS

textAlign:文本对齐方式。值有"start"、"end"、"left"、"right"和"center"。 建议使用"start:x坐标为文本起点"和"end"

textBaseline:文本的基线。值有"top:y坐标为文本顶端"、"hanging"、"middle"、"alphabetic"

context.font="bold 16px Arial";    //粗体,16px大小,Arial字体
context.textAlign="center";      //x在文本中间(居中对齐)
context("大家好",100,20);        //在(100,20)写入:大家好

可以使用measureText()方法输出文本的宽度,参数为要计算的文本字符。

var textwidth = context.measureText("Hello!").width;   //测量Hello!文本的宽度px

5、变换

通过上下文的变换可将处理后的图像绘制到画布上。使用不同的变换矩阵产生不同的结果。 可以通过如下方法来修改变换矩阵。
rotate(angle):围绕原点旋转图像angle弧度。

scale(scaleX, scaleY):以倍数缩放图像

translate(x, y):将坐标原点移动到(x, y)。

transform(m1_1, m1_2, m2_1, m2_2, dx, dy):直接修改变换矩阵,方式是乘以如下矩阵。

setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):将变换矩阵重置为默认状态,然后再调用transform()。

调用save()可以把设置保存到栈结构中,调用restore()方法回到之前保存的设置。

6、绘制图像

使用 drawImage()方法可以把一幅图像绘制到画布上,可以通过以下三种方式。

context.drawImage(document.images[0],10,10);   //将第一张图传到画布上,起点为(10,10)
context.drawImage(document.images[0],50,10,20,30); //起点为(50,10),大小为20*30像素
context.drawImage(image,0,0,30,30,40,0,15,15); //剪切图像,并在画布上定位被剪切的部分

剪切图像的方法:context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);

此方法参数按顺序为:剪切起点(sx,sy)   被剪宽高    将图片放在(x,y)    图片宽高

7、阴影

以下几个context的属性可设置形状或路径的阴影

shadowColor:用CSS颜色格式表示的阴影颜色,默认为黑色

shadowOffsetX:x轴方向的阴影偏移量,默认为0

shadowOffsetY:y轴方向 的阴影偏移量,默认为0

shadowBlur:模糊的像素数,默认 0,即不模糊。

context.shadowOffsetX=2;    //X方向阴影为2px
context.shadowOffsetY=2;    //y方向阴影为2px
context.shadowBlur=1;       //模糊值为1
context.shadowColor="rgba(0,0,0,0.2)"    //透明度为20%的黑色阴影

8、渐变

1、用createLinearGradient()方法创建一个新的线性渐变,参数为:起点(x,y)和终点(x,y)

使用 addColorStop()方法指定色标:参数为①色标(0~1)  ②颜色

var gradient = context.createLinearGradient(30,30,50,50);  //从(30,30)到(50,50)填充
gradient.addColorStop(0,"white");  //起点颜色为白色
gradient.addColorStop(1,"black");  //终点颜色为黑色
context.fillStyle = gradient;     //使用渐变填充

2、使用createRadialGradient()方法创建径向渐变,有6个参数,为起点坐标和圆半径、终点坐标和圆半径。

var gradient = context.createRadialGradient(30,30,10,30,30,20); //同心圆渐变

9、模式

模式就是重复的图像,可以用来填充或描边图形。用 createPattern()方法创建一个新模式并传入两个参数:HTML <img>元素和background-repeat 属性值,包括"repeat"、"repeat-x"、"repeaty"和"no-repeat"。

模式从(0,0)开始重复,填充样式显示的是画布某个区域的重复图像。

pattern = context.createPattern(image,"repeat");
context.fillStyle = pattern; 

10、使用图像数据

通过getImageData()取得原始图像数据,参数为图像的(x,y,width,height)。返回的是ImageData对象,有三个属性:width、height和data。其中data属性是一个数组,保存着图像中每一个像素的数据。每一个像素用4个元素来保存,分别表示红、绿、蓝和透明度值。因此,第一个像素的数据就保存在数组的第0到第3个元素中

var data = imageData.data,red=data[0],green=data[1],blue=data[2],alpha=data[3];    //获取图像第一个像素的红绿蓝以及透明度

11、合成

globalAlpha属性为设置全局透明度。

三、WebGL

WebGL是针对Canvas的3D上下文

1、类型化数组

类型化数组也是数组,但其元素被设置为特定类型的值。

ArrayBuffer能在内存中分配一定数量的字节,可通过其byteLength属性获取包含的字节数

var buffer = new ArrayBuffer(20);  //分配20B内存
var bytes = buffer.byteLength;    

1、视图

用ArrayBuffer来创建数组缓冲器视图,如DataView,可节选ArrayBuffer数据段。通过其buffer属性也可以取得数组缓冲器

var view = new DataView(buffer,8,10);  //从字节8开始,到字节18结束。
view.byteOffset;    //字节偏移量8存在byteOffset中
view.byteLength;    //字节长度存在byteLength中

读写DataView时,可选用相应的getter和setter方法,第一个参数都为字节偏移量。set方法第二个参数为要设置的数,get的第二个参数为是否采用小端字节序。

getInt8()       setInt8()      getUnit8()     setUnit8()

getInt16(,)    setInt16(,)      getUnit16(,)    SetUnit16(,)     也可以是32位,或者Float32,Float64

2、类型化视图

类型化数组分为几种,都继承了DataView。

Int8Array:8位二补整数     Uint8Array:8位无符号整数    Int16Array:16位二补整数    Uint16Array:16位无符号整数

Int32Array:32位二补整数    Uint32Array:32位无符号整数    Float32Array:32位IEEE浮点值    Float64Array:64位IEEE浮点值

使用构造函数来实例化参数:ArrayBuffer对象,起点的字节偏移量(默认为0),要包含的字节数。

var int16s = new Int16Array(buffer,9,10);   //使用从字节9到字节18的缓冲器

二、WebGL上下文

取得了WebGL上下文之后,就可以开始3D绘图了, 一般都把WebGL上下文对象命名为gl。通过给getContext()传递第二个参数,可以为 WebGL上下文设置一些选项。这个参数本身是一个对象,可以包含下列属性,但一般不需要设置。

alpha:true时可为上下文创建一个Alpha通道缓冲区       depth:true时可以使用16位深缓冲区

stencil:true时可以使用8位模板缓冲区                          antialias:true时使用默认机制执行抗锯齿操作

premultipliedAlpha:true时绘图缓冲区有预乘Alpha值    reserveDrawingBuffer:true时在绘图完成后保留绘图缓冲区;

if(drawing.getContext){    //是否支持getContextvar gl = drawing.getContext("experimental-webg1"),{alpha:false};    //创建上下文if(gl){//使用WebGL
} }

1、常量

2、方法命名:方法名的后缀会包含参数个数(1到4)和接收的数据类型(f表示浮点数,i表示整数,v为数组),如gl.uniform4f。

3、用clearColor(,,,)方法使用某种实色清除<canvas>,参数为红绿蓝和透明度,值为0~1

gl.clearColor(0,0,0,1);    //用黑色清除画布

4、视口与坐标

可以调用 viewport()方法来改变视口大小,有4个参数:(视口相对于<canvas>元素的)x、y、width、height。

视口坐标的原点(0,0)在<canvas>元素的左下角,x轴和y轴的正方向分别是向右和向上。

g1.viewport(0,0,drawing.width/2,drawing.height/2);  //视口在画布左下角1/4

5、缓冲区

创建缓冲区:调用gl.createBuffer(),然后使用gl.bindBuffer()绑定到WebGL上下文。

var buffer = gl.createBuffer();   //创建缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);    //将buffer设置为上下文的当前缓冲区
gl.bufferData(fl.ARRAY_BUFFER,new Float32Array([0,0.5,1]},gl.STATIC_DRAW);

可以使用 drawElements(gl.ELEMENT_ARRAY_BUFFER)输出缓冲区的内容。

gl.bufferData()的最后一个参数用于指定使用缓冲区的方式,可以取以下几个值
gl.STATIC_DRAW:数据只加载一 次,在多次绘图中使用。    gl.STREAM_DRAW:数据只加载一 次,在几次绘图中使用。gl.DYNAMIC_DRAW:数据动态改 变,在多次绘图中使用。

6、错误

WebGL操作一般不会抛出错误,调用gl.getError()方法可知道错误类型,

gl.NO_ERROR:没错,值为0   gl.INVALID_ENUM:应该给方法传入WebGL常量   gl.INVALID_VALUE:在无符号数的地方传入了负值

gl.INVALID_OPERATION:在当前状态下不能完成操作    gl.OUT_OF_MEMORY:内存不够

gl.CONTEXT_LOST_WEBGL:由于外部事件(如设备断电)干扰丢失了当前WebGL上下文

var errorCode = gl.getError();
while(errorCode){console.log("Error occurred:"+errorCode);    //循环调用getError直到没错时errorCode = gl.getError();
}    

7、着色器有两种:顶点着色器和片段 (或像素)着色器。顶点着色器用于将3D顶点转换为需要渲染的2D点。片段着色器用于准确计算要绘制的每个像素的颜色。这些着色器是使用GLSL(OpenGL着色语言)写的。

8.编写着色器:GLSL语言

每个着色器都有一个main()方法。attribute(顶点着色器)和uniform(向任何着色器传入常量值),在main方法外部定义
main()方法外部定义.

attribute vec2 aVertexPosition;  //顶点着色器
void main(){gl_Positon = vec4(aVertexPosition,0.0,1.0);  //把2D转成3D坐标
}

9、编写着色器程序

通常是把着色器包含在页面的<script>标签内,并为该标签指定一个自定义的type属性。

10、绘图

WebGL只能绘制三种形状:点、线和三角。  gl.drawArrays()方法用于数组缓冲区,gl.drawElements()方法用于元素数组缓冲区,第一个参数表示要绘制的形状,值为:

gl.POINTS:每个顶点都是点    gl.LINES:在这些顶点间连线    gl.LINE_LOOP:将顶点连起来,轮廓

gl.LINE_STRIP:将顶点连起来,但最后一个不和第一个点连    gl.TRIANGLES:顶点间画三角形

gl.TRIANGLES_STRIP:三角形,三角形间顶点相连    gl.TRIANGLES画三角形,三角形间边相连

11、纹理

调用gl.createTexture()创建一个新纹理,然后再将一幅图像绑定到该纹理。

12、读取像素

读取像素值的方法readPixels()与 OpenGL中的同名方法只有一点不同,即最后一个参数必须是类型化数组。

JavaScript 使用Canvas绘图相关推荐

  1. 每天一个JavaScript实例-canvas绘图

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  2. 【JavaScript】Canvas绘图整理

    文章目录 绘制矩形 点线模式 绘制艺术字 绘制圆形路径 绘制圆角矩形 绘制凹多边形 绘制曲线 绘制位图 绘制坐标变换 绘制坐标变换与路径结合 绘制矩阵变换 绘制叠加效果 绘制线性渐变和径向渐变 位图填 ...

  3. javascript:使用canvas绘图2D图形

    HTML5最少欢迎的一个新功能就是canvas元素,这个元素负责在页面中设定一个区域,然后就可以使用javascript进行动态的绘图. 基本用法 <canvas id="drawin ...

  4. JavaScript:使用Canvas绘图

    1.基本用法   要使用<canvas>元素,必须先设置其width和height属性,指定可以绘图的区域大小,出现在开始后结束标签中的内容是后备信息,如果浏览器不支持<canvas ...

  5. 如何使用canvas绘图

    这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [如何使用can ...

  6. H5 canvas 绘图

    H5的canvas绘图技术 canvas元素是HTML5中新添加的一个元素,该元素是HTML5中的一个亮点.Canvas元素就像一块画布,通过该元素自带的API结合JavaScript代码可以绘制各种 ...

  7. Canvas绘图在微信小程序中的应用:生成个性化海报

    Canvas绘图在微信小程序中的应用:生成个性化海报 如极客时间的一些实现案例: 基础语法 Canvas本质是一个可以使用脚本(通常为JavaScript)来绘制图形的 HTML 元素,默认大小为30 ...

  8. [转]基于Prototype,利用Canvas绘图实现的web流程图设计器(原型)

    基于Prototype,利用Canvas绘图实现的web流程图设计器(原型) 关键字: javascript prototype script.aculo.us canvas 流程图 web画线 刚才 ...

  9. html5怎么修改图片大小,HTML5 javascript修改canvas的大小

    方法1: 设定固定的值,这种方式跟在html中设定canvas的值没有什么区别: window.onload = function(){ canvas.height = 100; canvas.wid ...

最新文章

  1. C++ 笔记(19)— 标准模板库(STL容器、STL迭代器、STL算法、STL容器特点、STL字符串类)
  2. mysql执行计划中性能最差的是_面试中:mysql性能调优-执行计划explain
  3. Chapter 2 Open Book——16
  4. python解释器是什么-python的解释器是什么?
  5. 蒙面也能识别?俄罗斯开发新技术,伪装犯罪将在监控下无处遁行
  6. altera fpga 型号说明_基于FPGA的USB2.0接口通信
  7. 【python教程入门学习】7个习惯提升python效率
  8. pydev导入eclipse
  9. sql server表分区_介绍分区表SQL Server增量统计信息
  10. ChaLearn Gesture Challenge_3:Approximated gradients源码简单分析
  11. python中列表中的字典的排序问题
  12. Linux下kafka之C/C++客户端库librdkafka的编译,安装以及函数介绍
  13. 文献阅读---普通狗牙根阳江基因组单倍型解析与基因组稳定性和匍匐性研究
  14. 【Mind+ 玩转Maixduino系列0】工欲善其事必先利其器
  15. Ubuntu中程序崩溃,杀死进程方法
  16. Docker安装配置Redis最全教程
  17. TensorFlow实现CGAN
  18. C语言程序设计-餐厅点餐系统
  19. 编程心得之逻辑判断的先后顺序
  20. 4核处理器_麒麟990和麒麟990e哪个处理器好?选择哪款芯片更好?

热门文章

  1. 《淘宝网开店 拍摄 修图 设计 装修 实战150招》一一1.14 如何掌握拍摄角度
  2. 前端VUE常用UI框架总结
  3. 支付宝转卡飞行模式原理
  4. SSM+LayUi实现的学籍管理系统(分为管理员、教师、学生三个角色,实现了专业管理,班级管理,学生管理,老师管理,课程管理,开课管理以及用户管理等)
  5. 对宏offsetof理解
  6. 【怎么看有没有被蹭网】
  7. Redis核心原理与应用实践
  8. 中国通信设备商占全球5G设备市场近半数份额,强化研发自主芯片
  9. Console 3000字完整指南,让你不只会用console.log !
  10. 扎克曼的《信息系统架构框架》