使用canvas绘制平面直角坐标系

<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,绘制效果较差,不能够投入实际使用。

你可能感兴趣的:(canvas)