canvas移动坐标空间_前端canvas画布

canvas移动坐标空间_前端canvas画布前言最近在做自己维护的一个可视化工具的时候,在添加基于echart的雷达图的时候,按照echart官网案例写完发现在自己项目中无法正常运行,排查了一番发现是我项目中echart的版本太低。找到问题原

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前言

最近在做自己维护的一个可视化工具的时候,在添加基于echart的雷达图的时候,按照echart官网案例写完发现在自己项目中无法正常运行,排查了一番发现是我项目中echart的版本太低。找到问题原因之后就升级echart,但是升级echart之后发现原本正常运行的echart地图组件又无法使用,百度了一番发现echart在最新的版本中地图数据进行了切换,原先的数据由于不符合规范被砍掉,导致2.0以前的echart地图都无法正常使用了。既然出现这样的情况,那就没办法了,项目中使用的echart地图有三种类型,迁徙图、标记图和热力图。思来想去,echart最终还是要升级,所以就决定自己开发项目中需要的基于canvas的迁徙图,标记图和热力图。这篇稳重主要就阐述canvas如何实现类似于echart中的迁徙图。

原理说明

1、轨迹开始位置和结束位置之间的轨迹通过二次贝塞尔曲线quadraticCurveTo来实现,其中绘制贝塞尔曲线的控制点需要根据开始位置和结束位置来确定;

2、轨迹上运行的标记通过二次贝塞尔曲线反推获取贝塞尔曲线不同位置的x,y坐标,然后通过不断设置轨迹上点位置来实现轨迹上点;

3、轨迹上点移动和开始和结束位置动画通过requestAnimationFrame来实现,切换重回canvas的时候需要调用cancelAnimationFrame来实现。

演示示例实例效果图如下:

canvas移动坐标空间_前端canvas画布

轨迹绘制方法

 1 function drawTravel (start,end) {
 2   var middleX = 0;
 3   var middleY = 0;
 4   var gnt1 = ctx.createLinearGradient(start.pos[0],start.pos[1],end.pos[0],end.pos[1]);
 5   gnt1.addColorStop(0,start.color);
 6   gnt1.addColorStop(1,end.color);
 7   if (start.pos[0] > end.pos[0] && start.pos[1] > end.pos[1]) {
 8      middleX = (start.pos[0] + end.pos[0]) / 2 * rate;
 9      middleY = (start.pos[1] + end.pos[1]) / 2 * (2 - rate);
10   } 
11   if (start.pos[0] > end.pos[0] && start.pos[1] < end.pos[1]) {
12      middleX = (start.pos[0] + end.pos[0]) / 2 * rate;
13      middleY = (start.pos[1] + end.pos[1]) / 2 * rate;
14   } 
15   if (start.pos[0] < end.pos[0] && start.pos[1] > end.pos[1]) {
16      middleX = (start.pos[0] + end.pos[0]) / 2 * (2 - rate);
17      middleY = (start.pos[1] + end.pos[1]) / 2 * (2 - rate);
18   } 
19   if (start.pos[0] < end.pos[0] && start.pos[1] < end.pos[1]) {
20      middleX = (start.pos[0] + end.pos[0]) / 2 * (2 - rate);
21      middleY = (start.pos[1] + end.pos[1]) / 2 * rate;
22   }
23   ctx.strokeStyle = gnt1;
24   ctx.beginPath();
25   ctx.moveTo(start.pos[0],start.pos[1]);
26   ctx.quadraticCurveTo(middleX,middleY,end.pos[0],end.pos[1]);
27   ctx.stroke();
28   // 获取贝塞尔曲线上的点
29   for (var i = 0; i < dotNumber; i++) {
30     var _t = (t - animationDotSpeed * i * 2) >= 0 ? (t - animationDotSpeed * i * 2) : 1 + (t - animationDotSpeed * i * 2);
31     var x = Math.pow(1-_t, 2) * start.pos[0] + 2 * _t * (1-_t) * middleX + Math.pow(_t, 2) * end.pos[0];
32     var y = Math.pow(1-_t, 2) * start.pos[0] + 2 * _t * (1-_t) * middleY + Math.pow(_t, 2) * end.pos[1];
33     ctx.fillStyle = 'rgba(' + dotColor.split('(')[1].split(')')[0] + ',' + (1 - 1 / dotNumber * i) + ')'
34     ctx.beginPath();
35     ctx.arc(x,y,dotRadius,0,2*Math.PI);
36     ctx.fill();
37     ctx.closePath()
38   }
39 }

