import * as noise from "https://cdn.skypack.dev/perlin.js@1.0.0"; ("use strict"); /** * @name womb3-simplex.mjs * * @description * The library for creating creepy sticky background * * @class * @public * * {@link https://git.svoboda.works/mirzaev/womb3-simplex.mjs} * {@link https://codepen.io/mirzaev-sexy/pen/BaxQjYo} * * @license http://www.wtfpl.net/ Do What The Fuck You Want To Public License * @author Arsen Mirzaev Tatyano-Muradovich */ export default class womb { constructor(shell) { if (typeof shell === "object") { // Получены входные параметры // Элемент для отрисовки this.shell = shell; // Поле отрисовки this.canvas = this.shell.getContext("2d"); this.shell.width = document.body.offsetWidth; this.shell.height = document.body.offsetHeight; 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 = document.body.offsetWidth; this.shell.height = document.body.offsetHeight; // Генерация шума // noise.seed(Math.random()); } generate(offset = 0, color = "red") { 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, color, 0.5 + noise.simplex2(x + offset, y + offset) / 2 ); } } } interactive(offset = 0, color = "red") { 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 (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, color, alpha); } } } } document.dispatchEvent( new CustomEvent("womb.loaded", { detail: { womb }, }) );