Pen Settings

HTML

CSS

CSS Base

Vendor Prefixing

Add External Stylesheets/Pens

Any URLs added here will be added as <link>s in order, and before the CSS in the editor. You can use the CSS from another Pen by using its URL and the proper URL extension.

+ add another resource

JavaScript

Babel includes JSX processing.

Add External Scripts/Pens

Any URL's added here will be added as <script>s in order, and run before the JavaScript in the editor. You can use the URL of any other Pen and it will include the JavaScript from that Pen.

+ add another resource

Packages

Add Packages

Search for and use JavaScript packages from npm here. By selecting a package, an import statement will be added to the top of the JavaScript editor for this package.

Behavior

Auto Save

If active, Pens will autosave every 30 seconds after being saved once.

Auto-Updating Preview

If enabled, the preview panel updates automatically as you code. If disabled, use the "Run" button to update.

Format on Save

If enabled, your code will be formatted when you actively save your Pen. Note: your code becomes un-folded during formatting.

Editor Settings

Code Indentation

Want to change your Syntax Highlighting theme, Fonts and more?

Visit your global Editor Settings.

HTML

              
                <script src="https://unpkg.com/vue"></script>

<div id="app">
    <div class="rating-container">
    <div class="rating-control">
      <div class="rating-option" rating="1" selected-fill="#FFA98D">
        <div class="icon">
          <svg width="100%" height="100%" viewBox="0 0 50 50">
            <path d="M50,25 C50,38.807 38.807,50 25,50 C11.193,50 0,38.807 0,25 C0,11.193 11.193,0 25,0 C38.807,0 50,11.193 50,25" class="base" fill="#C6CCD0"></path>
            <path d="M25,31.5 C21.3114356,31.5 17.7570324,32.4539319 14.6192568,34.2413572 C13.6622326,34.7865234 13.3246514,36.0093483 13.871382,36.9691187 C14.4181126,37.9288892 15.6393731,38.2637242 16.5991436,37.7169936 C19.1375516,36.2709964 22.0103269,35.5 25,35.5 C27.9896731,35.5 30.8610304,36.2701886 33.4008564,37.7169936 C34.3606269,38.2637242 35.5818874,37.9288892 36.128618,36.9691187 C36.6753486,36.0093483 36.3405137,34.7880878 35.3807432,34.2413572 C32.2429676,32.4539319 28.6885644,31.5 25,31.5 Z" class="mouth" fill="#FFFFFF"></path>
            <path d="M30.6486386,16.8148522 C31.1715727,16.7269287 31.2642212,16.6984863 31.7852173,16.6140137 C32.3062134,16.529541 33.6674194,16.3378906 34.5824585,16.1715729 C35.4974976,16.0052551 35.7145386,15.9660737 36.4964248,15.8741891 C36.6111841,15.9660737 36.7220558,16.0652016 36.8284271,16.1715729 C37.7752853,17.118431 38.1482096,18.4218859 37.9472002,19.6496386 C37.8165905,20.4473941 37.4436661,21.2131881 36.8284271,21.8284271 C35.26633,23.3905243 32.73367,23.3905243 31.1715729,21.8284271 C29.8093655,20.4662198 29.6350541,18.3659485 30.6486386,16.8148522 Z" class="right-eye" fill="#FFFFFF"></path>
            <path d="M18.8284271,21.8284271 C20.1906345,20.4662198 20.3649459,18.3659485 19.3513614,16.8148522 C18.8284273,16.7269287 18.7357788,16.6984863 18.2147827,16.6140137 C17.6937866,16.529541 16.3325806,16.3378906 15.4175415,16.1715729 C14.5025024,16.0052551 14.2854614,15.9660737 13.5035752,15.8741891 C13.3888159,15.9660737 13.2779442,16.0652016 13.1715729,16.1715729 C12.2247147,17.118431 11.8517904,18.4218859 12.0527998,19.6496386 C12.1834095,20.4473941 12.5563339,21.2131881 13.1715729,21.8284271 C14.73367,23.3905243 17.26633,23.3905243 18.8284271,21.8284271 Z" class="left-eye" fill="#FFFFFF"></path>
          </svg>
        </div>
        <div class="label">Terrible</div>
        <div class="touch-marker"></div>
      </div>
      <div class="rating-option" rating="2" selected-fill="#FFC385">
        <div class="icon">
          <svg width="100%" height="100%" viewBox="0 0 50 50">
            <path d="M50,25 C50,38.807 38.807,50 25,50 C11.193,50 0,38.807 0,25 C0,11.193 11.193,0 25,0 C38.807,0 50,11.193 50,25" class="base" fill="#C6CCD0"></path>
            <path d="M25,31.9996 C21.7296206,31.9996 18.6965022,32.5700242 15.3353795,33.7542598 C14.2935825,34.1213195 13.7466,35.2634236 14.1136598,36.3052205 C14.4807195,37.3470175 15.6228236,37.894 16.6646205,37.5269402 C19.617541,36.4865279 22.2066846,35.9996 25,35.9996 C28.1041177,35.9996 31.5196849,36.5918872 33.0654841,37.4088421 C34.0420572,37.924961 35.2521232,37.5516891 35.7682421,36.5751159 C36.284361,35.5985428 35.9110891,34.3884768 34.9345159,33.8723579 C32.7065288,32.6948667 28.6971052,31.9996 25,31.9996 Z" class="mouth" fill="#FFFFFF"></path>
            <path d="M30.7014384,16.8148522 C30.8501714,16.5872449 31.0244829,16.3714627 31.2243727,16.1715729 C32.054483,15.3414625 33.1586746,14.9524791 34.2456496,15.0046227 C34.8805585,15.7858887 34.945378,15.8599243 35.5310714,16.593811 C36.1167648,17.3276978 36.1439252,17.3549194 36.5988813,17.9093628 C37.0538374,18.4638062 37.2801558,18.7149658 38,19.6496386 C37.8693903,20.4473941 37.496466,21.2131881 36.8812269,21.8284271 C35.3191298,23.3905243 32.7864699,23.3905243 31.2243727,21.8284271 C29.8621654,20.4662198 29.6878539,18.3659485 30.7014384,16.8148522 Z" class="right-eye" fill="#FFFFFF"></path>
            <path d="M18.8284271,21.8284271 C20.1906345,20.4662198 20.3649459,18.3659485 19.3513614,16.8148522 C19.2026284,16.5872449 19.0283169,16.3714627 18.8284271,16.1715729 C17.9983168,15.3414625 16.8941253,14.9524791 15.8071502,15.0046227 C15.1722413,15.7858887 15.1074218,15.8599243 14.5217284,16.593811 C13.9360351,17.3276978 13.9088746,17.3549194 13.4539185,17.9093628 C12.9989624,18.4638062 12.772644,18.7149658 12.0527998,19.6496386 C12.1834095,20.4473941 12.5563339,21.2131881 13.1715729,21.8284271 C14.73367,23.3905243 17.26633,23.3905243 18.8284271,21.8284271 Z" class="left-eye" fill="#FFFFFF"></path>
          </svg>
        </div>
        <div class="label">Bad</div>
        <div class="touch-marker"></div>
      </div>
      <div class="rating-option" rating="3">
        <div class="icon">
          <svg width="100%" height="100%" viewBox="0 0 50 50">
            <path d="M50,25 C50,38.807 38.807,50 25,50 C11.193,50 0,38.807 0,25 C0,11.193 11.193,0 25,0 C38.807,0 50,11.193 50,25" class="base" fill="#C6CCD0"></path>
            <path d="M25.0172185,32.7464719 C22.4651351,33.192529 19.9789584,33.7240143 17.4783686,34.2837667 C16.4004906,34.5250477 15.7222686,35.5944568 15.9635531,36.6723508 C16.2048377,37.7502449 17.2738374,38.4285417 18.3521373,38.1871663 C20.8031673,37.6385078 23.2056119,37.1473427 25.7416475,36.6803253 C28.2776831,36.2133079 30.8254642,35.7953113 33.3839467,35.4267111 C34.4772031,35.2692059 35.235822,34.2552362 35.0783131,33.1619545 C34.9208042,32.0686729 33.89778,31.3113842 32.8135565,31.4675881 C30.2035476,31.8436117 27.6044107,32.2700339 17.4783686,34.2837667 Z" class="mouth" fill="#FFFFFF"></path>
            <path d="M30.6486386,16.8148522 C30.7973716,16.5872449 30.9716831,16.3714627 31.1715729,16.1715729 C32.0016832,15.3414625 33.1058747,14.9524791 34.1928498,15.0046227 C35.0120523,15.0439209 35.8214759,15.3337764 36.4964248,15.8741891 C36.6111841,15.9660737 36.7220558,16.0652016 36.8284271,16.1715729 C37.7752853,17.118431 38.1482096,18.4218859 37.9472002,19.6496386 C37.8165905,20.4473941 37.4436661,21.2131881 36.8284271,21.8284271 C35.26633,23.3905243 32.73367,23.3905243 31.1715729,21.8284271 C29.8093655,20.4662198 29.6350541,18.3659485 30.6486386,16.8148522 Z" class="right-eye" fill="#FFFFFF"></path>
            <path d="M18.8284271,21.8284271 C20.1906345,20.4662198 20.3649459,18.3659485 19.3513614,16.8148522 C19.2026284,16.5872449 19.0283169,16.3714627 18.8284271,16.1715729 C17.9983168,15.3414625 16.8941253,14.9524791 15.8071502,15.0046227 C14.9879477,15.0439209 14.1785241,15.3337764 13.5035752,15.8741891 C13.3888159,15.9660737 13.2779442,16.0652016 13.1715729,16.1715729 C12.2247147,17.118431 11.8517904,18.4218859 12.0527998,19.6496386 C12.1834095,20.4473941 12.5563339,21.2131881 13.1715729,21.8284271 C14.73367,23.3905243 17.26633,23.3905243 18.8284271,21.8284271 Z" class="left-eye" fill="#FFFFFF"></path>
          </svg>
        </div>
        <div class="label">Okay</div>
        <div class="touch-marker"></div>
      </div>
      <div class="rating-option" rating="4">
        <div class="icon">
          <svg width="100%" height="100%" viewBox="0 0 50 50">
            <path d="M50,25 C50,38.807 38.807,50 25,50 C11.193,50 0,38.807 0,25 C0,11.193 11.193,0 25,0 C38.807,0 50,11.193 50,25" class="base" fill="#C6CCD0"></path>
            <path d="M25,35 C21.9245658,35 18.973257,34.1840075 16.3838091,32.6582427 C15.4321543,32.0975048 14.2061178,32.4144057 13.64538,33.3660605 C13.0846422,34.3177153 13.401543,35.5437517 14.3531978,36.1044896 C17.5538147,37.9903698 21.2054786,39 25,39 C28.7945214,39 32.4461853,37.9903698 35.6468022,36.1044896 C36.598457,35.5437517 36.9153578,34.3177153 36.35462,33.3660605 C35.7938822,32.4144057 34.5678457,32.0975048 33.6161909,32.6582427 C31.026743,34.1840075 28.0754342,35 25,35 Z" class="mouth" fill="#FFFFFF"></path>
            <path d="M30.6486386,16.8148522 C30.7973716,16.5872449 30.9716831,16.3714627 31.1715729,16.1715729 C32.0016832,15.3414625 33.1058747,14.9524791 34.1928498,15.0046227 C35.0120523,15.0439209 35.8214759,15.3337764 36.4964248,15.8741891 C36.6111841,15.9660737 36.7220558,16.0652016 36.8284271,16.1715729 C37.7752853,17.118431 38.1482096,18.4218859 37.9472002,19.6496386 C37.8165905,20.4473941 37.4436661,21.2131881 36.8284271,21.8284271 C35.26633,23.3905243 32.73367,23.3905243 31.1715729,21.8284271 C29.8093655,20.4662198 29.6350541,18.3659485 30.6486386,16.8148522 Z" class="right-eye" fill="#FFFFFF"></path>
            <path d="M18.8284271,21.8284271 C20.1906345,20.4662198 20.3649459,18.3659485 19.3513614,16.8148522 C19.2026284,16.5872449 19.0283169,16.3714627 18.8284271,16.1715729 C17.9983168,15.3414625 16.8941253,14.9524791 15.8071502,15.0046227 C14.9879477,15.0439209 14.1785241,15.3337764 13.5035752,15.8741891 C13.3888159,15.9660737 13.2779442,16.0652016 13.1715729,16.1715729 C12.2247147,17.118431 11.8517904,18.4218859 12.0527998,19.6496386 C12.1834095,20.4473941 12.5563339,21.2131881 13.1715729,21.8284271 C14.73367,23.3905243 17.26633,23.3905243 18.8284271,21.8284271 Z" class="left-eye" fill="#FFFFFF"></path>
          </svg>
        </div>
        <div class="label">Good</div>
        <div class="touch-marker"></div>
      </div>
      <div class="rating-option" rating="5">
        <div class="icon">
          <svg width="100%" height="100%" viewBox="0 0 50 50">
            <path d="M50,25 C50,38.807 38.807,50 25,50 C11.193,50 0,38.807 0,25 C0,11.193 11.193,0 25,0 C38.807,0 50,11.193 50,25" class="base" fill="#C6CCD0"></path>
            <path d="M25.0931396,31 C22.3332651,31 16.6788329,31 13.0207,31 C12.1907788,31 11.6218259,31.4198568 11.2822542,32.0005432 C10.9061435,32.6437133 10.8807853,33.4841868 11.3937,34.17 C14.4907,38.314 19.4277,41 24.9997,41 C30.5727,41 35.5097,38.314 38.6067,34.17 C39.0848493,33.5300155 39.0947422,32.7553501 38.7884086,32.1320187 C38.4700938,31.4843077 37.8035583,31 36.9797,31 C34.3254388,31 28.6616205,31 25.0931396,31 Z" class="mouth" fill="#FFFFFF"></path>
            <path d="M30.6486386,16.8148522 C30.7973716,16.5872449 30.9716831,16.3714627 31.1715729,16.1715729 C32.0016832,15.3414625 33.1058747,14.9524791 34.1928498,15.0046227 C35.0120523,15.0439209 35.8214759,15.3337764 36.4964248,15.8741891 C36.6111841,15.9660737 36.7220558,16.0652016 36.8284271,16.1715729 C37.7752853,17.118431 38.1482096,18.4218859 37.9472002,19.6496386 C37.8165905,20.4473941 37.4436661,21.2131881 36.8284271,21.8284271 C35.26633,23.3905243 32.73367,23.3905243 31.1715729,21.8284271 C29.8093655,20.4662198 29.6350541,18.3659485 30.6486386,16.8148522 Z" class="right-eye" fill="#FFFFFF"></path>
            <path d="M18.8284271,21.8284271 C20.1906345,20.4662198 20.3649459,18.3659485 19.3513614,16.8148522 C19.2026284,16.5872449 19.0283169,16.3714627 18.8284271,16.1715729 C17.9983168,15.3414625 16.8941253,14.9524791 15.8071502,15.0046227 C14.9879477,15.0439209 14.1785241,15.3337764 13.5035752,15.8741891 C13.3888159,15.9660737 13.2779442,16.0652016 13.1715729,16.1715729 C12.2247147,17.118431 11.8517904,18.4218859 12.0527998,19.6496386 C12.1834095,20.4473941 12.5563339,21.2131881 13.1715729,21.8284271 C14.73367,23.3905243 17.26633,23.3905243 18.8284271,21.8284271 Z" class="left-eye" fill="#FFFFFF"></path>
          </svg>
        </div>
        <div class="label">Great</div>
        <div class="touch-marker"></div>
      </div>
      <div class="current-rating">
        <div class="svg-wrapper"></div>
        <div class="touch-marker"></div>
      </div>
    </div>
  </div>
