一、简述

大家在用Canvas实现球体碰撞的动画场景时是否感觉无从下手,或者是知道怎么去实现,但是要进行大量的计算,考虑非常多的细节,比如要考虑将外力分解为水平和垂直两个方向,然后考虑各种碰撞的检测,发生重叠后的修正,还有可能考虑引力方向和大小、透明度渐变等等这些,思考这些个计算逻辑时真的很让人头大,今天我就和大家分享一个非常好用的库,一个专门用于在Canvas上实现球体碰撞和球体交互场景的库–sphere-collision,通过简单配置便可快速实现碰撞效果,而且还提供了钩子函数,扩展性极强,让你实现想要的效果。

二、案例展示

下面展示几个案例的实现效果,这些都是使用这个库实现的动画效果,只要涉及到球体碰撞或球体交互的场景都可以使用这个库。

1.探照灯效果

2.球体碰撞交互效果

3.消灭行星小游戏

4.各类球体自由落体交互效果

5. 炫酷倒计时动画

以上案例源码均在visualization-collection开源项目中,github地址:https://github.com/hepengwei/visualization-collection

三、基本用法

安装

npm i sphere-collision

使用

import SphereCollision from "sphere-collision";const canvasWidth = 600; // 画布宽度
const canvasHeight = 600; // 画布高度
const globuleRadius = 60; // 球半径const beforeDrawGlobules = (sphereCollision) => {const { ctx } = sphereCollision;// 绘制整个画布的背景色ctx.clearRect(0, 0, canvasWidth, canvasHeight);ctx.beginPath();ctx.fillStyle = "#000000";ctx.fillRect(0, 0, canvasWidth, canvasHeight);
};const canvas = document.getElementById("myCanvas");
if (canvas) {canvas.width = canvasWidth;canvas.height = canvasHeight;const ctx = canvas.getContext("2d");// 实例化SphereCollision对象const sphereCollision = new SphereCollision(ctx,canvas,[{initX: 400,initY: 400,vx: 6,vy: 3,radius: globuleRadius,},],{ beforeDrawGlobules });// 开使执行动画sphereCollision.start();
}

四、API文档

SphereCollisionC

参数(顺序从上往下依次传入) 数据类型 说明 默认值 是否必需
ctx CanvasRenderingContext2D Context对象 null
canvas HTMLCanvasElement Canvas对象 null
globuleOptionsList GlobuleOptions[] 初始化球体的配置列表 []
options SphereCollisionOptions 配置参数 SphereCollisionOptions
属性
ctx CanvasRenderingContext2D Context对象
canvas HTMLCanvasElement Canvas对象
frameId number requestAnimationFrame方法返回的ID
globuleList GlobuleC[] 保存所有球体实例的列表
animationState enum AnimationState{“waitStart”,“inAnimation”,“stop”} 当前动画状态
mousePos MousePos 当前鼠标在Canvas中的位置坐标
prevMousePos(v1.1.0新增) MousePos 前一次鼠标在Canvas中的位置坐标
isMouseDown(v1.1.0新增) boolean 当前鼠标在Canvas中是否按下
mouseDownPos(v1.1.0新增) MousePos 鼠标在Canvas中按下时的位置坐标
mouseInGlobuleList(v1.1.0新增) GlobuleC[] 当前鼠标所在球体中的球体实例列表
方法
start () => void 必须调用该方法,Canvas才渲染,开始执行相关动画
createGlobule (globuleOptions: GlobuleOptions) => Globule 创建球体实例的方法
updateGlobuleList (newGlobuleList: GlobuleC[]) => void 更新球体实例列表,用于动态增加或减少球体实例
stop () => void 停止整个frame动画

GlobuleOptions

