JSFiddle - React, Tailwind, and code Playground
by Rolf
HTML
<div class="smilyrating" tabindex="0"></div>
CSS
.smilyrating {
position: relative;
width: 500px;
padding: 4px;
border: 1px solid green;
}
.smilyrating div {
display: block;
box-sizing: border-box;
width: 150px;
height: 150px;
margin: 0;
padding: 0;
}
JavaScript
EventTarget.provideEventsFor = function(object) {
let eventTarget = new EventTarget();
object.addEventListener = (t,l,o)=>eventTarget.addEventListener(t,l,o);
object.removeEventListener = (t,l,o)=>eventTarget.removeEventListener(t,l,o);
object.dispatchEvent = e=>eventTarget.dispatchEvent(e);
}
SmileRating = (function() {
let symPrivates = Symbol("privates");
function slantedEyePath(cx, cy, r, angle, opening) {
let d0 = angle - opening/2, d1 = angle + opening/2;
let w1 = d0*Math.PI/180, w2 = d1*Math.PI/180
let sx = Math.round(cx + r*Math.cos(w1), 0);
let sy = Math.round(cy - r*Math.sin(w1), 0);
let ex = Math.round(cx + r*Math.cos(w2), 0);
let ey = Math.round(cy - r*Math.sin(w2), 0);
return "M"+sx+" "+sy+" A"+r+" "+r+" 0 1 1 "+ex+" "+ey;
}
function changeEyes(eyes, rating) {
let angle=90,
opening=10;
if (rating < .25) {
opening = 100;
angle = 65+rating*4*70;
}
else if (rating < .5) {
angle = 135;
opening = (0.5-rating)*4*100;
}
eyes[0].setAttribute("d", slantedEyePath(300, 350, 100, angle, opening));
eyes[1].setAttribute("d", slantedEyePath(700, 350, 100, 180-angle, opening)) ;
}
function changeFaceColor(face, rating) {
let green = 255;
let red = 255;
if (rating < .25) {
red = 200 + rating*4*55;
green = 80 + rating*4*175;
}
let color = "rgb("+Math.round(red,0)+","+Math.round(green,0)+",80)";
face.setAttribute("fill", color);
}
let mouthRanges = [
{ value: 0.00, left: { y: 750, c1: 600, c2: 650 }, right: { y: 750, c1: 600, c2: 650 } },
{ value: 0.25, left: { y: 750, c1: 600, c2: 650 }, right: { y: 750, c1: 600, c2: 650 } },
{ value: 0.50, left: { y: 700, c1: 700, c2: 700 }, right: { y: 600, c1: 600, c2: 600 } },
{ value: 0.75, left: { y: 600, c1: 750, c2: 650 }, right: { y: 600, c1: 750, c2: 650 } },
{ value: 1.00, left: { y: 600, c1: 750, c2: 600 }, right: { y: 600, c1: 750,...