</div>

              
            
!

CSS

              
                body.dragging,
body.dragging .rating-option {
  cursor: -webkit-grabbing !important;
  cursor: grabbing !important;
  -webkit-font-smoothing: antialiased;
}
.rating-container {
  position: absolute;
  top: 65%; 
  left: 50%; 
  transform: translate(-50%, -50%);
  font-size: 14px;
  font-weight: 500;
  margin-top: -5px;
  margin-bottom: 20px;
  color: #6E787C;
  width: 300px;
  font-family: -apple-system,"Helvetica Neue",Helvetica,Arial,sans-serif;
}

.touch-marker {
    position: absolute;
    width: 37px;
    height: 37px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.5);
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 6px rgba(0, 0, 0, 0.06);
    -webkit-transform: scale(2);
    transform: scale(2);
    opacity: 0;
    transition-property: -webkit-transform, opacity;
    transition-property: transform, opacity;
    transition-duration: .25s;
    transition-timing-function: cubic-bezier(.215, .61, .355, 1);
    pointer-events: none;
    will-change: transform
}

.show-touch .touch-marker {
    -webkit-transform: none;
    transform: none;
    opacity: 1
}

.rating-control {
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-justify-content: space-between;
    -ms-flex-pack: justify;
    justify-content: space-between;
    position: relative;
    width: 100%;
    max-width: 300px;
    padding-bottom: 9px
}

