canvas烟花-娱乐

网上看到一个释放烟花的canvas案例,很好看哦。

新建文本,把下面代码复制进去,后缀名改为html,用浏览器打开即可。

看懂注释后,可以自己修改烟花的各个效果。我试过让烟花炸成了心型。:-)

<!DOCTYPE html>
<html dir="ltr" lang="zh-CN">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>HTML5 Canvas烟花特效 场景十分华丽在线演示</title>
    <style>
        /* basic styles for black background and crosshair cursor */
        body {
            background: #000;
            margin: 0;
        }

        canvas {
            cursor: crosshair;
            display: block;
        }
    </style>

</head>
<body>
    <div style="text-align:center;clear:both">
        <script src="/gg_bd_ad_720x90.js" type="text/javascript"></script>
        <script src="/follow.js" type="text/javascript"></script>
    </div>
    <canvas id="canvas">Canvas is not supported in your browser.</canvas>
    <script>
        // 当动画在canvas上,最好使用requestAnimationFrame代替setTimeout和setInterval
        // 不支持在所有的浏览器,有时需要一个前缀,所以我们需要一个重置
        window.requestAnimFrame = (function () {
            return window.requestAnimationFrame ||
                        window.webkitRequestAnimationFrame ||
                        window.mozRequestAnimationFrame ||
                        function (callback) {
                            window.setTimeout(callback, 1000 / 60);
                        };
        })();

        // 设置基本变量
        var canvas = document.getElementById(‘canvas‘),
                ctx = canvas.getContext(‘2d‘),
                // 全屏幕尺寸
                cw = window.innerWidth,
                ch = window.innerHeight,
                // firework collection 烟花集合
                fireworks = [],
                // particle collection 爆炸粒子集合
                particles = [],
                // starting hue 开始色调
                hue = 120,
                // when launching fireworks with a click, too many get launched at once without a limiter, one launch per 5 loop ticks
                // 通过点击释放烟花没有限制,每5次循环释放一次
                limiterTotal = 5,
                limiterTick = 0,
                // this will time the auto launches of fireworks, one launch per 80 loop ticks
                // 自动发射80循环一次
                timerTotal = 20,
                timerTick = 0,
                mousedown = false,
                // mouse x coordinate  X坐标
                mx,
                // mouse y coordinate  Y坐标
                my;

        // set canvas dimensions 设置画布尺寸
        canvas.width = cw;
        canvas.height = ch;

        // now we are going to setup our function placeholders for the entire demo

        // get a random number within a range
        // 获取范围内随机数
        function random(min, max) {
            return Math.random() * (max - min) + min;
        }

        // calculate the distance between two points
        // 计算两点距离
        function calculateDistance(p1x, p1y, p2x, p2y) {
            var xDistance = p1x - p2x,
                    yDistance = p1y - p2y;
            return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2));
        }

        // 创建烟花
        function Firework(sx, sy, tx, ty) {
            // actual coordinates  实际坐标
            this.x = sx;
            this.y = sy;
            // starting coordinates  开始坐标
            this.sx = sx;
            this.sy = sy;
            // target coordinates  目标坐标
            this.tx = tx;
            this.ty = ty;
            // distance from starting point to target  计算飞行距离
            this.distanceToTarget = calculateDistance(sx, sy, tx, ty);
            this.distanceTraveled = 0;
            // track the past coordinates of each firework to create a trail effect, increase the coordinate count to create more prominent trails
            // 追踪每个烟花经过的坐标,来创建一个跟踪效果,增加坐标数量来创造更多杰出的轨迹
            this.coordinates = [];
            this.coordinateCount = 3;
            // populate initial coordinate collection with the current coordinates
            // 填充初始坐标集合与当前坐标
            while (this.coordinateCount--) {
                this.coordinates.push([this.x, this.y]);
            }
            this.angle = Math.atan2(ty - sy, tx - sx); // 从x轴到指定坐标点(x, y)的角度(以弧度为单位)
            this.speed = 2;  // 速度
            this.acceleration = 1.05;  // 加速度
            this.brightness = random(50, 70);  // 亮度
            // circle target indicator radius
            // 圆形目标指示器半径
            this.targetRadius = 1;
        }

        // update firework  更新烟花
        Firework.prototype.update = function (index) {
            // remove last item in coordinates array 删除烟花坐标数组里最后一个坐标
            this.coordinates.pop();
            // add current coordinates to the start of the array 当前的坐标添加到烟花坐标数组的开始
            this.coordinates.unshift([this.x, this.y]);

            // 循环圆形目标指示器半径
            if (this.targetRadius < 8) {
                this.targetRadius += 0.3;
            } else {
                this.targetRadius = 1;
            }

            // speed up the firework  烟花速度
            this.speed *= this.acceleration;

            // get the current velocities based on angle and speed
            // 获取x,y两个方向的速度
            var vx = Math.cos(this.angle) * this.speed,
                    vy = Math.sin(this.angle) * this.speed;
            // how far will the firework have traveled with velocities applied?
            // 烟花会随速度飞行多远
            this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy);

            // if the distance traveled, including velocities, is greater than the initial distance to the target, then the target has been reached
            // 如果距离, 包括速度大于初始距离的目标, 那么目标已经达到
            if (this.distanceTraveled >= this.distanceToTarget) {
                createParticles(this.tx, this.ty); // 创建粒子
                // remove the firework, use the index passed into the update function to determine which to remove
                // 删除烟花,使用索引传递到更新函数来确定删除
                fireworks.splice(index, 1);
            } else {
                // target not reached, keep traveling 目标没有达到,继续飞行
                this.x += vx;
                this.y += vy;
            }
        }

        // draw firework 绘制烟花
        Firework.prototype.draw = function () {
            ctx.beginPath();
            // move to the last tracked coordinate in the set, then draw a line to the current x and y
            // 移动到最后一个跟踪坐标,然后画一条线到当前的x和y
            ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
            ctx.lineTo(this.x, this.y);
            // 色调(0或360表示红色,120表示绿色,240表示蓝色);饱和度;亮度
            ctx.strokeStyle = ‘hsl(‘ + hue + ‘, 100%, ‘ + this.brightness + ‘%)‘;
            ctx.stroke();

            ctx.beginPath();
            // draw the target for this firework with a pulsing circle
            // 使用圆跳动画这个烟花的目标点
            ctx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2); // 画圆
            ctx.stroke();
        }

        // create particle  创建爆炸粒子
        function Particle(x, y) {
            this.x = x;
            this.y = y;
            // track the past coordinates of each particle to create a trail effect, increase the coordinate count to create more prominent trails
            // 追踪每个爆炸粒子经过的坐标,来创建一个跟踪效果,增加坐标数量来创造更多杰出的轨迹
            this.coordinates = [];
            this.coordinateCount = 5;
            while (this.coordinateCount--) {
                this.coordinates.push([this.x, this.y]);
            }
            // set a random angle in all possible directions, in radians
            // 在所有可能的方向,设置一个随机角弧度
            this.angle = random(0, Math.PI * 2);
            this.speed = random(1, 10);
            // friction will slow the particle down 摩擦会使粒子慢下来
            this.friction = 0.95;
            // gravity will be applied and pull the particle down  重力将应用粒子拉下来
            this.gravity = 2;
            // set the hue to a random number +-20 of the overall hue variable
            // 在烟花色度范围内随机取爆炸粒子色度
            this.hue = random(hue - 50, hue + 50);
            this.brightness = random(50, 80);
            this.alpha = 1;
            // set how fast the particle fades out  设置粒子消失的速度
            this.decay = random(0.015, 0.03);
        }

        // update particle  更新爆炸粒子
        Particle.prototype.update = function (index) {
            // remove last item in coordinates array  删除爆炸粒子坐标数组里最后一个坐标
            this.coordinates.pop();
            // add current coordinates to the start of the array  当前的坐标添加到爆炸粒子坐标数组的开始
            this.coordinates.unshift([this.x, this.y]);
            // slow down the particle  减缓粒子
            this.speed *= this.friction;
            // apply velocity
            this.x += Math.cos(this.angle) * this.speed;
            this.y += Math.sin(this.angle) * this.speed + this.gravity;
            // fade out the particle 粒子消失参数
            this.alpha -= this.decay;

            // remove the particle once the alpha is low enough, based on the passed in index
            // 删除粒子,使用索引传递到更新函数来确定删除
            if (this.alpha <= this.decay) {
                particles.splice(index, 1);
            }
        }

        // draw particle  绘制爆炸粒子
        Particle.prototype.draw = function () {
            ctx.beginPath();
            // move to the last tracked coordinates in the set, then draw a line to the current x and y
            // 移动到最后一个坐标跟踪设置,然后画一条线到当前的x和y
            ctx.moveTo(this.coordinates[this.coordinates.length - 1][0], this.coordinates[this.coordinates.length - 1][1]);
            ctx.lineTo(this.x, this.y);
            // 色调(0或360表示红色,120表示绿色,240表示蓝色);饱和度;亮度
            ctx.strokeStyle = ‘hsla(‘ + this.hue + ‘, 100%, ‘ + this.brightness + ‘%, ‘ + this.alpha + ‘)‘;
            ctx.stroke();
        }

        // create particle group/explosion  创建爆炸粒子组
        function createParticles(x, y) {
            // increase the particle count for a bigger explosion, beware of the canvas performance hit with the increased particles though
            // 增加粒子数创造更大的爆炸,谨防增加粒子造成canvas与性能影响
            var particleCount = parseInt(random(20, 50));
            while (particleCount--) {
                particles.push(new Particle(x, y));
            }
        }

        // 主循环
        function loop() {
            // this function will run endlessly with requestAnimationFrame
            // 这个函数将无限运行requestAnimationFrame
            requestAnimFrame(loop);

            // increase the hue to get different colored fireworks over time
            // 增加颜度,随着时间的推移得到不同颜色的烟火
            hue += random(0.5,10);

            // normally, clearRect() would be used to clear the canvas
            // we want to create a trailing effect though
            // setting the composite operation to destination-out will allow us to clear the canvas at a specific opacity, rather than wiping it entirely
            // 设置复合操作destination-out将使我们能够把画布清理在在一个特定的不透明度,而不是完全抹去它
            ctx.globalCompositeOperation = ‘destination-out‘; // 在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
            // decrease the alpha property to create more prominent trails
            // 降低alpha属性来创建更加显著的轨迹(0.5是透明度)
            ctx.fillStyle = ‘rgba(0, 0, 0, 0.5)‘;
            ctx.fillRect(0, 0, cw, ch);
            // change the composite operation back to our main mode  改变复合操作回到我们的主要模式
            // lighter creates bright highlight points as the fireworks and particles overlap each other
            ctx.globalCompositeOperation = ‘lighter‘; // 显示源图像 + 目标图像。

            // loop over each firework, draw it, update it
            // 循环绘制烟花
            var i = fireworks.length;
            while (i--) {
                fireworks[i].draw();
                fireworks[i].update(i);
            }

            // 循环绘制粒子
            var i = particles.length;
            while (i--) {
                particles[i].draw();
                particles[i].update(i);
            }

            // launch fireworks automatically to random coordinates, when the mouse isn‘t down
            // 当鼠标不点击,自动随机坐标发射烟火
            if (timerTick >= timerTotal) {
                if (!mousedown) {
                    var sw = random(0, cw);
                    // start the firework at the bottom middle of the screen, then set the random target coordinates, the random y coordinates will be set within the range of 

the top half of the screen
                    // 启动烟花在屏幕中间的底部, 然后设置随机目标坐标, 随机y坐标将范围内的屏幕的上半部分
                    fireworks.push(new Firework(sw, ch, sw, random(0, ch / 2)));
                    timerTick = 0;
                }
            } else {
                timerTick++;
            }

            // limit the rate at which fireworks get launched when mouse is down
            // 限制鼠标点击时烟花发射的速度
            if (limiterTick >= limiterTotal) {
                if (mousedown) {
                    // start the firework at the bottom middle of the screen, then set the current mouse coordinates as the target
                    // 启动烟花在屏幕中间的底部,然后将鼠标当前坐标设置为目标
                    fireworks.push(new Firework(mx, ch, mx, my));
                    limiterTick = 0;
                }
            } else {
                limiterTick++;
            }
        }

        // mouse event bindings
        // update the mouse coordinates on mousemove
        // 更新鼠标当前坐标
        canvas.addEventListener(‘mousemove‘, function (e) {
            mx = e.pageX - canvas.offsetLeft;
            my = e.pageY - canvas.offsetTop;
        });

        // toggle mousedown state and prevent canvas from being selected
        // 切换mousedown状态,防止canvas被选中
        canvas.addEventListener(‘mousedown‘, function (e) {
            e.preventDefault();
            mousedown = true;
        });

        canvas.addEventListener(‘mouseup‘, function (e) {
            e.preventDefault();
            mousedown = false;
        });

        // 登录启动
        window.onload = loop;
    </script>
