使用canvas绘制六边形

近期遇到了一个六边形边框的需求,实现如下图效果:有六边形边框,中间是一张图片,图片超出的部分要裁切掉。

在这里插入图片描述

代码实现如下:

<html>
	<head>
		<style>
			html,body{
				width:100%;
				height:100%;
				padding:0;
				margin:0;
			}
			canvas{
				position: absolute;
				top:0;
				left:0;
				right:0;
				bottom:0;
				margin:auto;
			}
		</style>
	</head>
	<body>
		<canvas></canvas>
	</body>
	<script type="text/javascript">
		var canvas = document.getElementsByTagName('canvas')[0];
		var context = canvas.getContext("2d");
		
		//六边形横向宽
		width = 209;
		//边框粗细
		borderWidth = 3;
		//六边形边长
		hexagonWidth = (width - borderWidth)/4;
		
		//设置canvas宽高
		canvas.width = width;
		canvas.height = width / 2 * Math.sqrt(3) + borderWidth;
		
		//图片缩放比例
		imgScale = 0.5;
		
		//绘制图片
		var img = new Image()
		img.src = './1.png'
		img.onload = function(){
		    context.drawImage(this, canvas.width/2 - img.width/2*imgScale , canvas.height/2 - img.height/2*imgScale , img.width*imgScale , img.height*imgScale)
			
			//如果图片绘制后覆盖边框,可再次调用一边绘制六边形代码
		}
		
		//绘制六边形,裁切
		context.beginPath();
		context.save(); 
		context.translate(canvas.width/2,canvas.height/2);
		context.strokeStyle = '#79b1f7'; 
		context.lineWidth = borderWidth; 
		context.lineTo(-1*hexagonWidth,Math.sqrt(3)*hexagonWidth);
		context.lineTo(1*hexagonWidth,Math.sqrt(3)*hexagonWidth);
		context.lineTo(2*hexagonWidth,0*hexagonWidth);
		context.lineTo(1*hexagonWidth,-1 * Math.sqrt(3)*hexagonWidth);
		context.lineTo(-1*hexagonWidth,-1 * Math.sqrt(3)*hexagonWidth);
		context.lineTo(-2*hexagonWidth,0*hexagonWidth);
		context.lineTo(-1*hexagonWidth,Math.sqrt(3)*hexagonWidth);
		context.stroke(); 
		context.restore();
		context.clip();
		context.closePath();
	</script>
</html>

如果图片太大时会出现覆盖边框的问题,如下图。这是由于canvas绘制线条的特性而导致的(以中心向两边绘制固定宽度,比如代码中设置的宽度为3,则连接线外部与内部的宽度各为1.5,所以覆盖的边框宽为1.5)。
在这里插入图片描述
解决代码如下:

//图片缩放比例
imgScale = 1;
		
img.onload = function(){
    context.drawImage(this, canvas.width/2 - img.width/2*imgScale , canvas.height/2 - img.height/2*imgScale , img.width*imgScale , img.height*imgScale)
	
	//如果图片绘制后覆盖边框,可再次调用一边绘制六边形代码
	context.beginPath();
	context.save(); 
	context.translate(canvas.width/2,canvas.height/2);
	context.strokeStyle = '#79b1f7'; 
	context.lineWidth = borderWidth; 
	context.lineTo(-1*hexagonWidth,Math.sqrt(3)*hexagonWidth);
	context.lineTo(1*hexagonWidth,Math.sqrt(3)*hexagonWidth);
	context.lineTo(2*hexagonWidth,0*hexagonWidth);
	context.lineTo(1*hexagonWidth,-1 * Math.sqrt(3)*hexagonWidth);
	context.lineTo(-1*hexagonWidth,-1 * Math.sqrt(3)*hexagonWidth);
	context.lineTo(-2*hexagonWidth,0*hexagonWidth);
	context.lineTo(-1*hexagonWidth,Math.sqrt(3)*hexagonWidth);
	context.stroke(); 
	context.restore();
	context.closePath();
}

解决后效果图如下:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风舞红枫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值