属性 数据类型 说明 默认值 是否必需
id any 任意值,可存放数据
initX number 初始x坐标(向右为正方向) 0
initY number 初始y坐标(向下为正方向) 0
vx number 在水平方向的速度(向右为正方向) 0
vy number 在垂直方向的速度(向下为正方向) 0
radius number 半径 10
color string 颜色 “#666666”
isPureColor(v1.1.3新增) boolean 是否为纯色 false
alpha number 透明度 1
alphaChangeV number 透明度改变的速度(正数增加,负数减小) 0
bgImg string 背景图片 “”
collisionLossV number 碰撞时的速度损失 0
moveLossV number 移动时的速度损失 0
gDirection “toInit” | “toBottom” | “toTop” | “toLeft” | “toRight” 引力方向。“toInit”,指向球体的初始位置;“toBottom”,指向正下方;“toTop”,指向正上方;“toLeft”,指向正左方;“toRight”,指向正右方(后四个为v1.1.0新增)
gCoefficient number 引力系数 0
requiredMouseInteraction boolean 是否需要鼠标交互 false
mouseInteractionBehavior(v1.1.0新增) “over” | “drag” 鼠标交互行为。“over”,鼠标穿过;“drag”,鼠标拖拽 当requiredMouseInteraction为true时,默认值为"over",当为false时,则没有默认值
fixedPos boolean 是否固定位置 false
receiveOutForce boolean 是否接受外力 true
receiveWallForce boolean 是否接受墙的力(与墙体发生碰撞) true
resistanceWallDirection(v1.1.3新增) Direction[] 有阻力的墙的方向 [“bottom”, “top”, “left”, “right”]
onlyCheckCollision boolean 当不接受外力时,是否检测碰撞(检测碰撞相关状态但不获取外力) false
maxMouseOutForce number 鼠标交互时能提供的最大力限制 null
maxMoveV number 最大移动速度 null
beforeDrawGlobule (globule: GlobuleC) => void 每一帧绘制该球体之前执行的钩子函数 null
afterDrawGlobule (globule: GlobuleC) => void 每一帧绘制该球体之后执行的钩子函数 null
afterCalculateNextFrameGlobule (nextFrameGlobule: GlobuleC) => void 每一帧绘制球体后,计算并修改为下一帧状态后执行的钩子函数 null

SphereCollisionOptions

属性 数据类型 说明
collisionRectX number 球体发生碰撞的矩形区域的左上角x坐标(向右为正方向) 0
collisionRectY number 球体发生碰撞的矩形区域的左上角y坐标(向下为正方向) 0
collisionRectWidth number 球体发生碰撞的矩形区域的宽度 canvas.width
collisionRectHeight number 球体发生碰撞的矩形区域的高度 canvas.height
monitorMousePos boolean 是否监听鼠标的位置 false
beforeDrawGlobules (sphereCollision: SphereCollisionC) => void 每一帧绘制所有球体之前执行的钩子函数 null
afterDrawGlobules (sphereCollision: SphereCollisionC) => void 每一帧绘制所有球体之后执行的钩子函数 null
onMouseDownCanvas(v1.1.0新增) (event: MouseEvent, sphereCollision: SphereCollisionC) => void 鼠标按下时执行的钩子函数 null
onMouseMoveCanvas(v1.1.0新增) (event: MouseEvent, sphereCollision: SphereCollisionC) => void 鼠标移动时执行的钩子函数 null
onMouseUpCanvas(v1.1.0新增) (event: MouseEvent, sphereCollision: SphereCollisionC) => void 鼠标松开时执行的钩子函数 null
onMouseLeaveCanvas(v1.1.0新增) (event: MouseEvent, sphereCollision: SphereCollisionC) => void 鼠标离开时执行的钩子函数 null

MousePos

属性 数据类型 说明
mouseX number | null 鼠标在Canvas中的x坐标(向右为正方向)
mouseY number | null 鼠标在Canvas中的y坐标(向下为正方向)

Direction

属性 数据类型 说明
Direction “bottom” | “top” | “left” | “right” 方向

GlobuleC

