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 шт):

Автор решения: De.Minov

Кажется вы что-то не договариваете.

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="Сдвинуть">

→ Ссылка