codepens/svg-gradient-wave-generator/dist/script.js

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();
}