<!-- TS10 - Модификация для Тильды. Эффект заливки фона краской https://mod.tistols.com/fill-effect -->
<style>
/*цвет краски*/
:root {
--pathBg:#5805FF
}
.shape-overlays {
width: 100vw;
height: 100vh;
pointer-events: none;
position: fixed;
top: 0;
left: 0;
z-index: 1;
opacity: 0;
transition: opacity 0.5s;
}
.shape-overlays .shape-overlays__path {
fill: var(--pathBg)
}
.shape-overlays__blue {
width: 100vw;
height: 100vh;
pointer-events: none;
position: absolute;
top: 0;
left: 0
}
</style>
<svg class="shape-overlays" viewBox="0 0 100 100" preserveAspectRatio="none"><path class="shape-overlays__path" d="M 0 0 V 100 C 10 100 10 100 20 100 C 30 100 30 100 40 100 C 50 100 50 100 60 100 C 70 100 70 100 80 100 C 90 100 90 100 100 100 V 0 H 0"></path></svg>
<script>
const DURATION = 2400; // продолжительность анимации
const DELAY_POINTS_MAX = 1160; // максимальная задержка для каждой точки
const DELAY_PER_PATH = 340; // задержка для каждого path
const preTimer = 1000; //задержка начала анимации после загрузки страницы
const points = 6; //количество точек
class J {
constructor(e) {
this.elm = e;
this.path = e.querySelectorAll(".shape-overlays path");
this.numPoints = points; //
this.duration = DURATION;
this.delayPointsArray = [];
this.delayPointsMax = DELAY_POINTS_MAX;
this.delayPerPath = DELAY_PER_PATH;
this.timeStart = Date.now();
this.isOpened = false;
this.isAnimating = false;
}
toggle() {
this.isAnimating = true;
const t = Math.random() * Math.PI * 2;
for (let e = 0; e < this.numPoints; e++) {
const n = e / (this.numPoints - 1) * Math.PI * 2;
this.delayPointsArray[e] = (Math.sin(n + t) + 1) / 2 * this.delayPointsMax;
}
!this.isOpened ? this.open() : this.close();
}
open() {
this.isOpened = true;
this.elm.classList.add("is-opened");
this.timeStart = Date.now();
this.renderLoop();
}
close() {
this.isOpened = false;
this.elm.classList.remove("is-opened");
this.timeStart = Date.now();
this.renderLoop();
}
updatePath(t) {
const e = [];
for (let n = 0; n < this.numPoints; n++) {
e[n] = 100 * this.constructor.cubicInOut(Math.min(Math.max(t - this.delayPointsArray[n], 0) / this.duration, 1));
}
let i = "";
i += this.isOpened ? "M 0 0 V " + e[0] + " " : "M 0 " + e[0] + " ";
for (let r = 0; r < this.numPoints - 1; r++) {
const a = (r + 1) / (this.numPoints - 1) * 100;
const o = a - 1 / (this.numPoints - 1) * 100 / 2;
i += "C " + o + " " + e[r] + " " + o + " " + e[r + 1] + " " + a + " " + e[r + 1] + " ";
}
return i += this.isOpened ? "V 0 H 0" : "V 100 H 0";
}
render() {
if (this.isOpened) {
for (let t = 0; t < this.path.length; t++) {
this.path[t].setAttribute("d", this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * t)));
}
} else {
for (let e = 0; e < this.path.length; e++) {
this.path[e].setAttribute("d", this.updatePath(Date.now() - (this.timeStart + this.delayPerPath * (this.path.length - e - 1))));
}
}
}
renderLoop() {
this.render();
if (Date.now() - this.timeStart < this.duration + this.delayPerPath * (this.path.length - 1) + this.delayPointsMax) {
requestAnimationFrame(() => this.renderLoop());
} else {
this.isAnimating = false;
}
}
static cubicInOut(t) {
return t < 0.5 ? 4 * t * t * t : 0.5 * Math.pow(2 * t - 2, 3) + 1;
}
}
document.addEventListener("DOMContentLoaded", () => {
const svgElement = document.querySelector(".shape-overlays");
const jInstance = new J(svgElement);
setTimeout(() => {
svgElement.style.opacity = 1;
if (!jInstance.isAnimating) {
jInstance.toggle();
}
}, preTimer);
});
</script>