JSFiddle - React, Tailwind, and code Playground

Clip-Path Simple Shapes

by Travis Almand

HTML

<div id="app">
	<div class="title">
		<h1>Clip-Path: Simple Shapes</h1>
	</div>
	<div class="panel">
		<label for="shapes">Shapes</label>
		<select id="shapes" v-model="currentTransition">
			<option value="circle">circle</option>
			<option value="ellipse">ellipse</option>
			<option value="inset">inset</option>
			<option value="polygon">polygon</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 four different types of clip-path shapes in the "Shapes" 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: circle(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: 'circle',
    mode: 'out-in',
		descriptions: {
			circle: '<p>The circle shape is set with a radius.</p><p>In this example the circle is animated from 75% (to go beyond the box elements) down to 0% (to essentially disappear) in the leave transition.</p><p>The animation is reversed in the enter transition.</p>',
			ellipse: '<p>The ellipse shape is set with two radii, one for x and y directions of the shape.</p><p>In this example the ellipse is animated from (80% 80%) to (0% 20%) in the leave transition. This shrinks the ellipse down to nothing in a non-circular fashion.</p><p>The animation is reversed in the enter transition.</p>',
			inset: '<p>The inset shape can be defined as a distance inward from one, two, or four sides of the parent.</p><p>In this example the inset is animated from 0% to 50% in the leave transition, essentially disappearing. At the same time the corners are rounded (same as border-radius) from 0% to 50%. This gives it the appearance of changing from a square to a circle as it animates.</p><p>The animation is reversed in the enter transition.</p>',
			polygon: '<p>The polygon shape is defined by at least three vertices with x and y coordinates each within the parent. Straight lines will connect each vertex in order to create the final shape. Two vertices at the same coordinates will appear  to be "welded" together. To be animated smoothly, there must always be a consistent number of vertices.</p><p>In this example eight vertices are created; the four corners animate inward to the center and the points on the four sides animate inward to halfway to the center. This essentially makes the shape disappear in the enter transition.</p><p>The animation is reversed in the enter transition.</p>'
		}
  },
  methods:...