I have checked and come up with a solution.
First of all, Add this two scripts into your theme.liquid file. (Ignore if you have already added)
HTML : Please open the code file, where your card is located. Add the below HTML classes to the cards. So the CSS and js can be applied automatically on to those classes.
CSS : Please add this given CSS into your style.css or any other named CSS file which you are using.
.icon {
display: inline-block;
width: 1em;
height: 1em;
stroke-width: 0;
stroke: currentColor;
fill: currentColor;
}
.blend-image {
filter: brightness(250%) grayscale(100%);
mix-blend-mode: screen;
}
.center-image {
width: 100%;
min-height: 100%;
position: absolute;
top: 50%;
transform: translateY(-50%);
object-fit: cover;
}
.slick-slide {
padding: 2em .5em;
}
.card-slider {
margin: auto;
width: 100%;
}
.card {
background: #fff;
display: flex;
padding: 2em;
flex-direction: column;
align-items: flex-start;
justify-content: flex-end;
border-radius: $card__border-radius;
overflow: hidden;
position: relative;
z-index: 1;
height: 350px;
box-shadow: 0 30px 50px -25px rgba(0,0,0,0.25);
}
.card > * {
transition: opacity 350ms;
}
.card &--opened > *{
opacity: 0;
}
.card__background {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
background: $background-color;
z-index: -1;
text-align: left;
}
.card__background img {
@extend .center-image;
@extend .blend-image;
}
.card__background &::after {
content:'';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: linear-gradient(to top, #fff 0, rgba(255,255,255,0) 70%);
}
.card__category {
text-transform: uppercase;
color: #fff;
background: $background-color;
font-size: 0.85em;
font-weight: 600;
padding: 0.2em 0.5em 0.25em;
}
.card__title {
text-transform: uppercase;
margin: 0.5em 0;
color: #2e5f80;
}
.card__duration {
color: #6f7070;
}
.modal-wrapper, .overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.modal-wrapper {
display: flex;
}
.overlay {
background: rgba(0,0,0,0.5);
transition: opacity 150ms ease;
}
.modal {
overflow: hidden;
position: relative;
margin: auto;
width: 90vw;
height: $card__modal-height;
max-width: $card__modal-max-width;
background: #fff;
border-radius: $card__border-radius;
}
.modal__scroll-area {
height: inherit;
overflow: auto;
border-radius: inherit;
position: relative;
z-index: 1;
}
.modal__close-button {
background: transparent;
border: none;
margin-bottom: auto;
color: #2e5f80;
position: absolute;
top: 0;
right: 0;
padding: 2em;
z-index: 2;
}
.modal__header {
text-align: center;
position: relative;
display: flex;
padding: .5em;
flex-direction: column;
justify-content: flex-end;
align-items: center;
min-height: $card__modal-header-height;
z-index: 1;
}
.modal__content {
padding: 2em;
color: #666;
line-height: 1.5;
}
[data-modal-state="closed"] {
}
[data-modal-state="closed"] .modal-wrapper {
pointer-events: none;
}
[data-modal-state="closed"] .overlay {
pointer-events: none;
}
[data-modal-state="closed"] .modal {
opacity: 0;
}
[data-modal-state="closed"] .overlay {
opacity: 0;
}
[data-modal-state="opening"],[data-modal-state="closing"] .modal__header, .modal__content, .modal__close-button {
opacity: 0;
}
[data-modal-state="opening"] .overlay {
transition: opacity 500ms ease;
}
[data-modal-state="closing"] .overlay {
opacity: 0;
transition: opacity 500ms ease;
}
[data-modal-state="open"] .modal__header, .modal__content {
transition: opacity 450ms;
}
JS : Please add this given JS code into your theme.js file.
$('.card-slider').slick({
slidesToShow:3,
autoplay: true,
slidesToScroll:1,
dots: false,
responsive:[
{
breakpoint: 768,
settings: {
slidesToShow: 2
}
},
{
breakpoint: 600,
settings: {
slidesToShow: 1
}
}
]
});
let cards = document.querySelectorAll('.card');
let card;
let modal = document.querySelector('.modal');
let closeButton = document.querySelector('.modal__close-button');
let page = document.querySelector('.page');
const cardBorderRadius = 20;
const openingDuration = 600; //ms
const closingDuration = 600; //ms
const timingFunction = 'cubic-bezier(.76,.01,.65,1.38)';
var Scrollbar = window.Scrollbar;
Scrollbar.init(document.querySelector('.modal__scroll-area'));
function flipAnimation(first, last, options) {
let firstRect = first.getBoundingClientRect();
let lastRect = last.getBoundingClientRect();
let deltas = {
top: firstRect.top - lastRect.top,
left: firstRect.left - lastRect.left,
width: firstRect.width / lastRect.width,
height: firstRect.height / lastRect.height
};
return last.animate([{
transformOrigin: 'top left',
borderRadius:`
${cardBorderRadius/deltas.width}px / ${cardBorderRadius/deltas.height}px`,
transform: `
translate(${deltas.left}px, ${deltas.top}px)
scale(${deltas.width}, ${deltas.height})
`
},{
transformOrigin: 'top left',
transform: 'none',
borderRadius: `${cardBorderRadius}px`
}],options);
}
cards.forEach((item)=>{
item.addEventListener('click',(e)=>{
jQuery('.card-slider').slick('slickPause');
card = e.currentTarget;
page.dataset.modalState = 'opening';
card.classList.add('card--opened');
card.style.opacity = 0;
document.querySelector('body').classList.add('no-scroll');
let animation = flipAnimation(card,modal,{
duration: openingDuration,
easing: timingFunction,
fill:'both'
});
animation.onfinish = ()=>{
page.dataset.modalState = 'open';
animation.cancel();
};
});
});
closeButton.addEventListener('click',(e)=>{
page.dataset.modalState = 'closing';
document.querySelector('body').classList.remove('no-scroll');
let animation = flipAnimation(card,modal,{
duration: closingDuration,
easing: timingFunction,
direction: 'reverse',
fill:'both'
});
animation.onfinish = ()=>{
page.dataset.modalState = 'closed';
card.style.opacity = 1;
card.classList.remove('card--opened');
jQuery('.card-slider').slick('slickPlay');
animation.cancel();
};
});
I hope It works for you.
Happy Coding!!