属性 数据类型 说明
id any 任意值,可存放数据
ctx CanvasRenderingContext2D Context对象
canvas HTMLCanvasElement Canvas对象
requiredMouseInteraction boolean 是否需要鼠标交互
mouseInteractionBehavior(v1.1.0新增) “over” | “drag” 鼠标交互行为。“over”,鼠标穿过;“drag”,鼠标拖拽
maxMouseOutForce number | null 鼠标交互时能提供的最大力限制
initX number 初始x坐标(向右为正方向)
initY number 初始y坐标(向下为正方向)
x number x坐标(向右为正方向)
y number y坐标(向下为正方向)
vx number 在水平方向的速度(向右为正方向)
vy number 在垂直方向的速度(向下为正方向)
radius number 半径
color string 颜色
isPureColor(v1.1.3新增) boolean 是否为纯色
alpha number 透明度
alphaChangeV number 透明度改变的速度(正数增加,负数减小)
bgImg string 背景图片
collisionLossV number 碰撞时的速度损失
moveLossV number 移动时的速度损失
gDirection “toInit” | “toBottom” | “toTop” | “toLeft” | “toRight” 引力方向。“toInit”,指向球体的初始位置;“toBottom”,指向正下方;“toTop”,指向正上方;“toLeft”,指向正左方;“toRight”,指向正右方(后四个为v1.1.0新增)
gCoefficient number 引力系数
fixedPos boolean 是否固定位置
receiveOutForce boolean 是否接受外力
receiveWallForce boolean 是否接受墙的力(与墙体发生碰撞)
resistanceWallDirection(v1.1.3新增) Direction[] 有阻力的墙的方向
onlyCheckCollision boolean 当不接受外力时,是否检测碰撞(检测碰撞相关状态但不获取外力)
mousePos MousePos 鼠标相对于canvas的位置坐标
maxMoveV number | null 最大移动速度
controlledByMouse(v1.1.0新增) boolean 当前是否受鼠标控制(被鼠标拖拽)
inCollisionGlobule boolean 是否与其他球体发生碰撞的状态
inCollisionGlobuleList GlobuleC[] 与其他球体碰撞的其他球体实例列表
inCollisionWall boolean 是否与墙体发生碰撞的状态
beforeDrawGlobule (globule: GlobuleC) => void | null 每一帧绘制该球体之前执行的钩子函数
afterDrawGlobule (globule: GlobuleC) => void | null 每一帧绘制该球体之后执行的钩子函数
afterCalculateNextFrameGlobule (nextFrameGlobule: GlobuleC) => void | null 每一帧绘制球体后,计算并修改为下一帧状态后执行的钩子函数
方法
addOutForce (outForceVX: number, outForceVY: number, isCollision?:boolean = false) => void 添加外力。用于动态增加或减小球体的速度

五、特别说明

  • 球体的fixedPos属性为true时, 获取不了外力,所以球体不会移动,但还是会使其他球体受到外力,进行反弹。
  • 球体的receiveOutForce属性为false时,获取不了鼠标穿过和其他球体碰撞产生的外力,即使另一个球体的receiveOutForce属性为true。
  • 球体的receiveWallForce属性为false时,获取不了来自墙体的外力,所以不会与墙体发生碰撞。
  • 球体的beforeDrawGlobule和afterDrawGlobule两个钩子函数,主要作用是在绘制球体之前和之后分别去绘制其他元素,而afterCalculateNextFrameGlobule钩子函数是用于做一些其他的逻辑判断,因为只有这个函数里拿到的球体实例是带有是否发生碰撞等相关信息的
  • 如果实例化SphereCollision对象时传入了beforeDrawGlobules钩子函数,并且需要在每一帧绘制前要清除整个画布,则需要使用者自己清除,这是考虑到有些不需要清除的场景。
  • 如果要获取鼠标相关的信息或者想要实现鼠标交互,实例化SphereCollision对象时就必须在第四个参数options中传入monitorMousePos为true。
  • 如果需要的话,可以在任何时候动态地修改球体实例的所有属性值,以满足自己的自定义需求。

六、关键版本更新日志

  • v1.1.3

  1. 新增支持纯色球体
  2. 新增支持四面墙中只有部分墙面有阻力,与球体发生碰撞
  3. 解决一些已知bug
  • v1.1.0

  1. 考虑后续的功能扩展,修改了SphereCollision类的参数,将之前的第四个及之后的参数都统一放到options对象中,并作为第四个参数传入。
  2. 新增支持上下左右四个引力方向
  3. 新增支持球体进行鼠标拖拽交互
  4. 新增的相关属性及方法可自行查阅API文档

更多个人文章

  1. 两个跨域页面进行跳转传参的终极方案
  2. 彻底搞懂盒子模型
  3. hashHistory和browserHistory的区别
  4. 十分钟带你入门Chrome插件开发
  5. 面试秘籍之排序算法

