Анимация превращения фигуры

Видеоинструкция по подключению

Пошаговая инструкция с подключением кода

ID Шаблона
Категория
Последнее обновление
23 Марта, 2026
Бесплатно, Эффекты, GSAP
127518316
Скриншоты шаблона
Шаг 1
Создаём Zero-блок и вешаем на него класс uc-svg-morph-1 (-1,-2,3 и тд, если нужно несколько таких анимаций)
Шаг 2
В Zero-блоке создаём HTML-блок и помещаем в него код
CSS / JS

<!--Поместить в Zero-блок (HTML)-->
<!--1200+-->
<svg viewBox="0 0 1200 800"
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
class="morph-svg morph-1200">
<g class="shape-rotate">
<path class="morph-start"
d="M607.336 390.982H638V407.336H607.336V438H590.982V407.336H561V390.982H590.982V361H607.336V390.982Z"
fill="#fff"/>
</g>
<path class="morph-middle"
d="M597 397H603.25V403.25H597V397Z"
opacity="0"/>
<path class="morph-end"
d="M0 0H1200V800H0V0Z"
fill="#ff0000"
opacity="0"/>
</svg>
<!--960-->
<svg viewBox="0 0 1200 800"
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
class="morph-svg morph-960">
<g class="shape-rotate">
<path class="morph-start"
d="M607.336 390.982H638V407.336H607.336V438H590.982V407.336H561V390.982H590.982V361H607.336V390.982Z"
fill="#fff"/>
</g>
<path class="morph-middle"
d="M597 397H603.25V403.25H597V397Z"
opacity="0"/>
<path class="morph-end"
d="M0 0H1200V800H0V0Z"
fill="#ff0000"
opacity="0"/>
</svg>
<!--640-->
<svg viewBox="0 0 1200 800"
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
class="morph-svg morph-640">
<g class="shape-rotate">
<path class="morph-start"
d="M606.522 391.867H634V406.522H606.522V434H591.867V406.522H565V391.867H591.867V365H606.522V391.867Z"
fill="#fff"/>
</g>
<path class="morph-middle"
d="M597 397H603.25V403.25H597V397Z"
opacity="0"/>
<path class="morph-end"
d="M0 0H1200V800H0V0Z"
fill="#ff0000"
opacity="0"/>
</svg>
<!--480-->
<svg viewBox="0 0 1200 800"
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
class="morph-svg morph-480">
<g class="shape-rotate">
<path class="morph-start"
d="M603.876 394.743H621V403.876H603.876V421H594.743V403.876H578V394.743H594.743V378H603.876V394.743Z"
fill="#fff"/>
</g>
<path class="morph-middle"
d="M597 397H603.25V403.25H597V397Z"
opacity="0"/>
<path class="morph-end"
d="M0 0H1200V800H0V0Z"
fill="#ff0000"
opacity="0"/>
</svg>
<!--320-->
<svg viewBox="0 0 1200 800"
width="100%"
height="100%"
preserveAspectRatio="xMidYMid slice"
class="morph-svg morph-320">
<g class="shape-rotate">
<path class="morph-start"
d="M602.248 396.514H613V402.248H602.248V413H596.514V402.248H586V396.514H596.514V386H602.248V396.514Z"
fill="#fff"/>
</g>
<path class="morph-middle"
d="M597 397H603.25V403.25H597V397Z"
opacity="0"/>
<path class="morph-end"
d="M0 0H1200V800H0V0Z"
fill="#ff0000"
opacity="0"/>
</svg>
Шаг 3
В этом же Zero-блоке создаём два шейпа с классами morph-top и morph-bottom Они будут служить в качестве вылетов и триггерами для запуска и окончания анимации. morph-top должен касаться верхней границы Zero-блока, а нижняя его граница будет служить триггером на запуск. morph-bottom выравниваем по нижней границе Zero-блока, его верхняя граница будет окончанием анимации. Растояние, что у вас останется между ними и будет продолжительностью анимации
Шаг 4
На HTML-блок вешаем доп класс morph
Шаг 5
Дополнительно анимируем сам HTML-блок с помощью пошаговой анимации. Я немного его сдвигаю в сторону, также фиксирую во время самой анимации
Шаг 6
Чтобы заменить фигуру, необходимо изменить путь SVG, который выглядит примерно так: d="M0 0H1200V800H0V0Z". Для этого выгрузите из редактора frame размером 1200×800 px с нужной SVG-фигурой. Перед экспортом убедитесь, что все элементы фигуры объединены в один контур
Шаг 7
Откройте SVG-файл через Блокнот и скопируйте значение пути
Шаг 8
Заменяем путь на свой
Шаг 9
В конце страницы или футере добавляем код, через блок T123
CSS / JS

