canvas(五角星碰撞)
马上9月份要找工作了,琢磨着要做个作品作为面试时的加分项。
本来打算仿一个淘宝网,但写完淘宝首页竟花了我一个星期!!!光html、css就有4000多行,看着首页都能想象出来后台数据的庞大,估计半年都写不完这个作业了,想罢果断放弃掉做淘宝的任务。
最终决定做一个尽量炫一点的个人网站。
在参考了liuyubobobo老师关于canvas的课程(这位老师的canvas课程真的炒鸡好~!!)后,我在这个个人网站的顶部横幅中添加了一个这样的效果,如下图
在canvas画布我添加了30个大小随机、运动方向随机、运动速度随机、碰到画布边缘会反弹回来的五角星。
作为一个从来没用过canvas画图的新手,在这个过程中也踩了不少坑。
实现:
html代码如下:
- <div class="carouselBox">
- <canvas id="stars">请升级到最新的浏览器以观看最佳效果</canvas>
- <h1>兴趣使然的小站</h1>
- </div>
当canvas无法显示的时候,canvas标签内的字符就会显示出来。
css代码如下,这里我是用less表示的(不懂这种表示法的同学稍微百度一下,so easy):
- .carouselBox{
- width: 100%;
- height: 300px;
- background-color: rgba(200, 200, 255, 0.3);
- position: relative;
- text-align: center;
- #stars{
- position: absolute;
- left: 0;
- top: 0;
- z-index: 5;
- }
- h1{
- position: relative;
- z-index: 10;
- font-size: 50px;
- line-height: 300px;
- color: rgba(0, 0, 0, 0.7)
- }
- }
h1标签的字要在canvas画布的上方,不能被遮盖,因此设置了z-index,为了让z-index生效,设置了position:relative。
canvas画布的长度和宽度我放在了js文件中实现。
重点在JS代码上:
我这里在获取元素用到了jquery,你不用jqueyr来获取,改用document.getElementById之类的原生javascript方法当然也没有问题。
首先获取canvas对象和canvas上下文,并设置canvas画布的高宽。
- //五角星画布
- var carouselBox = $('.carouselBox')
- var carouselHeight = carouselBox.height()//获取canvas外层的盒子高度
- var carouselWidth = carouselBox.width()//获取canvas外层的盒子高度
- var drawing2 = $('#stars').get(0)//通过jquery获得一个用jquery包装的canvas对象,由get(0)方法获取原生canvas对象
- //一定不能用jquery来设置高度与宽度,否则会出现莫名其妙的错误
- drawing2.height = carouselHeight//将canvas画布填满到外层盒子
- drawing2.width = carouselWidth
- var context2 = drawing2.getContext('2d')//获取canvas的上下文
这其中要注意的是,canvas画布设置宽高一定要通过 canvas.height和canvas.width的方式来设置。
一定不能由canvas.style.height,canvas.style.width或者jquery方式$canvas.css({....})来设置宽高!!!否则会让画布里的坐标单位出现问题,导致你画的图像完全不在你预期的位置上。
接下来,先设置一个for循环来随机生成30个五角星的属性,每一组属性生成一个对象,并将生成的30个对象依次推入一个数组中。
- var stars = []//用来装五角星的数组
- for (var i = 0; i < 30; i++) {
- var R = Math.floor(Math.random()*100+155)
- var G = Math.floor(Math.random()*100+155)
- var B = Math.floor(Math.random()*100+155)
- var r = Math.random()*30 + 20
- var rot = Math.random()*360
- aStar = {
- color:'rgb('+R+','+G+','+B+')',
- r:r,
- x:Math.random()*(drawing2.width - 2*r) + r,
- y:Math.random()*(drawing2.height - 2*r) + r,
- rot:rot,
- vx:(Math.random()*2+2)*Math.pow(-1,Math.floor(Math.random()*100)),
- vy:(Math.random()*2+2)*Math.pow(-1,Math.floor(Math.random()*100)),
- wv:(Math.random()*2+2)*Math.pow(-1,Math.floor(Math.random()*100))
- }
- stars[i] = aStar
- }
用setInterval()方法来每隔30毫秒调用绘制函数,并调用函数更新每个五角星的位置状态和速度状态
- setInterval(function(){
- draw(context2)//绘制函数
- update(drawing2.width,drawing2.height)//更新每个五角星的状态
- },30)
绘制函数如下:
将每个五角星的属性传入到drawStar()方法,从而创建大小、运动方向不同的五角星
- function draw(context){
- var canvas = context.canvas
- context.clearRect(0,0,canvas.width,canvas.height)//设置一个矩形区域,将该矩形区域中的所有内容清除,会将背景一起清除掉
- context.globalCompositeOperation = 'xor'//全局设定,两图案相交处取空
- for (var i = 0; i < stars.length; i++) {
- context.fillStyle = stars[i].color//设置五角星填充颜色
- drawStar(context2,stars[i].r,stars[i].x,stars[i].y,stars[i].rot)
- context.fill()
- }
- }
drawStar方法如下
这里用图形变换的方法来绘制每个五角星,由于图形变换都是基于上次变换结果进行绘制的,因此需要设置“存储点”,在绘制完一个五角星之后回到“存储点”。
- function drawStar(context,R,x,y,rot){
- context.save()//设置存储点
- context.translate(x,y)//平移变换
- context.rotate(rot/180*Math.PI)//旋转变换
- context.scale(R,R)//缩放变换
- starPath(context)//绘制五角星的边
- context.restore()//回到存储点
- }
五角星边按如下方法绘制:
由于context.scale()不仅会缩放图形大小,也会缩放图形的位置点和边框,因此在五角星边的绘制中,我们没有设置边的宽度和五角星的偏移。
在下列代码中,即XcanterP和YcenterP都没有设置。
- function starPath(context){
- context.beginPath()
- for (var i = 0; i < 5; i++) {
- //x = Rcosθ + XcenterP
- //θ = α/180*π 其中α为度数表示的角度,θ为以π为单位表示的角度
- //y = -Rsinθ + YcenterP
- context.lineTo(Math.cos((18+i*72)/180*Math.PI),-Math.sin((18+i*72)/180*Math.PI))
- context.lineTo(Math.cos((54+i*72)/180*Math.PI)/1.8,-Math.sin((54+i*72)/180*Math.PI)/1.8)
- }
- context.closePath()
- }
最后,更新五角星状态的代码如下
这里更新了五角星的位移、角度,也检测了画布边缘碰撞,当碰触到边缘时,五角星的速度取反。
PS这里:五角星的X和Y坐标位于五角星的中心。
- //更新小球的状态(属性)
- function update(canvasWidth,canvasHeight){
- for (var i = 0; i < stars.length; i++) {
- stars[i].x += stars[i].vx
- stars[i].y += stars[i].vy
- stars[i].rot += stars[i].wv
- if (stars[i].x - stars[i].r <= 0) {
- stars[i].vx = -stars[i].vx
- stars[i].x = stars[i].r
- }
- if (stars[i].x + stars[i].r >= canvasWidth) {
- stars[i].vx = -stars[i].vx
- stars[i].x = canvasWidth - stars[i].r
- }
- if (stars[i].y - stars[i].r <= 0) {
- stars[i].vy = -stars[i].vy
- stars[i].y = stars[i].r
- }
- if (stars[i].y + stars[i].r >= canvasHeight) {
- stars[i].vy = -stars[i].vy
- stars[i].y = canvasHeight - stars[i].r
- }
- }
- }
最后,等我网站写完了,我会附上链接让大家看看效果哦~!
canvas(五角星碰撞)相关推荐
- canvas绘制碰撞球动画
碰撞球动画 画一个简单的球 通过选择器获取画布. var canvas = document.getElementById('canvas');或var canvas = document.query ...
- canvas 形状碰撞_【案例】如何用html5 制作canvas酷炫的网状图形动画特效
点击上方[我分享我快乐]→[...]右上角→[设为星标⭐]即可第一时间获取最新设计资源 哈喽大家好,又到了每周二案例环节啦,在教学开始前先插播一条招聘信息~ 高薪招聘 杭州招聘(非技术) 公司背景: ...
- 带着canvas去流浪系列之八 碰撞
[摘要] canvas动画-碰撞仿真 示例代码托管在:http://www.github.com/dashnowords/blogs 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生A ...
- 用html画一个企鹅图案的代码,HTML5 Canvas来绘制图形
1.HTML5元素用于图形的绘制,通过脚本(通常是javascript)来完成. 2.标签只是图形容器,必须使用脚本来绘制图形. 3.可以通过多种方法通过Canvas绘制路径.盒.圆.字符以及添加图像 ...
- Chipmunk僵尸物理对象的出现和解决(七)
首先判断问题出现在Star的类方法doStickShorterWork中,于是逐步分词注释代码,最后剩下如下代码: +(void)doStickShorterWork:(Stick *)stick{G ...
- 分享112个JS特效动画效果,总有一款适合您
分享112个JS特效动画效果,总有一款适合您 112个JS特效动画效果下载链接:https://pan.baidu.com/s/1uC61pccye_oYqBnUugIuig?pwd=u21z 提取 ...
- 场景检测:Audio Listener、RigidBody和Prefab连接
在上一期<场景检测:雾效.Canvas和碰撞体>中,我们依托本地资源检测中和场景检测相关的规则,把涉及到的知识点跟大家进行了简单的讲解.这些看似细小的知识点,很容易在大家的开发和学习过程中 ...
- 分享111个JS特效动画效果,总有一款适合您
分享111个JS特效动画效果,总有一款适合您 111个JS特效动画效果下载链接:https://pan.baidu.com/s/1s8mWkRlIZML2t5v1g1rlDA?pwd=pe5p 提取 ...
- 场景检测:面片、光影和物理属性
在上一期<场景检测:Audio Listener.RigidBody和Prefab连接>中,我们依托本地资源检测中和场景检测相关的规则,把涉及到的知识点讲解.这些看似细小的知识点,很容易在 ...
最新文章
- SQL2000 好书 《SQL Server 2000数据库管理与开发技术大全》----求是科技 人民邮电出版社
- SVN switch 用法详解 (ZZ)
- 廖雪峰python学习笔记——函数式编程
- 数据结构与算法 / 总章
- 三剑客之sed常用操作
- 如何破解您忘记的Windows密码
- RegOpenKeyEx 返回值 2
- C++混淆点-构造函数参数
- 创业者需要知道的50句话
- Python与R的争锋:大数据初学者该怎样选?
- 麦克纳姆轮全向移动机器人自旋转运动分析
- 使用docker run的选项以覆盖Dockerfile中的设置详解
- 《高翔视觉slam十四讲》学习笔记 第六讲 非线性优化
- 特效编辑器开发手记2——cocos2d-x粒子系统的plist文件
- Java:等额本息还款计算
- python中def demo是什么意思_python中def是什么意思
- postgresql源码学习(38)—— 备份还原② - do_pg_stop_backup函数
- 书籍推荐:国内第一本ASP.NET 3.5 MVC技术专著
- 联想拯救者y7000电脑开机一直是锁屏界面,点一下就黑屏,无法进入输密码界面
- XC6206P332MR(0.25V低压差线性LDO稳压器,稳压输出3.3V,最大电压输入6V,输出电流250mA)