本次目标:在canvas画布上绘制彩色小球并实现模拟烟花般的动画效果。

程序很简单,只需要理解canvas元素,在指定位置用指定颜色绘制圆球然后逐帧形成动画就可以了。

考虑到性能因素,在球离开视觉区域或颜色完全变淡后就移除对象,并在每帧补上一定数量的球,这样也能够保证视觉效果。

演示效果如下(浏览器需支持HTML5):

源码如下(由于结构并不复杂,代码中的注释应该能解决大部分疑惑,代码后面附有简单解析。感兴趣的话不妨复制下来自行调试):

HTML5烟火

//配置参数

var maxballcount = 300 //小球最大数量

var ballradius = 4//小球半径

var startspeedx = 2//横向初速度范围(-x到x)

var startspeedy = 6//纵向初速度范围(向上,-y到0)

var gravity = 0.1 //重力加速度

var colorweaken = 0.008//颜色衰减速度

var newballcount = 4//每轮补球最大数量

var tail = 0.2//小球拖尾效果(1为无,0为拖尾不消失)

//全局对象

var canvas //绘图对象

var context //绘图内容

var imgData //当前图形

var balls = new Array() //小球数组

var framestarttime//计算帧数开始时间

var framecount = 0//上次计数清空以来经过的帧数

var lastframecount = 0//上一秒的帧数

//页面加载

$(function () {

init()

})

//初始化

function init() {

canvas = document.getElementById("image")

if (!canvas.getContext) self.location = "/nohtml5.html"

else {

var container = $("#container")

container.width($(window).width())

container.height($(window).height())

canvas.width = container.width()

canvas.height = container.height()

context = canvas.getContext("2d")

context.font = "16px Arial"

framestarttime = new Date()

//开始动画

animeframe()

}

}

//运行动画

function animeframe() {

//绘制半透明遮罩,淡化上一帧的颜色以达到拖尾效果

context.fillStyle = "rgba(0,0,0," + tail + ")"

context.fillRect(0, 0, canvas.width, canvas.height)

var newballs = new Array()//下一帧小球数组

for (var i in balls) {

var ball = balls[i]

ball.speedy += gravity//重力

ball.x += ball.speedx

ball.y += ball.speedy

ball.alpha -= colorweaken

if (ball.x > 0 && ball.x < canvas.width && ball.y > 0 && ball.y < canvas.height && ball.alpha > 0) {

//只有小球在界内并尚未完全透明时才显示并保留到下一帧

newballs.push(ball)

drawball(ball)

}

}

//如果数量不足(初始,或有球出界),则补球,但不能超过最大数量

if (newballs.length < maxballcount) {

for (var i = 0; i < Math.min(newballcount, maxballcount - newballs.length); i++) {

newballs.push(generaterandomball())

}

}

//交换帧

balls = newballs

newballs = null

//计算并在左上角绘制帧数

var thisframetime = new Date()

if (thisframetime - framestarttime >= 1000) {

lastframecount = framecount

framecount = 0

framestarttime = thisframetime

}

framecount++

context.fillStyle = "#000"

context.fillRect(0, 0, 80, 40)

context.fillStyle = "#FF0"

context.fillText("FPS:" + lastframecount, 10, 20)

requestAnimationFrame(animeframe)

}

//绘制单个小球

function drawball(ball) {

if (!ball) return

context.beginPath()

context.arc(ball.x, ball.y, ball.r, 0, Math.PI * 2, true)

context.closePath()

context.fillStyle = "rgba(" + ball.color + "," + ball.alpha + ")"

context.fill()

}

//生成随机颜色和速度的球

function generaterandomball() {

var ball = new Object()

//初始位置在中央区域

ball.x = Math.round(Math.random() * canvas.width / 10) + (canvas.width / 2 - canvas.width / 20)

ball.y = Math.round(Math.random() * canvas.height / 10) + (canvas.height / 2 - canvas.height / 20)

ball.r = ballradius

ball.color = randomcolor()

ball.alpha = 1

//小球初速度,横向随机,纵向默认向上

ball.speedx = Math.round(Math.random() * startspeedx * 2) - startspeedx

ball.speedy = -Math.round(Math.random() * startspeedy)

return ball

}

//生成RGB字符串格式的颜色

function randomcolor() {

var yellow = Math.round(Math.random() * 255)

return "255," + yellow + ",0"

}

body {

margin: 0px;

}

#container {

width: 100%;

height: 100%;

}

#image {

background-color: #000;

}

代码解析:

在设置各项基本参数的值之后,执行init()方法初始化页面;

初始化画布尺寸和基本对象,然后执行animeframe()开始动画;

每个animeframe()显示一帧动画,结束后递归自己显示下一帧;

每帧要通过各小球的位置和速度计算运动轨迹,并计算重力加速度对纵向速度的影响;

小球出界则从数组中移除。这里使用的是相反的方法:只有检测到在界内的才添加到新数组,循环完成后将新旧数组交换;

运动中的小球颜色逐渐变淡(增加alpha透明度);

使用drawball()方法绘制小球;

如果小球数量太少则补球;

生成随机球的方法是generaterandomball(),颜色在全红(255,0,0)到全黄(255,255,0)间随机选择。只需要第二个值取随机即可;

每秒统计帧数并显示在左上角。

补注:旧版代码使用的是setTimeout实现动画。加入一段兼容性脚本后,改用requestAnimationFrame代替setTimeout来达到更好的性能,并在左上角加入帧数显示(用于测试不同浏览器和设备上的性能)

脚本如下(已保存到单独的requestAnimationFrame.js文件中):

//requestAnimationFrame动画方法的兼容性

