马上9月份要找工作了,琢磨着要做个作品作为面试时的加分项。

本来打算仿一个淘宝网,但写完淘宝首页竟花了我一个星期!!!光html、css就有4000多行,看着首页都能想象出来后台数据的庞大,估计半年都写不完这个作业了,想罢果断放弃掉做淘宝的任务。

最终决定做一个尽量炫一点的个人网站。

在参考了liuyubobobo老师关于canvas的课程(这位老师的canvas课程真的炒鸡好~!!)后,我在这个个人网站的顶部横幅中添加了一个这样的效果,如下图

在canvas画布我添加了30个大小随机、运动方向随机、运动速度随机、碰到画布边缘会反弹回来的五角星。

作为一个从来没用过canvas画图的新手,在这个过程中也踩了不少坑。

实现:

html代码如下:

[html] view plain copy
  1. <div class="carouselBox">
  2. <canvas id="stars">请升级到最新的浏览器以观看最佳效果</canvas>
  3. <h1>兴趣使然的小站</h1>
  4. </div>

当canvas无法显示的时候,canvas标签内的字符就会显示出来。

css代码如下,这里我是用less表示的(不懂这种表示法的同学稍微百度一下,so easy):

[css] view plain copy
  1. .carouselBox{
  2. width: 100%;
  3. height: 300px;
  4. background-color: rgba(200, 200, 255, 0.3);
  5. position: relative;
  6. text-align: center;
  7. #stars{
  8. position: absolute;
  9. left: 0;
  10. top: 0;
  11. z-index: 5;
  12. }
  13. h1{
  14. position: relative;
  15. z-index: 10;
  16. font-size: 50px;
  17. line-height: 300px;
  18. color: rgba(0, 0, 0, 0.7)
  19. }
  20. }

h1标签的字要在canvas画布的上方,不能被遮盖,因此设置了z-index,为了让z-index生效,设置了position:relative。

canvas画布的长度和宽度我放在了js文件中实现。

重点在JS代码上:

我这里在获取元素用到了jquery,你不用jqueyr来获取,改用document.getElementById之类的原生javascript方法当然也没有问题。

首先获取canvas对象和canvas上下文,并设置canvas画布的高宽。

[javascript] view plain copy
  1. //五角星画布
  2. var carouselBox = $('.carouselBox')
  3. var carouselHeight = carouselBox.height()//获取canvas外层的盒子高度
  4. var carouselWidth = carouselBox.width()//获取canvas外层的盒子高度
  5. var drawing2 = $('#stars').get(0)//通过jquery获得一个用jquery包装的canvas对象,由get(0)方法获取原生canvas对象
  6. //一定不能用jquery来设置高度与宽度,否则会出现莫名其妙的错误
  7. drawing2.height = carouselHeight//将canvas画布填满到外层盒子
  8. drawing2.width = carouselWidth
  9. var context2 = drawing2.getContext('2d')//获取canvas的上下文

这其中要注意的是,canvas画布设置宽高一定要通过 canvas.height和canvas.width的方式来设置。

一定不能由canvas.style.height,canvas.style.width或者jquery方式$canvas.css({....})来设置宽高!!!否则会让画布里的坐标单位出现问题,导致你画的图像完全不在你预期的位置上。

接下来,先设置一个for循环来随机生成30个五角星的属性,每一组属性生成一个对象,并将生成的30个对象依次推入一个数组中。

[javascript] view plain copy
  1. var stars = []//用来装五角星的数组
  2. for (var i = 0; i < 30; i++) {
  3. var R = Math.floor(Math.random()*100+155)
  4. var G = Math.floor(Math.random()*100+155)
  5. var B = Math.floor(Math.random()*100+155)
  6. var r = Math.random()*30 + 20
  7. var rot = Math.random()*360
  8. aStar = {
  9. color:'rgb('+R+','+G+','+B+')',
  10. r:r,
  11. x:Math.random()*(drawing2.width - 2*r) + r,
  12. y:Math.random()*(drawing2.height - 2*r) + r,
  13. rot:rot,
  14. vx:(Math.random()*2+2)*Math.pow(-1,Math.floor(Math.random()*100)),
  15. vy:(Math.random()*2+2)*Math.pow(-1,Math.floor(Math.random()*100)),
  16. wv:(Math.random()*2+2)*Math.pow(-1,Math.floor(Math.random()*100))
  17. }
  18. stars[i] = aStar
  19. }

