Javascript利用canvas绘制两点间曲线、箭头等

Javascript利用canvas,在两点间绘制曲线,矩形,并且在矩形中绘制文字,实现居中对齐,同时实现了箭头绘制,效果如图:Javascript利用canvas绘制两点间曲线、箭头等_第1张图片

一、html,代码如下

<canvas id="canvas" width="1000" height="600">canvas>

二、css代码如下:

canvas {
			    display: block;
			    width: 1000px;
			    height: 600px;
			    background: conic-gradient(#eee 25%, white 0deg 50%, #eee 0deg 75%, white 0deg) 0 / 20px 20px;
			    margin-inline: auto;
			}
			@media (max-width: 640px) {
			    canvas {
			        width: 100vw;
			        height: 60vw;
			    }    
			}

三、Javascript代码如下

var context = document.getElementById("canvas").getContext("2d"); ;
			// 绘制尺寸
			var width = canvas.width;
			var height = canvas.height;
			
			// 两个方块的坐标、尺寸,颜色等数据
			var data = [{
			    x: 800,
			    y: 180,
			    width: 200,
			    height: 50,
			    color: 'deepskyblue',
				text:"+u+ate"
			}, {
			    x: 600,
			    y: 680,
			    width: 200,
			    height: 50,
			    color: 'deeppink',
				text:"gress 迈步"
			}];
			// 绘制矩形方法
			var drawRect = function () {
			    data.forEach(function (obj) {
			        context.beginPath();
			        context.fillStyle = obj.color;
			        context.fillRect(obj.x, obj.y, obj.width, obj.height);
			        context.closePath();
					context.font="30px Verdana";
					context.fillStyle="#fff";
					console.log(context.measureText(obj.text))
					const textMetrics = context.measureText(obj.text);					 
					// 所有字在这个字体下的高度
					let fontHeight = textMetrics.fontBoundingBoxAscent + textMetrics.fontBoundingBoxDescent; 
					console.log(fontHeight)
					
					context.fillText(obj.text,0,0)
					context.fillText(obj.text,obj.x+(obj.width-context.measureText(obj.text).width)/2,obj.y+fontHeight);
			    });
				
			};
			
			// 绘制连接曲线方法
			var drawCurve = function () {
			    // 按照坐标位置排序
			    var dataSort = data.sort(function (objA, objB) {
			        return (objA.y + objA.height) - (objB.y + objB.height);
			    });
			    // 知道上下数据
			    var from = dataSort[0];
			    var to = dataSort[1];
			    
			    // 曲线的起点终点
			    var fromX = from.x + from.width / 2;
			    var fromY = from.y + from.height;
			    var toX = to.x + to.width / 2;
			    var toY = to.y;
			    
			    // 曲线控制点坐标
			    var cp1x = fromX;
			    var cp1y = fromY + (toY - fromY) / 2;
			    
			    var cp2x = toX;
			    var cp2y = toY - (toY - fromY) / 2;
			    
			    // 开始绘制曲线
			    context.beginPath();
			    context.lineWidth = 1
			    context.strokeStyle = '#000';
			    context.moveTo(fromX, fromY);
			    // 绘制曲线点
			    context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, toX, toY);
			    context.stroke();
			};
			
			// 绘制方法
			var draw = function () {
			    context.clearRect(0, 0, width, height);			    
			     drawRect();
			     drawCurve();
			};
			
			draw();
			
			canvas_arrow(ctx, 10, 30, 200, 150); 
			canvas_arrow(ctx, 100, 200, 400, 50); 
			canvas_arrow(ctx, 200, 30, 10, 150); 
			canvas_arrow(ctx, 400, 200, 100, 50); 
			ctx.stroke(); 		 
			 
			function canvas_arrow(context, fromx, fromy, tox, toy) { 
			  var headlen = 10; // length of head in pixels 
			  var dx = tox - fromx; 
			  var dy = toy - fromy; 
			  var angle = Math.atan2(dy, dx); 
			  context.moveTo(fromx, fromy); 
			  context.lineTo(tox, toy); 
			  context.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6)); 
			  context.moveTo(tox, toy); 
			  context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6)); 
			}

ok,代码就是如此,完整代码如下:

