使用Canvas绘制六边形网格。
主要思路是先画给定中心点的六边形,然后二重循环遍历所有中心点,画所有的六边形。

<!DOCTYPE HTML>
<html>
<body><canvas id="myCanvas" width="300" height="150"><p>你的浏览器不支持Canvas</p>
</canvas>
<br>
<p id='p1'></p>
<script type="text/javascript">
"use strict";
var canvas=document.getElementById('myCanvas');
if (canvas.getContext) {var k=3;var d=30;var w=Math.sqrt(3)*d;var h=3/2*d;canvas.width=2*k*w;canvas.height=2*k*h+h/2;var o=[canvas.width/2,canvas.height/2];document.getElementById('p1').innerHTML='画布宽'+canvas.width+',高'+canvas.height;var ctx=canvas.getContext('2d');ctx.fillStyle='AntiqueWhite';ctx.fillRect(0,0,canvas.width,canvas.height);ctx.strokeStyle='blue';ctx.beginPath();var vs=[[0,d],[-w/2,d/2],[-w/2,-d/2],[0,-d],[w/2,-d/2],[w/2,d/2]];function one(xo,yo){ctx.moveTo(xo+vs[5][0],yo+vs[5][1]);for(var i=0;i<vs.length;i++){ctx.lineTo(xo+vs[i][0],yo+vs[i][1]);}}for(var i=-k+1;i<k;i++){for(var j=0;j<2*k-1-Math.abs(i);j++){one(o[0]+(-k+1+Math.abs(i)/2+j)*w,o[1]+h*i);}}ctx.stroke();
}
else{console.log('你的浏览器不支持Canvas');
}
</script></body>
</html>

效果如下:

更新:增加了一些选项,边长和颜色可以设置。网页的图标也用六边形画出。

<!DOCTYPE HTML>
<html>
<head>
<title>六边形网格</title>
<link id="link" rel="shortcut icon" type="image/x-icon">
<style>
#bc1,#bc2{width:25px;}
#bj,#xt,#tc{width:20px;}
</style>
</head>
<body>
<p>设置大六边形边长: <input id='bc1' value="3" onchange="generate()"> 小六边形<br>
设置小六边形边长: <input id='bc2' value="24" onchange="generate()"> 像素(px)<br>
设置背景色 <input type="color" id="bj" value="#c8ffff" onchange="generate()"/>
设置线条色 <input type="color" id="xt" value="#0000ff" onchange="generate()"/>
设置填充色 <input type="color" id="tc" value="#faebd7" onchange="generate()"/></p>
<p id='p1'></p>
<canvas id="myCanvas" width="300" height="150">
<p>你的浏览器不支持Canvas</p>
</canvas>
<script type="text/javascript">
"use strict";
document.getElementById('bc1').value=2;
generate();
link.href=myCanvas.toDataURL({format:'image/png', quality:1});
document.getElementById('bc1').value=3;
generate();
function generate(){var bc1=document.getElementById('bc1').value;var bc2=document.getElementById('bc2').value;var k=Number(bc1);var d=Number(bc2);var bj=document.getElementById('bj').value;var xt=document.getElementById('xt').value;var tc=document.getElementById('tc').value;var canvas=document.getElementById('myCanvas');if(bc1>200){var c=confirm('六边形个数过多时网页会卡,是否继续?');if(!c){return;}}if(canvas.getContext) {var w=Math.sqrt(3)*d;var h=3/2*d;var count=3*k*k-3*k+1;canvas.width=2*k*w;canvas.height=2*k*h+h/2;var o=[canvas.width/2,canvas.height/2];document.getElementById('p1').innerHTML='画布宽'+canvas.width+'px,高'+canvas.height+'px,含有'+count+'个小六边形';var ctx=canvas.getContext('2d');ctx.fillStyle=bj;ctx.fillRect(0,0,canvas.width,canvas.height);ctx.beginPath();var vs=[[0,d],[-w/2,d/2],[-w/2,-d/2],[0,-d],[w/2,-d/2],[w/2,d/2]];function one(xo,yo){ctx.beginPath();ctx.moveTo(xo+vs[5][0],yo+vs[5][1]);for(var i=0;i<vs.length;i++){ctx.lineTo(xo+vs[i][0],yo+vs[i][1]);}ctx.strokeStyle=xt;ctx.lineWidth=2;ctx.stroke();ctx.fillStyle=tc;ctx.fill();}for(var i=-k+1;i<k;i++){for(var j=0;j<2*k-1-Math.abs(i);j++){one(o[0]+(-k+1+Math.abs(i)/2+j)*w,o[1]+h*i);}}}else{console.log('你的浏览器不支持Canvas');}
}
</script>
</body>
</html>

