117 lines
3.7 KiB
JavaScript
117 lines
3.7 KiB
JavaScript
"use strict";
|
||
|
||
/**
|
||
* @author Arsen Mirzaev Tatyano-Muradovich <arsen@mirzaev.sexy>
|
||
*/
|
||
class hollow {
|
||
// Размытие дальних слоёв
|
||
blur = true;
|
||
|
||
// Затемнение дальних слоёв
|
||
blackout = false;
|
||
|
||
// Увеличение размера дальнего слоя до краёв
|
||
expand = false;
|
||
|
||
next() {
|
||
// Инициализация идентификатора активного слоя
|
||
const current = this.current();
|
||
|
||
// Генерация с защитой от выхода за предел масштабирования
|
||
this.generate(
|
||
current === document.getElementsByTagName("section").length - 1
|
||
? current
|
||
: current + 1
|
||
);
|
||
}
|
||
|
||
previous() {
|
||
// Инициализация идентификатора активного слоя
|
||
const current = this.current();
|
||
|
||
// Генерация с защитой от выхода за предел масштабирования
|
||
this.generate(current === 0 ? current : current - 1);
|
||
}
|
||
|
||
current() {
|
||
// Инициализация номера слоя
|
||
let id = 0;
|
||
|
||
for (const layer of document.getElementsByTagName("section")) {
|
||
// Перебор слоёв
|
||
|
||
// Поиск активного слоя
|
||
if (layer.style.scale === "1") return id;
|
||
|
||
// Запись идентификатора следующего слоя
|
||
++id;
|
||
}
|
||
}
|
||
|
||
generate(zoom = 0) {
|
||
// Инициализация номера слоя
|
||
let id = 1;
|
||
|
||
for (const layer of document.getElementsByTagName("section")) {
|
||
// Перебор слоёв
|
||
|
||
// Запись размера
|
||
layer.style.scale = (zoom * 0.2 + 1 - 0.2 * (id - 1)).toFixed(1);
|
||
|
||
// Запись минимального размера
|
||
if (+layer.style.scale < 0) layer.style.scale = 0;
|
||
|
||
// Запись максимального размера
|
||
if (+layer.style.scale > 2) layer.style.scale = 2;
|
||
|
||
// Запись индекса
|
||
layer.style.zIndex = zoom * 100 + 100 - id * 100;
|
||
|
||
if (this.expand && +layer.style.scale < 1) {
|
||
// Расширение слоёв до границ
|
||
|
||
// Запись степени расширения
|
||
const expand = +layer.style.scale <= 0.1 ? 0.1 : layer.style.scale;
|
||
|
||
layer.style.width = "calc(100% / " + expand + ")";
|
||
layer.style.height = "calc(100% / " + expand + ")";
|
||
layer.style.left = "calc((-100% / " + expand + " + 100%) / 2)";
|
||
layer.style.top = "calc((-100% / " + expand + " + 100%) / 2)";
|
||
}
|
||
|
||
if (+layer.style.scale <= 0 || +layer.style.scale > 1) {
|
||
// Слой вышел за рамки отображаемых размеров
|
||
|
||
// Запись прозрачности
|
||
layer.style.opacity = 0;
|
||
} else if (+layer.style.scale === 1) {
|
||
// Активный слой
|
||
|
||
// Запись эффектов
|
||
layer.style.filter = null;
|
||
|
||
// Запись прозрачности
|
||
layer.style.opacity = 1;
|
||
} else {
|
||
// Дальние слои
|
||
|
||
// Запись эффектов
|
||
if (this.blur)
|
||
layer.style.filter = "blur(" + (4 - layer.style.scale * 2) + "px)";
|
||
if (this.blackout)
|
||
layer.style.filter += "brightness(" + layer.style.scale * 100 + "%)";
|
||
|
||
// Запись прозрачности
|
||
layer.style.opacity = layer.style.scale - 0.2;
|
||
}
|
||
|
||
// Запись активности слушателей
|
||
if (id === zoom + 1) layer.style.pointerEvents = "all";
|
||
else layer.style.pointerEvents = "none";
|
||
|
||
// Запись идентификатора следующего слоя
|
||
++id;
|
||
}
|
||
}
|
||
}
|