新年快来了,分享一套自己整理的新年套装。
13天前
主要把背景颜色改成红色和添加一对灯笼,在添加了一下烟花特效。
<div class="deng-box1"> <div class="deng"> <div class="xian"></div> <div class="deng-a"> <div class="deng-b"><div class="deng-t">新年</div></div> </div> <div class="shui shui-a"><div class="shui-c"></div><div class="shui-b"></div></div> </div> </div>
<div class="deng-box2"> <div class="deng"> <div class="xian"></div> <div class="deng-a"> <div class="deng-b"><div class="deng-t">快乐</div></div> </div> <div class="shui shui-a"><div class="shui-c"></div><div class="shui-b"></div></div> </div> </div>
<canvas id=c></canvas>
<style>
body {
background: #bf1f18;
}
canvas {
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
.deng-box1 {
position: fixed;
top: 35px;
left: 5px;
z-index: 9999;
pointer-events: none;
}
.deng {
position: relative;
width: 84px; /* 120px * 0.7 */
height: 63px; /* 90px * 0.7 */
margin: 35px; /* 50px * 0.7 */
background: #d8000f;
background: rgba(216, 0, 15, 0.8);
border-radius: 50% 50%;
-webkit-transform-origin: 50% -70px; /* -100px * 0.7 */
-webkit-animation: swing 3s infinite ease-in-out;
box-shadow: -3.5px 3.5px 35px 2.8px rgba(250, 108, 0, 1); /* 缩小阴影 */
}
.deng::before {
position: absolute;
top: -4.9px; /* -7px * 0.7 */
left: 20.3px; /* 29px * 0.7 */
height: 8.4px; /* 12px * 0.7 */
width: 42px; /* 60px * 0.7 */
content: " ";
display: block;
z-index: 999;
border-radius: 3.5px 3.5px 0 0; /* 5px * 0.7 */
border: solid 0.7px #dc8f03; /* 1px * 0.7 */
background: #ffa500;
background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
}
.xian {
position: absolute;
top: -14px; /* -20px * 0.7 */
left: 42px; /* 60px * 0.7 */
width: 1.4px; /* 2px * 0.7 */
height: 14px; /* 20px * 0.7 */
background: #dc8f03;
}
.deng-box1 {
pointer-events: none;
}
.deng-a {
width: 70px; /* 100px * 0.7 */
height: 63px; /* 90px * 0.7 */
background: #d8000f;
background: rgba(216, 0, 15, 0.1);
margin: 8.4px 5.6px 5.6px 7px; /* 缩小margin */
border-radius: 50% 50%;
border: 1.4px solid #dc8f03; /* 2px * 0.7 */
}
.deng-b {
width: 31.5px; /* 45px * 0.7 */
height: 63px; /* 90px * 0.7 */
background: #d8000f;
background: rgba(216, 0, 15, 0.1);
margin: -1.4px 5.6px 5.6px 18.2px; /* 缩小margin */
border-radius: 50% 50%;
border: 1.4px solid #dc8f03; /* 2px * 0.7 */
}
.deng-t {
font-family: 华文行楷,Arial,Lucida Grande,Tahoma,sans-serif;
font-size: 1.05rem; /* 1.5rem * 0.7 */
color: #ffa500;
font-weight: bold;
line-height: 29.4px; /* 42px * 0.7 */
text-align: center;
width: 17.5px; /* 25px * 0.7 */
margin: 0 auto;
}
.shui-a {
position: relative;
width: 3.5px; /* 5px * 0.7 */
height: 14px; /* 20px * 0.7 */
margin: -3.5px 0 0 41.3px; /* 缩小margin */
-webkit-animation: swing 4s infinite ease-in-out;
-webkit-transform-origin: 50% -31.5px; /* -45px * 0.7 */
background: #ffa500;
border-radius: 0 0 3.5px 3.5px; /* 5px * 0.7 */
}
.shui-c {
position: absolute;
top: 12.6px; /* 18px * 0.7 */
left: -1.4px; /* -2px * 0.7 */
width: 7px; /* 10px * 0.7 */
height: 24.5px; /* 35px * 0.7 */
background: #ffa500;
border-radius: 0 0 0 3.5px; /* 5px * 0.7 */
}
.shui-b {
position: absolute;
top: 9.8px; /* 14px * 0.7 */
left: -1.4px; /* -2px * 0.7 */
width: 7px; /* 10px * 0.7 */
height: 7px; /* 10px * 0.7 */
background: #dc8f03;
border-radius: 50%;
}
.deng::after {
position: absolute;
bottom: -4.9px; /* -7px * 0.7 */
left: 7px; /* 10px * 0.7 */
height: 8.4px; /* 12px * 0.7 */
width: 42px; /* 60px * 0.7 */
content: " ";
display: block;
margin-left: 14px; /* 20px * 0.7 */
border-radius: 0 0 3.5px 3.5px; /* 5px * 0.7 */
border: solid 0.7px #dc8f03; /* 1px * 0.7 */
background: #ffa500;
background: linear-gradient(to right, #dc8f03, #ffa500, #dc8f03, #ffa500, #dc8f03);
}
.deng-box2 {
position: fixed;
top: 35px;
right: 5px;
z-index: 9999;
pointer-events: none;
}
.deng-box2 .deng {
position: relative;
width: 84px; /* 120px * 0.7 */
height: 63px; /* 90px * 0.7 */
margin: 35px; /* 50px * 0.7 */
background: #d8000f;
background: rgba(216, 0, 15, 0.8);
border-radius: 50% 50%;
-webkit-transform-origin: 50% -70px; /* -100px * 0.7 */
-webkit-animation: swing 5s infinite ease-in-out;
box-shadow: -3.5px 3.5px 21px 2.8px rgba(252, 144, 61, 1); /* 缩小阴影 */
}
.deng-box2 {
pointer-events: none;
}
@-moz-keyframes swing {
0% {
-moz-transform: rotate(-10deg)
}
50% {
-moz-transform: rotate(10deg)
}
100% {
-moz-transform: rotate(-10deg)
}
}
@-webkit-keyframes swing {
0% {
-webkit-transform: rotate(-10deg)
}
50% {
-webkit-transform: rotate(10deg)
}
100% {
-webkit-transform: rotate(-10deg)
}
}
</style>
<script>
var gl = c.getContext( 'webgl', { preserveDrawingBuffer: true } )
, w = c.width = window.innerWidth
, h = c.height = window.innerHeight
, webgl = {}
, opts = {
projectileAlpha: .8,
projectileLineWidth: 1.3,
fireworkAngleSpan: .5,
baseFireworkVel: 3,
addedFireworkVel: 3,
gravity: .03,
lowVelBoundary: -.2,
xFriction: .995,
baseShardVel: 1,
addedShardVel: .2,
fireworks: 100,
baseShardsParFirework: 10,
addedShardsParFirework: 10,
shardFireworkVelMultiplier: .3,
initHueMultiplier: 1/360,
runHueAdder: .1/360
}
webgl.vertexShaderSource = `
uniform int u_mode;
uniform vec2 u_res;
attribute vec4 a_data;
varying vec4 v_color;
vec3 h2rgb( float h ){
return clamp( abs( mod( h * 6. + vec3( 0, 4, 2 ), 6. ) - 3. ) -1., 0., 1. );
}
void clear(){
gl_Position = vec4( a_data.xy, 0, 1 );
v_color = vec4( 0, 0, 0, a_data.w );
}
void draw(){
gl_Position = vec4( vec2( 1, -1 ) * ( ( a_data.xy / u_res ) * 2. - 1. ), 0, 1 );
v_color = vec4( h2rgb( a_data.z ), a_data.w );
}
void main(){
if( u_mode == 0 )
draw();
else
clear();
}
`;
webgl.fragmentShaderSource = `
precision mediump float;
varying vec4 v_color;
void main(){
gl_FragColor = v_color;
}
`;
webgl.vertexShader = gl.createShader( gl.VERTEX_SHADER );
gl.shaderSource( webgl.vertexShader, webgl.vertexShaderSource );
gl.compileShader( webgl.vertexShader );
webgl.fragmentShader = gl.createShader( gl.FRAGMENT_SHADER );
gl.shaderSource( webgl.fragmentShader, webgl.fragmentShaderSource );
gl.compileShader( webgl.fragmentShader );
webgl.shaderProgram = gl.createProgram();
gl.attachShader( webgl.shaderProgram, webgl.vertexShader );
gl.attachShader( webgl.shaderProgram, webgl.fragmentShader );
gl.linkProgram( webgl.shaderProgram );
gl.useProgram( webgl.shaderProgram );
webgl.dataAttribLoc = gl.getAttribLocation( webgl.shaderProgram, 'a_data' );
webgl.dataBuffer = gl.createBuffer();
gl.enableVertexAttribArray( webgl.dataAttribLoc );
gl.bindBuffer( gl.ARRAY_BUFFER, webgl.dataBuffer );
gl.vertexAttribPointer( webgl.dataAttribLoc, 4, gl.FLOAT, false, 0, 0 );
webgl.resUniformLoc = gl.getUniformLocation( webgl.shaderProgram, 'u_res' );
webgl.modeUniformLoc = gl.getUniformLocation( webgl.shaderProgram, 'u_mode' );
gl.viewport( 0, 0, w, h );
gl.uniform2f( webgl.resUniformLoc, w, h );
gl.blendFunc( gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA );
gl.enable( gl.BLEND );
gl.lineWidth( opts.projectileLineWidth );
webgl.data = [];
webgl.clear = function(){
gl.uniform1i( webgl.modeUniformLoc, 1 );
var a = .1;
webgl.data = [
-1, -1, 0, a,
1, -1, 0, a,
-1, 1, 0, a,
-1, 1, 0, a,
1, -1, 0, a,
1, 1, 0, a
];
webgl.draw( gl.TRIANGLES );
gl.uniform1i( webgl.modeUniformLoc, 0 );
webgl.data.length = 0;
}
webgl.draw = function( glType ){
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( webgl.data ), gl.STATIC_DRAW );
gl.drawArrays( glType, 0, webgl.data.length / 4 );
}
var fireworks = []
, tick = 0
, sins = []
, coss = []
, maxShardsParFirework = opts.baseShardsParFirework + opts.addedShardsParFirework
, tau = 6.283185307179586476925286766559;
for( var i = 0; i < maxShardsParFirework; ++i ){
sins[ i ] = Math.sin( tau * i / maxShardsParFirework );
coss[ i ] = Math.cos( tau * i / maxShardsParFirework );
}
function Firework(){
this.reset();
this.shards = [];
for( var i = 0; i < maxShardsParFirework; ++i )
this.shards.push( new Shard( this ) );
}
Firework.prototype.reset = function(){
var angle = -Math.PI / 2 + ( Math.random() - .5 )* opts.fireworkAngleSpan
, vel = opts.baseFireworkVel + opts.addedFireworkVel * Math.random();
this.mode = 0;
this.vx = vel * Math.cos( angle );
this.vy = vel * Math.sin( angle );
this.x = Math.random() * w;
this.y = h;
this.hue = tick * opts.initHueMultiplier;
}
Firework.prototype.step = function(){
if( this.mode === 0 ){
var ph = this.hue
, px = this.x
, py = this.y;
this.hue += opts.runHueAdder;
this.x += this.vx *= opts.xFriction;
this.y += this.vy += opts.gravity;
webgl.data.push(
px, py, ph, opts.projectileAlpha * .2,
this.x, this.y, this.hue, opts.projectileAlpha * .2 );
if( this.vy >= opts.lowVelBoundary ){
this.mode = 1;
this.shardAmount = opts.baseShardsParFirework + opts.addedShardsParFirework * Math.random() | 0;
var baseAngle = Math.random() * tau
, x = Math.cos( baseAngle )
, y = Math.sin( baseAngle )
, sin = sins[ this.shardAmount ]
, cos = coss[ this.shardAmount ];
for( var i = 0; i < this.shardAmount; ++i ){
var vel = opts.baseShardVel + opts.addedShardVel * Math.random();
this.shards[ i ].reset( x * vel, y * vel )
var X = x;
x = x * cos - y * sin;
y = y * cos + X * sin;
}
}
} else if( this.mode === 1 ) {
this.ph = this.hue
this.hue += opts.runHueAdder;
var allDead = true;
for( var i = 0; i < this.shardAmount; ++i ){
var shard = this.shards[ i ];
if( !shard.dead ){
shard.step();
allDead = false;
}
}
if( allDead )
this.reset();
}
}
function Shard( parent ){
this.parent = parent;
}
Shard.prototype.reset = function( vx, vy ){
this.x = this.parent.x;
this.y = this.parent.y;
this.vx = this.parent.vx * opts.shardFireworkVelMultiplier + vx;
this.vy = this.parent.vy * opts.shardFireworkVelMultiplier + vy;
this.starty = this.y;
this.dead = false;
this.tick = 1;
}
Shard.prototype.step = function(){
this.tick += .05;
var px = this.x
, py = this.y;
this.x += this.vx *= opts.xFriction;
this.y += this.vy += opts.gravity;
var proportion = 1 - ( this.y - this.starty ) / ( h - this.starty );
webgl.data.push(
px, py, this.parent.ph, opts.projectileAlpha / this.tick,
this.x, this.y, this.parent.hue, opts.projectileAlpha / this.tick );
if( this.y > h )
this.dead = true;
}
function anim(){
window.requestAnimationFrame( anim )
webgl.clear();
++tick;
if( fireworks.length < opts.fireworks )
fireworks.push( new Firework );
fireworks.map( function( firework ){ firework.step(); } );
webgl.draw( gl.LINES );
}
anim();
window.addEventListener( 'resize', function(){
w = c.width = window.innerWidth;
h = c.height = window.innerHeight;
gl.viewport( 0, 0, w, h );
gl.uniform2f( webgl.resUniformLoc, w, h );
})
window.addEventListener( 'click', function( e ){
var firework = new Firework();
firework.x = e.clientX;
firework.y = e.clientY;
firework.vx = 0;
firework.vy = 0;
fireworks.push( firework );
});
</script>