JSFiddle - React, Tailwind, and code Playground

by nkovacs

HTML

<script src="https://rawgit.com/yyx990803/vue/master/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue-router.min.js"></script>
<script src="https://unpkg.com/[email protected]/hammer.min.js"></script>
<div id="app">
  <transition v-on:before-enter="onBeforeEnter" v-on:before-leave="onBeforeLeave" v-on:leave="onLeave" v-bind:css="false">
    <router-view></router-view>
  </transition>
</div>

SCSS

#app {
  -webkit-user-select: none;
  -webkit-user-drag: none;
  position: relative;
  height: 100vh;
  width: 100vw;
}

#app > div {
  position: absolute;
  height: 100%;
  width: 100%;
  background-color: rgba(#FFF, 0.75);
  text-align: center;
  line-height: 100vh;
  font-size: 30vh;
}

JavaScript

const Foo = {
  data: function() {
    return {foo: ""}
  },
	template: `<div>foo<input type="text" v-model="foo"></div>`
}

const Bar = {
  data: function() {
    return {foo: ""}
  },
	template: `<div>bar<input type="text" v-model="foo"></div>`
}

const router = new VueRouter({
	routes: [
		{ path: '/', component: Foo },
		{ path: '/bar', component: Bar }
	]
})

new Vue({
	el: '#app',
	router,
	data: {
		panning: false,
		panningStartPosition: 0,
		abortedTransition: false,
	},
	mounted() {
		// Set up touch events
		this.hammer = new Hammer(this.$el)

		this.hammer.on('panstart', (event) => {
    	console.log('hello!')
    	event.preventDefault()
			this.panning = true
			this.panningStartPosition = this.$el.getBoundingClientRect().left
	  	this.$router.push({ path: '/bar' }) // initiate transition process
		})
	},
	methods: {
		onBeforeEnter(element) {
			element.style.zIndex = this.abortedTransition ? 1 : 0
		},
		onBeforeLeave(element) {
			element.style.zIndex = this.abortedTransition ? 0 : 1
		},
		onLeave(element, done) {
			if(this.abortedTransition) {
				this.abortedTransition = false
				done()
			} else {
				element = $(element)
				if(this.panning) {
					// User is using touch gestures to go back
					this.hammer.on('pan', (event) => {
			    	event.preventDefault()
						// Make sure, the element follows the touch gesture
						element.css({
	            transition: 'transform 0ms linear',
							transform: 'translate3d(' + (this.panningStartPosition + event.deltaX) + 'px, 0, 0)'
						})
					})
					// When the swipe motion stops and the user lets go, we need to decide what happens
					this.hammer.on('panend', (event) => {
           	event.preventDefault()
						let remainingDistance = Math.max(0, element.width() - event.deltaX)
						let remainingDistancePercent = (100 / element.width() * remainingDistance - 100) * -1
						// If the swipe was short and at a low speed, we cancel it and revert to the original...