html
<! DOCTYPE html >
< html lang = " en" >
< head>
< meta charset = " UTF-8" >
< title> Rainbow Space Unicorn</ title>
< link rel = " stylesheet" href = " css/style.css" >
</ head>
< body>
< img src = " img/unicorn.png" alt = " unicorn" id = " unicorn" hidden >
< script src = " js/index.js" > </ script>
</ body>
</ html>
js
var __extends = ( this && this . __extends) || ( function ( ) {
var extendStatics = Object. setPrototypeOf ||
( { __proto__ : [ ] } instanceof Array && function ( d, b ) { d. __proto__ = b; } ) ||
function ( d, b ) { for ( var p in b) if ( b. hasOwnProperty ( p) ) d[ p] = b[ p] ; } ;
return function ( d, b ) {
extendStatics ( d, b) ;
function __ ( ) { this . constructor = d; }
d. prototype = b === null ? Object. create ( b) : ( __ . prototype = b. prototype, new __ ( ) ) ;
} ;
} ) ( ) ;
window. addEventListener ( 'DOMContentLoaded' , init) ;
var Vector = ( function ( ) {
function Vector ( ) {
this . x = 0 ;
this . y = 0 ;
this . vx = 0 ;
this . vy = 0 ;
this . angle = 0 ;
this . va = 0.05 ;
}
return Vector;
} ( ) ) ;
var Particle = ( function ( _super ) {
__extends ( Particle, _super) ;
function Particle ( ) {
var _this = _super !== null && _super . apply ( this , arguments) || this ;
_this. id = Math. random ( ) . toString ( ) ;
_this. color = randomColor ( ) ;
_this. radius = 8 ;
_this. opacity = 1 ;
return _this;
}
return Particle;
} ( Vector) ) ;
var Unicorn = ( function ( _super ) {
__extends ( Unicorn, _super) ;
function Unicorn ( image ) {
var _this = _super . call ( this ) || this ;
_this. image = image;
return _this;
}
return Unicorn;
} ( Vector) ) ;
var Tile = ( function ( _super ) {
__extends ( Tile, _super) ;
function Tile ( ) {
var _this = _super !== null && _super . apply ( this , arguments) || this ;
_this. color = randomColor ( ) ;
_this. width = 30 ;
_this. height = 10 ;
_this. opacity = 1 ;
return _this;
}
return Tile;
} ( Vector) ) ;
var ParticleFactory = ( function ( ) {
function ParticleFactory ( ) {
}
ParticleFactory. archive = function ( p ) {
ParticleFactory. particleArchive[ p. id] = Object. assign ( { } , p) ;
} ;
ParticleFactory. retrieve = function ( p ) {
if ( p. id in ParticleFactory. particleArchive) {
return ParticleFactory. particleArchive[ p. id] ;
}
return null ;
} ;
ParticleFactory. create = function ( options ) {
var p = new Particle ( ) ;
Object. assign ( p, options) ;
ParticleFactory. archive ( p) ;
return p;
} ;
ParticleFactory. reset = function ( p ) {
var archivedVersion = ParticleFactory. retrieve ( p) ;
if ( archivedVersion) {
;
Object. assign ( p, archivedVersion) ;
}
} ;
ParticleFactory. particleArchive = { } ;
return ParticleFactory;
} ( ) ) ;
var Renderer = ( function ( ) {
function Renderer ( $ ) {
var _this = this ;
this . $ = $;
this . renderParticle = function ( p ) {
var $ = _this. $;
var x = p. x, y = p. y, radius = p. radius, color = p. color, opacity = p. opacity;
$. save ( ) ;
$. globalAlpha = opacity;
$. fillStyle = color;
$. translate ( x, y) ;
$. beginPath ( ) ;
$. arc ( 0 , 0 , radius, 0 , PI2 ) ;
$. fill ( ) ;
$. stroke ( ) ;
$. restore ( ) ;
} ;
this . renderStar = function ( p ) {
var $ = _this. $;
var radius = p. radius, color = p. color, x = p. x, y = p. y, opacity = p. opacity;
$. save ( ) ;
$. translate ( x, y) ;
$. fillStyle = color;
$. globalAlpha = opacity;
$. beginPath ( ) ;
for ( var i = 5 ; i-- ; ) {
$. lineTo ( 0 , radius) ;
$. translate ( 0 , radius) ;
$. rotate ( PI2 / 10 ) ;
$. lineTo ( 0 , - radius) ;
$. translate ( 0 , - radius) ;
$. rotate ( - ( ( Math. PI * 6 ) / 10 ) ) ;
}
$. lineTo ( 0 , radius) ;
$. fill ( ) ;
$. stroke ( ) ;
$. restore ( ) ;
} ;
this . renderTile = function ( t ) {
var $ = _this. $;
var x = t. x, y = t. y, width = t. width, height = t. height, color = t. color, opacity = t. opacity;
$. save ( ) ;
$. globalAlpha = opacity;
$. fillStyle = color;
$. translate ( x, y) ;
$. beginPath ( ) ;
$. rect ( 0 , 0 , width, height) ;
$. fill ( ) ;
$. stroke ( ) ;
$. restore ( ) ;
} ;
}
Renderer . prototype. clearScreen = function ( ) {
var $ = this . $;
$. clearRect ( 0 , 0 , $. canvas. width, $. canvas. height) ;
} ;
Renderer . prototype. renderImage = function ( img, x, y ) {
var $ = this . $;
$. save ( ) ;
$. drawImage ( img, x, y) ;
$. restore ( ) ;
} ;
Renderer . prototype. renderUnicorn = function ( u ) {
this . renderImage ( u. image, u. x, u. y) ;
} ;
return Renderer;
} ( ) ) ;
var CANVAS = document. createElement ( 'canvas' ) ;
var CTX = CANVAS . getContext ( '2d' ) ;
var WIDTH = ( CANVAS . width = window. innerWidth) ;
var HEIGHT = ( CANVAS . height = window. innerHeight) ;
var PI2 = 2 * Math. PI ;
var GRAVITY = 0.125 ;
var COLOR_FADE = 0.01 ;
var COLORS = [
'#9400D3' ,
'#4B0082' ,
'#0000FF' ,
'#00FF00' ,
'#FFFF00' ,
'#FF7F00' ,
'#FF0000'
] ;
var RENDERER = new Renderer ( CTX ) ;
var TILES = [ ] ;
var PARTICLES = [ ] ;
var PARTICLE_COUNT = 40 ;
var UNICORN_IMAGE = document. getElementById ( 'unicorn' ) ;
var UNICORN = new Unicorn ( UNICORN_IMAGE ) ;
function randomColor ( ) {
return sample ( COLORS ) ;
}
function randomNumber ( min, max ) {
return Math. random ( ) * ( max - min) + min;
}
function randomBoolean ( ) {
return Math. random ( ) > 0.5 ;
}
function sample ( a ) {
return a[ Math. floor ( Math. random ( ) * a. length) ] ;
}
function outsideScreen ( p ) {
var diameter = p. radius * 2 ;
var yExceeded = p. y - diameter > HEIGHT || p. y + diameter < 0 ;
var xExceeded = p. x - diameter > WIDTH || p. x + diameter < 0 ;
return yExceeded || xExceeded;
}
function updateParticle ( p ) {
p. vy += GRAVITY ;
p. y += p. vy;
p. x += p. vx;
if ( p. opacity > COLOR_FADE ) {
p. opacity -= COLOR_FADE ;
}
if ( outsideScreen ( p) ) {
ParticleFactory. reset ( p) ;
}
}
function updateUnicorn ( unicorn ) {
var image = unicorn. image;
var centerX = WIDTH / 2 - image. width / 2 ;
var centerY = HEIGHT / 2 - image. height / 2 - 50 ;
var radiusX = 20 ;
var radiusY = 8 ;
unicorn. x = centerX + Math. cos ( unicorn. angle) * radiusX;
unicorn. y = centerY + Math. sin ( unicorn. angle) * radiusY;
unicorn. angle += unicorn. va;
}
function animation ( ) {
requestAnimationFrame ( animation) ;
RENDERER . clearScreen ( ) ;
TILES . forEach ( updateTile) ;
TILES . forEach ( RENDERER . renderTile) ;
PARTICLES . forEach ( updateParticle) ;
PARTICLES . forEach ( RENDERER . renderStar) ;
if ( UNICORN_IMAGE . complete) {
updateUnicorn ( UNICORN ) ;
RENDERER . renderUnicorn ( UNICORN ) ;
}
}
function createParticles ( ) {
for ( var i = PARTICLE_COUNT ; i > 0 ; -- i) {
var p = ParticleFactory. create ( {
x : WIDTH / 2 ,
y : HEIGHT / 2 ,
vx : randomNumber ( - 14 , - 3 ) ,
vy : randomNumber ( - 8 , 2 )
} ) ;
var i_1 = Math. floor ( randomNumber ( 0 , 60 ) ) + 1 ;
while ( i_1-- ) {
updateParticle ( p) ;
}
PARTICLES . push ( p) ;
}
}
function updateTile ( t ) {
t. vx -= GRAVITY ;
t. x += t. vx;
t. y += t. vy;
if ( t. x + t. width < 0 ) {
t. x = randomNumber ( 0 , WIDTH ) + WIDTH ;
t. vx = 0 ;
}
}
function createTiles ( ) {
var tileCount = HEIGHT / 10 ;
for ( var i = tileCount; i > 0 ; -- i) {
var tileWidth = randomNumber ( 60 , 120 ) ;
var t = new Tile ( ) ;
t. opacity = randomNumber ( 0.1 , 0.6 ) ;
t. width = tileWidth;
t. x = tileWidth * ( i - 1 ) ;
t. y = t. height * ( i - 1 ) ;
var ii = Math. floor ( randomNumber ( 0 , 260 ) ) + 1 ;
while ( ii-- ) {
updateTile ( t) ;
}
TILES . push ( t) ;
}
}
function setup ( ) {
document. body. appendChild ( CANVAS ) ;
var unicornX = WIDTH / 2 - UNICORN . image. width / 2 ;
var unicornY = HEIGHT / 2 - UNICORN . image. height / 2 ;
UNICORN . x = unicornX;
UNICORN . y = unicornY;
createTiles ( ) ;
createParticles ( ) ;
}
function init ( ) {
setup ( ) ;
animation ( ) ;
}
css
body {
background : linear-gradient ( 180deg, #FF7F0022, white, #9400D322) ;
box-sizing : border-box;
margin : 0;
overflow : hidden;
text-align : center;
}
.made-by {
position : absolute;
bottom : 16px;
right : 16px;
padding : 8px 16px;
background : white;
color : hotpink;
font-family : monospace;
font-size : 12px;
}
效果