Canvas:绘制多边形
前言
CanvasRenderingContext2D 没有提供绘制多边形的函数,所以只能由我们自己来实现绘制多边形的函数。以六边形为基础,需要用到三角函数:sin 和 cos。
点 A 坐标

(一)连接必要的辅助线:①连接点 A 和点 O;②从点 A 往下作一条垂直线;③连接点 A1 和点 O。(二)已知的量:①AO 实际就是圆 O 的半径。点 A 坐标的求解步骤:
- 求 ∠AOB;
- 求 OB 的长;
- 求 AB 的长;
- X 轴上的坐标:O 的 X 轴 + OB 的长度;
- Y 轴上的坐标:O 的 Y 轴 - AB 的长度;
求 A 点的坐标就必须要知道 OB 和 AB。
求 OB 的长
领边比斜边用 COS 函数,那么 OB 的长就是:
\]
求 AB 的长
对边比斜边用 SIN 函数,那么 AB 的长就是:
\]
求 ∠AOB
求 OB 和 AB 就必须要知道 ∠AOB。观察可知,∠AOB 的度数是360° / 6 = 60°。
代码实现
let circX = 100, circY = 100, // 圆心坐标
let sides = 6, angleAOB = (Math.PI * 2) / sides; // ∠AOB
let sideOB = Math.cos(angleAOB) * radius, sideAB = Math.sin(angleAOB) * radius;
let aX = circX + sideOB, // 点 A 的 x 坐标
let aY = circY - sideAB; // 点 A 的 y 坐标
所以最终求得点 A 的坐标:(140, 30.717967697244916)。
点 F 坐标
点 F 不能直接构成一个三角形,所以度数是 0°。sin0° = 0、cos0°= 1:
let circX = 100, circY = 100, // 圆心坐标
let sides = 6, angle = 0;
let adjacentSide = Math.cos(angle) * radius, beveledSide = Math.sin(angle) * radius;
let aX = circX + adjacentSide, // 点 F 的 x 坐标
let aY = circY - beveledSide; // 点 F 的 y 坐标
所以最终求得点 F 的坐标:(180, 100)。
求所有点坐标
通过上面两个坐标的求解过程可知,只有三角形的度数在增加,从点 F 顺时针开始,每一个角是自身的角度再加 60°。
let radius = 80, sides = 6, circX = 100, circY = 100;
let angle = (Math.PI * 2) / sides, accumulator = 0;
for ( let i = 0; i < sides; i++ ) {
let adjacentSide = Math.cos(accumulator) * radius;
let beveledSide = Math.sin(accumulator) * radius;
let aX = circX + adjacentSide;
let aY = circY - beveledSide;
ctx.lineTo(aX, aY);
accumulator += angle;
}
6 个点坐标的结果依次是:

封装成函数
只需提供多边形有多少面、多边形的圆心半径:
function drawPolygonPath(sides, radius, circX, circY, ctx) {
let angle = (Math.PI * 2) / sides, accumulator = 0;
ctx.beginPath();
for ( let i = 0; i < sides; i++ ) {
let adjacentSide = Math.cos(accumulator) * radius;
let beveledSide = Math.sin(accumulator) * radius;
let aX = circX + adjacentSide;
let aY = circY - beveledSide;
ctx.lineTo(aX, aY);
accumulator += angle;
}
ctx.closePath();
ctx.stroke();
}
ctx.lineTo(aX, aY) 确定多边形所有的点,在循环结束之后关闭路径,再调用ctx.stroke() 函数,完成多边形的绘制。
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
drawPolygonPath(6, 80, 100, 100, ctx);

