diff --git a/index.html b/index.html new file mode 100644 index 0000000..e9c810a --- /dev/null +++ b/index.html @@ -0,0 +1,418 @@ +<!DOCTYPE html> +<html lang="en"> + +<head> + <meta charset="UTF-8"> + <meta name="viewport" + content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> + + <title>womb3</title> + <link rel="stylesheet" type="text/css" href="css/main.css" /> + <link rel="stylesheet" type="text/css" href="css/fira.css" /> + <link rel="stylesheet" type="text/css" href="css/hack.css" /> +</head> + +<body> + <header> + <h1 id="text">УТРОБА 3</h1> + </header> + <canvas class="shell"></canvas> + + <svg style="position: absolute"> + <defs> + <filter id="blob"> + <feGaussianBlur in="SourceGraphic" stdDeviation="12" result="blur"></feGaussianBlur> + <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="blob"> + </feColorMatrix> + </filter> + </defs> + </svg> + + <script src="js/womb3-simplex.js" type="module"></script> + <script> + document.addEventListener('womb.loaded', function (e) { + for (const shell of document.getElementsByClassName('shell')) { + // Перебор оболочек + const layer = new e.detail.womb(shell); + if (layer instanceof e.detail.womb) { + // Удалось инициализировать слой + + layer.init(); + + layer.generate(); + // Инициализация сдвига + + const text = document.getElementById('text'); + const filter = document.getElementById('blob'); + const blur = filter.getElementsByTagName('feGaussianBlur')[0]; + const matrix = filter.getElementsByTagName('feColorMatrix')[0]; + const html = document.getElementsByTagName('html')[0]; + let render = 30; + let zoom = 1; + let speed = 0.01; + let offset = 0; + let color = 'red'; + let drawing_diameter = 40; + let drawing_delay = 20; + let drawing_render = 50; + let flashlight_diameter = 300; + let flashlight_delay = 555; + let flashlight_render = 20; + let mask = 'unset'; + let mask_target_name = "noise_text"; + let mask_target = document.body; + let mask_blur = 'unset'; + let mask_contrast = 'unset'; + let mask_circle = 30; + let mask_custom = 'circle(30% at 50% 50%)'; + let text_border_x, text_border_y, text_border_blur, text_border_color, text_border_depth; + let matrix_1 = '1 0 0 0 0'; + let matrix_2 = '0 1 0 0 0'; + let matrix_3 = '0 0 1 0 0'; + let matrix_4 = '0 0 0 19 -9'; + + let x = Math.floor(Math.random() * (window.outerWidth + 1)); + let y = Math.floor(Math.random() * (window.outerHeight + 1)); + window.addEventListener("mousemove", (e) => (x = e.clientX, y = e.clientY)); + + // Инициализация инстанции выполнения + let instance; + + // Инициализация инстанции выполнения рисования + let drawing_instance; + let drawing_timeouts = new Set; + function drawing() { + clearInterval(drawing_instance); + for (const drawing_timeout of drawing_timeouts) clearTimeout(drawing_timeout); + drawing_instance = setInterval(function () { + const __x = (x - mask_target.offsetLeft) / zoom; + const __y = (y - mask_target.offsetTop) / zoom; + drawing_timeouts.add( + setTimeout(() => { + for (let _y = 0; _y < layer.shell.height; _y += layer.block.height) { + // Перебор колонок + if (_y - drawing_diameter < __y && _y + drawing_diameter > __y) { + // Входит в диапазон по вертикали + for (let _x = 0; _x < layer.shell.width; _x += layer.block.width) { + // Перебор строк + if (_x - drawing_diameter < __x && _x + drawing_diameter > __x) { + // Входит в диапазон по горизонтали + layer.clean(_x, _y, offset, 0, 0.3, drawing_decay); + } + } + } + } + }, drawing_delay)); + }, drawing_render); + } + + // Инициализация инстанции выполнения фонаря + let flashlight_instance; + let flashlight_timeouts = new Set; + function flashlight() { + clearInterval(flashlight_instance); + for (const flashlight_timeout of flashlight_timeouts) clearTimeout(flashlight_timeout); + flashlight_instance = setInterval(() => { + const _x = (x - mask_target.offsetLeft) / zoom; + const _y = (y - mask_target.offsetTop) / zoom; + flashlight_timeouts.add( + setTimeout(() => mask_target.style.clipPath = `circle(${flashlight_diameter}px at ${_x}px ${_y}px)`, flashlight_delay) + ); + }, flashlight_render); + } + + function text_border() { + shadow = ''; + for (let i = 0; i < text_border_depth; ++i) shadow += `${text_border_x}px ${text_border_y}px ${text_border_blur}px ${text_border_color}, `; + shadow = shadow.slice(0, -2); + + if (text_border_x !== 0 || text_border_y !== 0 || text_border_blur !== 0) text.style.setProperty('--text-shadow', shadow); + else text.style.setProperty('--text-shadow', 'unset'); + } + + function matrix_value() { + matrix.setAttribute('values', matrix_1.length > 0 && matrix_2.length > 0 && matrix_3.length > 0 && matrix_4.length > 0 + ? `${matrix_1} ${matrix_2} ${matrix_3} ${matrix_4}` + : '' + ); + } + + function init() { + clearInterval(instance); + instance = setInterval(function () { + layer.dump(); + drawing ? layer.interactive(offset += speed, color) : layer.generate(offset += speed, color); + }, render); + } + + // Первичная инициализация + init(); + + window.addEventListener('resize', function (e) { + layer.init(); + init() + }, true); + + // Wallpaper Engine настройки + window.wallpaperPropertyListener = { + applyUserProperties: function (properties) { + // Text + if (properties.text) text.innerText = properties.text.value; + + // Font + if (properties.font) text.style.setProperty('--font', properties.font.value); + + // Font weight + if (properties.font_weight) text.style.setProperty('--font-weight', properties.font_weight.value * 100); + + // Text color + if (properties.text_color) text.style.color = 'rgb(' + properties.text_color.value.split(' ').map(function (c) { + return Math.ceil(c * 255); + }) + ')'; + + // Text size + if (properties.text_size) text.style.fontSize = properties.text_size.value + 'rem'; + + // Text left offset (%) + if (properties.text_left) text.style.setProperty('--left', properties.text_left.value + '%'); + + // Text top offset (%) + if (properties.text_top) text.style.setProperty('--top', properties.text_top.value + '%'); + + // Text opacity (%) + if (properties.text_opacity) text.style.setProperty('--opacity', properties.text_opacity.value / 100); + + // Text border X (px) + if (properties.text_border_x) { + text_border_x = properties.text_border_x.value; + text_border(); + } + + // Text border Y (px) + if (properties.text_border_y) { + text_border_y = properties.text_border_y.value; + text_border(); + } + + // Text border blur (px) + if (properties.text_border_blur) { + text_border_blur = properties.text_border_blur.value; + text_border(); + } + + // Text border depth + if (properties.text_border_depth) { + text_border_depth = properties.text_border_depth.value; + text_border(); + } + + // Text border color + if (properties.text_border_color) { + text_border_color = 'rgb(' + properties.text_border_color.value.split(' ').map(function (c) { + return Math.ceil(c * 255); + }) + ')'; + text_border(); + } + + // Background color + if (properties.background) document.body.style.backgroundColor = 'rgb(' + properties.background.value.split(' ').map(function (c) { + return Math.ceil(c * 255); + }) + ')'; + + // Blocks width + if (properties.blocks_width) layer.block.width = properties.blocks_width.value; + + // Blocks height + if (properties.blocks_height) layer.block.height = properties.blocks_height.value; + + // Left offset (%) + if (properties.left) document.body.style.setProperty('--left', properties.left.value + '%'); + + // Top offset (%) + if (properties.top) document.body.style.setProperty('--top', properties.top.value + '%'); + + // Zoom + if (properties.zoom) { + zoom = properties.zoom.value; + document.body.style.setProperty('--zoom', zoom); + layer.init(); + init() + } + + // Render frequency (ms) + if (properties.render) { + render = properties.render.value; + init(); + } + + // Stick to edges + if (properties.stick) { + shell.style.setProperty('--scale', properties.stick.value); + }; + + // Blur + if (properties.blur) document.body.style.setProperty('--blur', properties.blur.value + 'px'); + + // Contrast + if (properties.contrast) document.body.style.setProperty('--contrast', properties.contrast.value); + + // Noise blur + if (properties.noise_blur) blur.setAttribute('stdDeviation', properties.noise_blur.value); + + // Speed + if (properties.speed) speed = properties.speed.value / 10000; + + // Background color + if (properties.schemecolor) color = 'rgb(' + properties.schemecolor.value.split(' ').map(function (c) { + return Math.ceil(c * 255); + }) + ')'; + + // Drawing brush diameter + if (properties.drawing_diameter) { + drawing_diameter = properties.drawing_diameter.value / zoom; + drawing(); + } + + // Drawing decay + if (properties.drawing_decay) { + drawing_decay = properties.drawing_decay.value; + drawing(); + } + + // Drawing delay + if (properties.drawing_delay) { + drawing_delay = properties.drawing_delay.value; + drawing(); + } + + // Drawing render frequency + if (properties.drawing_render) { + drawing_render = properties.drawing_render.value; + drawing(); + } + + // Drawing + if (properties.drawing) { + if (properties.drawing.value) drawing(); + else { + clearInterval(drawing_instance); + for (const drawing_timeout of drawing_timeouts) clearTimeout(drawing_timeout); + } + } + + // Flashlight diameter + if (properties.flashlight_diameter) { + flashlight_diameter = properties.flashlight_diameter.value / zoom; + flashlight(); + } + + // Flashlight delay + if (properties.flashlight_delay) { + flashlight_delay = properties.flashlight_delay.value; + flashlight(); + } + + // Flashlight render frequency + if (properties.flashlight_render) { + flashlight_render = properties.flashlight_render.value; + flashlight(); + } + + // Mask: circle + if (properties.mask_circle) { + mask_circle = properties.mask_circle.value; + if (mask === 'circle') mask_target.style.clipPath = `circle(${mask_circle}% at 50% 50%)`; + } + + // Mask: custom + if (properties.mask_custom) { + mask_custom = properties.mask_custom.value; + if (mask === 'custom') mask_target.style.clipPath = mask_custom; + } + + // Mask target + if (properties.mask_target) { + mask_target_name = properties.mask_target.value; + + shell.style.clipPath = text.style.clipPath = document.body.style.clipPath = 'unset'; + + if (mask_target_name === 'noise') { + html.style.setProperty('--blur', 'unset'); + html.style.setProperty('--contrast', 'unset'); + mask_target = shell; + } + else if (mask_target_name === 'text') { + html.style.setProperty('--blur', 'unset'); + html.style.setProperty('--contrast', 'unset'); + mask_target = text; + } + else if (mask_target_name === 'noise_text') { + html.style.setProperty('--blur', mask_blur + 'px'); + html.style.setProperty('--contrast', mask_contrast); + mask_target = document.body; + } + + if (mask === 'flashlight') flashlight(); + } + + // Mask blur + if (properties.mask_blur) { + html.style.setProperty('--contrast', mask_blur = mask !== 'unset' ? mask_blur + 'px' : 'unset'); + } + + // Mask blur + if (properties.mask_blur) { + html.style.setProperty('--contrast', mask_blur = mask !== 'unset' ? mask_blur + 'px' : 'unset'); + } + + // Mask contrast + if (properties.mask_contrast) { + html.style.setProperty('--contrast', mask_contrast = mask !== 'unset' ? properties.mask_contrast.value : 'unset'); + } + + // Mask + if (properties.mask) { + mask = properties.mask.value; + + shell.style.clipPath = text.style.clipPath = document.body.style.clipPath = 'unset'; + + clearInterval(flashlight_instance); + for (const flashlight_timeout of flashlight_timeouts) clearTimeout(flashlight_timeout); + + if (mask === 'flashlight') flashlight(); + else if (mask === 'circle') shell.style.clipPath = `circle(${mask_circle}% at 50% 50%)`; + else if (mask === 'custom') shell.style.clipPath = mask_custom; + } + + // Matrix 1 [r-g-b-a-w] + if (properties.matrix_1) { + matrix_1 = properties.matrix_1.value; + matrix_value(); + } + + // Matrix 2 [r-g-b-a-w] + if (properties.matrix_2) { + matrix_2 = properties.matrix_2.value; + matrix_value(); + } + + // Matrix 3 [r-g-b-a-w] + if (properties.matrix_3) { + matrix_3 = properties.matrix_3.value; + matrix_value(); + } + + // Matrix 4 [r-g-b-a-w] + if (properties.matrix_4) { + matrix_4 = properties.matrix_4.value; + matrix_value(); + } + }, + } + } + }; + }); + </script> +</body> + +</html> \ No newline at end of file