效果如下:

第二次更新:其实本图形的绘制需求来自《蜂巢迷宫》游戏,下面的版本为的是能够直接在六边形网格上编辑文字。
首先在每个小六边形的相应位置添加输入框(用的绝对定位),改变背景色和边框使得不可见,当鼠标放上以及聚焦时改变背景色和边框,在改变大六边形边长时清空输入框并重新生成,在改变小六边形边长时修改输入框的位置,在改变颜色时无需改动输入框。
代码如下:


<!DOCTYPE HTML>
<html>
<head>
<title>六边形网格</title>
<link id="link" rel="shortcut icon" type="image/x-icon" href="">
<style>
#bc1,#bc2{width:25px;}
#bj,#xt,#tc{width:20px;}
input{font-size: 16px;
}
#note{font-size: 16px;font-family: 'Arial';height:90px;
}
input::-webkit-outer-spin-button,input::-webkit-inner-spin-button {-webkit-appearance: none;
}
input[type="number"]{-moz-appearance: textfield;
}
</style>
</head>
<body>
<p>
设置大六边形边长:
<input id='bc1' type="number" value="3" onchange="document.getElementById('bc1s').value=this.value;change(this.id,this.value)"> 小六边形
<input id="bc1s" type="range" min="1" max="20" step="1" value="3" oninput="document.getElementById('bc1').value=this.value;" onchange="change('bc1',this.value);"/>
<span style="color: gray;">(仅改变此项时会清空文本框内容)</span>
<br>
设置小六边形边长:
<input id='bc2' type="number" value="24" onchange="document.getElementById('bc2s').value=this.value;change(this.id,this.value)"> 像素(px)
<input id="bc2s" type="range" min="1" max="50" step="1" value="24" oninput="document.getElementById('bc2').value=this.value;" onchange="change('bc2',this.value);"/>
<br>
设置背景色 <input type="color" id="bj" value="#c8ffff" onchange="change(this.id,this.value)"/>
设置线条色 <input type="color" id="xt" value="#0000ff" onchange="change(this.id,this.value)"/>
设置填充色 <input type="color" id="tc" value="#faebd7" onchange="change(this.id,this.value)"/></p>
<p id='p1'></p>
<canvas id="myCanvas" width="300" height="150">
<p>你的浏览器不支持Canvas</p>
</canvas>
<div id='texts'>div</div>
<br>
<textarea id='note' placeholder='点击输入笔记(拖动右下角可调整输入框大小)'></textarea>
<script type="text/javascript">
"use strict";
var canvas=document.getElementById('myCanvas');
if(canvas.getContext) {//如果浏览器支持Canvasvar ctx=canvas.getContext('2d');var dic={};//输入参数的对象var para=['bc1','bc2','bj','xt','tc'];for(var i=0;i<para.length;i++){dic[para[i]]=document.getElementById(para[i]).value;}dic['bc1']=2;generate(0);link.href=myCanvas.toDataURL({format:'image/png', quality:1});//修改网页图标dic['bc1']=3;generate(2);
}
else{console.log('你的浏览器不支持Canvas');
}
function make_texts(i,j,xo,yo,w,h,c){//生成文本框//i,j为横纵序号,xo,yo为中心坐标,w,h为宽高var text =document.createElement('input');text.id='t_'+i+','+j;text.style['left']=xo-w/2+2+'px';text.style['top']=yo-h/2+1+'px';text.style['width']=w-6+'px';text.style['height']=h-6+'px';text.style['position']='absolute';text.style['text-align']='center';text.style['outline']='none';text.style['border']='0px';text.style['background-color']=hexToRgba(c,0);// text.value=text.id.slice(2);//填充文本框,测试用text.onmouseover=function(){text.style['background-color']=hexToRgba(c,0.9);};text.onmouseout=function(){text.style['background-color']=hexToRgba(c,0);}text.onfocus=function(){text.style['border']='1px solid red';}text.onblur=function(){text.style['border']='0px';}document.getElementById('texts').appendChild(text);
}
function move_texts(i,j,xo,yo,w,h){//移动文本框//i,j为横纵序号,xo,yo为中心坐标,w,h为宽高var text =document.getElementById('t_'+i+','+j);text.style['left']=xo-w/2+2+'px';text.style['top']=yo-h/2+1+'px';text.style['width']=w-6+'px';text.style['height']=h-6+'px';
}
function one(vs,xo,yo,xt,tc){ctx.beginPath();ctx.moveTo(xo+vs[5][0],yo+vs[5][1]);for(var i=0;i<vs.length;i++){ctx.lineTo(xo+vs[i][0],yo+vs[i][1]);}ctx.strokeStyle=xt;ctx.lineWidth=2;ctx.stroke();ctx.fillStyle=tc;ctx.fill();
}
function change(id,v){dic[id]=document.getElementById(id).value;if(dic['bc1']>100){var c=confirm('六边形个数过多时网页会卡,是否继续?');if(!c){return;}}if(id=='bc1'){generate(2);//大六边形边长修改时,清空文本框,重新生成}else if(id=='bc2'){generate(1);//小六边形边长修改时,移动文本框位置}else{generate(0);//颜色改变时,不改变文本框}
}
function generate(change_size){var k=Number(dic['bc1']);//大六边形边长,单位小六边形var d=Number(dic['bc2']);//小六边形边长,单位像素(px)var w=Math.sqrt(3)*d;//小六边形宽度var h=3/2*d;//小六边形高度var count=3*k*k-3*k+1;//小六边形个数canvas.width=2*k*w;canvas.height=2*k*h+h/2;document.getElementById('p1').innerHTML='画布宽'+canvas.width+'px,高'+canvas.height+'px,含有'+count+'个小六边形';var ctop=canvas.getBoundingClientRect().top;var cleft=canvas.getBoundingClientRect().left;var o=[canvas.width/2,canvas.height/2];ctx.fillStyle=dic['bj'];ctx.fillRect(0,0,canvas.width,canvas.height);ctx.beginPath();var vs=[[0,d],[-w/2,d/2],[-w/2,-d/2],[0,-d],[w/2,-d/2],[w/2,d/2]];if(change_size==2){//移除所有文本框document.getElementById('texts').innerHTML='';}for(var i=-k+1;i<k;i++){for(var j=0;j<2*k-1-Math.abs(i);j++){var xo=o[0]+(-k+1+Math.abs(i)/2+j)*w;var yo=o[1]+h*ione(vs,xo,yo,dic['xt'],dic['tc']);if(change_size==2) make_texts(i,j,cleft+xo,ctop+yo,w,d,dic['bj']);else if(change_size==1) move_texts(i,j,cleft+xo,ctop+yo,w,d);}}document.getElementById('note').style['width']=canvas.width+'px';document.getElementById('note').style['border']='1px solid'+dic['xt'];
}
function hexToRgba(hex, opacity) {return 'rgba(' + parseInt('0x' + hex.slice(1, 3)) + ',' + parseInt('0x' + hex.slice(3, 5)) + ','+ parseInt('0x' + hex.slice(5, 7)) + ',' + opacity + ')';//JS - 将十六进制的颜色值转成rgb、rgba格式 https://www.hangge.com/blog/cache/detail_2291.html
}
</script>
</body>
</html>

效果如下:

在线预览网址: https://fun.rth1.me/text6.html

Canvas绘制六边形网格相关推荐

  1. canvas绘制的文字如何换行

    <html><head><title>canvas绘制的文字如何换行</title><style type="text/css" ...

  2. HTML5 canvas绘制雪花飘落

    Canvas是HTML5新增的组件,它就像一块幕布,可以用JavaScript在上面绘制各种图表.动画等.没有Canvas的年代,绘图只能借助Flash插件实现,页面不得不用JavaScript和Fl ...

  3. canvas绘制时钟

    听了慕课网Sliav Zhou 的课程canvas绘制时钟,记录下来的代码,每句做了注解便于以后学习,原先每次边听别的课边敲码,错误百出,明明原封不动复制的代码,就会出错,还找不到原因,今天可能运气好 ...

  4. canvas绘制圆形

    canvas绘制圆形的思路: 1.创建路径 XXX.beginpath(); 2.创建圆形的路径: 3.关闭路径:XXX.closepath(); 路径不关闭也能绘制出图形 4.设定绘制样式. 创建圆 ...

  5. java canvas 画图片_[Java教程][HTML5] Canvas绘制简单图片

    [Java教程][HTML5] Canvas绘制简单图片 0 2016-05-13 13:00:04 获取Image对象,new出来 定义Image对象的src属性,参数:图片路径 定义Image对象 ...

  6. html5 canvas绘制圆形进度实例

    2019独角兽企业重金招聘Python工程师标准>>> html5 canvas绘制圆形进度实例 <canvas id="test" width=200 h ...

  7. 【Android 应用开发】Canvas 绘制文字 ( 文字尺寸测量 | 基线绘制 )

    文章目录 I . 文字尺寸测量 II . 基线绘制 I . 文字尺寸测量 1 . 精准绘制需求 : Canvas 绘制文字时 , 有时需要精准的控制文字的绘制 , 如绘制到指定的区域 , 居中 , 或 ...

  8. 小猿圈html5教程之canvas绘制线段方法

    HTML5现在是时下较火的编程语言之一,但是对于怎么学习很多朋友都是不了解的,不知道从何处下手,针对以上内容小猿圈web前端讲师每天会分享一个web前端知识,希望对你的前端学习有一定的帮助,今天分享的 ...

  9. 微信小程序canvas绘制环形图(含动画)

    页面版 效果图 思路 1.使用一个canvas绘制(带动画): 2.通过画弧线,设置线宽,来实现圆环效果: 3.计算每段圆弧的起始角度和终止角度,用递归做动画: 绘制完第一段圆弧块–>再绘制下一 ...

  10. 微信小程序-canvas绘制文字实现自动换行

    微信小程序-canvas绘制文字实现自动换行 在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvasContext.fillText参数为 我们只能设置文本的最大宽度,这就产生 ...

最新文章

  1. websocket工作原理
  2. 天气正好,hello world!
  3. mysql end log pos_MySql binlog日志详解
  4. 随时间的反向传播算法 BPTT
  5. c语言深度剖析第三版pdf_入门到入坟,蕴含全网最强知识点3283页笔记、pdf教程,活到老,学到老...
  6. 【leetcode】Combinations (middle)
  7. java中 下列不合法的语句_在Java中,下列( )是不合法的赋值语句。_学小易找答案...
  8. ios上textarea不能输入
  9. android elf 加固_android so加固之section加密
  10. 关于_beginthreadex、_beginthread和CreateThread
  11. 练习项目--cookie数据脱敏
  12. XP下安装ubuntu双系统
  13. HTTP协议详解(真的很经典)(转载)
  14. 第三章 最速下降法和牛顿法
  15. 零基础java学习笔记
  16. 在Ubuntu16-04版本上搭建离线免费地图osm(一)
  17. 机器学习为什么也可以像人一样认识cang老师
  18. 一个img文件-实验吧
  19. Smartbi报表工具的学习笔记,如何学好报表分析?
  20. cad菜单栏快捷键_干货|如何快速将图片转换成CAD文件格式

热门文章

  1. 网站建设就是要大胆创新
  2. SQL and NOSQL
  3. Educoder---Java继承与接口、文件
  4. Error 遇到错误:请求通道在等待 00:01:00 以后答复时超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能已经是更长超时的一部分
  5. ArcGIS提取NDVI
  6. 智能家居的应用研究现状
  7. validity.valueMissing无论写不写文本都为false
  8. win10小娜_win10小娜不好用,想禁用或彻底删除Cortana,就用这2招
  9. jsp 的ne 什么意思
  10. Unity Recorder的使用讲解