Skip to content

Instantly share code, notes, and snippets.

@artemuzz
Created September 30, 2019 01:24
Show Gist options
  • Save artemuzz/8746702ca9e58a6e908005ea7157e01b to your computer and use it in GitHub Desktop.
Save artemuzz/8746702ca9e58a6e908005ea7157e01b to your computer and use it in GitHub Desktop.
Anime.js Ease Visualizer
<div class="easings">
<div class="output">
<div class="visualizer-wrapper grid">
<div class="axis x"></div>
<div class="axis y"></div>
<div class="visualizer">
<div class="ball" style="transform: translateY(100px) scale(0)"></div>
<svg viewBox="0 0 100 100">
<path class="curve"/>
</svg>
</div>
</div>
<div class="value grid"></div>
</div>
<div class="options">
<label>Ease In</label>
<button class="active" value="0.550, 0.085, 0.680, 0.530" name="easeInQuad" >Quad</button>
<button value="0.550, 0.055, 0.675, 0.190" name="easeInCubic" >Cubic</button>
<button value="0.895, 0.030, 0.685, 0.220" name="easeInQuart" >Quart</button>
<button value="0.755, 0.050, 0.855, 0.060" name="easeInQuint" >Quint</button>
<button value="0.470, 0.000, 0.745, 0.715" name="easeInSine" >Sine</button>
<button value="0.950, 0.050, 0.795, 0.035" name="easeInExpo" >Expo</button>
<button value="0.600, 0.040, 0.980, 0.335" name="easeInCirc" >Circ</button>
<button value="0.600, -0.280, 0.735, 0.045" name="easeInBack" >Back</button>
<label>Ease Out</label>
<button value="0.250, 0.460, 0.450, 0.940" name="easeOutQuad" >Quad</button>
<button value="0.215, 0.610, 0.355, 1.000" name="easeOutCubic" >Cubic</button>
<button value="0.165, 0.840, 0.440, 1.000" name="easeOutQuart" >Quart</button>
<button value="0.230, 1.000, 0.320, 1.000" name="easeOutQuint" >Quint</button>
<button value="0.390, 0.575, 0.565, 1.000" name="easeOutSine" >Sine</button>
<button value="0.190, 1.000, 0.220, 1.000" name="easeOutExpo" >Expo</button>
<button value="0.075, 0.820, 0.165, 1.000" name="easeOutCirc" >Circ</button>
<button value="0.175, 0.885, 0.320, 1.275" name="easeOutBack" >Back</button>
<label>Ease In Out</label>
<button value="0.455, 0.030, 0.515, 0.955" name="easeInOutQuad" >Quad</button>
<button value="0.645, 0.045, 0.355, 1.000" name="easeInOutCubic" >Cubic</button>
<button value="0.770, 0.000, 0.175, 1.000" name="easeInOutQuart" >Quart</button>
<button value="0.860, 0.000, 0.070, 1.000" name="easeInOutQuint" >Quint</button>
<button value="0.445, 0.050, 0.550, 0.950" name="easeInOutSine" >Sine</button>
<button value="1.000, 0.000, 0.000, 1.000" name="easeInOutExpo" >Expo</button>
<button value="0.785, 0.135, 0.150, 0.860" name="easeInOutCirc" >Circ</button>
<button value="0.680, -0.550, 0.265, 1.550" name="easeInOutBack" >Back</button>
</div>
</div>
var pathEl = document.querySelector('.curve');
var presetsEls = document.querySelectorAll('.options button');
var ratio = window.innerWidth >= 980 ? 2 : 1;
var timeline = anime.timeline({
loop: true
});
function animateProgress(easingName) {
timeline.pause();
timeline = anime.timeline({
loop: true
});
timeline.add([
{
targets: '.axis.x',
opacity: [
{ value: [0, 1], delay: 0, duration: 500 },
{ value: 0, delay: 1500, duration: 500 }
],
translateX: { value: [0, (200 * ratio)], delay: 500, duration: 1500 },
easing: 'linear',
offset: 0
}, {
targets: '.axis.y',
opacity: [
{ value: [0, 1], delay: 0, duration: 500 },
{ value: 0, delay: 1500, duration: 500 }
],
translateY: { value: [0, -(200 * ratio)], delay: 500, duration: 1500, easing: easingName },
easing: 'linear',
offset: 0
}, {
targets: '.ball',
translateY: { value: [100, 0], delay: 500, duration: 1500, easing: easingName },
scale: [
{ value: [0, 1], delay: 0, duration: 500, easing: 'easeOutBack' },
{ value: 0, delay: 1500, duration: 500, easing: 'easeInBack' }
],
offset: 0
}
]);
}
function convertCoordinates(coords) {
var x1 = coords[0] * 100;
var y1 = 100 - (coords[1] * 100);
var x2 = coords[2] * 100;
var y2 = 100 - (coords[3] * 100);
return 'M0 100C' + x1 + ' ' + y1 + ' ' + x2 + ' ' + y2 + ' 100 0';
}
function getCoordinates(value) {
return convertCoordinates(value.split(','));
}
function changeEase(event) {
for (var i = 0; i < presetsEls.length; i++) {
presetsEls[i].classList.remove('active');
}
var buttonEl = event.target;
var value = buttonEl.value;
var name = buttonEl.name;
buttonEl.classList.add('active');
var coordinates = getCoordinates(value);
animateProgress(name);
anime.remove(pathEl);
anime({
targets: pathEl,
d: coordinates
});
}
for (var i = 0; i < presetsEls.length; i++) {
presetsEls[i].onclick = changeEase;
}
presetsEls[0].click();
pathEl.setAttribute('d', getCoordinates(presetsEls[0].value));
<script src="https://codepen.io/juliangarnier/pen/yMLaRG"></script>
.easings {
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
position: absolute;
width: 100%;
height: 100%;
}
.output {
display: flex;
justify-content: center;
align-items: center;
position: relative;
width: 100%;
height: 400px;
}
.options {
display: flex;
flex-wrap: wrap;
flex-direction: row;
width: 100%;
min-height: 300px;
border-top: 1px solid #09090B;
}
.grid {
border-top: 1px solid rgba(255,255,255,0.2);
border-right: 1px solid rgba(255,255,255,0.2);
background: linear-gradient(0deg, rgba(255,255,255,0.2) 1px, rgba(0,0,0,0) 1px),
linear-gradient(90deg, rgba(255,255,255,0.2) 1px, rgba(0,0,0,0) 1px),
linear-gradient(0deg, rgba(255,255,255,0.1) 1px, rgba(0,0,0,0) 1px),
linear-gradient(90deg, rgba(255,255,255,0.1) 1px, rgba(0,0,0,0) 1px);
background-position: 0px -1px;
background-size: 100px 100px, 100px 100px, 20px 20px, 20px 20px;
}
.visualizer-wrapper {
position: relative;
width: 200px;
height: 200px;
}
.visualizer {
position: relative;
width: 100px;
height: 100px;
transform: scale(2);
transform-origin: 0 0;
}
.value {
width: 20px;
height: 200px;
margin-left: 20px;
}
@media screen and (min-width: 980px) {
.easings {
flex-direction: row;
}
.output {
width: 50%;
height: 100%;
}
.options {
width: 50%;
height: 100%;
}
.visualizer-wrapper {
width: 400px;
height: 400px;
}
.visualizer {
transform: scale(4);
}
.value {
width: 40px;
height: 400px;
margin-left: 40px;
}
}
.axis {
opacity: 0;
position: absolute;
background: #5A87FF;
}
.axis.x {
width: 1px;
height: 100%;
transform-origin: 0 0;
}
.axis.y {
bottom: 0;
width: 100%;
height: 1px;
transform-origin: 100% 0;
}
.ball {
position: absolute;
z-index: 2;
top: 0;
left: 100%;
width: 10px;
height: 10px;
margin: -5px 0 0 10px;
background: #FF1461;
border-radius: 50%;
}
svg {
overflow: visible;
position: relative;
z-index: 1;
width: 100%;
height: 100%;
}
path {
fill: none;
stroke: #18FF92;
}
button {
opacity: 1;
position: relative;
color: currentColor;
font-size: 16px;
width: calc(25% + 1px);
border: 1px solid #09090B;
background: transparent;
margin: -1px 0 0 -1px;
letter-spacing: 1px;
}
label {
display: flex;
align-items: center;
justify-content: center;
width: calc(100% + 1px);
margin: -1px 0 0 -1px;
border-top: 0px;
border-left: 1px solid #09090B;
border-right: 1px solid #09090B;
color: rgba(255,255,255,.3);
}
button.active {
color: #18FF92;
z-index: 1;
opacity: 1;
border: 1px solid currentColor;
background: #222027;
}
button:focus {
outline: none;
}
button:hover {
background: #222027;
}
<link href="https://codepen.io/juliangarnier/pen/EWxgGx" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment