GSAP как изменять значения параметров анимации (Tween.vars) динамически?
JavaScript библиотека GSAP
Есть переменная типа Tween
let tweenMoveRight = gsap.to('#block', { x: 200 })
Могу ли я динамически изменять параметры этой анимации, вроде:
tweenMoveRight.vars.x = 400
Чтобы когда я снова запускал эту анимацию tweenMoveRight.play() блок сдвигался согласно новым параметрам (в данном случае сдвиг вправо на 400 пикселей, вместо 200)
Более конкретный пример: https://codepen.io/mazauka537/pen/gOeWJjK. В данном примере при нажатии на карточку она открывается, и закрывается при повторном нажатии. Однако если открыть карточку, затем закрыть её, после чего проскролить контейнер с карточками и попробовать снова открыть ту же карточку, то анимация будет проигрываться с предыдущей позиции карточки (не учитывая скролл).
let topSection = document.querySelector('.top-section')
let blocks = Array.from(document.querySelectorAll('.block'))
let isAnyCardOpened = false
blocks.forEach(block => {
let cardWrapper = block.querySelector('.card__wrapper')
let card = block.querySelector('.card')
let isCurrentCardOpened = false
let timeLineOpenCard = gsap.timeline({paused: true})
.fromTo(card, {
borderLeftWidth: 0,
left: () => cardWrapper.getBoundingClientRect().x,
top: () => cardWrapper.getBoundingClientRect().y,
width: cardWrapper.offsetWidth,
height: cardWrapper.offsetHeight,
}, {
position: 'fixed',
ease: 'none',
borderLeftWidth: 300,
left: 0,
top: 0,
width: document.body.offsetWidth * 0.45,
height: document.body.offsetHeight,
onReverseComplete: () => card.style.position = 'static',
onComplete: () => card.style.position = 'fixed',
})
.to(topSection, {
top: 0,
})
// isAnyCardOpened предназначена для того чтобы нельзя было открыть несколько карточек одновременно
card.onclick = async () => {
if (isCurrentCardOpened) {
isCurrentCardOpened = false
isAnyCardOpened = false
timeLineOpenCard.reverse()
} else {
if (isAnyCardOpened)
return
isCurrentCardOpened = true
isAnyCardOpened = true
timeLineOpenCard.play()
}
}
})
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
height: 100vh;
background: #2B2B2B;
display: flex;
justify-content: center;
align-items: center;
}
.btn {
padding: 20px;
min-height: 200px;
font-size: 40px;
color: #ccc;
border-bottom: 3px solid #2B2B2B;
text-align: center;
cursor: pointer;
}
.top-section {
width: 100%;
height: 100%;
position: fixed;
top: -100%;
right: 0;
background: #777777;
z-index: 10;
}
.blocks-container {
height: 600px;
width: 400px;
overflow-y: scroll;
}
.blocks-container__item {
padding: 10px 0;
height: 240px;
width: 100%;
}
.block {
height: 100%;
width: 100%;
background: #313335;
padding: 20px;
}
.card {
height: 100%;
width: 100%;
border-left: 0 solid brown;
background: #cccccc;
cursor: pointer;
z-index: 11;
}
.card__wrapper {
height: 100%;
width: 100%;
}
<body>
<div class="top-section"></div>
<div class="blocks-container">
<div class="blocks-container__item">
<div class="block">
<div class="card__wrapper">
<div class="card"></div>
</div>
</div>
</div>
<div class="blocks-container__item">
<div class="block">
<div class="card__wrapper">
<div class="card"></div>
</div>
</div>
</div>
<div class="blocks-container__item">
<div class="block">
<div class="card__wrapper">
<div class="card"></div>
</div>
</div>
</div>
<div class="blocks-container__item">
<div class="block">
<div class="card__wrapper">
<div class="card"></div>
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<script src="index.js"></script>
</body>
Ответы (1 шт):
Кажется вы что-то не договариваете.
gsap.to() не вызывается при помощи .play(), он сразу стартует.
Что вам мешает не вносить в переменную, а сразу анимировать при ивенте?
document.querySelector('#shift').addEventListener('click', function() {
gsap.to('.block', {x: () => Random(100)});
});
function Random(val) {
return Math.floor(Math.random() * val)
}
.block {
display: block;
width: 100px;
height: 100px;
background: red;
margin-bottom: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<div class="block"></div>
<input id="shift" type="button" value="Сдвинуть">