<div class="demo-container">
<h1>How was the help you received?</h1>
<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" style="transform: scale(0);">
<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" style="transform: translateY(9px); color: rgb(49, 59, 63);">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>
* {
margin: 0;
padding: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-webkit-text-size-adjust: none;
font-family: -apple-system, "Helvetica Neue", Helvetica, Arial, sans-serif
}
body {
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
-webkit-align-items: center;
-ms-flex-align: center;
align-items: center;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background-color: #FAFAFB
}
.demo-container {
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;
-webkit-justify-content: center;
-ms-flex-pack: center;
justify-content: center;
box-sizing: border-box;
position: relative;
width: 100%;
max-width: 400px;
height: 300px;
padding: 20px;
text-align: center
}
@media screen and (max-width: 479px) {
.demo-container {
padding: 10px
}
}
.demo-container h1 {
font-size: 14px;
font-weight: 500;
margin-top: -5px;
margin-bottom: 20px;
color: #6E787C
}
body.dragging,
body.dragging .rating-option {
cursor: -webkit-grabbing !important;
cursor: grabbing !important
}
.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: 400px;
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
}
.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: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
}
document.addEventListener("DOMContentLoaded", 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(".demo-container").classList.add("clip-marker");
var ratingControl = new RatingControl(document.querySelector(".rating-control"));
});
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.