Canvas:绘制多边形的更多相关文章
- canvas绘制多边形
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 浅谈使用canvas绘制多边形
本文主要使用坐标轴的使用来绘制多边形,点位则都是在y轴上寻找,这种方法能够更好的理解图形与修改. //id为html里canvas标签的属性id: //x,y为坐标轴的起始位置,因为canvas默认坐 ...
- JavaScript+canvas 绘制多边形
效果图: <body> <canvas id="square" width="500"></canvas> <canv ...
- (三)canvas绘制样式
beginPath() 对画线点的一个开始限制 moveTo() 画线的起点,只在开头使用 参数两个x轴,y轴 lineTo() 后续连线 两个参数x轴,y轴 stroke() 连线无填充 fill( ...
- 学习笔记:HTML5 Canvas绘制简单图形
HTML5 Canvas绘制简单图形 1.添加Canvas标签,添加id供js操作. <canvas id="mycanvas" height="700" ...
- [WebGL入门]十四,绘制多边形
注意:文章翻译http://wgld.org/.原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:].另外,鄙人webgl研究还不够深入.一些专业词语,假设翻译有误,欢迎大家 ...
- Canvas绘制不规则图形,实现可拖动,编辑--V1.0第一篇
目前的工作在做在线的标注工具,接触canvas一年了,各种绘制,基本上图像的交互canvas都可以完成,也写了几篇关于canvas的文章,遇到的问题也写博客上了,对于canvas有问题的朋友可以去看看 ...
- Canvas学习:封装Canvas绘制基本图形API
Canvas学习:封装Canvas绘制基本图形API Canvas Canvas学习 从前面的文章中我们了解到,通过Canvas中的CanvasRenderingContext2D对象中的属性和方 ...
- JS实现鼠标点击爱心&绘制多边形&每日一言功能
本篇文章主要介绍我的个人博客 程序猿刘川枫 中页面使用的美化功能(基于JS实现): 1.鼠标点击出现不同颜色爱心特效 2.页面浮动多边形跟随鼠标移动 3.每日一言功能 1.鼠标点击出现爱心特效 经常在 ...
- HTML5学习总结——canvas绘制象棋(canvas绘图)
一.HTML5学习总结——canvas绘制象棋 1.第一次:canvas绘制象棋(笨方法)示例代码: <!DOCTYPE html> <html> <head> & ...
随机推荐
- 关于Mybatis-Plus中update()、updateById()方法的使用及null值的判断
使用场景说明: 在 Mybatis-Plus 的使用过程中,经常会遇对数据库更新的情况 更新常用方法:update().updateById() 问题:经常会遇见对 null 值的处理,对传入的实体参 ...
- pandas中groupby的使用
一.缘由 在爬取大量的数据之后,需要对数据进行分组的处理,于是就使用了groupby,但是我需要的并不是分组之后数据的聚合分析,我需要的是原生的某些数据.但是却找不到网上的相关案例.于是,我就自己尝试 ...
- SpringBoot内置tomcat启动过程及原理
作者:李岩科 1 背景 SpringBoot 是一个框架,一种全新的编程规范,他的产生简化了框架的使用,同时也提供了很多便捷的功能,比如内置 tomcat 就是其中一项,他让我们省去了搭建 tomca ...
- Prometheus高可用架构介绍
Prometheus作为新生代的开源监控系统,慢慢成为了云原生体系的监控事实标准,也证明了其设计得到业界认可.但在多集群,大集群等场景下,Prometheus由于没有分片能力和多集群支持,还有Prom ...
- [OpenCV实战]16 使用OpenCV实现多目标跟踪
目录 1 背景介绍 2 基于MultiTracker的多目标跟踪 2.1 创建单个对象跟踪器 2.2 读取视频的第一帧 2.3 在第一帧中确定我们跟踪的对象 2.4 初始化MultiTrackerer ...
- python进阶之路20 正则表达式 re模块
正则表达式前情 案例:京东注册手机号校验 基本需求:手机号必须是11位.手机号必须以13.15.17.18.19开头.必须是纯数字 '''纯python代码实现''' # while True: # ...
- [cocos2d-x]关于菜单项
菜单项的分类 MenuItem:菜单项类,它是一个虚基类,因此必须实现它的子类,再把子类对象赋给父类指针. MenuItemFont:字体菜单项. MenuItemAtlasFont:字体菜单项,和第 ...
- odoo资料
https://www.cnblogs.com/smarttony/category/1484288.html
- 除了Navicat和DBeaver,还有没有免费又好用的数据库管理/SQL工具推荐
很多国内SQL学习者和开发者对Navicat.DBeaver等国外数据库管理工具已经很熟悉了.但是,有没有比他们更适合SQL开发者的数据库管理/SQL工具呢?这里,笔者结合自己的调研来聊一下. 笔者做 ...
- 一把梭:REST API 全用 POST(转载)
一把梭:REST API 全用 POST(转载) 原文链接: https://coolshell.cn/articles/22173.html 写这篇文章的原因主要还是因为V2EX上的这个贴子,这个贴 ...