<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Пример веб-страницы</title>
<style>
body {
font-family: sans-serif;
padding: 0;
margin: 0;
background-color: #eee9e9;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-o-user-select: none;
-ms-user-select: none;
user-select: none;
}
canvas {
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<canvas id='c'></canvas>
<p>Hi</p>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.1/dat.gui.js"></script>
<script type="text/javascript" src="https://rawgit.com/akm2/simplex-noise.js/master/simplex-noise.js"></script>
<script>
/**
* requestAnimationFrame
*/
window.requestAnimationFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
// Configs
var Configs = {
backgroundColor: '#eee9e9',
particleNum: 1000,
step: 5,
base: 1000,
zInc: 0.001
};
// Vars
var canvas,
context,
screenWidth,
screenHeight,
centerX,
centerY,
particles = [],
hueBase = 0,
simplexNoise,
zoff = 0,
gui;
// Initialize
function init() {
canvas = document.getElementById('c');
window.addEventListener('resize', onWindowResize, false);
onWindowResize(null);
for (var i = 0, len = Configs.particleNum; i < len; i++) {
initParticle((particles[i] = new Particle()));
}
simplexNoise = new SimplexNoise();
canvas.addEventListener('click', onCanvasClick, false);
gui = new dat.GUI();
gui.add(Configs, 'step', 1, 10);
gui.add(Configs, 'base', 500, 3000);
gui.add(Configs, 'zInc', 0.0001, 0.01);
gui.close();
update();
}
// Event listeners
function onWindowResize(e) {
screenWidth = canvas.width = window.innerWidth;
screenHeight = canvas.height = window.innerHeight;
centerX = screenWidth / 2;
centerY = screenHeight / 2;
context = canvas.getContext('2d');
context.lineWidth = 0.3;
context.lineCap = context.lineJoin = 'round';
}
function onCanvasClick(e) {
context.save();
context.globalAlpha = 0.8;
context.fillStyle = Configs.backgroundColor;
context.fillRect(0, 0, screenWidth, screenHeight);
context.restore();
simplexNoise = new SimplexNoise();
}
// Functions
function getNoise(x, y, z) {
var octaves = 4,
fallout = 0.5,
amp = 1, f = 1, sum = 0,
i;
for (i = 0; i < octaves; ++i) {
amp *= fallout;
sum += amp * (simplexNoise.noise3D(x * f, y * f, z * f) + 1) * 0.5;
f *= 2;
}
return sum;
}
function initParticle(p) {
p.x = p.pastX = screenWidth * Math.random();
p.y = p.pastY = screenHeight * Math.random();
p.color.h = hueBase + Math.atan2(centerY - p.y, centerX - p.x) * 180 / Math.PI;
p.color.s = 1;
p.color.l = 0.5;
p.color.a = 0;
}
// Update
function update() {
var step = Configs.step,
base = Configs.base,
i, p, angle;
for (i = 0, len = particles.length; i < len; i++) {
p = particles[i];
p.pastX = p.x;
p.pastY = p.y;
angle = Math.PI * 6 * getNoise(p.x / base * 1.75, p.y / base * 1.75, zoff);
p.x += Math.cos(angle) * step;
p.y += Math.sin(angle) * step;
if (p.color.a < 1) p.color.a += 0.003;
context.beginPath();
context.strokeStyle = p.color.toString();
context.moveTo(p.pastX, p.pastY);
context.lineTo(p.x, p.y);
context.stroke();
if (p.x < 0 || p.x > screenWidth || p.y < 0 || p.y > screenHeight) {
initParticle(p);
}
}
hueBase += 0.1;
zoff += Configs.zInc;
requestAnimationFrame(update);
}
/**
* HSLA
*/
function HSLA(h, s, l, a) {
this.h = h || 0;
this.s = s || 0;
this.l = l || 0;
this.a = a || 0;
}
HSLA.prototype.toString = function() {
return 'hsla(' + this.h + ',' + (this.s * 100) + '%,' + (this.l * 100) + '%,' + this.a + ')';
}
/**
* Particle
*/
function Particle(x, y, color) {
this.x = x || 0;
this.y = y || 0;
this.color = color || new HSLA();
this.pastX = this.x;
this.pastY = this.y;
}
// Run
init();
</script>
</body>
</html>