css和js文件如下
* {
/* 清除预设margin和padding */
margin: 0;
padding: 0;
/* 把borders和padding全都包含在定义的宽高里面 */
box-sizing: border-box;
/* 设置字体(cursive为备选字体) */
font-family: "MV Boli", cursive;
}
body {
background: #111;
}
html, body {height:100%;overflow:auto;margin: 0;}
html{overflow-y:scroll;}
h2 {
/* flex布局 */
display: flex;
/* 初始文字透明 */
color: transparent;
/* 文字水平垂直居中显示 */
justify-content: center;
align-items: center;
/* h2高度 */
height: 90vh;
/* 字号 */
font-size: 13vw;
}
h2 span:nth-child(6) {
/* 单词间隙 */
margin-left: 5vw;
}
h2 span {
animation: LetterColor 3s linear infinite;
/* 计算每个字的动画起始时间 */
animation-delay: calc(0.1s * var(--o));
}
@keyframes LetterColor {
0% {
color: #fff;
/* 利用模糊距离不同的阴影实现霓虹灯光晕效果 */
text-shadow:
0 0 10px #00b3ff,
0 0 20px #00b3ff,
0 0 40px #00b3ff,
0 0 80px #00b3ff,
0 0 120px #00b3ff,
0 0 200px #00b3ff,
0 0 300px #00b3ff,
0 0 400px #00b3ff;
/* 设置高斯模糊与色调,实现模糊效果和颜色变换 */
filter: blur(2px) hue-rotate(0deg);
}
30%,
70% {
color: #fff;
/* 减少光晕大小 */
text-shadow:
0 0 10px #00b3ff,
0 0 20px #00b3ff,
0 0 40px #00b3ff,
0 0 80px #00b3ff,
0 0 120px #00b3ff,
0 0 200px #00b3ff;
/* 色调变换360度 */
filter: blur(2px) hue-rotate(360deg);
}
100% {
/* 动画结束字变透明 */
color: transparent;
/* 动画结束消除阴影 */
text-shadow: none;
/* 动画结束色调重置 */
filter: blur(2px) hue-rotate(0deg);
}
}
/* 下面是按钮的设置 */
button {
/* 相对定位 */
position: fixed;
left: 40%;
top: 80%;
bottom: 0;
width: 400px;
height: 100px;
line-height: 100px;
text-align: center;
text-decoration: none;
text-transform: uppercase;
font-size: 24px;
color: #fff;
/* 圆角属性 */
border-radius: 50px;
/* 背景渐变色 */
background-image: linear-gradient(to right, #03a9f4, #f441a5, #ffeb3b, #09a8f4);
/* 背景渐变色大小 */
background-size: 400%;
z-index: 1;
}
/* 下面设计 发光效果 */
button::before {
content: '';
position: absolute;
top: -5px;
bottom: -5px;
left: -5px;
right: -5px;
border-radius: 50px;
/* 背景渐变色 */
background-image: linear-gradient(to right, #03a9f4, #f441a5, #ffeb3b, #09a8f4);
/* 背景渐变色大小 */
background-size: 400%;
/* 元素的位置 底层或者顶层 -值表示底层 + 值表示顶层 */
z-index: -1;
/* 设置模糊度 显示发光效果 */
filter: blur(20px);
}
button:hover {
/* 动画 名称 时间 infinite 是无限次播放 */
animation: sun 8s infinite;
}
button:hover::before {
animation: sun 8s infinite;
}
@keyframes sun {
100% {
/* 背景位置 */
background-position: -400% 0;
}
}
(function ($) {
$.fn.fireworks = function(options) {
// set the defaults
options = options || {};
options.sound = options.sound || false;
options.opacity = options.opacity || 1;
options.width = options.width || $(this).width();
options.height = options.height || $(this).height();
var fireworksField = this,
particles = [],
rockets = [],
MAX_PARTICLES = 400,
SCREEN_WIDTH = options.width,
SCREEN_HEIGHT = options.height;
// cache the sounds if the plugin has been configured to use sound
var sounds = [], audio;
// create canvas and get the context
var canvas = document.createElement('canvas');
canvas.id = 'fireworksField';
canvas.width = SCREEN_WIDTH;
canvas.height = SCREEN_HEIGHT;
canvas.style.width = SCREEN_WIDTH + 'px';
canvas.style.height = SCREEN_HEIGHT + 'px';
canvas.style.position = 'absolute';
canvas.style.top = '0px';
canvas.style.left = '0px';
canvas.style.opacity = options.opacity;
var context = canvas.getContext('2d');
// The Particles Object
function Particle(pos) {
this.pos = {
x: pos ? pos.x : 0,
y: pos ? pos.y : 0
};
this.vel = {
x: 0,
y: 0
};
this.shrink = 0.97;
this.size = 2;
this.resistance = 1;
this.gravity = 0;
this.flick = false;
this.alpha = 1;
this.fade = 0;
this.color = 0;
}
Particle.prototype.update = function() {
// apply resistance
this.vel.x *= this.resistance;
this.vel.y *= this.resistance;
// gravity down
this.vel.y += this.gravity;
// update position based on speed
this.pos.x += this.vel.x;
this.pos.y += this.vel.y;
// shrink
this.size *= this.shrink;
// fade out
this.alpha -= this.fade;
};
Particle.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
gradient.addColorStop(0.1, "rgba(255,255,255," + this.alpha + ")");
gradient.addColorStop(0.8, "hsla(" + this.color + ", 100%, 50%, " + this.alpha + ")");
gradient.addColorStop(1, "hsla(" + this.color + ", 100%, 50%, 0.1)");
c.fillStyle = gradient;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
Particle.prototype.exists = function() {
return this.alpha >= 0.1 && this.size >= 1;
};
// The Rocket Object
function Rocket(x) {
Particle.apply(this, [{
x: x,
y: 600 //SCREEN_HEIGHT
}]);
this.explosionColor = 0;
}
Rocket.prototype = new Particle();
Rocket.prototype.constructor = Rocket;
Rocket.prototype.explode = function() {
if (options.sound) {
var randomNumber = function (min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}(0, 2);
audio.src = sounds[randomNumber].prefix + sounds[randomNumber].data;
audio.play();
}
var count = Math.random() * 10 + 80;
for (var i = 0; i < count; i++) {
var particle = new Particle(this.pos);
var angle = Math.random() * Math.PI * 2;
// emulate 3D effect by using cosine and put more particles in the middle
var speed = Math.cos(Math.random() * Math.PI / 2) * 15;
particle.vel.x = Math.cos(angle) * speed;
particle.vel.y = Math.sin(angle) * speed;
particle.size = 10;
particle.gravity = 0.2;
particle.resistance = 0.92;
particle.shrink = Math.random() * 0.05 + 0.93;
particle.flick = true;
particle.color = this.explosionColor;
particles.push(particle);
}
};
Rocket.prototype.render = function(c) {
if (!this.exists()) {
return;
}
c.save();
c.globalCompositeOperation = 'lighter';
var x = this.pos.x,
y = this.pos.y,
r = this.size / 2;
var gradient = c.createRadialGradient(x, y, 0.1, x, y, r);
gradient.addColorStop(0.1, "rgba(255, 255, 255 ," + this.alpha + ")");
gradient.addColorStop(1, "rgba(0, 0, 0, " + this.alpha + ")");
c.fillStyle = gradient;
c.beginPath();
c.arc(this.pos.x, this.pos.y, this.flick ? Math.random() * this.size / 2 + this.size / 2 : this.size, 0, Math.PI * 2, true);
c.closePath();
c.fill();
c.restore();
};
var loop = function() {
// update screen size
if (SCREEN_WIDTH != window.innerWidth) {
canvas.width = SCREEN_WIDTH = window.innerWidth;
}
if (SCREEN_HEIGHT != window.innerHeight) {
canvas.height = SCREEN_HEIGHT = window.innerHeight;
}
// clear canvas
context.fillStyle = "rgba(0, 0, 0, 0.05)";
context.fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
var existingRockets = [];
for (var i = 0; i < rockets.length; i++) {
// update and render
rockets[i].update();
rockets[i].render(context);
// calculate distance with Pythagoras
var distance = Math.sqrt(Math.pow(SCREEN_WIDTH - rockets[i].pos.x, 2) + Math.pow(SCREEN_HEIGHT - rockets[i].pos.y, 2));
// random chance of 1% if rockets is above the middle
var randomChance = rockets[i].pos.y < (SCREEN_HEIGHT * 2 / 3) ? (Math.random() * 100 <= 1) : false;
/* Explosion rules
- 80% of screen
- going down
- close to the mouse
- 1% chance of random explosion
*/
if (rockets[i].pos.y < SCREEN_HEIGHT / 5 || rockets[i].vel.y >= 0 || distance < 50 || randomChance) {
rockets[i].explode();
} else {
existingRockets.push(rockets[i]);
}
}
rockets = existingRockets;
var existingParticles = [];
for (i = 0; i < particles.length; i++) {
particles[i].update();
// render and save particles that can be rendered
if (particles[i].exists()) {
particles[i].render(context);
existingParticles.push(particles[i]);
}
}
// update array with existing particles - old particles should be garbage collected
particles = existingParticles;
while (particles.length > MAX_PARTICLES) {
particles.shift();
}
};
function random(numbers) {
return numbers[Math.floor(Math.random()*numbers.length)];
}
var launchFrom = function(x) {
if (rockets.length < 10) {
var rocket = new Rocket(x);
rocket.explosionColor = random([210, 270, 255, 30, 285]);
rocket.vel.y = Math.random() * -6 - 4;
rocket.vel.x = Math.random() * 6 - 3;
rocket.size = 8;
rocket.shrink = 0.999;
rocket.gravity = 0.01;
rockets.push(rocket);
}
};
var launch = function() {
launchFrom(SCREEN_WIDTH * Math.random());
};
// Append the canvas and start the loops
$(fireworksField).append(canvas);
setInterval(launch, 800);
setInterval(loop, 1000 / 50);
return fireworksField;
};
}(jQuery));