JavaScript半知半解
前言
JavaScript简介
基本概念
语法
数据类型
运算符
表达式
语句
对象
数组
函数
引用类型(对象)
Object对象
Array对象
Date对象
RegExp对象
基本包装类型(Boolean、Number、String)
单体内置对象(Global、Math)
console对象
DOM
DOM-属性和CSS
BOM
Event 事件
正则表达式
JSON
AJAX
表单和富文本编辑器
表单
富文本编辑器
canvas
离线应用
客户端存储(Cookie、Storage、IndexedDB)
HTML5 API
Video/Audio
Geolocation API
requestAnimationFrame
File API
FullScreen API
IndexedDB
检测设备方向
Blob
vibrate
Luminosity API
WebRTC
Page Visibility API
Performance API
Web Speech
Notification
面向对象的程序设计
概述
this关键字
原型链
作用域
常用API合集
SVG
错误处理机制
JavaScript开发技巧合集
编程风格
垃圾回收机制
本书使用 GeChiUI.com 发布
canvas
canvas
最后更新于:2022-04-01 23:54:06
## Canvas **二、canvas** HTML5`
`元素用于图形的绘制,通过脚本 (通常是JavaScript)来完成。 `
`标签只是图形容器,您必须使用脚本来绘制图形。 要使用Canvas API,首先需要新建一个`
`网页元素 ```
您的浏览器不支持canvas!
``` width 和 height 属性定义的画布的大小。 接着,我们可以通过标签选择获取到
元素: ``` var canvas = document.getElementById('canvas'); ``` 然后,创建context对象: ``` if(canvas.getContext){ var ctx = canvas.getContext('2d'); } ``` 调用getContext()方法时,传递一个“2d”参数,会获得一个CanvasRenderingContext2D对象,使用该对象可以在画布上绘制二维图形。我们也可将CanvasRenderingContext2D简称为“上下文对象”。 **2.1 canvas的绘图用法** canvas画布提供了一个用来作图的平面空间,该空间的每个点都有自己的坐标,x表示横坐标,y表示竖坐标。原点(0, 0)位于图像左上角,x轴的正向是原点向右,y轴的正向是原点向下。 **(1)绘制矩形** - rect(x,y,width,height)方法用来绘制矩形。 - fillRect(x, y, width, height)方法用来绘制矩形,它的四个参数分别为矩形左上角顶点的x坐标、y坐标,以及矩形的宽和高。fillStyle属性用来设置矩形的填充色。 - strokeRect(x, y, width, height)方法同样是绘制矩形,但只画线不填充,也可以说是画空心矩形。strokeStyle属性用来设置矩形的绘制色。 - clearRect(x, y, width, height)方法用来清除某个矩形区域的内容。 **(2)绘制圆形和扇形** - arc(x, y, radius, startAngle, endAngle, anticlockwise)方法用来绘制圆形和扇形。 arc方法的x和y参数是圆心坐标,radius是半径,startAngle和endAngle则是扇形的起始角度和终止角度(以弧度表示),anticlockwise表示做图时应该逆时针画(true)还是顺时针画(false)。 - arcTo(x1,y1,x2,y2,r)方法在画布上创建介于两个切线之间的弧/曲线。 参数:x1 弧的起点的 x 坐标,y1 弧的起点的 y 坐标,x2 弧的终点的 x 坐标,y2 弧的终点的 y 坐标,r 弧的半径。 **(3)绘制文本** - fillText(string, x, y) 用来绘制文本,它的三个参数分别为文本内容、起点的x坐标、y坐标。使用之前,需用font设置字体、大小、样式(写法类似与CSS的font属性)。 strokeText(string,x,y)方法,用来添加空心字。 ``` // 设置字体 ctx.font = "Bold 20px Arial"; // 设置对齐方式,start、end、right、center ctx.textAlign = "left"; // 设置填充颜色 ctx.fillStyle = "#008600"; //设置垂直对齐方式,top、hanging、middle、alphabetic、ideographic、bottom ctx.textBaseline = top; ``` 我们还可以计算字体宽度(px): ``` var name = 'aaa'; ctx.measureText(name); ``` measureText() 方法返回包含一个对象,该对象包含以像素计的指定字体宽度。 ``` ctx.measureText(name).width ``` **(4)绘制路径** `beginPath()`方法表示开始绘制路径,`moveTo(x, y)`方法设置线段的起点,`lineTo(x, y)`方法设置线段的终点,`stroke()`方法用来给透明的线段着色。 ``` ctx.beginPath(); // 开始路径绘制 ctx.moveTo(20, 20); // 设置路径起点,坐标为(20,20) ctx.lineTo(200, 20); // 绘制一条到(200,20)的直线 ctx.lineWidth = 1.0; // 设置线宽 ctx.strokeStyle = '#CC0000'; // 设置线的颜色 ctx.stroke(); // 进行线的着色,这时整条线才变得可见 moveTo()和lineTo()方法可以多次使用。 ``` 注意:如果使用closePath()方法,会自动绘制一条当前点到起点的直线,形成一个封闭图形。 fill()和stroke()分别填充当前绘图(路径)和绘制已定义的路径。 **isPointInPath()** ``` isPointInPath(x,y); ``` 如果指定的点位于当前路径中,isPointInPath() 方法返回 true,否则返回 false。 **clip()** clip()方法从原始画布中剪切任意形状和尺寸。 注意:一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内(不能访问画布上的其他区域)。您也可以在使用 clip() 方法前通过使用 save() 方法对当前画布区域进行保存,并在以后的任意时间对其进行恢复(通过 restore() 方法)。 closePath()方法创建当前点回到起始点的路径。 **其他样式属性:** - lineCap 设置或返回线条的结束端点样式,可能值: butt|round|square(平直边缘|圆形线帽|正方形线帽) - lineJoin 设置或返回两条线相交时,所创建的拐角类型,可能值:bevel|round|miter(斜角|圆角|尖角(默认值)) - lineWidth 设置或返回当前的线条宽度。 - miterLimit 正数,设置或返回最大斜接长度。如果斜接长度超过 miterLimit 的值,边角会以 lineJoin 的 "bevel" 类型来显示。 - fillStyle 设置填充色 - strokeStyle 设置绘制线色 颜色格式: ``` //可直接用颜色名称 'red' 'green' //十六进制颜色 '#d9d9d9' //rgb rgb(0,0,0) //rgba rgba(0,0,0,1) ``` **(5)设置渐变色** **线性渐变** createLinearGradient方法用来设置渐变色。 ``` var gradient = ctx.createLinearGradient(0, 0, 0, 160); gradient.addColorStop(0, "#BABABA"); gradient.addColorStop(1, "#636363"); ``` createLinearGradient()方法的参数是(x1, y1, x2, y2),其中x1和y1是起点坐标,x2和y2是终点坐标。通过不同的坐标值,可以生成从上至下、从左到右的渐变等等。 使用方法: ``` ctx.fillStyle = myGradient; ctx.fillRect(10,10,200,100); ``` **环形渐变** createRadialGradient()方法的参数是(x0,y0,r0,x1,y1,r1),其中x0 渐变的开始圆的 x 坐标,y0 渐变的开始圆的 y 坐标,r0 开始圆的半径,x1 渐变的结束圆的 x 坐标,y1 渐变的结束圆的 y 坐标,r1 结束圆的半径。 ``` var grd=ctx.createRadialGradient(75,50,5,90,60,100); grd.addColorStop(0,"red"); grd.addColorStop(1,"white"); ctx.fillStyle=grd; ctx.fillRect(10,10,150,100); ``` **(6)设置阴影** 我们还可以设置阴影 ``` ctx.shadowOffsetX = 10; // 设置水平位移 ctx.shadowOffsetY = 10; // 设置垂直位移 ctx.shadowBlur = 5; // 设置模糊度 ctx.shadowColor = "rgba(0,0,0,0.5)"; // 设置阴影颜色 ctx.fillStyle = "#CC0000"; ctx.fillRect(10,10,200,100); ``` **(7)合成** `globalAlpha` 属性设置或返回绘图的当前透明值(alpha 或 transparency)。 `globalAlpha` 属性值必须是介于 0.0(完全透明) 与 1.0(不透明) 之间的数字。 ctx.globalAlpha = number `globalCompositeOperation`属性设置或返回如何将一个源(新的)图像绘制到目标(已有的)的图像上。 源图像 = 您打算放置到画布上的绘图。 目标图像 = 您已经放置在画布上的绘图。 ``` source-over 默认。在目标图像上显示源图像。 source-atop 在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。 source-in 在目标图像中显示源图像。只有目标图像之内的源图像部分会显示,目标图像是透明的。 source-out 在目标图像之外显示源图像。只有目标图像之外的源图像部分会显示,目标图像是透明的。 destination-over 在源图像上显示目标图像。 destination-atop 在源图像顶部显示目标图像。目标图像位于源图像之外的部分是不可见的。 destination-in 在源图像中显示目标图像。只有源图像之内的目标图像部分会被显示,源图像是透明的。 destination-out 在源图像之外显示目标图像。只有源图像之外的目标图像部分会被显示,源图像是透明的。 lighter 显示源图像 + 目标图像。 copy 显示源图像。忽略目标图像。 xor 使用异或操作对源图像与目标图像进行组合。 ``` **2.2 绘制图像** Canvas API 允许将图像文件插入画布。 我们可以使用Image对象来加载图片,然后绘制: ``` var image = new Image(); image.onload = function(){ ctx.drawImage(image,0,0); }; image.src='new.jpg'; ``` **drawImage方法** ``` drawImage(img,x,y) drawImage(img,x,y,width,height) drawImage(img,sx,sy,switch,sheight,x,y,width,height) ``` 参数: img 规定要使用的图像、画布或视频;sx 可选,开始剪切的 x 坐标位置;sy 可选,开始剪切的 y 坐标位置;swidth 可选,被剪切图像的宽度;sheight 可选,被剪切图像的高度;x 表示在画布上放置图像的 x 坐标位置;y 在画布上放置图像的 y 坐标位置;width 可选,表示要使用的图像的宽度(伸展或缩小图像);height 可选,表示要使用的图像的高度(伸展或缩小图像)。 **图像平铺** ``` createPattern(image,type) ``` 参数: type: no-repeat:不平铺 ;repeat-x:横方向平铺;repeat-y:纵方向平铺;repeat:全方向平铺 **2.3 像素处理** 通过`getImageData`方法和`putImageData`方法,可以处理每个像素,进而操作图像内容。 `getImageData()`方法可以用来读取Canvas的内容,返回一个对象,包含了每个像素的信息。 ``` var imageData = ctx.getImageData(x,y,w,h) ``` 参数:x是canvas的X轴坐标,y是canvas的Y轴坐标,w是宽度,h是高度。 getImageData()方法返回一个像素颜色数组(该数组的长度等于图像的像素宽度*图像的像素高度*4,每个值的范围是0-255,可读写),imageData的属性data就是指向它,顺序是所取像素范围的从左到右,从上到下,数组的元素是(所有图形,包括图片,和绘制的图形)每个像素的rgba : ``` [r1,g1,b1,a1,r2,g2,b2,a2...] ``` `putImageData()`方法可将数组内容重新绘制到Canvas上。 ``` putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight); ``` 参数:imgData 规定要放回画布的 ImageData 对象;x 是ImageData 对象左上角的 x 坐标,以像素计;y 是ImageData 对象左上角的 y 坐标,以像素计;dirtyX 可选,水平值(x),以像素计,在画布上放置图像的位置;dirtyY 可选,垂直值(y),以像素计,在画布上放置图像的位置;dirtyWidth 可选,在画布上绘制图像所使用的宽度;dirtyHeight 可选,在画布上绘制图像所使用的高度。 当然,我们也可以创建一个空白的ImageData对象。 ``` var imgData=context.createImageData(width,height); ``` 也可创建与指定的另一个ImageData对象尺寸相同的新ImageData对象(其不会复制图像数据): ``` var imgData=context.createImageData(imageData); ``` ImageData对象有data属性,它包含 color/alpha 信息的数组。 **2.4 保存与恢复** save()方法用于保存上下文环境,restore()方法用于恢复到上一次保存的上下文环境。 **2.5 保存图像** 我们可以使用toDataURL()方法将Canvas数据重新转化成图像文件形式: ``` canvas.toDataURL('image/png') ``` 上面的代码将Canvas数据,转化成PNG data URI。 **2.6 转换** **(1)scale()** scale() 方法缩放当前绘图至更大或更小。 ``` scale(scalewidth,scaleheight) ``` 参数:scalewidth 缩放当前绘图的宽度;scaleheight 缩放当前绘图的高度。 注意:如果您对绘图进行缩放,所有之后的绘图也会被缩放。定位也会被缩放。如果您 scale(2,2),那么绘图将定位于距离画布左上角两倍远的位置。 **(2)rotate()** rotate() 方法旋转当前的绘图。 ``` rotate(angle) ``` 参数:angle 旋转角度,以弧度计。 注意:旋转只会影响到旋转完成后的绘图。 **(3)translate()** translate() 方法重新映射画布上的 (0,0) 位置。 ``` translate(x,y) ``` 参数:x 添加到水平坐标(x)上的值;y 添加到垂直坐标(y)上的值。 **(4)transform()** ``` transform(a,b,c,d,e,f) ``` 参数:a 水平缩放绘图,b 水平倾斜绘图,c 垂直倾斜绘图,d 垂直缩放绘图,e 水平移动绘图,f 垂直移动绘图。 **(5)setTransform()** setTransform() 方法把当前的变换矩阵重置为单位矩阵,然后以相同的参数运行 transform()。 ``` setTransform(a,b,c,d,e,f) ``` 参数:a 水平缩放绘图,b 水平倾斜绘图,c 垂直倾斜绘图,d 垂直缩放绘图,e 水平移动绘图,f 垂直移动绘图。 注意:该变换只会影响 setTransform() 方法调用之后的绘图。 **2.7 动画** 我们可以使用`setInterval()`和`setTimeout()`来产生动画效果。 还可以使用`requestAnimationFrame()`来制作动画。 requestAnimationFrame()函数是全局函数。 考虑兼容,如下: ``` var requestAnimFrame = function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(a) {window.setTimeout(a, 1e3 / 60, (new Date).getTime())}; }(); ``` 使用方法: ``` function step(){ requestAnimationFrame(step); } ``` requestAnimationFrame()方法会返回一个requestID,是一个长整型非零值,作为一个唯一的标识符,可将该值作为参数传递给window.cancelAnimationFrame()来取消这个函数。 ``` cancelAnimationFrame(requestID); ``` 兼容性代码: ``` var cancelAnimFrame = function() { return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) { clearTimeout(id); }; }(); ```
';