Появление изображений
Жидкое искажение
Кадр «плывёт» при наведении — feTurbulence + feDisplacementMap с лерп-затуханием.
Наведите на фото.
Код
<svg width="0" height="0" style="position:absolute">
<filter id="turb">
<feTurbulence type="fractalNoise" baseFrequency="0 0"
numOctaves="2" result="n" id="gen"/>
<feDisplacementMap in="SourceGraphic" in2="n" scale="0"
id="map" xChannelSelector="R" yChannelSelector="G"/>
</filter>
</svg>
<img class="wavy" src="photo.jpg" style="filter:url(#turb)">
<script>
var gen = document.getElementById("gen");
var map = document.getElementById("map");
var target = 0, cur = 0;
var img = document.querySelector(".wavy");
img.addEventListener("pointerenter", function () { target = 38; });
img.addEventListener("pointerleave", function () { target = 0; });
(function loop() {
cur += (target - cur) * .09; // мягкий вход и выход
map.setAttribute("scale", cur); // сила искажения
gen.setAttribute("baseFrequency",
(0.012 + cur * 0.0004) + " " + (0.02 + cur * 0.0006));
requestAnimationFrame(loop);
})();
</script>
Промпт для ИИ
Сделай жидкое искажение фото по ховеру без WebGL: SVG-фильтр feTurbulence (fractalNoise) + feDisplacementMap, повешенный на img через filter:url(#id). В rAF лерпом (0.09) веди scale смещения от 0 к ~38 на ховере и обратно, синхронно слегка меняя baseFrequency — кадр «плывёт» как под водой и мягко успокаивается. На тачах отключай. Один фильтр можно переиспользовать на несколько картинок.