easing-sandbox

by Matthieu Savary

HTML

<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<div id="app">
  <div class="row">

    <div style="width:130px">
      <h5 class="text-secondary">
        Amortis&nbsp;:
      </h5>
      <button v-on:click.prevent="setValuesAndBoom('linear')" class="btn btn-secondary mb-1" title="linear">aucun</button>
      <button v-on:click.prevent="setValuesAndBoom('easein')" class="btn btn-secondary mb-1" title="ease in">début</button>
      <button v-on:click.prevent="setValuesAndBoom('easeout')" class="btn btn-secondary mb-1" title="ease out">fin</button>
      <button v-on:click.prevent="setValuesAndBoom('easeinout')" class="btn btn-secondary mb-1" title="ease in/out">début et fin</button>
    </div>

    <div style="width:150px">
      <h5 class="text-secondary">
        Poignées&nbsp;:
      </h5>
      <form>
        <!--class="form-inline"-->
        <div class="input-group mb-1">
          <div class="input-group-prepend">
            <span class="input-group-text text-success" id="basic-addon1">x1</span>
          </div>
          <input type="number" class="form-control" step="0.01" v-on:change="boom()" v-model="x1">
        </div>
        <div class="input-group mb-1">
          <div class="input-group-prepend">
            <span class="input-group-text text-success" id="basic-addon1">y1</span>
          </div>
          <input type="number" class="form-control" step="0.01" v-on:change="boom()" v-model="y1">
        </div>
        <div class="input-group mb-1">
          <div class="input-group-prepend">
            <span class="input-group-text text-primary" id="basic-addon1">x2</span>
          </div>
          <input type="number" class="form-control" step="0.01" v-on:change="boom()" v-model="x2">
        </div>
        <div class="input-group mb-1">
          <div class="input-group-prepend">
            <span class="input-group-text text-primary" id="basic-addon1">y2</span>
          </div><input...

SCSS

body {
  background: #fff;
  padding: 20px;
}

#app {
  background: #fff;
  margin: 0 auto;
  width: 690px;
  transition: all 0.2s;
  
  .col {
    height: 200px;
  }
  
  input[type=number] {
    width: 70px;
    padding: 5px;
  }
  
  svg {
    border-radius: .25rem;
    border: 1px solid #ced4da;
  }
}

$height : 155px;

@keyframes bounce {
     0%   {transform: translateY(0);}
     75%, 100% {transform: translateY(-$height);}
}
#bouncer {
  margin-top: $height;
  border-radius: .25rem;
  width: 200px; height: 45px; padding: 10px;
  text-align: center;
  background: #ff0052; //#20af30;
  color: white;
  box-shadow: 0px 0px 10px rgba(black, 0.25);
  animation-name: bounce;
  animation-duration: 2s; /* or: Xms */
  animation-delay: 1s;
  animation-iteration-count: infinite; //10;
  animation-direction: normal; /* or: alternate */
  //animation-timing-function: ease-out;  /*or: ease, ease-in, ease-in-out, linear, cubic-bezier(x1, y1, x2, y2) */
  animation-timing-function: cubic-bezier(.82,.04,.45,.96);
  animation-fill-mode: forwards; /* or: backwards, both, none */
  animation-delay: 2s; /* or: Xms */
}

JavaScript

new Vue({
  el: "#app",
  data: {
    w: 150,
    h: 200,
    x1: .82,
    y1: .04,
    x2: .45,
    y2: .96,
    styleObj: {
      animationTimingFunction: 'cubic-bezier(.82,.04,.45,.96)'
    },
    curve: "M0 200 C 123 192, 67.5 8, 150 0",
    cx1: 123,
    cy1: 192,
    cx2: 67.5,
    cy2: 8
  },
  methods: {
    setValuesAndBoom: function(easing) {
      if (easing == 'linear') {
        this.x1 = 0.5
        this.y1 = 0.5
        this.x2 = 0.5
        this.y2 = 0.5
      } else if (easing == 'easein') {
        this.x1 = 0.91
        this.y1 = 0.02
        this.x2 = 0.95
        this.y2 = 0.5
      } else if (easing == 'easeout') {
        this.x1 = 0.05
        this.y1 = 0.5
        this.x2 = 0.05
        this.y2 = 0.95
      } else if (easing == 'easeinout') {
        this.x1 = 0.82
        this.y1 = 0.04
        this.x2 = 0.45
        this.y2 = 0.96
      }
      this.boom()
    },
    boom: function() {
      this.styleObj.animationTimingFunction = 'cubic-bezier(' + this.x1 + ',' + this.y1 + ',' + this.x2 + ',' + this.y2 + ')'
      this.curve = "M0 " + this.h + " C " + this.x1 * this.w + " " + (this.h - this.y1 * this.h) + ", " + this.x2 * this.w + " " + (this.h - this.y2 * this.h) + ", " + this.w + " 0"
      this.cx1 = this.x1 * this.w
      this.cy1 = this.h - this.y1 * this.h
      this.cx2 = this.x2 * this.w
      this.cy2 = this.h - this.y2 * this.h

      console.log(this.styleObj.animationTimingFunction)
    }
  }
})