专栏首页前端迷一文 get 入门 canvas 的最佳路径

一文 get 入门 canvas 的最佳路径

咱们一起来看看这个问题,这个问题问了两个小问题:

1.如何在 canvas 上绘制多边形? 2.鼠标怎么选中绘制的某一个图形?

那么咱们就来分为两个问题解答。

绘制多边形

要绘制一个多边形,多边形图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤。

  • 首先,你需要创建路径起始点
  • 然后你使用画图命令去画出路径。
  • 之后你把路径封闭
  • 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。以上这些步骤会用到一些 API:

beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。

closePath() 闭合路径之后图形绘制命令又重新指向到上下文中。

stroke() 通过线条来绘制图形轮廓。

fill() 通过填充路径的内容区域生成实心的图形。

详解绘制过程

这里详细解答一下绘制的过程: 第一步,生成路径,调用 beginPath,本质上路径是有很多子路径所构成的,这些子路径全部在一个列表里面,所有的子路径(线、弧)构成图形。而每次调用这个方法之后,列表都会被重置,然后就可以绘制新的图形。(你需要在设置路径之后指定你的起始位置); 第二步,调用指定函数绘制路径; 第三步,闭合路径 closePath(不是必须的);

笔式绘图仪模型

绘制一个三角形例子:

var ctx = canvas.getContext("2d");
ctx.beginPath(); //开始路径
ctx.moveTo(75, 50); //指定起始位置
ctx.lineTo(100, 75); //绘制到这个位置的一条线
ctx.lineTo(100, 25); //绘制到这个位置的一条线
ctx.fill(); //填充图形,默认就制动结束路径了

在这个过程中,有一个比较有用的函数,moveTo,这个函数实际上画不出来任何东西,它是属于上面描述的路径列表的一部分。

看下这个函数的作用:

moveTo() 将笔触移动到指定的坐标 x 以及 y 上。

当 canvas 初始化或者 beginPath()调用后,你通常会使用 moveTo()函数设置起点。我们也能够使用 moveTo()绘制一些不连续的路径。

这个时候你可以想象一下在纸上画东西,笔尖从一个点到另一个点的移动过程。这个过程的模式叫做笔式绘图仪模式。所以 canvas 2d 绘图的模式也就是这种模式。

现在绘制多边形就没有什么问题了。

canvas 上找出指定的图形

首先,完成描述一下这个问题:按下鼠标,如何判断出选中了某一个图形? 比如下图:

鼠标点击了这个不规则多边形的内部,怎么判断?

第一反应就是 isPointInPath,或者是迭代所有图形,拿鼠标的点去与图形的点碰撞检测,这个方法可以用,但是适用场景比较少,还有就是性能开销比较大,如果图形太多,每一个都需要经过计算,那么这个交互会变得非常的不友好。

有没有其他方案了,在游戏界有一个普遍使用的方案——包围盒,什么是包围盒呢?我们以上面的图形举例,外面画的红线框就是这个多边形的包围盒。

很形象的一个例,就是公司发的月饼盒子,就是里面圆圆的月饼 ? 的包围盒。

包围盒的方案有个缺点,选取的范围比较粗。比如上图的红框,框选了不是多边形部分的内容。如果你想用包围盒的方案来做,那就要分的足够细,比如下图:

分出来了多个包围盒,这种情况在图形特别复杂的时候,包围盒这个方案就有点粗糙了。

还有下图这种,实心和空心圆,用包围盒也就非常的不友好。

那怎么办?

方案

如果想要快速选中某一个图形,我们能不能对我们的每一个图形有一个对应的 hash,而在鼠标点击的时候,又能够取到这个 hash。用 hash 的值,去找这个图形,这个过程的时间复杂度是 O(1)。

比如在画布的这些图形:

在另一张一模一样的画布上,画了这些图形

上层画布(显示出来的)是正常的图形,但是每个图形分配一个 rgb 色值。 下层画布(隐藏)用这个 rgb 色值做填充或者 stroke。 当鼠标点击的时候,在隐藏画布相同的位置,取一个像素点。

而这个像素点的rgb值就是我们要找的 hash。

至此,两个问题已经解答了。

本文分享自微信公众号 - 前端迷(love_frontend),作者:蜀中亮子

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-08-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 软技能提升:转转中后台规范落地实践

    中台覆盖了多线业务,自然对应的不少后台系统,考虑日后到项目应用,满足业务的快速迭代,无论是技术版本升级、敏捷开发、可复用性和可维护性等。

    前端迷
  • 图片压缩原理

    说起图片压缩,大家想到的或者平时用到的很多工具都可以实现,例如,客户端类的有图片压缩工具 PPDuck3, JS 实现类的有插件 compression.js ...

    前端迷
  • webpack深入浅出实战系列

    https://github.com/luoxue-victor/learn_webpack/

    前端迷
  • 一个有趣的例子带你入门canvas

    要绘制一个多边形,多边形图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘...

    刘小夕
  • TiDB 在摩拜单车在线数据业务的应用和实践

    摩拜单车于 2015 年 1 月成立,2016 年 4 月 22 日地球日当天正式推出智能共享单车服务,截至 2017 年 11 月中旬,已先后进入国内外超过 ...

    PingCAP
  • 美团点评 TiDB 深度实践之旅

    在美团,基于 MySQL 构建的传统关系型数据库服务已经难于支撑公司业务的爆发式增长,促使我们去探索更合理的数据存储方案和实践新的运维方式。随着近一两年来分布式...

    PingCAP
  • 解读 TiDB:行走在 GKE 上的 NewSQL 开源数据库

    数字化时代下,企业的发展与数据库的建设息息相关。如果搭建云下数据库,不仅要通过大量的运维投入保证数据库稳定运行,随着企业规模与数据量的发展,还要应对数据库扩容、...

    深度学习与Python
  • TiDB 助力东南亚领先电商 Shopee 业务升级

    Shopee(https://shopee.com/)是东南亚和台湾地区领先的电子商务平台,覆盖新加坡、马来西亚、菲律宾、印度尼西亚、泰国、越南和台湾等七个市场...

    PingCAP
  • 我们为什么放弃 MongoDB 和 MySQL,选择 TiDB

    技术选型是由技术方向和业务场景 trade-off 决定的,脱离业务场景来说技术选型是没有任何意义的,所以本文只是阐述了伴鱼技术团队数据库选型的过程,这并不是 ...

    深度学习与Python
  • TiDB-Lightning Toolset & TiDB-DM 正式开源,前排开“坑”、PR 走起!

    **TiDB-Lightning Toolset 是一套快速全量导入 SQL dump 文件到 TiDB 集群的工具集**,自 2.1.0 版本起随 TiDB ...

    PingCAP

扫码关注云+社区

领取腾讯云代金券