<div id="app">
  <div class="container">
    <div class="left-pane" :class="{'open': open}"></div><!-- this comment removes the space
  --><div class="right-pane" :class="{'open': open}"></div>
  </div>
  <div @click="toggle" ref="actionbtn" class="action-btn">+</div>
</div>
body {
  margin: 0;
  padding: 0;
}
.container {
  height: 600px;
}
.left-pane {
  display: inline-block;
  background-color: #307490;
  width: 30%;
  height: 600px;
}
.left-pane.open {
  width: 70%;
}
.right-pane {
  display: inline-block;
  width: 70%;
  height: 100%;
  height: 600px;
  
  background-image: url("https://placeimg.com/1000/600/nature");
  background-size: cover;
  background-repeat: no-repeat;
  background-position: 50% 50%;
}
.right-pane.open {
  width: 30%;
}
.right-pane, .left-pane {
  transition: width 0.7s;
}
.action-btn {
  position: absolute;
  left: calc(30% - 25px);
  top: 300px;
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: black;
  color: white;
  font-size: 40px;
  text-align: center;
  cursor: pointer;
} 
new Vue({
  el: '#app',
  data: {
    open: false,
    animating: false
  },
  methods: {
    toggle () {
      if(this.animating) {
        // avoid any action if button clicked when animated
        return
      }
      
      this.open = !this.open
      this.animateButton()
    },
    animateButton () {
      this.animating = true

      // animate out
      const propsOut = {
        scale: 0,
        ease: Back.easeIn,
        onComplete: this.animateIn
      }
      TweenMax.to(this.$refs.actionbtn, 0.2, propsOut)
      
    },
    animateIn () {
      //set new position
      TweenMax.set(this.$refs.actionbtn, this.actionBtnPosition)
      
      const propsIn = {
        delay: 0.4,
        scale: 1,
        ease: Back.easeOut,
      }
      TweenMax.to(this.$refs.actionbtn, 0.2, propsIn)
      
      const propsRotation = {
        delay: 0.4,
        rotation: this.actionBtnRotation,
        onComplete: this.endedAnimating
      }
      TweenMax.to(this.$refs.actionbtn, 0.3, propsRotation)
    },
    endedAnimating () {
      this.animating = false
    }
  },
  computed: {
    actionBtnPosition () {
      const perc = this.open ? '70%' : '30%'
      const top = this.open ? '200px' : '300px'
      return {
        top: top,
        left: `calc(${perc} - 25px)` 
      }
    },
    actionBtnRotation () {
      return this.open ? -135 : 0
    }
  }
})

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.js
  2. https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/TweenMax.min.js