开始位置和结束位置标记绘制方法

 1 function drawCoordinate (coordinate) {
 2   ctx.fillStyle = centerColor;
 3   ctx.beginPath();
 4   ctx.arc(coordinate.pos[0], coordinate.pos[1], radiusCenter,0,2*Math.PI);
 5   ctx.closePath();
 6   ctx.fill()
 7   ctx.fillStyle = ringColor.split(',').slice(0,3).join(',') + ',0.5)';
 8   ctx.beginPath();
 9   ctx.arc(coordinate.pos[0], coordinate.pos[1], radiusCenter + 5,0,2*Math.PI);
10   ctx.closePath();
11   ctx.fill()
12   if (radiusRing >= radiusRingMax) {
13       radiusRing = radiusRingMin;
14   }
15   ctx.fillStyle = ringColor;
16   ctx.beginPath();
17   ctx.arc(coordinate.pos[0], coordinate.pos[1], radiusRing,0,2*Math.PI);
18   ctx.closePath();
19   ctx.fill()
20   radiusRing += animationSpeed;
21   ringColor = ringColor.split(',').slice(0,3).join(',') + ',' + (0.5 - (radiusRing - radiusRingMin) * 0.02) + ')';
22 }

执行canvas绘制方法

 1 function draw () {
 2   cancelAnimationFrame(requestAnimationFrameName);
 3   ctx.clearRect(0,0,width,height)
 4   array.forEach(function (item, index) {
 5     drawCoordinate(item);
 6     if (index > 0) {
 7         drawTravel(array[0],item)
 8     }
 9   })
10   if (t >= 1) {
11       t = 0;
12   }
13   t += animationDotSpeed;
14   requestAnimationFrameName = requestAnimationFrame(draw)
15 }

实例预览地址:canvas实现平面地图迁徙图

希望上述说明能够帮助到您。

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/167360.html原文链接:https://javaforall.net

(0)
上一篇 2022年8月4日 下午11:36
下一篇 2022年8月4日 下午11:36


相关推荐

  • Jedis里SortedSet相关操作

    Jedis里SortedSet相关操作Jedis 里的 SortedSet 可以理解为有序集合或者优先队列 每个 key 都是有分值的 所以可以应用于排行榜或者某个用户的成就值成就排名之类的关于分值排行相关当然 index 也都是从 0 开始的 1 结尾的 有双向性 默认排名是从小到大 Jedisjedis newJedis jedis flushAll 清空 SortedSet 有序集合 优先队

    2026年3月26日
    3
  • Scene Graph(视觉关系场景图检测)

    Scene Graph(视觉关系场景图检测)SceneGraphNe SceneGraphPa 开山经典之作 motif 指场景图中重复出现的子结构 引入 relationprio 主语和宾语确定 relation 很容易确定 并且类似的 motif 会大量出现 后 直接通过统计的方法 不需要图片信息就能得到较高的准确率 文中的方法先将图片做 proposal

    2026年3月19日
    2
  • intellij idea激活码2021_最新在线免费激活

    (intellij idea激活码2021)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月27日
    73
  • keepalived工作原理

    keepalived工作原理keepalived 工作原理 Keepalived 简介 Keepalived 是什么 VRRP 协议与工作原理 VRRP 选举机制工作过程 Keepalvied 的工作原理 Keepalived 体系结构与 heartbeat corosync 等比较 Keepalived 简介 Keepalived 是 Linux 下一个轻量级别的高可用解决方案 高可用 广义来讲 是指整个系统的高可用行 狭义的来讲就是主机的冗余和接管 它与 HeartBeat 实现类似的功能 都可以实现服务或者网络的高可用 但是又有差别 HeartBeat 是一个专业的

    2026年2月2日
    3
  • vim乱码恢复_linux保存退出命令

    vim乱码恢复_linux保存退出命令初始时,安装好Ubuntu以后,使用Vim退出以后会显示乱码,这是由于Ubuntu的Vim默认是链接到了/usr/bin/gnome,这是不同于一般使用习惯的Vim,所以我们如果需要使用一般习惯的Vim,并且解决Vim退出以后的乱码问题,我们必须使Vim链接到我们常用的Vim.basic,步骤如下:1.使用apt-get安装Vim包,系统默认安装的是Vim-gnome包,命令如下:sud

    2022年8月24日
    10
  • mysql修改密码方法大全

    mysql修改密码方法大全MySQL 是一个关系型数据库管理系统 在 WEB 应用方面 MySQL 是最好的 RDBMS RelationalDa 关系数据库管理系统 应用软件之一 搭配 PHP 和 Apache 可组成良好的开发环境 因此用的很广泛 很多人都会遇到 MySQL 需要修改密码的情况 比如密码太简单 忘记密码等等 这里我就教大家几种修改 MySQL 密码的方法 这里以修改 root 密码为例 操作系统为 windows 注意 修改 MySQL 是需要有 mysql 里的 root 权限的

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号