282 lines
8.0 KiB
JavaScript
282 lines
8.0 KiB
JavaScript
|
/*--------------------
|
||
|
SETTINGS
|
||
|
--------------------*/
|
||
|
let settings = {
|
||
|
amplitudeX: 100,
|
||
|
amplitudeY: 20,
|
||
|
lines: 20,
|
||
|
hueStartColor: 53,
|
||
|
saturationStartColor: 74,
|
||
|
lightnessStartColor: 67,
|
||
|
hueEndColor: 216,
|
||
|
saturationEndColor: 100,
|
||
|
lightnessEndColor: 7,
|
||
|
smoothness: 3,
|
||
|
offsetX: 10,
|
||
|
fill: true,
|
||
|
crazyness: false
|
||
|
}
|
||
|
|
||
|
|
||
|
/*--------------------
|
||
|
VARS
|
||
|
--------------------*/
|
||
|
let svg = document.getElementById('svg'),
|
||
|
winW = window.innerWidth,
|
||
|
winH = window.innerHeight,
|
||
|
Colors = [],
|
||
|
Paths = [],
|
||
|
Mouse = {
|
||
|
x: winW / 2,
|
||
|
y: winH / 2
|
||
|
},
|
||
|
overflow,
|
||
|
startColor,
|
||
|
endColor,
|
||
|
gui;
|
||
|
|
||
|
|
||
|
/*--------------------
|
||
|
PATH
|
||
|
--------------------*/
|
||
|
class Path {
|
||
|
constructor (y, fill, offsetX) {
|
||
|
this.rootY = y;
|
||
|
this.fill = fill;
|
||
|
this.offsetX = offsetX;
|
||
|
};
|
||
|
|
||
|
createRoot() {
|
||
|
this.root = [];
|
||
|
let offsetX = this.offsetX;
|
||
|
let x = -overflow + offsetX;
|
||
|
let y = 0;
|
||
|
let rootY = this.rootY;
|
||
|
let upSideDown = 0;
|
||
|
|
||
|
this.root.push({ x: x, y: rootY});
|
||
|
|
||
|
while (x < winW) {
|
||
|
let value = Math.random() > 0.5 ? 1 : -1;
|
||
|
|
||
|
// Crazyness
|
||
|
if (settings.crazyness) {
|
||
|
x += parseInt((Math.random() * settings.amplitudeX / 2) + (settings.amplitudeX / 2));
|
||
|
y = (parseInt((Math.random() * settings.amplitudeY / 2) + (settings.amplitudeY / 2)) * value) + rootY;
|
||
|
} else {
|
||
|
// Geometric
|
||
|
upSideDown = !upSideDown;
|
||
|
value = (upSideDown == 0) ? 1 : -1;
|
||
|
|
||
|
x += settings.amplitudeX;
|
||
|
y = settings.amplitudeY * value + rootY;
|
||
|
}
|
||
|
|
||
|
this.root.push({ x: x, y: y});
|
||
|
};
|
||
|
|
||
|
this.root.push({ x: winW + overflow, y: rootY});
|
||
|
};
|
||
|
|
||
|
createCircles() {
|
||
|
const fill = '#fff';
|
||
|
this.root.forEach(function(key, obj) {
|
||
|
const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
|
||
|
circle.setAttribute('r', 1);
|
||
|
circle.setAttribute('cx', key.x);
|
||
|
circle.setAttribute('cy', key.y);
|
||
|
circle.setAttribute('fill', 'rgba(255, 255, 255, .3)');
|
||
|
svg.appendChild(circle);
|
||
|
})
|
||
|
};
|
||
|
|
||
|
createPath(){
|
||
|
const root = this.root;
|
||
|
const fill = this.fill;
|
||
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||
|
path.setAttribute('fill', fill);
|
||
|
path.setAttribute('stroke', fill);
|
||
|
svg.appendChild(path);
|
||
|
if (settings.fill) {
|
||
|
svg.setAttribute('class','path');
|
||
|
} else {
|
||
|
svg.setAttribute('class','stroke');
|
||
|
}
|
||
|
|
||
|
// first & second points
|
||
|
let d = `M -${overflow} ${winH + overflow}`;
|
||
|
d += ` L ${root[0].x} ${root[0].y}`;
|
||
|
|
||
|
// magic points
|
||
|
for (let i = 1; i < this.root.length - 1; i++) {
|
||
|
let prevPoint = root[i - 1];
|
||
|
let actualPoint = root[i];
|
||
|
let diffX = (actualPoint.x - prevPoint.x) / settings.smoothness;
|
||
|
let x1 = prevPoint.x + diffX;
|
||
|
let x2 = actualPoint.x - diffX;
|
||
|
let x = actualPoint.x;
|
||
|
let y1 = prevPoint.y;
|
||
|
let y2 = actualPoint.y;
|
||
|
let y = actualPoint.y;
|
||
|
|
||
|
d += ` C ${x1} ${y1}, ${x2} ${y2}, ${x} ${y}`;
|
||
|
}
|
||
|
|
||
|
// Second last
|
||
|
const reverseRoot = root.reverse();
|
||
|
d += ` L ${reverseRoot[0].x} ${reverseRoot[0].y}`;
|
||
|
root.reverse();
|
||
|
|
||
|
// Last point
|
||
|
d += ` L ${winW + overflow} ${winH + overflow}`;
|
||
|
|
||
|
// Close path
|
||
|
d += ` Z`;
|
||
|
|
||
|
path.setAttribute('d', d);
|
||
|
};
|
||
|
|
||
|
createLines(){
|
||
|
const root = this.root;
|
||
|
const fill = this.fill;
|
||
|
const path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
|
||
|
path.setAttribute('fill', fill);
|
||
|
path.classList.add('path');
|
||
|
svg.appendChild(path);
|
||
|
|
||
|
// first & second points
|
||
|
let d = `M -${overflow} ${winH + overflow}`;
|
||
|
d += ` L ${root[0].x} ${root[0].y}`;
|
||
|
|
||
|
// Magic points
|
||
|
for (let i = 1; i < root.length - 1; i++) {
|
||
|
d += ` L ${root[i].x} ${root[i].y}`;
|
||
|
}
|
||
|
|
||
|
// Second last & last points
|
||
|
const reverseRoot = root.reverse();
|
||
|
d += ` L ${reverseRoot[0].x} ${reverseRoot[0].y}`;
|
||
|
d += ` L ${winW + overflow} ${winH + overflow}`;
|
||
|
root.reverse();
|
||
|
|
||
|
// Close path
|
||
|
d += ` Z`;
|
||
|
|
||
|
path.setAttribute('d', d);
|
||
|
};
|
||
|
};
|
||
|
|
||
|
|
||
|
/*--------------------
|
||
|
INIT
|
||
|
--------------------*/
|
||
|
function init(){
|
||
|
// Overflow
|
||
|
overflow = Math.abs(settings.lines * settings.offsetX);
|
||
|
|
||
|
// Colors
|
||
|
startColor = `hsl(${settings.hueStartColor}, ${settings.saturationStartColor}%, ${settings.lightnessStartColor}%)`;
|
||
|
endColor = `hsl(${settings.hueEndColor}, ${settings.saturationEndColor}%, ${settings.lightnessEndColor}%)`;
|
||
|
Colors = chroma.scale([startColor, endColor]).mode('lch').colors(settings.lines + 2);
|
||
|
|
||
|
// Reset
|
||
|
Paths = [];
|
||
|
document.body.removeChild(svg);
|
||
|
svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||
|
svg.setAttribute('id', 'svg');
|
||
|
document.body.appendChild(svg);
|
||
|
|
||
|
// Background
|
||
|
if (settings.fill) {
|
||
|
svg.style.backgroundColor = Colors[0];
|
||
|
} else {
|
||
|
svg.style.backgroundColor = '#000';
|
||
|
}
|
||
|
|
||
|
// Lines
|
||
|
for (let i = 0; i < settings.lines + 1; i++) {
|
||
|
let rootY = parseInt(winH / settings.lines * i);
|
||
|
const path = new Path(rootY, Colors[i + 1], settings.offsetX * i);
|
||
|
Paths.push(path);
|
||
|
path.createRoot();
|
||
|
}
|
||
|
Paths.forEach(function(path) {
|
||
|
path.createPath();
|
||
|
});
|
||
|
};
|
||
|
init();
|
||
|
|
||
|
|
||
|
/*--------------------
|
||
|
WIN RESIZE
|
||
|
--------------------*/
|
||
|
window.addEventListener('resize', function() {
|
||
|
winW = window.innerWidth;
|
||
|
winH = window.innerHeight;
|
||
|
init();
|
||
|
});
|
||
|
|
||
|
|
||
|
/*--------------------
|
||
|
DAT GUI
|
||
|
--------------------*/
|
||
|
function datgui(){
|
||
|
gui = new dat.GUI();
|
||
|
|
||
|
// Settings
|
||
|
let guiSettings = gui.addFolder('Settings');
|
||
|
guiSettings.add(settings, 'lines', 5, 50).step(1).onChange(init);
|
||
|
guiSettings.add(settings, 'amplitudeX', 20, 300).step(1).onChange(init);
|
||
|
guiSettings.add(settings, 'amplitudeY', 0, 200).step(1).onChange(init);
|
||
|
guiSettings.add(settings, 'offsetX', -100, 100).step(1).onChange(init);
|
||
|
guiSettings.add(settings, 'smoothness', 0.5, 10).step(0.2).onChange(init);
|
||
|
guiSettings.add(settings, 'fill', false).onChange(init);
|
||
|
guiSettings.add(settings, 'crazyness', false).onChange(init);
|
||
|
guiSettings.open();
|
||
|
|
||
|
// Start Color
|
||
|
let guiStartColor = gui.addFolder('Start Color');
|
||
|
guiStartColor.add(settings, 'hueStartColor', 0, 360).step(1).onChange(init);
|
||
|
guiStartColor.add(settings, 'saturationStartColor', 0, 100).step(1).onChange(init);
|
||
|
guiStartColor.add(settings, 'lightnessStartColor', 0, 100).step(1).onChange(init);
|
||
|
guiStartColor.open();
|
||
|
|
||
|
// End Color
|
||
|
let guiEndColor = gui.addFolder('End Color');
|
||
|
guiEndColor.add(settings, 'hueEndColor', 0, 360).step(1).onChange(init);
|
||
|
guiEndColor.add(settings, 'saturationEndColor', 0, 100).step(1).onChange(init);
|
||
|
guiEndColor.add(settings, 'lightnessEndColor', 0, 100).step(1).onChange(init);
|
||
|
guiEndColor.open();
|
||
|
|
||
|
// Randomize
|
||
|
let guiRandomize = { randomize:function(){ randomize() }};
|
||
|
gui.add(guiRandomize,'randomize');
|
||
|
|
||
|
return gui;
|
||
|
}
|
||
|
datgui();
|
||
|
|
||
|
|
||
|
/*--------------------
|
||
|
RANDOMIZE
|
||
|
--------------------*/
|
||
|
function randomize(){
|
||
|
settings = {
|
||
|
lines: parseInt(5 + Math.random() * 45),
|
||
|
amplitudeX: parseInt(20 + Math.random()* 300),
|
||
|
amplitudeY: parseInt(Math.random() * 200),
|
||
|
hueStartColor: parseInt(Math.random() * 360),
|
||
|
saturationStartColor: 74,
|
||
|
lightnessStartColor: 67,
|
||
|
hueEndColor: parseInt(Math.random() * 360),
|
||
|
saturationEndColor: 90,
|
||
|
lightnessEndColor: 14,
|
||
|
smoothness: 1 + parseInt(Math.random() * 9),
|
||
|
offsetX: parseInt(-20 + Math.random() * 40),
|
||
|
fill: Math.random() * 1 > 0.3 ? true : false,
|
||
|
crazyness: Math.random() * 1 > 0.9 ? true : false
|
||
|
}
|
||
|
init();
|
||
|
gui.destroy();
|
||
|
datgui();
|
||
|
}
|