实现球体碰撞,使用这个库就够了相关推荐

  1. Canvas实现球体碰撞交互效果(一)

    一.Canvas简介 提到Canvas相信做前端开发的同学都不陌生,它是一个用于绘制图形的容器,我们会在一些特殊场景时需要用到Canvas,比如我们要在页面上显示一个流程图,这个流程图需要根据后端返回 ...

  2. MD5碰撞与撞库和题

    MD5 相同的情况叫做"碰撞",现在网络中已经出现了两个相同的 MD5 可执行文件,所以MD5现在已经被弃用了,发生碰撞的概率是1/(2^128). SHA-1 也会发生碰撞,但是 ...

  3. python 统计组合用什么库_Python数据科学,用这些库就够了

    为了方便学习,本文列出的20个Python库将按领域进行分类,有些你可能并不熟悉,但是真的能提高你的模型算法实现效率,多一点尝试,多一些努力! ▌核心库和统计数据 1. NumPy (Commits: ...

  4. unity 画球面_unity3d第一个例子--制作一个简单的球体碰撞墙面

    思路 当然首先应该先新建立一个地面,有地面才有一切(floor) 再建立一面墙WaLl,一面墙也就是用100个预制的正方体组成 我们不可能让发射的子弹bullet,朝着一个方向射击shoot 所以需要 ...

  5. uni-app框架看这五款组件库就够了

    uni-app 是一个使用 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.Web(响应式).以及各种小程序(微信/支付宝/百度/头条/飞书/QQ/快手/钉钉 ...

  6. 设计必备丨ICON素材哪里找 这五个素材库就够了

    页面设计和特效制作中我们会用到一些ICON图标和插画,但有些ICON不足够精美,今天就来给大家推荐5个ICON素材网站,供大家日常的设计及使用. 1.Iconfont(日常使用必备) Iconfont ...

  7. 视频剪辑有这6个高清视频素材库就够了

    视频剪辑必备的6个网站,免费.可商用,建议收藏! 1.菜鸟图库 https://www.sucai999.com/video.html?v=NTYxMjky 菜鸟图库网素材类型非常多,平面设计.UI设 ...

  8. 胶囊体 ,正方体,球体碰撞器差别,碰撞体以脚为基准与以腰为基准

  9. 企业云盘够快云库的「战斗与前行」

    由36氪举办的2016 wise独角兽大会将于12月6日召开.作为国内首家挂牌的企业云盘--够快云库也应邀参加了此次wise独角兽大会,并独家支持现场资料下载.现场将会有50位独角兽公司CEO.200 ...

最新文章

  1. 建模案例:最优截断切割问题
  2. Java 文件 IO 操作
  3. EL与JSTL注意事项汇总
  4. percona-toolkit(pt工具)使用总结
  5. Java基础视频笔记(四):泛型
  6. Your account has been locked out. Please contact the system administrator for further assistance.
  7. 开源中国翻译频道链接收藏
  8. 克劳斯比的零缺陷——《可以量化的管理学》
  9. java时间格式转换
  10. Python 用异常处理改写猜数游戏程序
  11. 在国产系统(Linux)上,安装运行Steam游戏详解
  12. SpringBoot图片上传报错:The field headImg exceeds its maximum permitted size of 1048576 bytes.
  13. thrift开源项目研究
  14. Protected multilib versions XXX
  15. 2017双11核心技术揭秘—双十一海量数据下EagleEye的使命和挑战
  16. 360断网急救箱 dns服务器未响应,发现DNS服务异常,用360断网急救箱修复后过一段时间又复发。怎么办?...
  17. 计算机毕业设计Java物流信息管理系统录像演示(源码+系统+mysql数据库+Lw文档)
  18. 重温马云英文演讲:最伟大的成功
  19. 商业智慧——三国职场人
  20. 高薪诚聘中高级软件工程师

热门文章

  1. pytorch 模型并行 model parallel
  2. linux 分区 4k对齐,分区4K对齐那些事,你想知道的都在这里
  3. 百度,互联网的“流氓大亨”?
  4. 如何利用字符串格式化漏洞
  5. 对于矩估计的一些理解
  6. 尽己力,听天命。无愧于心,不惑于情
  7. 医疗无菌加工之冷冻干燥 –冻干机搁板温度分布验证的指南规范与工艺建议
  8. python飞机大战简单的实现
  9. 手机如何拍出中背景模糊虚化的拍摄技巧
  10. react native 出现程序包com.facebook.react不存在