.rating-control::before {
    content: "";
    position: absolute;
    width: 80%;
    height: 2px;
    top: 50%;
    margin-top: -13px;
    left: 10%;
    background-color: #E9ECEE
}

.rating-control .current-rating {
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-justify-content: center;
    -ms-flex-pack: center;
    justify-content: center;
    position: absolute;
    width: 20%;
    height: 55px;
    top: 0;
    left: 0;
    will-change: transform;
    cursor: -webkit-grab;
    cursor: grab
    opacity 0
    transition opacity 0.4875s cubic-bezier(.215, .61, .355, 1)
}

.rating-control .current-rating:active {
    cursor: -webkit-grabbing;
    cursor: grabbing
}

.rating-control .current-rating .svg-wrapper {
    position: relative;
    width: 55px;
    height: 55px;
    border-radius: 50%;
    box-shadow: 0 3px 5px rgba(0, 0, 0, 0.08);
    pointer-events: none
}

.rating-control .current-rating .svg-wrapper svg {
    position: absolute;
    width: 55px;
    height: 55px;
    top: 0;
    left: 0;
    will-change: transform
}

@media (-webkit-min-device-pixel-ratio:2),
(min-device-pixel-ratio:2),
(min-resolution:2dppx) {
    .rating-control .current-rating .svg-wrapper svg {
        -webkit-transform: translate(.5px, .5px);
        transform: translate(.5px, .5px)
    }
}