用setInterval()方法来每隔30毫秒调用绘制函数,并调用函数更新每个五角星的位置状态和速度状态

[javascript] view plain copy
  1. setInterval(function(){
  2. draw(context2)//绘制函数
  3. update(drawing2.width,drawing2.height)//更新每个五角星的状态
  4. },30)

绘制函数如下:

将每个五角星的属性传入到drawStar()方法,从而创建大小、运动方向不同的五角星

[javascript] view plain copy
  1. function draw(context){
  2. var canvas = context.canvas
  3. context.clearRect(0,0,canvas.width,canvas.height)//设置一个矩形区域,将该矩形区域中的所有内容清除,会将背景一起清除掉
  4. context.globalCompositeOperation = 'xor'//全局设定,两图案相交处取空
  5. for (var i = 0; i < stars.length; i++) {
  6. context.fillStyle = stars[i].color//设置五角星填充颜色
  7. drawStar(context2,stars[i].r,stars[i].x,stars[i].y,stars[i].rot)
  8. context.fill()
  9. }
  10. }

drawStar方法如下

这里用图形变换的方法来绘制每个五角星,由于图形变换都是基于上次变换结果进行绘制的,因此需要设置“存储点”,在绘制完一个五角星之后回到“存储点”。

[javascript] view plain copy
  1. function drawStar(context,R,x,y,rot){
  2. context.save()//设置存储点
  3. context.translate(x,y)//平移变换
  4. context.rotate(rot/180*Math.PI)//旋转变换
  5. context.scale(R,R)//缩放变换
  6. starPath(context)//绘制五角星的边
  7. context.restore()//回到存储点
  8. }

五角星边按如下方法绘制:

由于context.scale()不仅会缩放图形大小,也会缩放图形的位置点和边框,因此在五角星边的绘制中,我们没有设置边的宽度和五角星的偏移。

在下列代码中,即XcanterP和YcenterP都没有设置。

[javascript] view plain copy
  1. function starPath(context){
  2. context.beginPath()
  3. for (var i = 0; i < 5; i++) {
  4. //x = Rcosθ + XcenterP
  5. //θ = α/180*π       其中α为度数表示的角度,θ为以π为单位表示的角度
  6. //y = -Rsinθ + YcenterP
  7. context.lineTo(Math.cos((18+i*72)/180*Math.PI),-Math.sin((18+i*72)/180*Math.PI))
  8. context.lineTo(Math.cos((54+i*72)/180*Math.PI)/1.8,-Math.sin((54+i*72)/180*Math.PI)/1.8)
  9. }
  10. context.closePath()
  11. }

最后,更新五角星状态的代码如下

这里更新了五角星的位移、角度,也检测了画布边缘碰撞,当碰触到边缘时,五角星的速度取反。

PS这里:五角星的X和Y坐标位于五角星的中心。

[javascript] view plain copy
  1. //更新小球的状态(属性)
  2. function update(canvasWidth,canvasHeight){
  3. for (var i = 0; i < stars.length; i++) {
  4. stars[i].x += stars[i].vx
  5. stars[i].y += stars[i].vy
  6. stars[i].rot += stars[i].wv
  7. if (stars[i].x - stars[i].r <= 0) {
  8. stars[i].vx = -stars[i].vx
  9. stars[i].x = stars[i].r
  10. }
  11. if (stars[i].x + stars[i].r >= canvasWidth) {
  12. stars[i].vx = -stars[i].vx
  13. stars[i].x = canvasWidth - stars[i].r
  14. }
  15. if (stars[i].y - stars[i].r <= 0) {
  16. stars[i].vy = -stars[i].vy
  17. stars[i].y = stars[i].r
  18. }
  19. if (stars[i].y + stars[i].r >= canvasHeight) {
  20. stars[i].vy = -stars[i].vy
  21. stars[i].y = canvasHeight - stars[i].r
  22. }
  23. }
  24. }

最后,等我网站写完了,我会附上链接让大家看看效果哦~!

