refreshed 2025
This commit is contained in:
47
README.md
Normal file
47
README.md
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# womb3-simplex.mjs
|
||||||
|
The library for creating creepy sticky background
|
||||||
|
|
||||||
|
## Example
|
||||||
|
```html
|
||||||
|
<canvas class="wrap"></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>
|
||||||
|
```
|
||||||
|
```js
|
||||||
|
import("/js/modules/gallery.mjs").then((module) => {
|
||||||
|
// Initializing the instance
|
||||||
|
const womb = new module.womb(document.getElementById("wrap"));
|
||||||
|
womb.init();
|
||||||
|
womb.generate();
|
||||||
|
|
||||||
|
// Initializing the process registers
|
||||||
|
let offset = 0;
|
||||||
|
let speed = 0.01;
|
||||||
|
|
||||||
|
// Starting the process
|
||||||
|
setInterval(function() {
|
||||||
|
womb.dump();
|
||||||
|
womb.generate(offset += speed);
|
||||||
|
}, 30);
|
||||||
|
|
||||||
|
// Initializing the resizing event processor
|
||||||
|
window.addEventListener('resize', function(e) {
|
||||||
|
womb.init();
|
||||||
|
womb.dump();
|
||||||
|
womb.generate(offset += speed);
|
||||||
|
}, true);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Demonstration
|
||||||
|
### [CodePen](https://codepen.io/mirzaev-sexy/pen/BaxQjYo)
|
||||||
|
<br>
|
||||||
|
|
||||||
|

|
||||||
322
womb3-simplex.js
322
womb3-simplex.js
@@ -1,192 +1,210 @@
|
|||||||
import * as noise from "https://cdn.skypack.dev/perlin.js@1.0.0";
|
import * as noise from "https://cdn.skypack.dev/perlin.js@1.0.0";
|
||||||
|
|
||||||
"use strict";
|
("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 <arsen@mirzaev.sexy>
|
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||||||
*/
|
*/
|
||||||
class womb {
|
export default class womb {
|
||||||
constructor(shell) {
|
constructor(shell) {
|
||||||
if (typeof shell === "object") {
|
if (typeof shell === "object") {
|
||||||
// Получены входные параметры
|
// Получены входные параметры
|
||||||
|
|
||||||
// Элемент для отрисовки
|
// Элемент для отрисовки
|
||||||
this.shell = shell;
|
this.shell = shell;
|
||||||
|
|
||||||
// Поле отрисовки
|
// Поле отрисовки
|
||||||
this.canvas = this.shell.getContext("2d");
|
this.canvas = this.shell.getContext("2d");
|
||||||
|
|
||||||
this.shell.width = document.body.offsetWidth;
|
this.shell.width = document.body.offsetWidth;
|
||||||
this.shell.height = document.body.offsetHeight;
|
this.shell.height = document.body.offsetHeight;
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
block = {
|
block = {
|
||||||
width: 28,
|
width: 28,
|
||||||
height: 28
|
height: 28,
|
||||||
};
|
};
|
||||||
|
|
||||||
draw(x, y, color = "red", alpha) {
|
draw(x, y, color = "red", alpha) {
|
||||||
// Запись цвета
|
// Запись цвета
|
||||||
this.canvas.fillStyle = color;
|
this.canvas.fillStyle = color;
|
||||||
|
|
||||||
// Запись прозрачности
|
// Запись прозрачности
|
||||||
this.canvas.globalAlpha = alpha;
|
this.canvas.globalAlpha = alpha;
|
||||||
|
|
||||||
// Рисование на полотне
|
// Рисование на полотне
|
||||||
this.canvas.fillRect(x, y, this.block.width, this.block.height);
|
this.canvas.fillRect(x, y, this.block.width, this.block.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
restricted = [];
|
restricted = [];
|
||||||
|
|
||||||
clean(x, y, offset, to = 0, smooth = 0.3, ticks = 3) {
|
clean(x, y, offset, to = 0, smooth = 0.3, ticks = 3) {
|
||||||
// Инициализация актуального значения альфа-канала
|
// Инициализация актуального значения альфа-канала
|
||||||
const alpha = 0.5 + noise.simplex2(x + offset, y + offset) / 2;
|
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.restricted.push({
|
||||||
this.canvas.clearRect(0, 0, this.shell.width, this.shell.height);
|
x,
|
||||||
}
|
y,
|
||||||
|
alpha,
|
||||||
|
from: alpha,
|
||||||
|
to,
|
||||||
|
smooth,
|
||||||
|
limit: ticks,
|
||||||
|
ticks: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
init() {
|
dump() {
|
||||||
// Запись размеров полотна
|
// Очистка полотна
|
||||||
this.shell.width = document.body.offsetWidth;
|
this.canvas.clearRect(0, 0, this.shell.width, this.shell.height);
|
||||||
this.shell.height = document.body.offsetHeight;
|
}
|
||||||
|
|
||||||
// Генерация шума
|
init() {
|
||||||
// noise.seed(Math.random());
|
// Запись размеров полотна
|
||||||
}
|
this.shell.width = document.body.offsetWidth;
|
||||||
|
this.shell.height = document.body.offsetHeight;
|
||||||
|
|
||||||
generate(offset = 0, color = 'red') {
|
// Генерация шума
|
||||||
for (let y = 0; y < this.shell.height; y += this.block.height) {
|
// noise.seed(Math.random());
|
||||||
// Перебор колонок
|
}
|
||||||
|
|
||||||
for (let x = 0; x < this.shell.width; x += this.block.width) {
|
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) {
|
this.draw(
|
||||||
// Перебор колонок
|
x,
|
||||||
|
y,
|
||||||
|
color,
|
||||||
|
0.5 + noise.simplex2(x + offset, y + offset) / 2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (let x = 0; x < this.shell.width; x += this.block.width) {
|
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) {
|
// Инициализация альфа-канала
|
||||||
// Перебор запрещённых блоков
|
let alpha = 0.5 + noise.simplex2(x + offset, y + offset) / 2;
|
||||||
|
|
||||||
// Инициализация блока
|
|
||||||
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) {
|
for (const i in this.restricted) {
|
||||||
// Процесс "затухание"
|
// Перебор запрещённых блоков
|
||||||
|
|
||||||
// Запись нового значения альфа-канала
|
// Инициализация блока
|
||||||
block.alpha -= block.smooth;
|
const block = this.restricted[i];
|
||||||
|
|
||||||
// Запись альфа-канала для рисования
|
if (x === block.x && y === block.y) {
|
||||||
alpha = block.alpha;
|
// Блок найден
|
||||||
} else {
|
|
||||||
// Завершён процесс "затухание"
|
|
||||||
|
|
||||||
if (block.ticks < block.limit) {
|
|
||||||
// Процесс "ожидание"
|
|
||||||
|
|
||||||
// Инкрементация значения тиков
|
|
||||||
++block.ticks;
|
|
||||||
|
|
||||||
// Запись альфа-канала для рисования
|
if (block.smooth === 0) {
|
||||||
alpha = block.to;
|
// Резкий переход
|
||||||
} else {
|
|
||||||
// Завершён процесс "ожидание"
|
|
||||||
|
|
||||||
if (block.ticks >= block.limit && block.alpha + block.smooth < block.from) {
|
|
||||||
// Процесс "появление"
|
|
||||||
|
|
||||||
// Запись нового значения альфа-канала
|
if (block.ticks <= block.limit) {
|
||||||
block.alpha += block.smooth;
|
// Процесс "затухание"
|
||||||
|
|
||||||
// Запись альфа-канала для рисования
|
// Запись альфа-канала для рисования
|
||||||
alpha = block.alpha;
|
alpha = block.to;
|
||||||
} else {
|
|
||||||
// Завершён процесс "появление"
|
|
||||||
|
|
||||||
// Запись альфа-канала для рисования
|
// Инкрементация значения тиков
|
||||||
alpha = block.from;
|
++block.ticks;
|
||||||
|
} else {
|
||||||
|
// Процесс "появление"
|
||||||
|
|
||||||
// Удаление из массива запрещённых для рисования блоков
|
// Запись альфа-канала для рисования
|
||||||
delete this.restricted[i];
|
alpha = block.from;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.draw(x, y, color, alpha);
|
// Удаление из массива запрещённых для рисования блоков
|
||||||
}
|
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(
|
document.dispatchEvent(
|
||||||
new CustomEvent("womb.loaded", {
|
new CustomEvent("womb.loaded", {
|
||||||
detail: { womb }
|
detail: { womb },
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user