<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no, email=no">
<title>quadrant</title>
<script type="text/javascript" src="http://www.w3school.com.cn/jquery/jquery-1.11.1.min.js"></script>
<style type="text/css">
body {
padding: 0;
margin: 0;
background-color: #333;
}
input {
border: solid 0px #DDD;
border-radius: 5px;
padding: 5px 10px;
}
button {
border: solid 0px #CCC;
border-radius: 5px;
background-color: #FFF;
padding: 5px 10px;
}
#quadrant {
background-color: #CCC;
width: 640px;
height: 640px;
margin: 50px auto 0 auto;
}
</style>
</head>
<body>
<div id="quadrant">
<canvas width="640" height="640"></canvas>
<div>
<input name="func" />
<button id="draw">draw</button>
<button id="reset">reset</button>
</div>
</div>
<script type="text/javascript">
var defaultColor = '#333';
var $quadrant = $('#quadrant');
var $canvas = $quadrant.find('canvas');
$quadrant.css('margin-top', ($(window).height() - $canvas.height()) / 2);
var ctx = $canvas.get(0).getContext("2d");
// 绘制线条
function drawLine(ctx, config) {
if(ctx && config && config.x0 && config.y0 && config.x1 && config.y1) {
// 默认线条颜色为灰色
var color = config.color;
if(typeof(color) === 'undefined' || color.length <= 0) {
color = defaultColor;
}
ctx.strokeStyle = color;
// 绘制线条
var x0 = config.x0,
y0 = config.y0,
x1 = config.x1,
y1 = config.y1;
ctx.moveTo(x0, y0);
ctx.lineTo(x1, y1);
ctx.stroke();
}
}
// 绘制点
function drawPoint(ctx, config) {
if(ctx && config && config.x && config.y) {
config.x0 = config.x - 1;
config.y0 = config.y - 1;
config.x1 = config.x;
config.y1 = config.y;
drawLine(ctx, config);
}
}
// 绘制尖角
function drawAngle(ctx, config) {
var size = config.size ? config.size : 5;
var top = config.top;
var left = config.left;
var mode = config.mode ? config.mode : 1;
var color = config.color ? config.color : ''
if(size && top && left && mode) {
if(mode > 4 || mode < 1) {
mode = 1;
}
var line1Config = {}, line2Config = {};
line1Config.x0 = line2Config.x0 = left;
line1Config.y0 = line2Config.y0 = top;
switch(mode) {
case 1:// 开口向左
line1Config.x1 = left - size;
line1Config.y1 = top + size;
line2Config.x1 = left - size;
line2Config.y1 = top - size;
break;
case 2:// 开口向上
line1Config.x1 = left - size;
line1Config.y1 = top - size;
line2Config.x1 = left + size;
line2Config.y1 = top - size;
break;
case 3:// 开口向右
line1Config.x1 = left + size;
line1Config.y1 = top + size;
line2Config.x1 = left + size;
line2Config.y1 = top - size;
break;
case 4:// 开口向下
line1Config.x1 = left - size;
line1Config.y1 = top + size;
line2Config.x1 = left + size;
line2Config.y1 = top + size;
break;
}
drawLine(ctx, line1Config);
drawLine(ctx, line2Config);
}
}
// 创建坐标系
var cWidth = $canvas.get(0).width;
var cHeight = $canvas.get(0).height;
var qPadding = 50;
var qWidth = cWidth - qPadding * 2;
var qHeight = cHeight - qPadding * 2;
function createQuadrant(ctx) {
// 绘制x轴
var xLine = {
x0: qPadding,
y0: qPadding + qHeight / 2,
x1: qPadding + qWidth,
y1: qPadding + qHeight / 2
};
drawLine(ctx, xLine);
drawAngle(ctx, {top: xLine.y1, left: xLine.x1, model: 1});
// 绘制y轴
var yLine = {
x0: qPadding + qWidth / 2,
y0: qPadding,
x1: qPadding + qWidth / 2,
y1: qPadding + qHeight
};
drawLine(ctx, yLine);
drawAngle(ctx, {top: yLine.y0, left: yLine.x0, mode: 4});
}
createQuadrant(ctx);
// 绘制函数图像
function drawFunction(ctx, func) {
// 绘制坐标系中的点
function drawQuadrantPoint(x, y) {
// 换算坐标系与画布中的点
var cX = qPadding + qWidth / 2 + x;// canvas x
if(cX > cWidth - qPadding) {
cX = cWidth - qPadding;
}
if(cX < qPadding) {
cx = qPadding;
}
var cY = qPadding + qHeight / 2 - y;
if(cY > cHeight - qPadding) {
cY = cHeight - qPadding;
}
if(cY < qPadding) {
cY = qPadding;
}
drawPoint(ctx, {'x': cX, 'y': cY});
}
// 计算坐标系的最大最小值
var minX = qWidth / -2, maxX = qWidth / 2;
for(var i=minX; i<=maxX; i++) {
var y = func(i);
drawQuadrantPoint(i, y);
}
}
// 清空坐标系
function resetQuadrant(ctx) {
ctx.beginPath();
ctx.clearRect(0, 0, cWidth, cHeight);
createQuadrant(ctx);
}
$(function() {
var $func = $('input[name="func"]').val('Math.tan(x)');
$('#draw').on('click', function(event) {
resetQuadrant(ctx);
var funcStr = $func.val();
drawFunction(ctx, function(x) {
return eval(funcStr);
});
}).click();
$('#reset').on('click', function(event) {
resetQuadrant(ctx);
});
});
</script>
</body>
</html>
本文为测试canvas的基本API,并实现了绘制平面直角坐标系及函数线条功能,但因目前画布像素仅为640*640,绘制效果较差,不能够投入实际使用。