<style>
.t396__elem[class*="joker-card-anim-"] {
perspective: 2000px;
transform-style: preserve-3d;
}
.t396__elem[class*="joker-content-after-"] {
zoom: 0 !important;
}
[class^="joker-wrapper-"] {
width: 100%;
height: 100%;
}
[class^="joker-wrapper-inside-"] {
perspective: 2000px;
backface-visibility: hidden;
width: 100%;
height: 100%;
transform-style: preserve-3d;
}
.t396__elem[class*="joker-card-after-"] {
transform: rotateY(-180deg);
}
}
[class^="joker-card-before-"] .tn-atom,
[class^="joker-card-after-"] .tn-atom {
backface-visibility: hidden;
}
[class^="joker-card-before-wrapper-"] div,
[class^="joker-card-after-wrapper-"] div,
.t396__elem[class*="joker-card-after-"],
.t396__elem[class*="joker-card-before-"] {
perspective: 2000px;
backface-visibility: hidden;
transform-style: preserve-3d;
}
[class^="joker-card-before-wrapper-"],
[class^="joker-card-after-wrapper-"] {
perspective: 2000px;
transform-style: preserve-3d;
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
}
[class^="joker-card-after-wrapper-"] {
transform: rotateY(-180deg);
}
[class^="joker-inside-"] {
backface-visibility: hidden;
}
[class^="joker-"] {
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
perspective: 2000px;
transform-style: preserve-3d;
}
@media only screen and (min-width: 320px) {
[class^="joker-card-before-"],
[class^="joker-card-after-"] {
backface-visibility: hidden;
zoom: 0 !important;
}
[class^="joker-card-before-wrapper-"] div,
[class^="joker-card-after-wrapper-"] div,
.t396__elem[class*="joker-card-after-"],
.t396__elem[class*="joker-card-before-"] {
zoom: 0 !important;
}
}
</style>
<script src="https://matilda-design.ru/library/GSAP.js"></script>
<script src="https://matilda-design.ru/library/ScrollTrigger.js"></script>
<script>
document.addEventListener("DOMContentLoaded", function () {
gsap.registerPlugin(ScrollTrigger);
function initAnimation() {
ScrollTrigger.getAll().forEach(trigger => trigger.kill());
gsap.globalTimeline.clear();
const isLarge = window.matchMedia('(min-width: 1200px)').matches;
const isLaptop = window.matchMedia('(min-width: 960px) and (max-width: 1199px)').matches;
const isTablet = window.matchMedia('(min-width: 640px) and (max-width: 959px)').matches;
const isSmallTablet = window.matchMedia('(min-width: 480px) and (max-width: 639px)').matches;
const isMobile = window.matchMedia('(min-width: 320px) and (max-width: 479px)').matches;
let initialTransforms;
// Начальное положение элементов
// 320px - 479px
if (isMobile) {
initialTransforms = {
1: { x: 0, y: 0, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
2: { x: 0, y: 430, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
3: { x: 0, y: 860, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
4: { x: 0, y: 1290, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
};
// 480px - 639px
} else if (isSmallTablet) {
initialTransforms = {
1: { x: -120, y: 0, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
2: { x: 120, y: 0, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
3: { x: -120, y: 330, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
4: { x: 120, y: 330, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
};
// 640px - 959px
} else if (isTablet) {
initialTransforms = {
1: { x: -160, y: 0, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
2: { x: 160, y: 0, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
3: { x: -160, y: 440, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
4: { x: 160, y: 440, z: 0, rotation: 0, rotationX: 0, rotationY: 0, rotationZ: 0 },
};
// 960px - 1199px
} else if (isLaptop) {
initialTransforms = {
1: { x: 0, y: 0, z: 20, rotation: 5, rotationX: 0, rotationY: 0, rotationZ: 0 },
2: { x: 0, y: 0, z: 10, rotation: 2, rotationX: 0, rotationY: 0, rotationZ: 0 },
3: { x: 0, y: 0, z: 0, rotation: -2, rotationX: 0, rotationY: 0, rotationZ: 0 },
4: { x: 0, y: 0, z: -10, rotation: -5, rotationX: 0, rotationY: 0, rotationZ: 0 },
};
// 1200px >
} else if (isLarge) {
initialTransforms = {
1: { x: 0, y: 0, z: 20, rotation: 5, rotationX: 0, rotationY: 0, rotationZ: 0 },
2: { x: 0, y: 0, z: 10, rotation: 2, rotationX: 0, rotationY: 0, rotationZ: 0 },
3: { x: 0, y: 0, z: 0, rotation: -2, rotationX: 0, rotationY: 0, rotationZ: 0 },
4: { x: 0, y: 0, z: -10, rotation: -5, rotationX: 0, rotationY: 0, rotationZ: 0 },
};
}
function getInitialGsapProps(index) {
const val = initialTransforms[index] || {};
return {
x: val.x || 0,
y: val.y || 0,
z: val.z || 0,
rotation: val.rotation || 0,
rotationX: val.rotationX || 0,
rotationY: val.rotationY || 0,
rotationZ: val.rotationZ || 0,
transformOrigin: 'center center',
};
}
function animateCard(sel, trig, step1, step2, initProps) {
gsap.set(sel, initProps);
gsap.timeline({
scrollTrigger: {
trigger: trig,
start: 'top center',
end: 'bottom center',
scrub: 1,
markers: false
}
})
.to(sel, { ...step1, ease: 'none' }, 0)
.to(sel, { ...step2, ease: 'none' }, 0.5);
}
// Конечное положение элементов
function getAnimParams() {
// 320px - 479px
if (isMobile) {
return [
[{ y:0, rotationY:0 }, {rotationY:180 }],
[{ y:430, rotationY:0, delay:0.4}, { rotationY:180, delay: 0.4}],
[{ y:860, rotationY:0 }, { rotationY:180, delay: 5 }],
[{ y:1290, rotationY:0 }, { rotationY:180, delay: 7.5 }]
];
// 480px - 639px
} else if (isSmallTablet) {
return [
[{ x:-120, rotationY:0 }, { rotationY:180 }],
[{ x:120, rotationY:0, delay: 0.4 }, { rotationY:180, delay: 0.4 }],
[{ x:-120, rotationY:0, y:330, delay: 0.8 }, { rotationY:180, delay: 0.8 }],
[{ x:120, rotationY:0, y:330, delay: 1.2 }, { rotationY:180, delay: 1.2 }]
];
// 640px - 959px
} else if (isTablet) {
return [
[{ x:-160, rotationY:0 }, { rotationY:180 }],
[{ x:160, rotationY:0, delay: 0.4 }, { rotationY:180, delay: 0.4 }],
[{ x:-160, y: 440, rotationY:0, delay: 0.8 }, { rotationY:180, delay: 0.8 }],
[{ x:160, y: 440, rotationY:0, delay: 1.2 }, { rotationY:180, delay: 1.2 }]
];
// 960px - 1199px
} else if (isLaptop) {
return [
[{ x:300, rotationY:30, rotationX:10, rotationZ:20 }, { x:357, rotationY:180, rotationX:0, rotationZ:0 }],
[{ x:100, rotationY:30, rotationX:10, rotationZ:15 }, { x:120, rotationY:180, rotationX:0, rotationZ:0 }],
[{ x:-100, rotationY:30, rotationX:10, rotationZ:0 }, { x:-120, rotationY:180, rotationX:0, rotationZ:0 }],
[{ x:-300, rotationY:30, rotationX:10, rotationZ:-15 }, { x:-357, rotationY:180, rotationX:0, rotationZ:0 }]
];
// 1200px >
} else if (isLarge) {
return [
[{ x:300, rotationY:30, rotationX:10, rotationZ:20 }, { x:405, rotationY:180, rotationX:0, rotationZ:0 }],
[{ x:100, rotationY:30, rotationX:10, rotationZ:15 }, { x:135, rotationY:180, rotationX:0, rotationZ:0 }],
[{ x:-100, rotationY:30, rotationX:10, rotationZ:0 }, { x:-135, rotationY:180, rotationX:0, rotationZ:0 }],
[{ x:-300, rotationY:30, rotationX:10, rotationZ:-15 }, { x:-405, rotationY:180, rotationX:0, rotationZ:0 }]
];
}
}
let i = 1, group = 1, cardsPerGroup = 4;
while (true) {
const cards = [];
for (let n = 0; n < cardsPerGroup; n++) {
const after = document.querySelectorAll(`.joker-card-after-${i}`);
const before = document.querySelectorAll(`.joker-card-before-${i}`);
if (!after.length || !before.length) break;
const card = document.createElement('div');
card.classList.add('joker-1', `joker-card-${i}`);
after[0].parentNode.insertBefore(card, after[0]);
after.forEach(el => card.appendChild(el));
before.forEach(el => card.appendChild(el));
cards.push(card);
i++;
}
if (!cards.length) break;
const wrapper = document.createElement('div');
wrapper.className = `joker-wrapper-${group}`;
const inside = document.createElement('div');
inside.className = `joker-wrapper-inside-${group}`;
wrapper.appendChild(inside);
cards.forEach(c => inside.appendChild(c));
const container = document.querySelector(`.joker-wrapper-inside-anim-${group} .tn-atom`);
if (!container) break;
container.appendChild(wrapper);
const animParams = getAnimParams();
cards.forEach((_, idx) => {
const cardIdx = (group - 1) * cardsPerGroup + idx + 1;
animateCard(
`.joker-card-${cardIdx}`,
`.joker-trigger-${group}`,
animParams[idx][0],
animParams[idx][1],
getInitialGsapProps(idx + 1)
);
});
group++;
}
}
initAnimation();
let rsz;
window.addEventListener('resize', () => {
clearTimeout(rsz);
rsz = setTimeout(initAnimation, 300);
});
});
$(document).ready(function() {
$('[class*="joker-card-after-"]').each(function() {
var classes = $(this).attr('class').split(/\s+/);
var cardNumber = null;
classes.forEach(function(c) {
var match = c.match(/^joker-card-after-(\d+)$/);
if (match) cardNumber = match[1];
});
if (cardNumber) {
var cardAtom = $(this).find('.tn-atom');
var content = $('.joker-content-after-' + cardNumber);
if (cardAtom.length && content.length) {
cardAtom.addClass('joker-cont-' + cardNumber);
content.appendTo(cardAtom);
}
}
});
});
</script>