(function() {

var lastTime = 0;

var vendors = ['webkit', 'moz'];

for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {

window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];

window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // Webkit中此取消方法的名字变了

window[vendors[x] + 'CancelRequestAnimationFrame'];

}

if (!window.requestAnimationFrame) {

window.requestAnimationFrame = function(callback, element) {

var currTime = new Date().getTime();

var timeToCall = Math.max(0, 16.7 - (currTime - lastTime));

var id = window.setTimeout(function() {

callback(currTime + timeToCall);

}, timeToCall);

lastTime = currTime + timeToCall;

return id;

};

}

if (!window.cancelAnimationFrame) {

window.cancelAnimationFrame = function(id) {

clearTimeout(id);

};

}

}());

html烟火源码,HTML5:烟火相关推荐

  1. 100行JS代码实现❤坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript )

    坦克大战js小游戏源码 HTML5坦克大战游戏代码(HTML+CSS+JavaScript ) HTML5坦克大战网页小游戏,完美还原小霸王学习机效果,以坦克战斗及保卫基地为主题,属于策略型类游戏. ...

  2. html5 mp3播放器源码,HTML5自定义mp3播放器源码

    audio对象 src兼容.ogg .wav .mp3 width autoplay loop muted静音 播放play() var myAudio = new Audio(); myAudio. ...

  3. HTML卡片式布局源码,html5自适应卡片式设计动态加载整站源码_

    html5自适应卡片式设计动态加载整站源码 该模板是非常容易存活的,这样的程序很容易吸引访客点击,提升ip流量和pv是非常有利的,随意挂点联盟广告都能养活程序. 本套整站源码采使用现在非常流行的全屏自 ...

  4. 仿网易云音乐源码html5

    HTML5仿网易云音乐播放器特效源码是一款仿网易云音乐外链播放器UI的HTML5 APlayer音乐播放器插件的代码.APlayer音乐播放器可以自定义歌曲封面,可以自定义同步歌词等,界面时尚大方,是 ...

  5. 用php写的亲亲鲜花网站_PHP鲜花网站模板植物园林花卉源码 html5手机自适应整站带后台...

    宝贝说明 (自适应手机版)响应式园林花卉类网站织梦模板 HTML5鲜花植物养护网站源码下载 响应式园林花卉类网站织梦模板(自适应手机端) 模板介绍: 这款dedecms模板使用范围极广,不仅仅局限于一 ...

  6. 枪战游戏html源码,html5西部牛仔枪战游戏源码

    压缩包内容概览: html5西部牛仔枪战游戏源码-H53dGAME ; 地图集 ; 旗帜 ; 羽毛灯.MIN ; 字体 ; 图标256 ; 图片 ; 索引 ; 模型 ; 声音 ; 菜单 ; 戏剧 ; ...

  7. html扑克牌游戏源码,html5扑克牌消除小游戏源码

    特效描述:html5扑克牌 消除小游戏源码.html5扑克牌消除小游戏源码 代码结构 1. 引入CSS 2. 引入JS 3. HTML代码 $(function(){ //实现随机洗牌 neusoft ...

  8. html直播源码,HTML5中的websocket实现直播功能

    做视频直播这一块,前期研究了很多方案,包括websocket,因为各种原因最后没有采取这个方案,但还是想记录一下学习的心得. WebSocket是HTML5开始提供的一种在单个 TCP 连接上进行全双 ...

  9. html5简单图片幻灯片转换源码,HTML5特效库 炫酷幻灯片切换特效源码

    效果图 各位叔叔阿姨,大哥大姐,弟弟妹妹,全国的老少爷们大家好! 今天给大家带来的HTML5特效 属于banner轮播的切换效果 前端源码免费分享裙581549454 废话不多说,上源码! CSS源码 ...

最新文章

  1. 在应用了皮肤的程序中制作透明的文本编辑控件(如:TcxMemo)
  2. day11--RabbitMQ、Redis
  3. Android中Context简介
  4. unbuntu安装阿里云
  5. Sun公司因为不懂销售和运营,导致陨落,最终软件还是打败了硬件
  6. 马斯克又要搞事情,不锈钢材质的Space X“星际飞船”正式亮相
  7. 软件就像大教堂:我们建造它们——然后祈祷
  8. VM虚拟机里安装Centos
  9. python 驱动级鼠标_电竞极速鼠标
  10. win10 升级出现0x80004002
  11. spring5.0之后Log4jConfigListener过期问题
  12. 华为2022年度伙伴奖项正式揭晓!恒驰信息荣获华为云GrowCloud优秀解决方案提供商奖
  13. cocos入门8:动画系统
  14. 数据结构形象动态演示的网站
  15. 彻底关闭win10更新自动更新 卸载win10自带杀毒软件 新增联想软件 lenovo quick fix
  16. gallery3D(3)
  17. 【STM32 Net MF开发板学习-11】步进电机控制(非PWM模式)
  18. python求解一阶常微分方程
  19. 2020年物联网发展现状与趋势预测
  20. vue-router有哪几种导航钩子?(具体怎么用的)

热门文章

  1. clion开发php,如何在 Mac 上用 Clion 调试 php7 源码
  2. jde多目标_《和平精英》PEL职业联赛S3赛季:DKG战队获第四周周冠军,JDE“逆风翻盘”...
  3. java m查询_信息查询系统,基于SSM框架的JAVA系统
  4. sqlserver垮库查询_sql跨库查询(sqlserver跨库查询)
  5. Python: TensorFlow2.4与CUDA11.1缺失 ‘cusolver64_10.dll‘动态库
  6. android ble 发送指令,Android – 如何通过蓝牙低能耗(BLE)链接发送数据?
  7. Failed to create AppDomain 'xxx'. Exception has been Failed to create AppDomain
  8. 你了解的工厂模式可能有误
  9. mui ajax方法
  10. 试着开发chrome插件