Let’s create a Monster Alien Star Rating system using HTML, CSS, and JavaScript. This project will allow users to rate monsters or aliens with a fun and interactive star rating interface.
We’ll keep it playful and engaging, using HTML to structure the rating system, CSS for styling the stars and monster/aliens, and JavaScript to handle the rating functionality.
Let’s dive into building the Monster Alien Star Rating system. Whether you’re a beginner or an experienced developer, this project offers an entertaining way to learn and add interactivity to your website.
Let’s unleash our creativity and have some fun rating monsters and aliens!
HTML :
This HTML code sets up a monster alien star rating form. It includes SVG symbols for stars and a no-rating option. The form allows users to rate a product from 0 to 5 stars. Each star is represented by a radio input element and a corresponding label. The styling and animations for the stars are provided by the accompanying CSS and JavaScript files.
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <title>Monster Alien Star Rating</title> <meta name="viewport" content="width=device-width, initial-scale=1"><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css"> <link rel="stylesheet" href="./style.css"> </head> <body> <!-- partial:index.partial.html --> <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: none;"> <symbol id="star" viewBox="0 0 48 45.7"> <path d="M24 37.9L9.2 45.7 12 29.1 0 17.4 16.6 15 24 0l7.4 15L48 17.4 36 29.1l2.8 16.6z"/> </symbol> <symbol id="no-rating" viewBox="0 0 44 44"> <path d="M22 0C9.9 0 0 9.9 0 22s9.9 22 22 22 22-9.9 22-22S34.1 0 22 0zm16 22c0 3.3-1 6.4-2.8 9L13 8.8C15.6 7 18.7 6 22 6c8.8 0 16 7.2 16 16zM6 22c0-3.3 1-6.4 2.8-9L31 35.2C28.4 37 25.3 38 22 38c-8.8 0-16-7.2-16-16z"/> </symbol> </svg> <form action="#" method="post"> <fieldset class="rate-radios"> <legend>How would you rate the product?</legend> <div id="avatar" aria-hidden="true" style="opacity: 0;"> <div> <svg xmlns="http://www.w3.org/2000/svg" focusable="false" viewBox="0 0 350 350" width="200"> <defs> <clipPath id="eye-clip"> <path id="eye-clippath" class="eye-path" fill="none" d="M211 76.91c-11.42.47-23.35.71-35.63.71s-24.21-.24-35.63-.71a39.82 39.82 0 00-4.37 18.18 40.25 40.25 0 001.16 9.57c12.39-.55 25.41-.85 38.84-.85s26.45.3 38.84.85a40.25 40.25 0 001.16-9.57A39.82 39.82 0 00211 76.91z"/> </clipPath> <clipPath id="mouth-clip"> <path id="mouth-clippath" class="mouth-path" fill="none" d="M147.32 165.64h56.12a8.94 8.94 0 018.94 8.94 33.06 33.06 0 01-33.06 33.06h-7.88a33.06 33.06 0 01-33.06-33.06 8.94 8.94 0 018.94-8.94z"/> </clipPath> </defs> <circle cx="175" cy="175" r="175" fill="#F8EDFF"/> <g id="ear-l"> <circle cx="66.93" cy="137.42" r="40" fill="#e7cafa" stroke="#62457a" stroke-linecap="round" stroke-width="5"/> <path fill="#e7cafa" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M64.55 123a14.39 14.39 0 000 28.78"/> </g> <g id="ear-r"> <circle cx="283.07" cy="137.42" r="40" fill="#e7cafa" stroke="#62457a" stroke-linecap="round" stroke-width="5"/> <path fill="#e7cafa" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M285.45 123a14.39 14.39 0 010 28.78"/> </g> <rect id="earring" width="12" height="30" x="284.65" y="169.64" fill="#faf18f" stroke="#62457a" stroke-linecap="round" stroke-width="4.73" rx="6"/> <path id="horn-2" fill="#f0a6df" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M224.58 46.46A98.05 98.05 0 01229-1.46 3.94 3.94 0 00223-6a61.34 61.34 0 00-21.44 27.72c-.57 0-2.22 12.57 5.64 20a19.76 19.76 0 0017.38 4.74z"/> <path id="horn-1" fill="#f0a6df" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M122.5 46.46a97.93 97.93 0 00-4.41-47.92 3.94 3.94 0 016-4.53 61.32 61.32 0 0121.43 27.72c.57 0 2.22 12.57-5.64 20a19.76 19.76 0 01-17.38 4.73z"/> <path fill="#A45CE0" d="M275 118.7c0-54.6-44.7-101-99.3-101.3C120.1 17 75 61.9 75 117.3v44.5c0 46-9.6 91.1-27.8 132.7C79.1 328.7 124.6 350 175 350s95.9-21.3 127.8-55.5C284.6 253 275 207.8 275 161.9v-43.2z"/> <path fill="none" stroke="#62457A" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" d="M302.8 294.5C284.6 253 275 207.8 275 161.9v-43.2c0-54.6-44.7-101-99.3-101.3C120.1 17 75 61.9 75 117.3v44.5c0 46-9.6 91.1-27.8 132.7"/> <path id="horn-5" fill="#f0a6df" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M169.31-24.43l-8.77 51.28a15.57 15.57 0 0026 0l-8.77-51.28a4.29 4.29 0 00-8.46 0z"/> <path id="horn-4" fill="#f0a6df" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M253.74 61.74c2.54-14.44 6.9-25.16 15.5-36.94a4 4 0 00-4.52-6c-11.41 3.88-26.8 15.66-34.48 25.2a15.39 15.39 0 004.39 16 24.18 24.18 0 0013.12 6.1 5.3 5.3 0 005.99-4.36z"/> <path id="horn-3" fill="#f0a6df" stroke="#62457a" stroke-linecap="round" stroke-width="5" d="M93.34 61.74c-2.54-14.44-6.9-25.16-15.5-36.94a4 4 0 014.52-6c11.41 3.88 26.8 15.66 34.48 25.2a15.39 15.39 0 01-4.39 16 24.18 24.18 0 01-13.12 6.1 5.3 5.3 0 01-5.99-4.36z"/> <g id="nose"> <circle cx="168.38" cy="147.81" r="3.5" fill="#62457a"/> <circle cx="182.38" cy="147.81" r="3.5" fill="#62457a"/> </g> <path id="chin" fill="#a45ce0" stroke="#62457a" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" d="M150.38 215.64a12.59 12.59 0 0011.87 8.36h1.26a12.59 12.59 0 0011.87-8.39 12.59 12.59 0 0011.87 8.39h1.26a12.59 12.59 0 0011.87-8.39"/> <path id="eye-bg" class="eye-path" fill="#fff" d="M211 76.91c-11.42.47-23.35.71-35.63.71s-24.21-.24-35.63-.71a39.82 39.82 0 00-4.37 18.18 40.25 40.25 0 001.16 9.57c12.39-.55 25.41-.85 38.84-.85s26.45.3 38.84.85a40.25 40.25 0 001.16-9.57A39.82 39.82 0 00211 76.91z"/> <g id="eye" clip-path="url(#eye-clip)"> <g id="pupil"> <circle cx="175.38" cy="95.09" r="25" fill="#ace4eb"/> <circle cx="175.38" cy="95.09" r="15" fill="#62457a"/> <circle cx="168.95" cy="84.37" r="4.29" fill="#fff"/> </g> </g> <path id="eye-outline" class="eye-path" fill="none" stroke="#62457a" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" d="M211 76.91c-11.42.47-23.35.71-35.63.71s-24.21-.24-35.63-.71a39.82 39.82 0 00-4.37 18.18 40.25 40.25 0 001.16 9.57c12.39-.55 25.41-.85 38.84-.85s26.45.3 38.84.85a40.25 40.25 0 001.16-9.57A39.82 39.82 0 00211 76.91z"/> <path id="mouth-bg" class="mouth-path" fill="#775196" d="M179.32 207.64h-7.88a33 33 0 01-33.06-33.06 8.94 8.94 0 018.94-8.94h56.12a8.94 8.94 0 018.94 8.94 33 33 0 01-33.06 33.06z"/> <g id="mouth" clip-path="url(#mouth-clip)"> <g id="tongue"> <circle cx="175.61" cy="204.34" r="16" fill="#e3468a"/> <ellipse cx="175.61" cy="191.34" fill="#fff" opacity=".1" rx="6" ry="3"/> </g> <path id="tooth-bot" fill="#fff" d="M160.95 200.64h4a4 4 0 014 4v7h-12v-7a4 4 0 014-4z"/> <path id="tooth-top" fill="#fff" d="M177.95 161.64h16v9a4 4 0 01-4 4h-8a4 4 0 01-4-4v-9z"/> </g> <path id="mouth-outline" class="mouth-path" fill="none" stroke="#62457a" stroke-linecap="round" stroke-linejoin="round" stroke-width="5" d="M179.32 207.64h-7.88a33 33 0 01-33.06-33.06h0a8.94 8.94 0 018.94-8.94h56.12a8.94 8.94 0 018.94 8.94h0a33 33 0 01-33.06 33.06z"/> </svg> </div> </div> <input checked type="radio" name="rate-input" id="rate-input_0" data-num="0"> <label for="rate-input_0" class="rate-radio rate-radio--none"> <svg aria-hidden="true" focusable="false"> <use xlink:href="#no-rating"/> </svg> <span role="presentation">No rating</span> </label> <input type="radio" name="rate-input" id="rate-input_1" data-num="1"> <label for="rate-input_1" class="rate-radio"> <svg aria-hidden="true" focusable="false"> <use xlink:href="#star"/> </svg> <span role="presentation">1 Star</span> </label> <input type="radio" name="rate-input" id="rate-input_2" data-num="2"> <label for="rate-input_2" class="rate-radio"> <svg aria-hidden="true" focusable="false"> <use xlink:href="#star"/> </svg> <span role="presentation">2 Stars</span> </label> <input type="radio" name="rate-input" id="rate-input_3" data-num="3"> <label for="rate-input_3" class="rate-radio"> <svg aria-hidden="true" focusable="false"> <use xlink:href="#star"/> </svg> <span role="presentation">3 Stars</span> </label> <input type="radio" name="rate-input" id="rate-input_4" data-num="4"> <label for="rate-input_4" class="rate-radio"> <svg aria-hidden="true" focusable="false"> <use xlink:href="#star"/> </svg> <span role="presentation">4 Stars</span> </label> <input type="radio" name="rate-input" id="rate-input_5" data-num="5"> <label for="rate-input_5" class="rate-radio"> <svg aria-hidden="true" focusable="false"> <use xlink:href="#star"/> </svg> <span role="presentation">5 Stars</span> </label> </fieldset> </form> <!-- partial --> <script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.5/gsap.min.js'></script> <script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/MorphSVGPlugin3.min.js'></script><script src="./script.js"></script> </body> </html>
CSS :
This CSS code sets up styling for a star rating system using the Inter font and a purple color scheme. It ensures the page elements are properly sized and spaced, and it provides visual feedback when users interact with the star rating options. The stars are styled to change color and size based on user selection, and there are animations for hover and focus states to enhance user experience.
@import url("https://rsms.me/inter/inter.css"); body, html { width: 100%; height: 100%; font-family: "Inter", sans-serif; } body * { box-sizing: border-box; } :root { --purple-bare: #F8EDFF; --purple-light: #e7cafa; --purple-core: #7E26C8; --purple-dark: #62457a; --red: #e3468a; --red-dark: #9e1852; --gold: #faf18f; } form { width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; } symbol { overflow: visible; } legend { margin: 0 0 1.5em; display: block; width: 100%; font-size: 1.25em; font-weight: 700; text-align: center; color: var(--purple-core); } #avatar { margin: 0 auto 1em; width: 150px; } #avatar div { position: relative; width: 100%; height: 0; padding-bottom: 100%; } #avatar div svg { position: absolute; width: 100%; height: 100%; overflow: visible; } input[type=radio] { position: absolute; top: auto; z-index: 2; width: 1.5em; height: 2em; -webkit-appearance: none; -moz-appearance: none; appearance: none; opacity: 0.0001; } .rate-radio { margin: 0 0.5em 0 0; position: relative; display: inline-block; vertical-align: top; color: #2a2a2a; line-height: 1; } .rate-radio:last-of-type { margin-right: 0; } .rate-radio svg { display: block; width: 3em; height: 2.85em; fill: var(--purple-bare); stroke: #000; stroke-width: 3px; stroke-linejoin: round; transform: scale(0.625); transition: transform 0.2s ease-in-out; overflow: visible; } .rate-radio span { padding: 0.4em 0.5em; position: absolute; left: 50%; top: 100%; background: #333; border: solid 2px var(--purple-dark); border-radius: 0.25em; color: #fff; font-size: 0.8em; font-weight: 600; text-align: center; white-space: nowrap; opacity: 0; transform: translateY(0.5em) translateX(-50%) scale(0); transition: opacity 0.25s ease-in-out, transform 0.25s ease-in-out; } .rate-radio span::before { content: ""; position: absolute; top: 0; left: 0; z-index: -1; width: 100%; height: 100%; border-radius: inherit; background: var(--purple-core); opacity: 0; transition: opacity 0.25s ease; } @media (prefers-reduced-motion: reduce) { .rate-radio svg { transform: none; transition: transform 0.5s ease-in-out; } .rate-radio span { transform: translateY(0.5em) translateX(-50%); transition: opacity 0.5s ease-in-out, transform 0.5s ease-in-out; } } .rate-radio--none svg { width: 2.85em; height: 2.85em; fill: #FFF; stroke: var(--red-dark); } input:focus + .rate-radio { outline: dotted 0.25em #CCC; outline-offset: 0.5em; } fieldset:not([disabled]) input:not([disabled]):hover + .rate-radio span, .rate-radio:hover span, input:focus + .rate-radio span { opacity: 1; transform: translateY(0.5em) translateX(-50%) scale(1); } fieldset:not([disabled]) input:not([disabled]):checked + .rate-radio span, .rate-radio:checked span, input:checked + .rate-radio span { opacity: 1; background: var(--purple-core); transform: translateY(0.5em) translateX(-50%) scale(1); } fieldset:not([disabled]) input:not([disabled]):checked + .rate-radio span::before, .rate-radio:checked span::before, input:checked + .rate-radio span::before { opacity: 1; } input:checked + .rate-radio span { background: #333; border: 2px solid var(--purple-dark); } input:checked ~ .rate-radio svg { fill: var(--purple-bare); transform: scale(0.625); } @media (prefers-reduced-motion: reduce) { input:checked ~ .rate-radio svg { transform: none; } } input:not(:checked) ~ .rate-radio--none svg { fill: var(--purple-dark); transform: scale(0.625); } @media (prefers-reduced-motion: reduce) { input:not(:checked) ~ .rate-radio--none svg { transform: none; } } .rate-radio svg, input:checked + .rate-radio svg { fill: var(--gold); stroke: var(--purple-dark); transform: scale(1) translateY(-0.25em); } @media (prefers-reduced-motion: reduce) { .rate-radio svg, input:checked + .rate-radio svg { transform: none; } } input:checked + .rate-radio--none svg { fill: var(--red); stroke: var(--red-dark); transform: scale(1); }
JavaScript:
This code creates a webpage where users can rate a product using stars, with a fun monster/alien theme. It includes HTML for the structure, CSS for styling, and JavaScript for animations. Users can select a star rating from 0 to 5, and the page uses SVG graphics for the star icons and monster/alien illustration.
console.clear(); /* selector functions */ const $ = (s, o = document) => o.querySelector(s); const $$ = (s, o = document) => o.querySelectorAll(s); /* store references to all of the elements we'll need */ const inputs = $$('input[type="radio"]'); const horn1 = $('#horn-1'), horn2 = $('#horn-2'), horn3 = $('#horn-3'), horn4 = $('#horn-4'), horn5 = $('#horn-5'); const earL = $('#ear-l'), earR = $('#ear-r'), earring = $('#earring'); const pupil = $('#pupil'); const eyePaths = $$('.eye-path'), mouthPaths = $$('.mouth-path'); const chin = $('#chin'), tongue = $('#tongue'), toothTop = $('#tooth-top'), toothBot = $('#tooth-bot'); const avatar = $('#avatar'); /* path data for shape morphing */ const eye0 = "M175.4,75.3c-12,0-23.4-0.9-33.7-2.5c-4.2,6.4-6.7,14-6.7,22.2c0,12.4,5.7,23.5,14.6,30.9c6.9,5.7,15.8,9.1,25.4,9.1c9.7,0,18.5-3.4,25.4-9.1c8.9-7.3,14.6-18.4,14.6-30.9c0-8.2-2.5-15.8-6.7-22.1C198.3,74.5,187.1,75.3,175.4,75.3z"; const eye1 = "M213.3,82.3c-9.7,4-23.1,6.5-37.9,6.5s-28.2-2.5-37.9-6.5c-1.3,4-2.1,8.3-2.1,12.8c0,11,4.4,20.9,11.6,28.1c8.2-1.8,18-2.9,28.4-2.9s20.2,1.1,28.4,2.9c7.2-7.2,11.6-17.2,11.6-28.1C215.4,90.6,214.6,86.3,213.3,82.3z"; const eye2 = "M215.4,95.1c0-7.4-2-14.3-5.5-20.3c-9.3,2.5-21.3,4-34.5,4s-25.1-1.5-34.5-4c-3.5,6-5.5,12.9-5.5,20.3c0,13.1,6.3,24.7,16,32c7.2-1.1,15.4-1.7,24-1.7s16.8,0.6,24,1.7C209.1,119.8,215.4,108.2,215.4,95.1z"; const eye3 = "M152.9,128.2c6.8-0.9,14.5-1.5,22.5-1.5s15.7,0.5,22.5,1.5c10.6-7.2,17.5-19.3,17.5-33.1c0-12.8-6-24.2-15.4-31.5c-7.4,2-15.7,3.2-24.6,3.2s-17.3-1.2-24.6-3.2c-9.4,7.3-15.4,18.7-15.4,31.5C135.4,108.8,142.3,121,152.9,128.2z"; const eye4 = "M150.7,128.1c7.3-1.1,15.6-1.7,24.3-1.7s17,0.6,24.3,1.7c10.1-7.5,16.7-19.5,16.7-33c0-13.4-6.4-25.3-16.4-32.8c-6.9-5.2-15.4-8.2-24.6-8.2c-9.5,0-18.2,3.2-25.2,8.6c-9.6,7.5-15.8,19.2-15.8,32.4C134,108.6,140.6,120.6,150.7,128.1z"; const eye5 = "M219,95.1c0,12-4.7,23-12.4,30.9c-7.9,8.1-19,13.1-31.6,13.1c-12.2,0-23.2-4.9-31.1-12.9c-8-8-12.9-19-12.9-31.1c0-13.7,6.2-25.9,16-34c7.6-6.3,17.4-10,28-10c9.9,0,19.1,3.3,26.4,8.8C212.1,67.9,219,80.7,219,95.1z"; const mouth0 = "M174.6,178.2h5.1H215c0,0,0.1,0,0.1,0c0,0,0,0-0.1,0h-35.3L174.6,178.2l-4.6,0.1h-35c0,0-0.1,0-0.1,0c0,0,0,0,0.1,0h35H174.6z"; const mouth1 = "M175,172.6h7c8.9,0,16.2,6.4,17.7,14.9c0.2,1,0.3,2,0.3,3.1c0,0.8-0.5,2-2,2l-16,0h-7h-7l-16,0c-1.4,0-2-1.2-2-2c0-1,0.1-1.9,0.2-2.8c1.4-8.6,8.8-15.1,17.7-15.1H175z"; const mouth2 = "M175,187c5.5,0,9.7-2.1,13.8-4.1c5.5-2.7,11.3-5.5,17.6-0.4c0.1,0.1,0.3,0.3,0.2,0.4c-0.1,0.1-0.3,0.1-0.4,0c-5.6-5.1-11.7-2.6-17.4,0.2c-4.2,2-7.3,4.1-13.9,4.1c-6.5,0-9-2.1-12.9-4.1c-5.1-2.8-10.6-5.8-18.6-0.6c-0.1,0-0.1,0-0.1,0c0,0,0-0.1,0.1-0.1c7.9-5.4,13.4-2.4,18.8,0.5C165.9,185,169.7,187,175,187z"; const mouth3 = "M175,179.8c2,0,4-0.1,6-0.2c11-0.9,22-4.1,32.9-9.7c0.1,0,0.2-0.1,0.2,0c0,0.1-0.1,0.2-0.2,0.2c-11.6,6-21.7,9-33,9.7c-2,0.1-4,0.3-6,0.3c-2.3,0-4.6-0.1-6.8-0.3c-10.9-0.8-20.8-3.9-32.1-9.7c-0.1,0-0.1-0.1-0.1-0.1c0,0,0.1,0,0.2,0c10.7,5.5,21.4,8.7,32.1,9.6C170.5,179.7,172.7,179.8,175,179.8z"; const mouth4 = "M174.8,172.6h10H200l0,4.9c0,1.4-0.2,2.7-0.6,4c-1.8,5.9-7.5,10.1-14.3,10.1h-10.4h-9.9c-6.7,0-12.3-4.2-14.2-9.9c-0.4-1.3-0.7-2.7-0.7-4.2v-4.9h14.3H174.8z"; const mouth5 = "M175,165.6h4.8l23.3,0c5.6,0,8.9,4.7,8.9,8.9c0,3-0.4,6-1.2,8.7c-3.8,14-16.7,24.3-31.9,24.3H175h-3.9c-15.5,0-28.6-10.7-32.1-25.2c-0.6-2.5-0.9-5.2-0.9-7.9c0-5,4.1-8.9,8.9-8.9l23.9,0H175z"; /* vars */ let curRating = 0; let tl; let durReduced = 0, durNoPref = .5, dur; let eyeTarg, mouthTarg, chinY, pupilS, earS, earY, earRotL, earRotR, earringX, earringY, tongueY, toothTopY, toothBotY; const horns = [horn1,horn2,horn3,horn4,horn5]; let hornsU = [], hornsD = horns; let mq; // set up matchMedia instance to detect the reduced motion media query mq = window.matchMedia('(prefers-reduced-motion: reduce)'); // safari doesn't support 'matchMedia.addEventListener' so we have to check support for that and add the legacy 'addListener' if not. if(mq.addEventListener) { mq.addEventListener('change', onReduceMotionMQ); } else { mq.addListener(onReduceMotionMQ); } // manually check media query initially onReduceMotionMQ(); // activate any gsap plugins gsap.registerPlugin(MorphSVGPlugin); // set initial visual properties of avatar gsap.set(earL, {transformOrigin: "40px 40px", rotate: "-15deg", y: 10, scale: .9}); gsap.set(earR, {transformOrigin: "40px 40px", rotate: "15deg", y: 10, scale: .9}); gsap.set(earring, {transformOrigin: "50% 0", x: -12, y: 8}); gsap.set(pupil, {transformOrigin: "50% 50%"}); gsap.set(eyePaths, {morphSVG: eye0}); gsap.set(mouthPaths, {morphSVG: mouth0}); gsap.set(chin, {y: 0}); gsap.set(horn1, {transformOrigin: "20px 45px", scale: 0}); gsap.set(horn2, {transformOrigin: "12px 45px", scale: 0}); gsap.set(horn3, {transformOrigin: "32px 38px", scale: 0}); gsap.set(horn4, {transformOrigin: "12px 38px", scale: 0}); gsap.set(horn5, {transformOrigin: "50% 90%", scale: 0}); gsap.set(avatar, {opacity: 1}); /* add click handler to inputs */ inputs.forEach(function(i) { i.addEventListener("click", onRatingClick); }); function onRatingClick(e) { // determine which rating was clicked let num = parseInt(e.target.getAttribute('data-num')); // crate new timeline tl = gsap.timeline({paused: true, defaults:{duration: dur, ease: "sine.out"}}); // determine which horns go up/down hornsU = horns.slice(0,num); if(hornsU.length > curRating) {hornsU = hornsU.slice(curRating);} hornsD = horns.slice(num,curRating); // set props based on which rating was clicked on switch (num) { case 0: eyeTarg = eye0; mouthTarg = mouth0; chinY = 0; pupilS = 1; earS = .9; earY = 10; earRotL = "-15deg"; earRotR = "15deg"; earringX = -12; earringY = 8; tongueY = 0; toothTopY = 0; toothBotY = 0; break; case 1: eyeTarg = eye1; mouthTarg = mouth1; chinY = 3; pupilS = .84; earS = 1.1; earY = -4; earRotL = "10deg"; earRotR = "-10deg"; earringX = 0; earringY = 0; tongueY = 2; toothTopY = 5; toothBotY = -17; break; case 2: eyeTarg = eye2; mouthTarg = mouth2; chinY = -2; pupilS = .94; earS = 1.05; earY = -2; earRotL = "5deg"; earRotR = "-5deg"; earringX = -2; earringY = -1; tongueY = 0; toothTopY = 0; toothBotY = 0; break; case 3: eyeTarg = eye3; mouthTarg = mouth3; chinY = -4; pupilS = 1; earS = 1; earY = 0; earRotL = "0deg"; earRotR = "0deg"; earringX = -4; earringY = -2; tongueY = 0; toothTopY = 0; toothBotY = 0; break; case 4: eyeTarg = eye4; mouthTarg = mouth4; chinY = 3; pupilS = 1.1; earS = .95; earY = -3; earRotL = "2deg"; earRotR = "-2deg"; earringX = -2; earringY = -5; tongueY = -4; toothTopY = 6; toothBotY = -16; break; case 5: eyeTarg = eye5; mouthTarg = mouth5; chinY = 14; pupilS = 1.2; earS = .9; earY = -6; earRotL = "4deg"; earRotR = "-4deg"; earringX = 0; earringY = -10; tongueY = 0; toothTopY = 2; toothBotY = -2; break; default: break; } tl .to(eyePaths, {morphSVG: eyeTarg}, 0) .to(mouthPaths, {morphSVG: mouthTarg}, 0) .to(chin, {y: chinY}, 0) .to(pupil, {scale: pupilS}, 0) .to(earL, {scale: earS, y: earY, rotate: earRotL}, 0) .to(earR, {scale: earS, y: earY, rotate: earRotR}, 0) .to(earring, {x: earringX, y: earringY}, 0) .to(tongue, {y: tongueY}, 0) .to(toothTop, {y: toothTopY}, 0) .to(toothBot, {y: toothBotY}, 0) ; if(hornsU.length) { if(dur) { gsap.to(hornsU, {scale: 1, stagger:{each:.1, ease: "power1.out"}, duration: dur, ease: "back.out"}); } else { gsap.set(hornsU, {scale: 1}); } } if(hornsD.length) { if(dur) { gsap.to(hornsD, {scale: 0, stagger: {each:-.08, ease: "power2.out"}, duration: dur, ease: "back.in"}); } else { gsap.set(hornsD, {scale: 0}); } } curRating = num; tl.play(); } function onReduceMotionMQ() { // change animation time depending on user preference if(mq.matches) { dur = durReduced; } else { dur = durNoPref; } }
In simple terms, crafting a Monster Alien Star Rating system with HTML, CSS, and JavaScript has been a fun journey into interactive web design. We’ve created a playful rating interface where users can rate monsters or aliens with animated stars. By using HTML for structure, CSS for style, and JavaScript for functionality, we’ve built a dynamic system that adds character to user interactions.
If your project has problems, don’t worry. Just click to download the source code and face your coding challenges with excitement. Have fun coding!