<!--Анимация превращения фигуры
https://mt-webdesign.ru/morph-->
<style>
.morph, .morph div {
display: flex !important;
align-items: center;
justify-content: center;
pointer-events: none;
}
.morph-svg{
opacity:0;
position:absolute;
pointer-events:none;
}
.morph-svg{
top:0;
left:0;
width:100vw;
height:100vh;
height:100dvh;
}
.morph-svg.active{
opacity:1;
position:relative;
}
@media (min-width:1200px){
.morph-1200{
opacity:1;
position:relative;
}
}
@media (min-width:960px) and (max-width:1199px){
.morph-960{
opacity:1;
position:relative;
}
}
@media (min-width:640px) and (max-width:959px){
.morph-640{
opacity:1;
position:relative;
}
}
@media (min-width:480px) and (max-width:639px){
.morph-480{
opacity:1;
position:relative;
}
}
@media (max-width:479px){
.morph-320{
opacity:1;
position:relative;
}
}
</style>
<script src="https://matilda-design.ru/library/GSAP.js"></script>
<script src="https://matilda-design.ru/library/ScrollTrigger.js"></script>
<script src="https://assets.codepen.io/16327/MorphSVGPlugin3.min.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function(){
gsap.registerPlugin(ScrollTrigger, MorphSVGPlugin);
function initMorphSVG(container){
const triggerStart = container.querySelector(".morph-top");
const triggerEnd = container.querySelector(".morph-bottom");
const activeSVG = [...container.querySelectorAll(".morph-svg")]
.find(svg => getComputedStyle(svg).opacity == "1");
if(!activeSVG) return;
const shapeStart = activeSVG.querySelector(".morph-start");
const shapeSquare = activeSVG.querySelector(".morph-middle");
const shapeRect = activeSVG.querySelector(".morph-end");
const rotateWrap = activeSVG.querySelector(".shape-rotate");
if(!triggerStart || !triggerEnd) return;
function getEffectiveHeight(elem){
const height = elem.offsetHeight;
const zoom = parseFloat(getComputedStyle(elem).zoom || "1");
return height * zoom;
}
const offsetTop = getEffectiveHeight(triggerStart);
const offsetBottom = getEffectiveHeight(triggerEnd);
const containerHeight = container.offsetHeight;
const scrollDistance = containerHeight - offsetTop - offsetBottom;
const zoom = parseFloat(getComputedStyle(document.body).zoom || "1");
function getHoldValue(){
const w = window.innerWidth;
if (w >= 1200) return 1500;
if (w >= 960) return 1100;
if (w >= 640) return 1400;
if (w >= 480) return 1200;
return 1200;
}
const holdPx = getHoldValue() * zoom;
let morphPx = (scrollDistance - holdPx) / 2;
morphPx = Math.max(morphPx, 0);
const stepRatio = morphPx / scrollDistance;
const holdRatio = holdPx / scrollDistance;
const holdStart = offsetTop + morphPx;
const holdEnd = holdStart + holdPx;
gsap.set(rotateWrap,{
transformOrigin:"50% 50%"
});
const tl = gsap.timeline({
scrollTrigger:{
trigger:container,
start:`top+=${offsetTop} center`,
end:`top+=${containerHeight-offsetBottom} center`,
scrub:true,
markers:false,
invalidateOnRefresh:true
}
});
tl.to(shapeStart,{
morphSVG:{
shape:shapeSquare,
shapeIndex:"auto"
},
fill:"#fff",
ease:"none",
duration:stepRatio
});
tl.to(rotateWrap,{
rotate:360,
ease:"none",
duration:stepRatio
},"<");
tl.to({},{
duration:holdRatio
});
tl.to(shapeStart,{
morphSVG:{
shape:shapeRect,
shapeIndex:"auto"
},
fill:"#DFFF5C",
ease:"none",
duration:stepRatio
});
ScrollTrigger.create({
trigger:container,
start:`top+=${holdStart} center`,
markers:false
});
ScrollTrigger.create({
trigger:container,
start:`top+=${holdEnd} center`,
markers:false
});
}
document.querySelectorAll('[class*="uc-svg-morph-"]').forEach(container=>{
initMorphSVG(container);
});
window.addEventListener("resize", ()=>{
ScrollTrigger.refresh();
});
});
</script>

Более подробные настройки, возможности взаимодействия и подключение в видео

Инструкция с копированием шаблона к себе

Создаём новую страницу на сайте
Шаг 1
Скроллим в самый низ и нажимаем кнопку «Указать ID шаблона»
Шаг 2
В графе указываем номер шаблона (ID Шаблона), нажимаем кнопку «Выбрать»
Шаг 3