canvas(五角星碰撞)相关推荐

  1. canvas绘制碰撞球动画

    碰撞球动画 画一个简单的球 通过选择器获取画布. var canvas = document.getElementById('canvas');或var canvas = document.query ...

  2. canvas 形状碰撞_【案例】如何用html5 制作canvas酷炫的网状图形动画特效

    点击上方[我分享我快乐]→[...]右上角→[设为星标⭐]即可第一时间获取最新设计资源 哈喽大家好,又到了每周二案例环节啦,在教学开始前先插播一条招聘信息~ 高薪招聘 杭州招聘(非技术) 公司背景: ...

  3. 带着canvas去流浪系列之八 碰撞

    [摘要] canvas动画-碰撞仿真 示例代码托管在:http://www.github.com/dashnowords/blogs 经过前面章节相对枯燥的练习,相信你已经能够上手canvas的原生A ...

  4. 用html画一个企鹅图案的代码,HTML5 Canvas来绘制图形

    1.HTML5元素用于图形的绘制,通过脚本(通常是javascript)来完成. 2.标签只是图形容器,必须使用脚本来绘制图形. 3.可以通过多种方法通过Canvas绘制路径.盒.圆.字符以及添加图像 ...

  5. Chipmunk僵尸物理对象的出现和解决(七)

    首先判断问题出现在Star的类方法doStickShorterWork中,于是逐步分词注释代码,最后剩下如下代码: +(void)doStickShorterWork:(Stick *)stick{G ...

  6. 分享112个JS特效动画效果,总有一款适合您

    分享112个JS特效动画效果,总有一款适合您 112个JS特效动画效果下载链接:https://pan.baidu.com/s/1uC61pccye_oYqBnUugIuig?pwd=u21z  提取 ...

  7. 场景检测:Audio Listener、RigidBody和Prefab连接

    在上一期<场景检测:雾效.Canvas和碰撞体>中,我们依托本地资源检测中和场景检测相关的规则,把涉及到的知识点跟大家进行了简单的讲解.这些看似细小的知识点,很容易在大家的开发和学习过程中 ...

  8. 分享111个JS特效动画效果,总有一款适合您

    分享111个JS特效动画效果,总有一款适合您 111个JS特效动画效果下载链接:https://pan.baidu.com/s/1s8mWkRlIZML2t5v1g1rlDA?pwd=pe5p  提取 ...

  9. 场景检测:面片、光影和物理属性

    在上一期<场景检测:Audio Listener.RigidBody和Prefab连接>中,我们依托本地资源检测中和场景检测相关的规则,把涉及到的知识点讲解.这些看似细小的知识点,很容易在 ...

最新文章

  1. SQL2000 好书 《SQL Server 2000数据库管理与开发技术大全》----求是科技 人民邮电出版社
  2. SVN switch 用法详解 (ZZ)
  3. 廖雪峰python学习笔记——函数式编程
  4. 数据结构与算法 / 总章
  5. 三剑客之sed常用操作
  6. 如何破解您忘记的Windows密码
  7. RegOpenKeyEx 返回值 2
  8. C++混淆点-构造函数参数
  9. 创业者需要知道的50句话
  10. Python与R的争锋:大数据初学者该怎样选?
  11. 麦克纳姆轮全向移动机器人自旋转运动分析
  12. 使用docker run的选项以覆盖Dockerfile中的设置详解
  13. 《高翔视觉slam十四讲》学习笔记 第六讲 非线性优化
  14. 特效编辑器开发手记2——cocos2d-x粒子系统的plist文件
  15. Java:等额本息还款计算
  16. python中def demo是什么意思_python中def是什么意思
  17. postgresql源码学习(38)—— 备份还原② - do_pg_stop_backup函数
  18. 书籍推荐:国内第一本ASP.NET 3.5 MVC技术专著
  19. 联想拯救者y7000电脑开机一直是锁屏界面,点一下就黑屏,无法进入输密码界面
  20. XC6206P332MR(0.25V低压差线性LDO稳压器,稳压输出3.3V,最大电压输入6V,输出电流250mA)

热门文章

  1. 找出100以内所有能被3整除的数,并把结果写入d:\xxx\data.dat文件中
  2. 蓝屏0X000000A0是什么原因
  3. python中leap是什么意思_leap
  4. 安徽科技学院 信网学院网络文化节 杜鸿飞
  5. 算法分析学习笔记(二) - 栈和队列(上)
  6. eclipse设置经典黑色主题样式
  7. MAC系统上设置华为手机的调试模式
  8. 关于烟草的知识(我不吸烟)
  9. adb清除锁屏密码方法
  10. Windows开启winrm服务