当前位置: 首页 > news >正文

58同城湛江网站建设百度应用商店app下载安装

58同城湛江网站建设,百度应用商店app下载安装,百度联盟网站怎么做,wordpress首页图片导航分类Canvas学习#xff1a;封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到#xff0c;通过Canvas中的CanvasRenderingContext2D对象中的属性和方法#xff0c;我们可以很轻松的绘制出一些基本图形#xff0c;比如直线、弧线、矩形、圆形、三角形等。但… Canvas学习封装Canvas绘制基本图形API Canvas Canvas学习   从前面的文章中我们了解到通过Canvas中的CanvasRenderingContext2D对象中的属性和方法我们可以很轻松的绘制出一些基本图形比如直线、弧线、矩形、圆形、三角形等。但有很多基本图形的绘制是没有现成的方法需要通过CanvasRenderingContext2D对象中的属性和方法组合在一起才能绘制出来比如说点划线、箭头和正多边形等。为了更好的帮助大家在Canvas中绘制这些基本图形可以将这些基本图形的绘制封装起来。今天这篇文章我们主要来看看怎么将这些函数封装。 回忆前面的内容 Canvas学习系列到目前为止已整理的都是关于基本图形绘制相关的知识主要涵盖 Canvas入门准备Canvas里的坐标系统Canvas坐标变换Canvas自定义的坐标变换Canvas绘制线段Canvas线型Canvas状态save()和restore()Canvas绘制矩形Canvas绘制圆和圆弧Canvas绘制贝塞尔曲线Canvas绘制虚线和圆点线Canvas绘制箭头Canvas绘制正多边形 如果您和我一样初次接触Canvas建议您先花一定的时间阅读上面这些文章有助于您更好的理解下面的内容。 Canvas绘图相关属性和方法 canvas元素有一个getContext()方法这个方法可以用来获取上下文和它的绘画功能。getContext()只有一个参数上下文的格式。我们目前学习的上下文环境都是一个2D环境所以我们所说的也是对于2D图像而言。它具CanvasRenderingContext2D对象。这个对象包括一些绘制图形方法和设置图形样式的属性。 状态 CanvasRenderingContext2D渲染环境包含了多种绘图的样式状态属性有线的样式、填充样式、阴影样式、文本样式等其中该对象提供了两个方法能帮助我们更好的使用好这些状态 CanvasRenderingContext2D.save()使用栈保存当前的绘画样式状态你可以使用 CanvasRenderingContext2D.restore() 恢复任何改变CanvasRenderingContext2D.restore()恢复到最近的绘制样式状态此状态是通过 CanvasRenderingContext2D.save() 保存到”状态栈“中最新的元素 有关于这方面的详细介绍可以阅读Canvas状态save()和restore() 一文。 变换 CanvasRenderingContext2D渲染背景中的对象会有一个当前的变换矩阵一些方法可以对其进行控制。当创建当前的默认路径、绘制文本、图形等会应用此变换矩阵。 CanvasRenderingContext2D.rotate(rad)在变换矩阵中增加旋转角度变量表示一个顺时针旋转角度并且用弧度表示CanvasRenderingContext2D.scale(sx, sy)根据sx水平方向和sy垂直方向为Canvas单位添加缩放变换CanvasRenderingContext2D.translate(dx,dy)通过在网格中移动Canvas和Canvas原点dx水平方向、原点dy垂直方向添加平移变换CanvasRenderingContext2D.transform(a, b, c, d, e, f)使用方法参数描述的矩阵多次叠加当前的变换矩阵CanvasRenderingContext2D.setTransform(a, b, c, d, e, f)重新设置当前的变换为单位矩阵并使用同样的变量调用CanvasRenderingContext2D.transform(a, b, c, d, e, f)方法CanvasRenderingContext2D.resetTransform()使用单位矩阵重新设置当前的变换 有关于Canvas中的变换涉及到了Canvas的坐标系统相关知识建议您阅读前面介绍的Canvas里的坐标系统、Canvas坐标变换和Canvas自定义的坐标变换三篇文章。 线型 CanvasRenderingContext2D提供了相关的方法和属性控制如何在Cavnas画布中绘制线的样式风格 CanvasRenderingContext2D.lineWidth线的宽度默认值1.0CanvasRenderingContext2D.lineCap线末端的类型。允许的值butt默认值、round和squareCanvasRenderingContext2D.lineJoin定义两线相交拐点的类型。允许值miter默认值、round和bevelCanvasRenderingContext2D.miterLimit斜接面限制比例默认10 有关于这几个属性的详细介绍可以阅读Canvas绘制线段和Canvas线型。 填充和描边 填充和描边有对应的属性和方法。其中属性主要用于填充设计用于图形内部的颜色和样式描边设计用于图形的边线方法主要用于填充路径和描边路径 CanvasRenderingContext2D.fillStyle图形内部的颜色和样式填充默认#000CanvasRenderingContext2D.strokeStyle图形边线的颜色和样式描边默认#000CanvasRenderingContext2D.fill()使用当前的样式填充子路径CanvasRenderingContext2D.stroke()使用当前的样式描边子路径 路径 Canvas的CanvasRenderingContext2D对象中用于操作路径的方法主要有 CanvasRenderingContext2D.beginPath()清空子路径列表开始一个新的路径。当你想创建一个新的路径时调用此方法CanvasRenderingContext2D.closePath()使笔点返回到当前子路径的起始点。它尝试从当前点到起点绘制一条直线。如果图形已经是封装的或者只有一个点那么此方法不会做任何操作CanvasRenderingContext2D.moveTo(x, y)将一个新的子路径的起始点移动到(x, y)坐标CanvasRenderingContext2D.lineTo(x, y)使用直线连接子路径的最后的点到(x, y)坐标CanvasRenderingContext2D.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)添加一个三次贝塞尔曲线路径。该方法需要三个点。 第一、第二个点是控制点第三个点是结束点。起始点是当前路径的最后一个点绘制贝赛尔曲线前可以通过调用 moveTo() 进行修改CanvasRenderingContext2D.quadraticCurveTo(cpx, cpy, x, y)添加一个二次贝塞尔曲线路径CanvasRenderingContext2D.arc(x, y, r, startAngle, endAngle, [anticlockwise])绘制一段圆弧路径圆弧路径的圆心在(x,y)位置圆弧的半径为r根据anticlockwise指定圆弧的方向从startAngle开始绘制到endAngle结束也就是旋转方向默认为顺时针CanvasRenderingContext2D.arcTo(x1, y1, x2, y2, radius)根据控制点和半径绘制圆弧路径使用直线连接前一个点CanvasRenderingContext2D.rect(x,y,width,height)创建一个矩形路径矩形的起始点位置是(x, y)尺寸为width和height 这些路径方法可以帮助我们在Canvas中绘制直线、曲线、弧线贝塞尔曲线、圆、矩形甚至结合这些路径方法可以绘制出其他的图形比如矩形、多边形三角形或者其他的复杂图形。这些方法也是绘制图形的基本方法也是核心方法只有更好的掌握这些方法才能更好的在Canvas中绘制出你自己想要的图形。 有关于这些方法的使用在下面这些文章都有详细介绍过 Canvas绘制线段Canvas绘制矩形Canvas绘制圆和圆弧Canvas绘制贝塞尔曲线Canvas绘制虚线和圆点线Canvas绘制箭头Canvas绘制正多边形 绘制矩形 在Canvas中除了可以使用CanvasRenderingContext2D对象中路径方法绘制之外还专门提供了几个方法来绘制矩形 CanvasRenderingContext2D.clearRect(x, y, width, height)设置指定矩形区域内以(x,y)为起点范围是(width, height)所有像素变成透明并擦除之前绘制的所有内容CanvasRenderingContext2D.fillRect(x, y, width, height) 绘制填充矩形矩形的起点在(x, y)位置矩形的尺寸是width和heightCanvasRenderingContext2D.strokeRect(x, y, width, height)在Canvas中使用当前的绘画样式描绘一个起点在(x, y)位置尺寸为width和height的矩形 前面我们专门花了一节的内容Canvas绘制矩形来介绍这几个方法的使用。 封装绘图的API 虽然Canvas中的CanvasRenderingContext2D对象有很多方法和属性能帮助我们绘不同的图形但如果你的工作每天都跟图形打交道的话建议你使用这些方法和属性封装出绘图的函数或者方法。在接下来的内容我们来看看怎么封装绘制基本图形的函数。 首先回想一下我们常常碰到的基本图形有线段分别实现、虚线和圆点线、箭头、弧线、圆、矩形、扇形和正多边形等。那下面的内容就是来看看怎么写代码。 声明环境 在Canvas中都有一个2D的绘图环境那么我们可以简单的封装一个initDrawCanvas()函数来处理 // 声明Canvas对象 var canvas; // 声明Context对象 function initDrawCanvas(canvas, ctx) { this.canvas canvas; this.ctx ctx; } 线段 线段我们主要常看到的有实线Solid、虚线Dashed和圆点线Dotted。在学习几何知识时我们知道两点确定一条线段。那么在我们封装的函数中我们需要两个点的坐标比如起始点坐标(startX, startY)和结束点坐标(endX, endY)。另外为了更好的通过封装的函数控制绘制的线段我们还需要设置线段的宽度和颜色也就是需要另外两个参数比如使用lineWidth来传线宽color传线段的颜色。 前面也说了线段分为三种也就是说我们封装的函数也封装成三个比如 实线线段drawSolidLine()虚线线段drawDashedLine()圆点线段drawDottedLine() 通过前面的知识我们可以使用moveTo()和lineTo()两个方法来控制线段的起点和终点另外lineWidth和fillStyle或者strokeStyle控制线段粗线和颜色。如此一来我们可以这样来写drawSolidLine()函数 // 绘制实线线段 // param {Number} startX - 线段起点x轴坐标 // param {Number} startY - 线段起点y轴坐标 // param {Number} endX - 线段终点x轴坐标 // param {Number} endY - 线段终点y轴坐标 // param {Number} lineWidth - 线宽 // param {String} color - 线颜色 function drawSolidLine(startX, startY, endX, endY, lineWidth, color){ ctx.save(); ctx.strokeStyle color; ctx.lineWidth lineWidth; ctx.beginPath(); ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); ctx.stroke(); ctx.restore(); } 对于虚线的绘制在Canvas的对象中提供了一个setLineDash()方法在这个方法中我们可以传递一个数组来控制虚线的间距和长度。在drawSolidLine()基础上我们进行一下扩展来封装drawDashedLine()函数 // 绘制虚线 // param {Number} startX - 线段起点x轴坐标 // param {Number} startY - 线段起点y轴坐标 // param {Number} endX - 线段终点x轴坐标 // param {Number} endY - 线段终点y轴坐标 // param {Array} setLineDash - 点划线间距 // param {Number} lineWidth - 线宽 // param {String} color - 线段颜色 function drawDashedLine(startX, startY, endX, endY, setLineDash, lineWidth, color) { ctx.save(); ctx.lineWidth lineWidth; ctx.strokeStyle color; ctx.beginPath(); ctx.setLineDash(setLineDash); ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); ctx.closePath(); ctx.stroke(); ctx.restore(); } 对于圆点线绘制函数相对而言要较为复杂一点因为在Canvas中没有提供一个类似setLineDash()方法让我们来控制圆点的圆点大小以及间距。既然我们绘制的是圆点线那么在Canvas中我们可以使用.arc()方法来绘制圆。如此一来就好办了 // 绘制圆点线 // param {Number} startX - 线段起点x轴坐标 // param {Number} startY - 线段起点y轴坐标 // param {Number} endX - 线段终点x轴坐标 // param {Number} endY - 线段终点y轴坐标 // param {Number} interval - 间隔 // param {Number} radius - 圆点半径 // param {String} color - 线段颜色 function drawDottedLine(startX, startY, endX, endY, radius, interval, color) { if (!interval) { interval 5; } var isHorizontal true; if (startX endX) { isHorizontal false; } var len isHorizontal ? endX - startX : endY - startY; ctx.strokeStyle color; ctx.fillStyle color; ctx.save(); ctx.beginPath(); ctx.moveTo(startX, startY); var progress 0; while (len progress) { progress interval; if (progress len) { progress len; } if (isHorizontal) { ctx.moveTo(startX progress, startY); ctx.arc(startX progress, startY, radius, 0, Math.PI * 2, true); ctx.fill(); } else { ctx.moveTo(startX, endX progress); ctx.arc(startX, startY progress, radius, 0, Math.PI * 2, true); ctx.fill(); } } ctx.restore(); } 通过前面的知识我们可以通过lineJoin和lineCap控制线型但在上面的函数封装中并没有做这方面相关的考虑。不过并不要紧在实际使用可以通过ctx.lineJoin或ctx.lineCap来设置当然你也可以修改上面的函数将这个参数传进去。 矩形 在Canvas中可能通过rect()路径的绘制也可以通过fillRect()和strokeRect()绘制矩形。使用这些方法绘制矩形都有相同的参数 (x,y)矩形起点坐标也就是矩形左上角的坐标width矩形的宽度height矩形的高度 在绘制矩形我们有填充和描边矩形之分另外在Canvas中可以直接使用fillRect()和strokeRect()来绘制。只不过Canvas中自带的方法只能绘制直角矩形如果我们要绘制圆角矩形那还是需要借用arcTo()方法来制作圆角。为了更好的区分直角矩形和圆角矩形我们各自为他们封装了一个函数 drawRect()直角矩形drawRoundedRect()圆角矩形 下面代码是各自函数对应的 // 封装直角矩形 // 矩形包括 填充矩形、边框矩形和清除矩形区域 // param {Number} x - 矩形起点的x坐标 // param {Number} y - 矩形起点的y坐标 // param {Number} width - 矩形宽度 // param {Number} height - 矩形高度 // param {Boolean} isClear - 是否绘制清除画布的矩形区域 true则是绘制一个清除画布矩形区域, false就是绘制其他两种矩形 // param {Boolean} isFill - 是否填充true绘制填充矩形 false绘制边框矩形 // param {String} color - 矩形颜色 function drawRect(x, y, width, height, isClear, isFill, color) { // 为true表示绘制清除画布的矩形区域那么传入的isFillcolor值可以为任意值 if (isClear) { ctx.clearRect(x, y, width, height); } else { if (isFill) { ctx.fillStyle color; ctx.fillRect(x, y, width, height); } else { ctx.strokeStyle color; ctx.strokeRect(x, y, width, height); } } } 其中isClear是一个布尔值用来判断是否要绘制一个清除矩形区域功能对应的是Canvas中的clearRect()方法。而isFill也是一个布尔值用来判断是否绘制一个填充矩形还是描边矩形如果值为true调用fillRect()绘制一个填充矩形false则调用strokeRect()绘制一个描边矩形。最后传了一个color参数用来控制矩形的填充颜色或者描边颜色。 从上面的代码中可以看出绘制描边矩形时并没有设置边框的粗线如果你绘制一个描边矩形时需要设置边框粗组时在实际调用时可以借用ctx.lineWidth属性来设置。 注drawRect()函数只能绘制填充或描边直角矩形如果你需要绘制具有填充和描边的一个矩形时上面的函数就无能为力了当然你可以通过其他的方法来进行封装这里就不做过多的阐述了。有兴趣的同学可以自己动手比如封装一个xxx函数。 上面是封装绘制直角矩形的函数接下来看圆角矩形的函数的封装。大致方法是类似的只不过我们封装圆角矩形时使用了arcTo()方法来实现圆角而这个圆角弧度需要一个半径所以在上面的直角矩形基础上再传一个radius参数 // 绘制圆角矩形 // param {Number} x - 矩形左上角x轴坐标 // param {Number} y - 矩形左上角y轴坐标 // param {Number} width - 矩形的宽度 // param {Number} height - 矩形的高度 // param {Number} radius - 矩形圆角的半径 // param {Boolean} isFill - 是否绘制填充true填充false边框 // param {String} color - 矩形的颜色 function drawRoundedRect(x, y, width, height, radius, isFill, color) { ctx.save(); ctx.beginPath(); ctx.moveTo(x radius, y); ctx.arcTo(x width, y, x width, y radius, radius); ctx.arcTo(x width, y height, x width - radius, y height, radius); ctx.arcTo(x, y height, x, y height - radius, radius); ctx.arcTo(x, y, x radius, y, radius); ctx.closePath(); if (isFill) { ctx.fillStyle color; ctx.fill(); } else { ctx.strokeStyle color; ctx.stroke(); } ctx.restore(); } 有关于矩形的绘制和对应函数封装在前面的Canvas绘制矩形一文中或多或少的介绍过对于arcTo()的详细使用可以阅读Canvas绘制圆和圆弧一文。 圆、圆弧和扇形 在Canvas中可以使用arc()和arcTo()绘制圆弧、圆和扇形等基本形状。当绘制圆弧时当startAngle角度值到endAngle角度值是0~360时就可以绘制一个圆。所以我们在这里只需要封装两个函数 drawArc()圆弧或圆函数drawSector()扇形函数 他们具有相同的参数圆心(x,y)、半径radius、startAngle起始弧度、endAngle结束弧度和anticlockwise旋转方向。由于startAngle和endAngle只接受弧度单位值所以在封装这两个函数之前先封装一个角度deg和弧度rad之间的转换函数方便后面函数的使用 // 将角度转换为弧度 // param {Number} deg - 角度值 function getAngle(deg) { return Math.PI * deg / 180; } // 绘制圆弧或圆 // 分类填充圆弧和边框圆弧 // param {Number} x - 圆心x轴坐标 // param {Number} y - 圆心y轴坐标 // param {Number} radius - 圆弧的半径 // param {Number} startAngle - 开始的弧度开始角度只接受弧度单位需要将deg先转换为rad rad Math.PI * deg / 180 // param {Number} endAngle - 结束的弧度结束的角度 // param {Boolean} anticlockwise - 旋转方向true为逆时针false为顺时针 // param {Boolean} isFill - 是否填充true为填充false为边框 // param {Boolean} isOnlyArc - 是否仅绘制弧边如果使用closePath()终点和起点会连接到一起否则不会。true时不连接false连接 // param {String} color - 圆弧的颜色 function drawArc(x, y, radius, startAngle, endAngle, anticlockwise, isOnlyArc, isFill, color) { if (isFill) { ctx.fillStyle color; ctx.save(); ctx.beginPath(); ctx.arc(x, y, radius, getAngle(startAngle), getAngle(endAngle), anticlockwise); ctx.closePath(); ctx.fill(); ctx.restore(); } else { ctx.strokeStyle color; ctx.save(); ctx.beginPath(); ctx.arc(x, y, radius, getAngle(startAngle), getAngle(endAngle), anticlockwise); if (isOnlyArc) { } else { ctx.closePath(); } ctx.stroke(); ctx.restore(); } } // 绘制扇形 // param {Number} x - 圆心x轴坐标 // param {Number} y - 圆心y轴坐标 // param {Number} radius - 圆半径 // param {Number} startAngle - 开始弧度 // param {Number} endAngle - 结束弧度 // param {Number} anticlockwise - 旋转方向 true逆时针false顺时针 // param {Boolean} isFill - true为填充false为边框 // param {String} color - 扇形的颜色 function drawSector(x, y, radius, startAngle, endAngle, anticlockwise, isFill, color) { ctx.save(); ctx.beginPath(); ctx.moveTo(x, y); ctx.arc(x, y, radius, getAngle(startAngle), getAngle(endAngle), false); ctx.closePath(); if (isFill) { ctx.fillStyle color; ctx.fill(); } else { ctx.strokeStyle color; ctx.stroke(); } ctx.restore(); } 绘制箭头 在Canvas中没有直接的方法可以绘制箭但Patrick Horgan在《Drawing lines and arcs with arrow heads on HTML5 Canvas》一文中把绘制箭对的函数已经封装好了。我直接把代码放这里 // From: http://www.dbp-consulting.com/tutorials/canvas/CanvasArrow.html // Draw arrow head function drawHead (x0, y0, x1, y1, x2, y2, style, color, width) { if (typeof(x0) string) { x0 parseInt(x0); } if (typeof(y0) string) { y0 parseInt(y0); } if (typeof(x1) string) { x1 parseInt(x1); } if (typeof(y1) string) { y1 parseInt(y1); } if (typeof(x2) string) { x2 parseInt(x2); } if (typeof(y2) string) { y2 parseInt(y2); } var radius 3, twoPI 2 * Math.PI; ctx.save(); ctx.beginPath(); ctx.strokeStyle color; ctx.fillStyle color; ctx.lineWidth width; ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.lineTo(x2, y2); switch (style) { case 0: var backdist Math.sqrt(((x2 - x0) * (x2 - x0)) ((y2 - y0) * (y2 - y0))); ctx.arcTo(x1, y1, x0, y0, .55 * backdist); ctx.fill(); break; case 1: ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.lineTo(x2, y2); ctx.lineTo(x0, y0); ctx.fill(); break; case 2: ctx.stroke(); break; case 3: var cpx (x0 x1 x2) / 3; var cpy (y0 y1 y2) / 3; ctx.quadraticCurveTo(cpx, cpy, x0, y0); ctx.fill(); break; case 4: var cp1x, cp1y, cp2x, cp2y, backdist; var shiftamt 5; if (x2 x0) { backdist y2 - y0; cp1x (x1 x0) / 2; cp2x (x1 x0) / 2; cp1y y1 backdist / shiftamt; cp2y y1 - backdist / shiftamt; } else { backdist Math.sqrt(((x2 - x0) * (x2 - x0)) ((y2 - y0) * (y2 - y0))); var xback (x0 x2) / 2; var yback (y0 y2) / 2; var xmid (xback x1) / 2; var ymid (yback y1) / 2; var m (y2 - y0) / (x2 - x0); var dx (backdist / (2 * Math.sqrt(m * m 1))) / shiftamt; var dy m * dx; cp1x xmid - dx; cp1y ymid - dy; cp2x xmid dx; cp2y ymid dy; } ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x0, y0); ctx.fill(); break; } ctx.restore(); } // draw arrow function drawArrow(x1, y1, x2, y2, style, which, angle, d, color, width) { if (typeof(x1) string) { x1 parseInt(x1); } if (typeof(y1) string) { y1 parseInt(y1); } if (typeof(x2) string) { x2 parseInt(x2); } if (typeof(y2) string) { y2 parseInt(y2); } style typeof(style) ! undefined ? style : 3; which typeof(which) ! undefined ? which : 1; angle typeof(angle) ! undefined ? angle : Math.PI / 9; d typeof(d) ! undefined ? d : 10; color typeof(color) ! undefined ? color : #000; width typeof(width) ! undefined ? width : 1; var toDrawHead typeof(style) ! function ? drawHead : style; var dist Math.sqrt((x2 - x1) * (x2 - x1) (y2 - y1) * (y2 - y1)); var ratio (dist - d / 3) / dist; var tox, toy, fromx, fromy; if (which 1) { tox Math.round(x1 (x2 - x1) * ratio); toy Math.round(y1 (y2 - y1) * ratio); } else { tox x2; toy y2; } if (which 2) { fromx x1 (x2 - x1) * (1 - ratio); fromy y1 (y2 - y1) * (1 - ratio); } else { fromx x1; fromy y1; } ctx.beginPath(); ctx.strokeStyle color; ctx.lineWidth width; ctx.moveTo(fromx, fromy); ctx.lineTo(tox, toy); ctx.stroke(); var lineangle Math.atan2(y2 - y1, x2 - x1); var h Math.abs(d / Math.cos(angle)); if (which 1) { var angle1 lineangle Math.PI angle; var topx x2 Math.cos(angle1) * h; var topy y2 Math.sin(angle1) * h; var angle2 lineangle Math.PI - angle; var botx x2 Math.cos(angle2) * h; var boty y2 Math.sin(angle2) * h; toDrawHead(topx, topy, x2, y2, botx, boty, style, color, width); } if (which 2) { var angle1 lineangle angle; var topx x1 Math.cos(angle1) * h; var topy y1 Math.sin(angle1) * h; var angle2 lineangle - angle; var botx x1 Math.cos(angle2) * h; var boty y1 Math.sin(angle2) * h; toDrawHead(topx, topy, x1, y1, botx, boty, style, color, width); } } // draw arced arrow function drawArcedArrow(x, y, r, startangle, endangle, anticlockwise, style, which, angle, d, color, width) { style typeof(style) ! undefined ? style : 3; which typeof(which) ! undefined ? which : 1; angle typeof(angle) ! undefined ? angle : Math.PI / 8; d typeof (d) ! undefined ? d : 10; color typeof(color) ! undefined ? color : #000; width typeof(width) ! undefined ? width : 1; ctx.save(); ctx.beginPath(); ctx.lineWidth width; ctx.strokeStyle color; ctx.arc(x, y, r, startangle, endangle, anticlockwise); ctx.stroke(); var sx, sy, lineangle, destx, desty; ctx.strokeStyle rgba(0,0,0,0); if (which 1) { sx Math.cos(startangle) * r x; sy Math.sin(startangle) * r y; lineangle Math.atan2(x - sx, sy - y); if (anticlockwise) { destx sx 10 * Math.cos(lineangle); desty sy 10 * Math.sin(lineangle); } else { destx sx - 10 * Math.cos(lineangle); desty sy - 10 * Math.sin(lineangle); } drawArrow(sx, sy, destx, desty, style, 2, angle, d, color, width); } if (which 2) { sx Math.cos(endangle) * r x; sy Math.sin(endangle) * r y; lineangle Math.atan2(x - sx, sy - y); if (anticlockwise) { destx sx - 10 * Math.cos(lineangle); desty sy - 10 * Math.sin(lineangle); } else { destx sx 10 * Math.cos(lineangle); desty sy 10 * Math.sin(lineangle); } drawArrow(sx, sy, destx, desty, style, 2, angle, d, color, width); } ctx.restore(); } 是不是好复杂呀。如果上面代码看起来痛苦的话可以阅读Patrick Horgan写的《Drawing lines and arcs with arrow heads on HTML5 Canvas》文章或者阅读早前整理的Canvas绘制箭头一文。 绘制正多边形 绘制正多边形也相对于其他的绘图函数封装而言也较为复杂一点。我们将封装一个drawStarPolygons()函数这个函数既能实现正多边形绘制也能实现星形多边形的绘制。具体代码如下 // 绘制正多边形 // param {Number} xCenter 中心坐标X点 // param {Number} yCenter 中心坐标Y点 // param {Number} radius 外圆半径 // param {Number} sides 多边形边数 // param {Number} sideIndent (0 ~ 1) // param {Number} alpha 角度 默认270度 // param {Boolean} isFill true填充false边框 // param {String} color 正多边形颜色 function drawStarPolygons(xCenter, yCenter, radius, sides, sideIndent, alpha, isFill, color) { var sideIndentRadius radius * (sideIndent || 0.38); var radAngle alpha ? alpha * Math.PI / 180 : -Math.PI / 2; var radAlpha Math.PI * 2 / sides / 2; ctx.save(); ctx.beginPath(); var xPos xCenter Math.cos(radAngle) * radius; var yPos yCenter Math.sin(radAngle) * radius; ctx.moveTo(xPos, yPos); for (var i 1; i sides * 2; i) { var rad radAlpha * i radAngle; var len (i % 2) ? sideIndentRadius : radius; var xPos xCenter Math.cos(rad) * len; var yPos yCenter Math.sin(rad) * len; ctx.lineTo(xPos, yPos); } ctx.closePath(); if (isFill) { ctx.fillStyle color; ctx.fill(); } else { ctx.strokeStyle color; ctx.stroke(); } } 详细的可以阅读Canvas绘制正多边形一文。 示例 前面我们封装了一些我们常常需要使用的绘图函数。那我们拿一个示例来验证一下。比如说我们要绘制一个时钟 var canvas document.getElementById(canvasOne); var ctx canvas.getContext(2d); var w canvas.width window.innerWidth; var h canvas.height window.innerHeight; initDrawCanvas(canvas, ctx); // 绘制一个时钟 var radius 150; var handTruncation canvas.width / 25; var hourHandTruncation canvas.width / 10; // 绘制时钟刻度盘 function drawClockFace() { // step1: 绘制时钟的外圆和圆心 ctx.lineWidth 4; ctx.translate(w / 2, h / 2); drawArc(0, 0, radius, 0, 360, true, true, false, #000); drawArc(0, 0, 10, 0, 360, true, true, true, #000); // step2: 绘制时钟刻度线 for (var i 0; i 60; i) { var rad getAngle(i * 6); ctx.save(); ctx.rotate(rad); if (i % 5 0) { drawSolidLine(radius - 15, -1, radius - 4, -1, 4, #000); } else { drawSolidLine(radius - 8, -1, radius - 4, -1, 2, #999); } ctx.restore(); } // step3: 绘制时钟数字 ctx.font radius * 0.15 px arial; ctx.textBaseline middle; ctx.textAlign center; for (var i 1; i 13; i) { var ang getAngle(30 * i); ctx.fillText(i.toString(), radius * 0.80 * Math.sin(ang), -radius * 0.80 * Math.cos(ang)); } } // 绘制时钟针 function drawHand(angle, length, width, color) { var endX Math.sin(angle) * length; var endY -Math.cos(angle) * length; ctx.lineCap round; drawSolidLine(0, 0, endX, endY, width, color); } function drawHands(radius) { var now new Date(); var hour now.getHours(); var minute now.getMinutes(); var second now.getSeconds(); hour hour % 12; hour getAngle(30) * hour getAngle(30) * minute / 60 getAngle(30) * second / 3600; minute Math.PI / 30 * minute second * Math.PI / 1800; second Math.PI / 30 * second; drawHand(hour, radius * 0.4, radius * 0.07); // 时针 drawHand(minute, radius * 0.6, radius * 0.05); // 分针 drawHand(second, radius * 0.7, radius * 0.03, red); // 秒针 } function drawClock() { ctx.resetTransform(); drawRect(0, 0, w, h, true); drawClockFace(); drawHands(radius); } setInterval(drawClock, 1000); 最终效果如下 总结 这篇文章我们整理了Canvas中CanvasRenderingContext2D对象中自带绘制基本图形的方法、属性和样式。并且借助这些方法封装了一些绘制基本图形的函数比如绘制线段、矩形、圆和正多边形的。最后绘制了一张图把相关的知识汇总在一起。这篇文章也是介绍Canvas绘制基本图形的最后一篇文章了。   转载于:https://www.cnblogs.com/qq984064199/p/9228358.html
http://www.laogonggong.com/news/116084.html