</body>
</html>
时间: 2024-10-25 22:23:56

canvas烟花-娱乐的相关文章

[转]canvas 烟花效果

看到一个类似于烟花爆炸类的canvas,谈不上多复杂. 源码如下: <!DOCTYPE HTML> <html> <head> <meta charset="utf-8"/> <title></title> <style type="text/css"> *{margin:0;padding:0;list-style: none;border:0;} body{background:

canvas烟花锦集

canvas可以实现不同动画效果,本文主要记录几种不同节日烟花效果实现. 实现一 效果地址 html <canvas id="canvas"></canvas> css body { background: #000; margin: 0; } canvas { cursor: crosshair; display: block; } js // when animating on canvas, it is best to use requestAnimati

烟花效果(Canvas和Proton)

最近看了很多的烟花效果,我自己的感觉就是代码不是很难,只是需要对它的原理好好理解一下.我们都知道一个烟花从发射到炸裂经过的几个阶段,以及这些过程中涉及到了那些东西.那些量会对最后的炸开效果有影响,我们首相应该把这些量考虑好,之后才能上手去写这个程序,我不知道第一个人是怎么写出的但是我看出基本上所有的烟花效果都是那几个量,没什么区别只是有一些具体的值的大小可能不一样.下面我就分享一下我从网上找的一段代码: 这个烟花效果是自动随机产生烟花,不是我们控制的,相对比较简单. 1 <!DOCTYPE ht

10款很酷的HTML5动画和实用应用 有源码

10款很酷的HTML5动画和实用应用,这里有菜单.SVG动画.Loading动画,总有你喜欢的,而且,每一款HTML5应用都提供源代码下载,方便大家学习和研究,一起来看看吧. 1.HTML5 SVG 树枝分叉动画特效 今天我们来分享一款基于HTML5和SVG的动画效果,它是一个可以自动分叉的树,动画将以二叉树的形式展开.这三颗SVG树先是用svg的g画笔来定义这些树枝,然后利用javascript来实现动态改变g从而实现树枝的分叉展开动画. 在线演示 源码下载 2.HTML5/CSS3 3D下拉

精选19款华丽的HTML5动画和实用案例

下面是本人收集的19款超酷HTML5动画和实用案例,觉得不错,分享给大家. 1.HTML5 Canvas火焰喷射动画效果 还记得以前分享过的一款HTML5烟花动画HTML5 Canvas烟花特效,今天我们要来分享一款类似的HTML5动画效果,一款基于HTML5 Canvas火焰喷射动画.用鼠标拖动一条直线,直线长度表示火焰喷射的力度,另外,火焰在运动中还可以反射效果哦. 在线演示        源码下载 2.HTML5 3D立方体旋转动画 之前我们已经分享一款HTML5 3D正方体旋转动画,可以

8个超震撼的HTML5和纯CSS3动画源码

HTML5和CSS3之所以强大,不仅因为现在大量的浏览器的支持,更是因为它们已经越来越能满足现代开发的需要.Flash在几年之后肯定会消亡,那么HTML5和CSS3将会替代Flash.今天我们要给大家分享8个最新的HTML5和纯CSS3动画及其源码,这些动画非常让人震撼,你也可以学习一下HTML5源码. 1.HTML5 Canvas水波纹动画特效 HTML5的Canvas特性非常实用,我们不仅可以在Canvas画布上绘制各种图形,也可以制作绚丽的动画,比如这次介绍的水波纹动画特效.以前我们也分享

精妙无比 8款HTML5动画实例及源码

1.jQuery垂直带小图标菜单导航插件 今天我们要来分享一款jQuery菜单插件,这款jQuery菜单是垂直的样式,鼠标滑过菜单项时会出现一个背景,菜单项的右侧也会出现一个小箭头.另外值得注意的是,这款jQuery菜单的每一个菜单项都可以定义一些漂亮的小图标,确实是一款很实用的jQuery菜单,尽管外观不怎么华丽. 在线演示 源码下载 2.HTML5/CSS3图片网格动画特效 HTML5技术可以让网页上的图片变得非常神奇,各种各样的HTML5图片动画特效让你眼花缭乱.今天要分享的这款HTML5

HTML5/jQuery动画应用 3D视觉效果

今天我们要来分享几款很酷的HTML5/CSS3动画应用,虽然不是HTML5 3D应用,但也有3D的视觉效果.HTML5结合jQuery,让网页应用变得更加强大了.一起来看看这些HTML5/jQuery动画应用吧. 1.HTML5 3D动画柱形图表 这次我们要来分享一款效果非常酷的HTML5 3D柱形图表,这款HTML5图表和之前分享的都不一样,主要是外观上比较吸引人,首先图表是3D立体的,有一种非常棒的视觉效果:其次,当鼠标划过柱形图表时,会有很不错的HTML5动画效果. 在线演示 源码下载 2

其实canvas真的很简单,复杂的部分其实是你的创意

江湖上流传开来的除了牛叉的"H5",还有牛叉的canvas应用. canvas是html5的一部分,当然他们说的H5也并不是html5的意思,只是表示在手机浏览器中,更侠义的是在微信浏览器中打开的酷炫的网页. 曾几何时,我也觉得canvas真的酷爆了,各种什么烟花.酷炫的动画效果.canvas游戏等,都燃烧着我学习的热情. 后来通过学习,多看书,其实canvas并不复杂,要用到的东西也不多. 大概整理一下: 1.绘制基本几何图形 (1)直线 ctx.moveTo(100,200); c