DOCTYPE HTML>
<html>
	<head>
		<style>
			canvas {
			    display: block;
			    width: 1000px;
			    height: 600px;
			    background: conic-gradient(#eee 25%, white 0deg 50%, #eee 0deg 75%, white 0deg) 0 / 20px 20px;
			    margin-inline: auto;
			}
			@media (max-width: 640px) {
			    canvas {
			        width: 100vw;
			        height: 60vw;
			    }    
			}
		style>
	head>
	<body>
		<canvas id="canvas" width="2000" height="1200">canvas>
		<script>
			var context = document.getElementById("canvas").getContext("2d"); ;
			// 绘制尺寸
			var width = canvas.width;
			var height = canvas.height;
			
			// 两个方块的坐标、尺寸,颜色等数据
			var data = [{
			    x: 800,
			    y: 180,
			    width: 200,
			    height: 50,
			    color: 'deepskyblue',
				text:"+u+ate"
			}, {
			    x: 600,
			    y: 680,
			    width: 200,
			    height: 50,
			    color: 'deeppink',
				text:"gress 迈步"
			}];
			// 绘制矩形方法
			var drawRect = function () {
			    data.forEach(function (obj) {
			        context.beginPath();
			        context.fillStyle = obj.color;
			        context.fillRect(obj.x, obj.y, obj.width, obj.height);
			        context.closePath();
					context.font="30px Verdana";
					context.fillStyle="#fff";
					console.log(context.measureText(obj.text))
					const textMetrics = context.measureText(obj.text);					 
					// 所有字在这个字体下的高度
					let fontHeight = textMetrics.fontBoundingBoxAscent + textMetrics.fontBoundingBoxDescent; 
					console.log(fontHeight)
					
					context.fillText(obj.text,0,0)
					context.fillText(obj.text,obj.x+(obj.width-context.measureText(obj.text).width)/2,obj.y+fontHeight);
			    });
				
			};
			
			// 绘制连接曲线方法
			var drawCurve = function () {
			    // 按照坐标位置排序
			    var dataSort = data.sort(function (objA, objB) {
			        return (objA.y + objA.height) - (objB.y + objB.height);
			    });
			    // 知道上下数据
			    var from = dataSort[0];
			    var to = dataSort[1];
			    
			    // 曲线的起点终点
			    var fromX = from.x + from.width / 2;
			    var fromY = from.y + from.height;
			    var toX = to.x + to.width / 2;
			    var toY = to.y;
			    
			    // 曲线控制点坐标
			    var cp1x = fromX;
			    var cp1y = fromY + (toY - fromY) / 2;
			    
			    var cp2x = toX;
			    var cp2y = toY - (toY - fromY) / 2;
			    
			    // 开始绘制曲线
			    context.beginPath();
			    context.lineWidth = 1
			    context.strokeStyle = '#000';
			    context.moveTo(fromX, fromY);
			    // 绘制曲线点
			    context.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, toX, toY);
			    context.stroke();
			};
			
			// 绘制方法
			var draw = function () {
			    context.clearRect(0, 0, width, height);			    
			     drawRect();
			     drawCurve();
			};
			
			draw();
			
			canvas_arrow(ctx, 10, 30, 200, 150); 
			canvas_arrow(ctx, 100, 200, 400, 50); 
			canvas_arrow(ctx, 200, 30, 10, 150); 
			canvas_arrow(ctx, 400, 200, 100, 50); 
			ctx.stroke(); 		 
			 
			function canvas_arrow(context, fromx, fromy, tox, toy) { 
			  var headlen = 10; // length of head in pixels 
			  var dx = tox - fromx; 
			  var dy = toy - fromy; 
			  var angle = Math.atan2(dy, dx); 
			  context.moveTo(fromx, fromy); 
			  context.lineTo(tox, toy); 
			  context.lineTo(tox - headlen * Math.cos(angle - Math.PI / 6), toy - headlen * Math.sin(angle - Math.PI / 6)); 
			  context.moveTo(tox, toy); 
			  context.lineTo(tox - headlen * Math.cos(angle + Math.PI / 6), toy - headlen * Math.sin(angle + Math.PI / 6)); 
			}
		script>
	body>
html>

你可能感兴趣的:(1024程序员节)