相关文章:

  • 青岛网站建设公司在哪上海公司注册查询
  • app开发 网站建设庆阳网站建设推广
  • 徐州建设局网新网站php在电子商务网站建设中的应用研究 戴书浩
  • 做空视频文件的网站电商设计属于什么专业
  • 制作可以赚钱的网站附近的计算机培训班
  • 网站备案到期了怎么办企业所得税计算方法举例
  • 遵义住房和城乡建设厅网站wordpress 邮箱发布
  • 模板建站代理企业网站建设怎么选择空间
  • 建立网站需要花多少费用有域名 如何免费建设网站
  • 闵行交大网站建设做a小视频免费观看网站
  • 论基层门户网站的建设湖北省建设交易协会网站
  • 有区域名和主机怎么做网站纺织行业网站怎么做
  • 如何建设网站脱颖而出wordpress rss采集插件
  • 利用阿里云虚拟主机做网站河北住房和城乡建设厅
  • 西安 网站 公司做临时工有哪些网站
  • 自己怎么做网站卖车如何做自己的vip视频解析网站
  • 手机网站一键生成app网站开发技术案例
  • 网站系统免费软件制作平台
  • 网站制作 文案界面做的比较好的网站
  • 网站服务器时间在哪里查询班级优化大师免费下载app
  • 成都百度网站排名优化上海奉贤 网站建设
  • 百度如何提交网站苏州工业园区属于哪个区
  • 网站建设合同司法解释广州网络推广专员
  • 备案的网站名称绵阳网站推广优化
  • 网站配色方案深圳龙华高级中学
  • 物流公司做网站注重什么萍乡商城网站建设
  • 免费建站网站教程上海网站建设-网建知识
  • 做公司网站的公司外贸网站联系方式模板免费
  • 建e网效果图怎么下载成都有实力的seo团队
  • 大型企业网站欣赏WordPress一键安装安全