diff --git a/womb3-simplex.js b/womb3-simplex.js new file mode 100644 index 0000000..9e846b9 --- /dev/null +++ b/womb3-simplex.js @@ -0,0 +1,196 @@ +import * as noise from "https://cdn.skypack.dev/perlin.js@1.0.0"; + +"use strict"; + +/** + * @author Arsen Mirzaev Tatyano-Muradovich + */ +class womb { + constructor(shell) { + if (typeof shell === "object") { + // Получены входные параметры + + // Элемент для отрисовки + this.shell = shell; + + // Поле отрисовки + this.canvas = this.shell.getContext("2d"); + + this.shell.width = window.innerWidth; + this.shell.height = window.innerHeight; + + return this; + } + + return null; + } + + block = { + width: 28, + height: 28 + }; + + draw(x, y, color = "red", alpha) { + // Запись цвета + this.canvas.fillStyle = color; + + // Запись прозрачности + this.canvas.globalAlpha = alpha; + + // Рисование на полотне + this.canvas.fillRect(x, y, this.block.width, this.block.height); + } + + restricted = []; + + clean(x, y, offset, to = 0, smooth = 0.3, ticks = 3) { + // Инициализация актуального значения альфа-канала + const alpha = 0.5 + noise.simplex2(x + offset, y + offset) / 2; + + // Запись в реестр + this.restricted.push({ + x, + y, + alpha, + from: alpha, + to, + smooth, + limit: ticks, + ticks: 0 + }); + } + + dump() { + // Очистка полотна + this.canvas.clearRect(0, 0, this.shell.width, this.shell.height); + } + + init() { + // Запись размеров полотна + this.shell.width = window.innerWidth; + this.shell.height = window.innerHeight; + + // Генерация шума + // noise.seed(Math.random()); + } + + generate(offset = 0) { + for (let y = 0; y < this.shell.height; y += this.block.height) { + // Перебор колонок + + for (let x = 0; x < this.shell.width; x += this.block.width) { + // Перебор строк + + // Рисование на полотне + this.draw( + x, + y, + "red", + 0.5 + noise.simplex2(x + offset, y + offset) / 2 + ); + } + } + } + + interactive(offset = 0) { + for (let y = 0; y < this.shell.height; y += this.block.height) { + // Перебор колонок + + for (let x = 0; x < this.shell.width; x += this.block.width) { + // Перебор строк + + // Инициализация альфа-канала + let alpha = 0.5 + noise.simplex2(x + offset, y + offset) / 2; + + for (const i in this.restricted) { + // Перебор запрещённых блоков + + // Инициализация блока + const block = this.restricted[i]; + + if (x === block.x && y === block.y) { + // Блок найден + + if (x === 0 && y === 0) { + console.log(block.alpha); + } + + if (block.smooth === 0) { + // Резкий переход + + if (block.ticks <= block.limit) { + // Процесс "затухание" + + // Запись альфа-канала для рисования + alpha = block.to; + + // Инкрементация значения тиков + ++block.ticks; + } else { + // Процесс "появление" + + // Запись альфа-канала для рисования + alpha = block.from; + + // Удаление из массива запрещённых для рисования блоков + delete this.restricted[i]; + } + } else { + // Плавный переход + + if (block.ticks < block.limit && block.alpha - block.smooth > block.to) { + // Процесс "затухание" + + // Запись нового значения альфа-канала + block.alpha -= block.smooth; + + // Запись альфа-канала для рисования + alpha = block.alpha; + } else { + // Завершён процесс "затухание" + + if (block.ticks < block.limit) { + // Процесс "ожидание" + + // Инкрементация значения тиков + ++block.ticks; + + // Запись альфа-канала для рисования + alpha = block.to; + } else { + // Завершён процесс "ожидание" + + if (block.ticks >= block.limit && block.alpha + block.smooth < block.from) { + // Процесс "появление" + + // Запись нового значения альфа-канала + block.alpha += block.smooth; + + // Запись альфа-канала для рисования + alpha = block.alpha; + } else { + // Завершён процесс "появление" + + // Запись альфа-канала для рисования + alpha = block.from; + + // Удаление из массива запрещённых для рисования блоков + delete this.restricted[i]; + } + } + } + } + } + } + + this.draw(x, y, "red", alpha); + } + } + } +} + +document.dispatchEvent( + new CustomEvent("womb.loaded", { + detail: { womb } + }) +);