JSFiddle - React, Tailwind, and code Playground

Clip-Path Simple Movements

by Travis Almand

HTML

<div id="app">
	<div class="title">
		<h1>Clip-Path: Simple Movements</h1>
	</div>
	<div class="panel">
		<label for="shapes">Animations</label>
		<select id="shapes" v-model="currentTransition">
			<option value="down">down</option>
      <option value=box-wipe>box wipe</option>
      <option value="rotate">rotate</option>
      <option value="spotlight">spotlight</option>
		</select>
		
		<label for="modes">Modes</label>
		<select id="modes" v-model="mode">
			<option value="">none</option>
			<option value="out-in">out-in</option>
			<option value="in-out">in-out</option>
		</select>
		
		<button @click="transition">transition</button>
	</div>
	<div class="boxes">
		<transition :name="currentTransition" :mode="mode">
      <box1 v-if="box1"></box1>
      <box2 v-else></box2>
    </transition>		
	</div>
	<div class="example">
		<transition name="fade" mode="out-in">
			<div class="container" :key="currentTransition" v-html="descriptions[currentTransition]"></div>
		</transition>
	</div>
	<div class="instructions">
		<ul>
			<li>Choose from five different types of clip-path animations in the "Animations" dropdown.</li>
			<li>Choose from the different Vue Transition Component modes in the "Modes" dropdown that control the order of the boxes transitioning.</li>
			<li>Click the "Transition" button to see the selected options being animated.</li>
		</ul>
	</div>
</div>

SCSS

@import url('https://fonts.googleapis.com/css?family=Luckiest+Guy');

html {
  box-sizing: border-box;
  font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
}
*, *:before, *:after {
  box-sizing: inherit;
}
html,
body {
  background-color: #1d1e22;
  margin: 0;
  padding: 0;
}
body {
	align-items: center;
	display: flex;
	height: 100vh;
	justify-content: center;
}

#app {
	display: grid;
  grid-template-columns: 200px 300px 400px;
  grid-gap: 20px;
	
	.title {
		color: #FFF;
		grid-column: 1 / 4;
	
		h1 {
			font-size: 20px;
			font-weight: bold;
		}
	}
	
	.instructions {
		color: #FFF;
		grid-column: 1 / 4;
		
		ul {
			list-style: disc;
		}
		li {
			margin-bottom: 10px;
		}
	}
}


.panel {
	display: flex;
	flex-direction: column;
	
	label {
		color: #fff;
	}
	
	button,
	select {
		font-size: 18px;
		margin: 10px 0;
		padding: 5px 0;
	}
}

.boxes {
  align-items: center;
  background-color: #C5C5C5;
  border: 3px solid #FFF;
  display: flex;
  height: 300px;
  justify-content: center;
  width: 300px;
  
  &::before {
    background-color: darken(#C5C5C5, 10%);
    content: '';
    display: block;
    height: 200px;
    position: absolute;
    width: 200px;
  }
  &::after {
    align-items: center;
    background-color: rgba(0, 0, 0, 0.8);
    color: #fff;
    content: "Sorry!\A\AThis browser doesn't support this type of clip-path animations!";
    display: flex;
    height: 200px;
    position: absolute;
    text-align: center;
    white-space: pre-wrap;
    width: 200px;
  }
	
	.box {
		align-items: center;
		background-color: #307B21;
		color: #fff;
		display: flex;
		font-family: 'Luckiest Guy';
		font-size: 60px;
		height: 200px;
		justify-content: center;
		position: absolute;
		width: 200px;
	}
	.box2 {
		background-color: #4371AD;
	}
}
@supports(clip-path: inset(0)) {
  .boxes::after {
    display: none;
  }
}

.example {
	color: #FFF;
	
	p {
		margin-bottom: 10px;
	}
	.container...

Vue

console.clear();

Vue.component('box1', {
	template: '<div class="box box1">box1</div>'
});
Vue.component('box2', {
	template: '<div class="box box2">box2</div>'
});

new Vue({
  el: "#app",
  data: {
  	box1: true,
    currentTransition: 'down',
    mode: 'out-in',
		descriptions: {
			down: '<p>The down animation uses the inset shape in two different animations to push the sides in a downward direction.</p><p>The leave transition starts with all four sides at 0 and then animates the top down to 100%.</p><p>The enter transition starts with the bottom side already pushed upward 100% and then animates the bottom down to 0.</p>',
      'box-wipe': '<p>The box wipe animation uses the inset shape to create a box that shrinks down to the left side and then moves off the right side.</p><p>The leave transition shrinks the large square to a half-size square placed on the left side of the element. It then moves the square to the right beyond the edge of the element.</p><p>The enter animation does the same in reverse.</p>',
      rotate: '<p>The rotate animation uses the polygon shape to create a rotating square.</p><p>The leave transition animates the square\'s four vertices inward and clockwise over five keyframes. This movement gives the appearance of a rotating and shrinking square.</p><p>The enter transition does the same in reverse giving the appearance of a rotating and growing square.</p>',
      spotlight: '<p>The spotlight animation uses the circle shape over five keyframes.</p><p>The leave transition starts with shrinking the circle from 100% down to 20% in the center. The next four keyframes animate the location of the circle to various spots in the box area until it moves off the left side.</p><p>The enter transition does the same in reverse.</p>'
		}
  },
  methods: {
  	transition () {
    	this.box1 = !this.box1;
    }
  }
})