.rating-control .current-rating .touch-marker {
    bottom: -10px;
    left: 50%;
    margin-left: -5px
}

.rating-control .rating-option 
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
    -webkit-align-items: center;
    -ms-flex-align: center;
    align-items: center;
    position: relative;
    -webkit-flex: 1;
    -ms-flex: 1;
    flex: 1;
    margin-top: 9px;
    cursor: pointer;
    -webkit-tap-highlight-color: rgba(0, 0, 0, 0)

.rating-control .rating-option
  animation fadein 0.75s cubic-bezier(0.25, 0.25, 0.25, 1.25) both 
  for num in (1..5)
    &:nth-child({num})
      animation-delay num * (.02s)

.rating-control .current-rating 
  opacity 1


@keyframes fadein
  0% 
    opacity 0
    transform translateX(50%) scale(0) rotateZ(-60deg)
  100%
    opacity 1
    transform translateX(0) scale(1) rotateZ(0deg)

.rating-control .rating-option:active .icon svg .base,
.rating-control .rating-option.active .icon svg .base {
    fill: #8B959A
}

.rating-control .rating-option:active .label,
.rating-control .rating-option.active .label {
    color: #313B3F !important
}

.rating-control .rating-option .icon {
    width: 36px;
    height: 36px;
    will-change: transform;
    pointer-events: none
}

