bootstrap实践录:用canvas画图
Posted 李迟
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bootstrap实践录:用canvas画图相关的知识,希望对你有一定的参考价值。
因工作需要,最近研究了一下 canvas 画图。
概述
最近业主方对网页提了需求,需要添加地图展示的功能,不一定要使用真实的地图,使用示意图即可。于是着手研,找到了 canvas。
一般地,通过<canvas>
标签定义画布,再使用 javascript 画图,即可显示图形或图像文件,画布的坐标和 MFC 图画是一致的,左上角为原点(0, 0)
,X轴向右,Y轴向下。
代码
使用 canvas 的模板方式如下:
- 创建画面,包括ID、大小。
- 获取 canvas 上下文,利用其提供的函数实现画图功能。
模板片段如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>foobar</title>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<script type="text/javascript">
var canvas = document.querySelector("#canvas")
var ctx = canvas.getContext('2d')
// ...
</script>
</body>
</html>
为方便使用,将常用的线段、圆形、三角形、文字等封装成函数。
总体看,将底层的绘制函数封装起来,对外提供的参数有坐标、颜色等,下面一一介绍。
文字
文字使用fillText
函数在指定的坐标上绘制,用font
定义字体及大小,fillStyle
指定颜色。代码如下:
function drawText(x, y, text, color)
ctx.beginPath()
ctx.font = "30px Arial"; // 如何只指定大小,不指定字体? Verdana Arial
ctx.fillStyle = color
ctx.fillText(text, x, y)
ctx.closePath()
线段
画线段比较简单,用moveTo
定位到起点,再用lineTo
指定终点,填充颜色用strokeStyle
函数,最后用stroke
函数绘制。有此基础,后面的图形画法就类似了,代码如下:
function drawLine(x1, y1, x2, y2, color)
ctx.beginPath();
ctx.strokeStyle = color;
ctx.lineWidth = 2;
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.closePath()
圆形
绘制图形使用画弧度的arc
函数,从0到2π画即得到圆。该函数可指定圆的外边颜色和填充颜色,代码如下:
function drawCircle(x, y, r, bcolor, fcolor)
ctx.beginPath()
ctx.lineWidth = 2;
ctx.arc(x, y, r, 0, 2*Math.PI)
ctx.strokeStyle = bcolor // 线的颜色
ctx.fillStyle = fcolor // 填充的颜色
ctx.fill()
ctx.stroke()
ctx.closePath()
三角形
绘制三角形提供2个接口,一是指定三个顶点的坐标,二是给出一个坐标和连长,函数自动推导顶点坐标,代码如下:
function drawTriangle1(x1, y1, x2, y2, x3, y3, bcolor, fcolor)
ctx.beginPath();
ctx.moveTo(x1, y1);
ctx.strokeStyle = bcolor
ctx.lineTo(x2, y2);
ctx.lineTo(x3, y3);
ctx.lineTo(x1, y1);
ctx.fillStyle = fcolor;
ctx.fill();
ctx.stroke();
ctx.closePath()
// 给出中心点和边长,画三角形(等腰,非等边)
function drawTriangle(x1, y1, width, bcolor, fcolor)
half = width * 0.5
ctx.beginPath();
ctx.moveTo(x1 - half, y1 + half);
ctx.strokeStyle = bcolor
ctx.lineTo(x1 + half, y1 + half);
ctx.lineTo(x1, y1 - half);
ctx.lineTo(x1 - half, y1 + half);
ctx.fillStyle = fcolor;
ctx.fill();
ctx.stroke();
ctx.closePath()
带箭头线段
带箭头线段较复杂,参考了网上资料作了修改。这里指定了箭头的角度和箭头长度,代码如下:
function drawLineArrow(x1, y1, x2, y2, color)
theta = 45
headlen = 7
width = 1
var angle = Math.atan2(y1 - y2, x1 - x2) * 180 / Math.PI,
angle1 = (angle + theta) * Math.PI / 180,
angle2 = (angle - theta) * Math.PI / 180,
topX = headlen * Math.cos(angle1),
topY = headlen * Math.sin(angle1),
botX = headlen * Math.cos(angle2),
botY = headlen * Math.sin(angle2);
ctx.save();
ctx.beginPath();
var arrowX = x1 - topX,
arrowY = y1 - topY;
ctx.moveTo(arrowX, arrowY);
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
arrowX = x2 + topX;
arrowY = y2 + topY;
ctx.moveTo(arrowX, arrowY);
ctx.lineTo(x2, y2);
arrowX = x2 + botX;
arrowY = y2 + botY;
ctx.lineTo(arrowX, arrowY);
ctx.strokeStyle = color;
ctx.lineWidth = width;
ctx.stroke();
ctx.restore();
将前面的函数综合起来进行测试,测试代码如下:
// 单独测试
// 圆
drawCircle(100, 100, 20, "#FF0000", "#FFFF00")
drawCircle(150, 100, 20, "#0000FF", "#FFFFFF")
drawCircle(200, 100, 20, "#0000FF", "#0000FF")
// 圆结束
drawTriangle1(100, 70, 200, 70, 150, 10, "#FF8000", "#FF8000")
drawTriangle(150, 200, 40, "#FF8000", "#FF8000")
drawLine(50, 10, 150, 10, "#0000FF");
drawLine(150, 10, 200, 20, "#FFD700");
drawLineArrow(200, 20, 250, 100, "#FFD700");
drawLineArrow(250, 100, 250, 150, "#FFD700");
drawText(0, 150, "hello world", "#000000");
效果图如下:
小结
目前主要研究如何绘制一些简单的图形。但对于如何快速画出大量图形,且足够性能要求,还是未知数。
工程中是否能用 canvas,有待继续研究。
以上是关于bootstrap实践录:用canvas画图的主要内容,如果未能解决你的问题,请参考以下文章
bootstrap实践录:输入框自动补全-typeahead篇
bootstrap实践录:输入框自动补全-typeahead篇
bootstrap实践录:输入框自动补全-typeahead篇
bootstrap实践录:输入框自动补全-autocomplete篇