Hinterlander Posted January 24, 2022 Posted January 24, 2022 Selecting a list-item works but doesn’t animate, because GSAP thinks that div._selected has left the DOM as onLeave() indicates. It’s still there, but in a new position. The beforeUpdate() and updated() lifecycle hooks are where I'm getting the state and performing the flip. As an aside, the animation works correctly when the List.vue data changes. ?♂️ Any idea how to approach this? --- Places.vue <template> <list> <list-item class="place" v-for="place in places" :key="place.id" @click="selectPlace(place)" :selected="place.id === $store.state.places.selected_record_id"> <div class="name">{{ place.name }}</div> </list-item> </list> </template> <script> export default { name: 'places-page', methods: { selectRecord ({ id }) { this.selected_record = id; } } } </script> ListItem.vue <template> <li class="_item" @click="$emit('click')"> <slot></slot> <!-- This is what moves around --> <div class="_selected" data-flip-id="selected" v-if="selected"> </div> </li> </template> <script> export default { name: 'list-item', props: { selected: { type: Boolean, default: false } } } </script> List.vue <template> <ul class="list-control"> <slot></slot> </ul> </template> <script> export default { name: 'list-control', data () { return { state: null }; }, beforeUpdate () { this.$data.state = Flip.getState(gsap.utils.toArray('.list-control [data-flip-id]')); }, updated () { Flip.from(this.$data.state, { duration: 0.8, ease: 'expo.out', simple: true, nested: true, onEnter: elements => { console.log('*** onEnter', elements); }, // When clicking on an item, this thinks that `div._selected` // has left the DOM and didn’t come back. Seems like // a race condition, but unsure how to proceed since the DOM // should be fully `updated` at this point onLeave: elements => { console.log('*** onLeave', elements); } }); } } </script>
OSUblake Posted January 24, 2022 Posted January 24, 2022 Welcome to the forums @Hinterlander It's impossible to tell what's going on from a code snippet. Can you put that in minimal demo, like on CodeSandbox? Thanks!
Hinterlander Posted January 25, 2022 Author Posted January 25, 2022 Absolutely! I've recreated the issue here: https://codesandbox.io/s/gsap-flip-exploration-v92g0 So as you can see, sorting the data triggers the Flip animation, but clicking an item does not. The click event triggers Vue's lifecycle hooks beforeUpdate() and updated(), but then it's followed by Flip's onLeave() which causes the animation to be suppressed.
Solution OSUblake Posted January 25, 2022 Solution Posted January 25, 2022 Thanks for the demo! Is this what you're looking for? https://codesandbox.io/s/gsap-flip-exploration-forked-fe4r8?file=/src/components/TopsyList.vue I just added targets to the Flip. Quote targets String | Element | Array | NodeList - by default, Flip will use the targets from the state object (first parameter), but you can specify a subset of those as either selector text (".class, #id"), an Element, an Array of Elements, or a NodeList. If any of the targets provided is NOT found in the state object, it will be passed to the onEnter and not included in the flip animation because there's no previous state from which to pull position/size data. 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now