.rating-control .rating-option .icon svg {
    display: block
}

.rating-control .rating-option .icon svg .base {
    transition: fill .1s ease-in-out
}

.rating-control .rating-option .label {
    font-size: 12px;
    font-weight: 500;
    color: #ABB2B6;
    margin-top: 8px;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    pointer-events: none;
    will-change: transform;
    transition: color .1s ease-in-out
}

.rating-control .rating-option .label.no-transition {
    transition: none
}

.rating-control .rating-option .touch-marker {
    bottom: 15px;
    left: 50%;
    margin-left: -18px
}
              
            
!

JS

              
                new Vue({
  el: '#app',
  data: {
    message: ''
  },
  mounted: function () {
    var RatingControl = function(element) {
    var self = this;
    self.containerElement = element;
    self.selectedRatingElement = self.containerElement.querySelector(".current-rating");
    self.selectedRatingSVGContainer = self.selectedRatingElement.querySelector(".svg-wrapper");
    self.ratingElements = [].slice.call(self.containerElement.querySelectorAll(".rating-option")).map(function(element) {
      return {
        container: element,
        icon: element.querySelector(".icon"),
        label: element.querySelector(".label"),
        selectedFill: self.hexToRGB(element.getAttribute("selected-fill") || "#FFD885")
      };
    });

    self.selectedRating;
    self.sliderPosition = 0;
    self.facePaths = [];
    self.labelColor = self.hexToRGB("#ABB2B6");
    self.labelSelectedColor = self.hexToRGB("#313B3F");
    self.dragging = false;
    self.handleDragOffset = 0;
    self.ratingTouchStartPosition = {x:0, y:0};
    self.onRatingChange = function() {};
    self.easings = {
      easeInOutCubic: function(t, b, c, d) {
        if ((t/=d/2) < 1) return c/2*t*t*t + b;
        return c/2*((t-=2)*t*t + 2) + b;
      },
      easeInOutQuad: function(t, b, c, d) {
        if ((t/=d/2) < 1) return c/2*t*t + b;
        return -c/2 * ((--t)*(t-2) - 1) + b;
      },
      linear: function (t, b, c, d) {
        return c*t/d + b;
      }
    };

    self.onHandleDrag = self.onHandleDrag.bind(this);
    self.onHandleRelease = self.onHandleRelease.bind(this);

    self.ratingElements.forEach(function(element) {
      // Copy face path data from HTML
      var paths = {};
      [].forEach.call(element.icon.querySelectorAll("path:not(.base)"), function(path) {
        var pathStr = path.getAttribute("d");
        paths[path.getAttribute("class")] = self.splitString(pathStr);
      });
      self.facePaths.push(paths);
      // On rating selected
      element.container.addEventListener("ontouchend" in document ? "touchend" : "click", function(e) {
        if ("ontouchend" in document) {
          var ratingTouchCurrentPosition = {x: e.pageX, y: e.pageY};
          var dragDistance = Math.sqrt(Math.pow(ratingTouchCurrentPosition.x - self.ratingTouchStartPosition.x, 2) + Math.pow(ratingTouchCurrentPosition.y - self.ratingTouchStartPosition.y, 2));
          if (dragDistance > 10) {
            return;
          }
        }
        var newRating = element.container.getAttribute("rating") - 1;
        self.setRating(newRating, {fireChange: true});
      });
    });

    if ("ontouchend" in document) {
      document.body.addEventListener("touchstart", function(e) {
        if (e.target.classList.contains("rating-option")) {
          self.ratingTouchStartPosition = {x: e.touches[0].pageX, y: e.touches[0].pageY};
        }
      });
      self.selectedRatingElement.addEventListener("touchstart", function(e) {
        self.dragging = true;
        self.handleDragOffset = e.touches[0].pageX - self.selectedRatingElement.getBoundingClientRect().left;
        self.setLabelTransitionEnabled(false);
      });
      self.selectedRatingElement.addEventListener("touchmove", self.onHandleDrag);
      self.selectedRatingElement.addEventListener("touchend", self.onHandleRelease);
    } else {
      document.body.addEventListener("mousedown", function(e) {
        if (e.target == self.selectedRatingElement) {
          e.preventDefault();
          self.dragging = true;
          self.handleDragOffset = e.offsetX;
          self.setLabelTransitionEnabled(false);
          document.body.classList.add("dragging");
          document.body.addEventListener("mousemove", self.onHandleDrag);
        }
      });
      document.body.addEventListener("mouseup", function(e) {
        if (self.dragging) {
          document.body.classList.remove("dragging");
          document.body.removeEventListener("mousemove", self.onHandleDrag);
          self.onHandleRelease(e);
        }
      });
    }

    self.setRating(3, {duration: 0});
  }

  RatingControl.prototype = {
    setRating: function(rating, options) {
      var self = this;
      var options = options || {};
      var startTime;
      var fireChange = options.fireChange || false;
      var onComplete = options.onComplete || function() {};
      var easing = options.easing || self.easings.easeInOutCubic;
      var duration = options.duration == undefined ? 550 : options.duration;
      var startXPosition = self.sliderPosition;
      var endXPosition = rating * self.selectedRatingElement.offsetWidth;

      if (duration > 0) {
        var anim = function(timestamp) {
          startTime = startTime || timestamp;
          var elapsed = timestamp - startTime;
          var progress = easing(elapsed, startXPosition, endXPosition - startXPosition, duration);
          self.setSliderPosition(progress);
          if (elapsed < duration) {
            requestAnimationFrame(anim);
          } else {
            self.setSliderPosition(endXPosition);
            self.setLabelTransitionEnabled(true);
            if (self.onRatingChange && self.selectedRating != rating && fireChange) {
              self.onRatingChange(rating);
            }
            onComplete();
            self.selectedRating = rating;
          }
        };

        self.setLabelTransitionEnabled(false);
        requestAnimationFrame(anim);
      } else {
        self.setSliderPosition(endXPosition);
        if (self.onRatingChange && self.selectedRating != rating && fireChange) {
          self.onRatingChange(rating);
        }
        onComplete();
        self.selectedRating = rating;
      }
    },

    setSliderPosition: function(position) {
      var self = this;
      self.sliderPosition = Math.min(Math.max(0, position), self.containerElement.offsetWidth - self.selectedRatingElement.offsetWidth);
      var stepProgress = self.sliderPosition / self.containerElement.offsetWidth * self.ratingElements.length;
      var relativeStepProgress = stepProgress - Math.floor(stepProgress);
      var currentStep = Math.round(stepProgress);
      var startStep = Math.floor(stepProgress);
      var endStep = Math.ceil(stepProgress);
      // Move handle
      self.selectedRatingElement.style.transform = "translateX(" + (self.sliderPosition / self.selectedRatingElement.offsetWidth * 100) + "%)";
      // Set face
      var startPaths = self.facePaths[startStep];
      var endPaths = self.facePaths[endStep];
      var interpolatedPaths = {};
      for (var featurePath in startPaths) {
        if (startPaths.hasOwnProperty(featurePath)) {
            var startPath = startPaths[featurePath];
            var endPath = endPaths[featurePath];
            var interpolatedPoints = self.interpolatedArray(startPath.digits, endPath.digits, relativeStepProgress);
            var interpolatedPath = self.recomposeString(interpolatedPoints, startPath.nondigits);
            interpolatedPaths[featurePath] = interpolatedPath;
        }
      }
      var interpolatedFill = self.interpolatedColor(self.ratingElements[startStep]["selectedFill"], self.ratingElements[endStep]["selectedFill"], relativeStepProgress);
      self.selectedRatingSVGContainer.innerHTML = '<svg width="55px" height="55px" viewBox="0 0 50 50"><path d="M50,25 C50,38.807 38.807,50 25,50 C11.193,50 0,38.807 0,25 C0,11.193 11.193,0 25,0 C38.807,0 50,11.193 50,25" class="base" fill="' + interpolatedFill + '"></path><path d="' + interpolatedPaths["mouth"] + '" class="mouth" fill="#655F52"></path><path d="' + interpolatedPaths["right-eye"] + '" class="right-eye" fill="#655F52"></path><path d="' + interpolatedPaths["left-eye"] + '" class="left-eye" fill="#655F52"></path></svg>';
      // Update marker icon/label
      self.ratingElements.forEach(function(element, index) {
        var adjustedProgress = 1;
        if (index == currentStep) {
          adjustedProgress = 1 - Math.abs((stepProgress - Math.floor(stepProgress) - 0.5) * 2);
        }
        element.icon.style.transform = "scale(" + adjustedProgress + ")";
        element.label.style.transform = "translateY(" + self.interpolatedValue(9, 0, adjustedProgress) + "px)";
        element.label.style.color = self.interpolatedColor(self.labelSelectedColor, self.labelColor, adjustedProgress);
      });
    },

    onHandleDrag: function(e) {
      var self = this;
      e.preventDefault();
      if (e.touches) {
        e = e.touches[0];
      }
      var offset = self.selectedRatingElement.offsetWidth / 2 - self.handleDragOffset;
      var xPos = e.clientX - self.containerElement.getBoundingClientRect().left;
      self.setSliderPosition(xPos - self.selectedRatingElement.offsetWidth / 2 + offset);
    },

    onHandleRelease: function(e) {
      var self = this;
      self.dragging = false;
      self.setLabelTransitionEnabled(true);
      var rating = Math.round(self.sliderPosition / self.containerElement.offsetWidth * self.ratingElements.length);
      self.setRating(rating, {duration: 200, fireChange: true});
    },

    setLabelTransitionEnabled: function(enabled) {
      var self = this;
      self.ratingElements.forEach(function(element) {
        if (enabled) {
          element.label.classList.remove("no-transition");
        } else {
          element.label.classList.add("no-transition");
        }
      });
    },

    interpolatedValue: function(startValue, endValue, progress) {
      return (endValue - startValue) * progress + startValue;
    },

    interpolatedArray: function(startArray, endArray, progress) {
      return startArray.map(function(startValue, index) {
        return (endArray[index] - startValue) * progress + startValue;
      });
    },

    interpolatedColor: function(startColor, endColor, progress) {
      var self = this;
      var interpolatedRGB = self.interpolatedArray(startColor, endColor, progress).map(function(channel) {
        return Math.round(channel);
      });
      return "rgba(" + interpolatedRGB[0] + "," + interpolatedRGB[1] + "," + interpolatedRGB[2] + ",1)";
    },

    easeInQuint: function(t, b, c, d) {
      return c*(t/=d)*t*t + b;
    },

    hexToRGB: function(hex) {
      // Expand shorthand form to full form
      var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
      hex = hex.replace(shorthandRegex, function(m, r, g, b) {
        return r + r + g + g + b + b;
      });
      var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
      return result ? [
        parseInt(result[1], 16),
        parseInt(result[2], 16),
        parseInt(result[3], 16)
      ] : null;
    },

    splitString: function(value) {
      var re = /-?\d*\.?\d+/g;
      var toStr = function toStr(val) {
        return typeof val == "string" ? val : String(val);
      };
      return {
        digits: toStr(value).match(re).map(Number),
        nondigits: toStr(value).split(re)
      };
    },

    recomposeString: function(digits, nondigits) {
      return nondigits.reduce(function (a, b, i) {
        return a + digits[i - 1] + b;
      });
    },

    simulateRatingTap(rating, delay, complete) {
      var self = this;
      var ratingElement = self.ratingElements[rating];
      setTimeout(function() {
        ratingElement.container.classList.add("show-touch");
        setTimeout(function() {
          ratingElement.container.classList.remove("show-touch");
          self.setRating(rating, {
            onComplete: function() {
              if (complete) {
                complete();
              }
            }
          });
        }, 250);
      }, delay || 0);
    },

    simulateRatingDrag(rating, delay, complete) {
      var self = this;
      setTimeout(function() {
        self.selectedRatingElement.classList.add("show-touch");
        setTimeout(function() {
          self.setRating(rating, {
            duration: 3000,
            easing: self.easings.easeInOutQuad,
            onComplete: function() {
              self.selectedRatingElement.classList.remove("show-touch");
              if (complete) {
                complete();
              }
            }
          });
        }, 250);
      }, delay || 0);
    }
  }


  document.querySelector(".rating-container").classList.add("clip-marker");
  var ratingControl = new RatingControl(document.querySelector(".rating-control"));
  }
})
              
            
!
999px

Console