Bouncy Star Animation | Html Css And JavaScript With Free Source Code

Create a captivating visual experience with the Bouncy Star Animation crafted using a combination of HTML, CSS, and JavaScript. This dynamic animation brings a celestial touch to your web projects, as a playful star bounces and glides across the screen, leaving a trail of delight in its wake.

The animation's smooth transitions and eye-catching design capture the essence of motion and wonder.

Unlock the secrets behind this interactive masterpiece by accessing the source code on our dedicated Telegram channel: "CODEATNOW".

With this source code at your fingertips, you can delve into the intricacies of the animation, modify it according to your creative vision, and seamlessly integrate it into your own web designs.

Elevate your digital projects with this engaging Bouncy Star Animation and watch your websites come alive with celestial charm.

HTML
<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>CodeAtNow | Bouncy Star Rating</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"><link rel="stylesheet" href="./style.css">

</head>
<body>
<!-- partial:index.partial.html -->
<form class="rating">
	<div class="rating__stars">
		<input id="rating-1" class="rating__input rating__input-1" type="radio" name="rating" value="1">
		<input id="rating-2" class="rating__input rating__input-2" type="radio" name="rating" value="2">
		<input id="rating-3" class="rating__input rating__input-3" type="radio" name="rating" value="3">
		<input id="rating-4" class="rating__input rating__input-4" type="radio" name="rating" value="4">
		<input id="rating-5" class="rating__input rating__input-5" type="radio" name="rating" value="5">
		<label class="rating__label" for="rating-1">
			<svg class="rating__star" width="32" height="32" viewBox="0 0 32 32" aria-hidden="true">
				<ellipse class="rating__star-shadow" cx="16" cy="31" rx="16" ry="1" />
				<g class="rating__star-body-g">
					<path class="rating__star-body" d="M15.5,26.8l-8.2,4.3c-0.8,0.4-1.7-0.3-1.6-1.1l1.6-9.2c0.1-0.3-0.1-0.7-0.3-1l-6.7-6.5c-0.6-0.6-0.3-1.7,0.6-1.8l9.2-1.3c0.4-0.1,0.7-0.3,0.8-0.6L15,1.3c0.4-0.8,1.5-0.8,1.9,0l4.1,8.3c0.2,0.3,0.5,0.5,0.8,0.6l9.2,1.3c0.9,0.1,1.2,1.2,0.6,1.8L25,19.9c-0.3,0.2-0.4,0.6-0.3,1l1.6,9.2c0.2,0.9-0.8,1.5-1.6,1.1l-8.2-4.3C16.2,26.7,15.8,26.7,15.5,26.8z" />
				</g>
			</svg>
			<span class="rating__sr">1 star</span>
		</label>
		<label class="rating__label" for="rating-2">
			<svg class="rating__star" width="32" height="32" viewBox="0 0 32 32" aria-hidden="true">
				<ellipse class="rating__star-shadow" cx="16" cy="31" rx="16" ry="1" />
				<g class="rating__star-body-g">
					<path class="rating__star-body" d="M15.5,26.8l-8.2,4.3c-0.8,0.4-1.7-0.3-1.6-1.1l1.6-9.2c0.1-0.3-0.1-0.7-0.3-1l-6.7-6.5c-0.6-0.6-0.3-1.7,0.6-1.8l9.2-1.3c0.4-0.1,0.7-0.3,0.8-0.6L15,1.3c0.4-0.8,1.5-0.8,1.9,0l4.1,8.3c0.2,0.3,0.5,0.5,0.8,0.6l9.2,1.3c0.9,0.1,1.2,1.2,0.6,1.8L25,19.9c-0.3,0.2-0.4,0.6-0.3,1l1.6,9.2c0.2,0.9-0.8,1.5-1.6,1.1l-8.2-4.3C16.2,26.7,15.8,26.7,15.5,26.8z" />
				</g>
			</svg>
			<span class="rating__sr">2 stars</span>
		</label>
		<label class="rating__label" for="rating-3">
			<svg class="rating__star" width="32" height="32" viewBox="0 0 32 32" aria-hidden="true">
				<ellipse class="rating__star-shadow" cx="16" cy="31" rx="16" ry="1" />
				<g class="rating__star-body-g">
					<path class="rating__star-body" d="M15.5,26.8l-8.2,4.3c-0.8,0.4-1.7-0.3-1.6-1.1l1.6-9.2c0.1-0.3-0.1-0.7-0.3-1l-6.7-6.5c-0.6-0.6-0.3-1.7,0.6-1.8l9.2-1.3c0.4-0.1,0.7-0.3,0.8-0.6L15,1.3c0.4-0.8,1.5-0.8,1.9,0l4.1,8.3c0.2,0.3,0.5,0.5,0.8,0.6l9.2,1.3c0.9,0.1,1.2,1.2,0.6,1.8L25,19.9c-0.3,0.2-0.4,0.6-0.3,1l1.6,9.2c0.2,0.9-0.8,1.5-1.6,1.1l-8.2-4.3C16.2,26.7,15.8,26.7,15.5,26.8z" />
				</g>
			</svg>
			<span class="rating__sr">3 stars</span>
		</label>
		<label class="rating__label" for="rating-4">
			<svg class="rating__star" width="32" height="32" viewBox="0 0 32 32" aria-hidden="true">
				<ellipse class="rating__star-shadow" cx="16" cy="31" rx="16" ry="1" />
				<g class="rating__star-body-g">
					<path class="rating__star-body" d="M15.5,26.8l-8.2,4.3c-0.8,0.4-1.7-0.3-1.6-1.1l1.6-9.2c0.1-0.3-0.1-0.7-0.3-1l-6.7-6.5c-0.6-0.6-0.3-1.7,0.6-1.8l9.2-1.3c0.4-0.1,0.7-0.3,0.8-0.6L15,1.3c0.4-0.8,1.5-0.8,1.9,0l4.1,8.3c0.2,0.3,0.5,0.5,0.8,0.6l9.2,1.3c0.9,0.1,1.2,1.2,0.6,1.8L25,19.9c-0.3,0.2-0.4,0.6-0.3,1l1.6,9.2c0.2,0.9-0.8,1.5-1.6,1.1l-8.2-4.3C16.2,26.7,15.8,26.7,15.5,26.8z" />
				</g>
			</svg>
			<span class="rating__sr">4 stars</span>
		</label>
		<label class="rating__label" for="rating-5">
			<svg class="rating__star" width="32" height="32" viewBox="0 0 32 32" aria-hidden="true">
				<ellipse class="rating__star-shadow" cx="16" cy="31" rx="16" ry="1" />
				<g class="rating__star-body-g">
					<path class="rating__star-body" d="M15.5,26.8l-8.2,4.3c-0.8,0.4-1.7-0.3-1.6-1.1l1.6-9.2c0.1-0.3-0.1-0.7-0.3-1l-6.7-6.5c-0.6-0.6-0.3-1.7,0.6-1.8l9.2-1.3c0.4-0.1,0.7-0.3,0.8-0.6L15,1.3c0.4-0.8,1.5-0.8,1.9,0l4.1,8.3c0.2,0.3,0.5,0.5,0.8,0.6l9.2,1.3c0.9,0.1,1.2,1.2,0.6,1.8L25,19.9c-0.3,0.2-0.4,0.6-0.3,1l1.6,9.2c0.2,0.9-0.8,1.5-1.6,1.1l-8.2-4.3C16.2,26.7,15.8,26.7,15.5,26.8z" />
				</g>
			</svg>
			<span class="rating__sr">5 stars</span>
		</label>
	</div>
</form>
<!-- partial -->
  <script  src="./script.js"></script>

</body>
</html>
CSS
* {
  border: 0;
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

:root {
  --hue: 223;
  --bg: hsl(var(--hue),90%,90%);
  --fg: hsl(var(--hue),90%,10%);
  --star: hsl(var(--hue),90%,50%);
  --star-dim: hsl(var(--hue),10%,70%);
  --star-down: hsl(var(--hue),90%,20%);
  --bezier: cubic-bezier(0.42,0,0.58,1);
  --trans-dur: 0.3s;
  font-size: calc(24px + (36 - 24) * (100vw - 320px) / (1280 - 320));
}

body {
  background-color: var(--bg);
  color: var(--fg);
  display: flex;
  font: 1em/1.5 sans-serif;
  height: 100vh;
  transition: background-color var(--trans-dur), color var(--trans-dur);
}

.rating {
  margin: auto;
}
.rating__stars {
  display: flex;
  position: relative;
}
.rating__star {
  display: block;
  overflow: visible;
  pointer-events: none;
  width: 2em;
  height: 2em;
}
.rating__star-body, .rating__star-body-g, .rating__star-shadow {
  animation-duration: 1.2s;
  animation-timing-function: var(--bezier);
  animation-fill-mode: forwards;
}
.rating__star-body {
  fill: var(--star-dim);
  transform-origin: 16px 17.45px;
  transition: fill var(--trans-dur) var(--bezier);
}
.rating__star-body-g {
  animation-name: starShrink;
  transform: scale(0.67);
  transform-origin: 16px 31px;
}
.rating__star-shadow {
  animation-name: starShadowShrink;
  fill: hsla(var(--hue), 90%, 10%, 0.3);
  transform: scale(0.67);
  transform-origin: 16px 31px;
}
.rating--pristine .rating__star-body, .rating--pristine .rating__star-body-g, .rating--pristine .rating__star-shadow {
  animation-duration: 0s;
}
.rating__label, .rating__input {
  -webkit-tap-highlight-color: transparent;
}
.rating__label {
  cursor: pointer;
  padding: 0.1875em;
}
.rating__label--delay1 .rating__star-body, .rating__label--delay1 .rating__star-body-g {
  animation-delay: 0.05s;
}
.rating__label--delay2 .rating__star-body, .rating__label--delay2 .rating__star-body-g {
  animation-delay: 0.1s;
}
.rating__label--delay3 .rating__star-body, .rating__label--delay3 .rating__star-body-g {
  animation-delay: 0.15s;
}
.rating__label--delay4 .rating__star-body, .rating__label--delay4 .rating__star-body-g {
  animation-delay: 0.2s;
}
.rating__input {
  -webkit-appearance: none;
  appearance: none;
}
.rating__input-1:hover ~ .rating__label:first-of-type .rating__star-body, .rating__input-2:hover ~ .rating__label:nth-of-type(-n + 2) .rating__star-body, .rating__input-3:hover ~ .rating__label:nth-of-type(-n + 3) .rating__star-body, .rating__input-4:hover ~ .rating__label:nth-of-type(-n + 4) .rating__star-body, .rating__input-5:hover ~ .rating__label:nth-of-type(-n + 5) .rating__star-body {
  fill: var(--star);
}
.rating__input-1:checked ~ .rating__label:first-of-type .rating__star-body, .rating__input-2:checked ~ .rating__label:nth-of-type(-n + 2) .rating__star-body, .rating__input-3:checked ~ .rating__label:nth-of-type(-n + 3) .rating__star-body, .rating__input-4:checked ~ .rating__label:nth-of-type(-n + 4) .rating__star-body, .rating__input-5:checked ~ .rating__label:nth-of-type(-n + 5) .rating__star-body {
  animation-name: starSpin;
  fill: var(--star);
}
.rating__input-1:checked ~ .rating__label:first-of-type .rating__star-body-g, .rating__input-2:checked ~ .rating__label:nth-of-type(-n + 2) .rating__star-body-g, .rating__input-3:checked ~ .rating__label:nth-of-type(-n + 3) .rating__star-body-g, .rating__input-4:checked ~ .rating__label:nth-of-type(-n + 4) .rating__star-body-g, .rating__input-5:checked ~ .rating__label:nth-of-type(-n + 5) .rating__star-body-g {
  animation-name: starJump;
}
.rating__input-1:checked ~ .rating__label:first-of-type .rating__star-shadow, .rating__input-2:checked ~ .rating__label:nth-of-type(-n + 2) .rating__star-shadow, .rating__input-3:checked ~ .rating__label:nth-of-type(-n + 3) .rating__star-shadow, .rating__input-4:checked ~ .rating__label:nth-of-type(-n + 4) .rating__star-shadow, .rating__input-5:checked ~ .rating__label:nth-of-type(-n + 5) .rating__star-shadow {
  animation-name: starShadow;
}
.rating__input-2:checked ~ .rating__label:nth-of-type(-n + 1):hover .rating__star-body, .rating__input-3:checked ~ .rating__label:nth-of-type(-n + 2):hover .rating__star-body, .rating__input-4:checked ~ .rating__label:nth-of-type(-n + 3):hover .rating__star-body, .rating__input-5:checked ~ .rating__label:nth-of-type(-n + 4):hover .rating__star-body {
  fill: var(--star-down);
}
.rating__sr {
  clip: rect(1px, 1px, 1px, 1px);
  overflow: hidden;
  position: absolute;
  width: 1px;
  height: 1px;
}

@keyframes starJump {
  from {
    transform: translateY(0) scale(0.67, 0.67);
  }
  20% {
    transform: translateY(0) scale(0.75, 0.5);
  }
  40% {
    transform: translateY(-100%) scale(1.15, 1.15);
  }
  60% {
    transform: translateY(0) scale(1.1, 0.6);
  }
  80% {
    transform: translateY(0) scale(0.95, 1.1);
  }
  to {
    transform: translateY(0) scale(1, 1);
  }
}
@keyframes starShadow {
  from {
    transform: scale(0.67, 1);
  }
  20% {
    transform: scale(0.75, 1);
  }
  40% {
    transform: scale(1.15, 1);
  }
  60% {
    transform: scale(1.1, 1);
  }
  80% {
    transform: scale(0.95, 1);
  }
  to {
    transform: scale(1, 1);
  }
}
@keyframes starShrink {
  from {
    animation-timing-function: ease-in;
    transform: scale(1, 1);
  }
  20% {
    animation-timing-function: ease-out;
    transform: scale(0.6, 0.6);
  }
  40%, to {
    transform: scale(0.67, 0.67);
  }
}
@keyframes starShadowShrink {
  from {
    animation-timing-function: ease-in;
    transform: scale(1, 1);
  }
  20% {
    animation-timing-function: ease-out;
    transform: scale(0.6, 1);
  }
  40%, to {
    transform: scale(0.67, 1);
  }
}
@keyframes starSpin {
  from, 20% {
    transform: rotate(0);
  }
  60%, to {
    transform: rotate(144deg);
  }
}
JS
window.addEventListener("DOMContentLoaded",() => {
	const rating = new BouncyStarRating("form");
});

class BouncyStarRating {
	rating = null;
	ratings = [
		{id: 1},
		{id: 2},
		{id: 3},
		{id: 4},
		{id: 5}
	];
	pristineClass = "rating--pristine";

	constructor(qs) {
		this.el = document.querySelector(qs);

		this.init();
	}
	init() {
		try {
			this.el.addEventListener("change",this.updateRating.bind(this));
			// stop Firefox from preserving form data between refreshes
			this.el.reset();
			this.el.classList.add(this.pristineClass);
		} catch (err) {
			console.error("Element isn’t a form.");
		}
	}
	updateRating(e) {
		this.el.classList.remove(this.pristineClass);
		// clear animation delays
		Array.from(this.el.querySelectorAll(`[for*="rating"]`)).forEach(el => {
			el.className = "rating__label";
		});

		const ratingObject = this.ratings.find(r => r.id === +e.target.value);
		const prevRatingID = this.rating?.id || 0;

		let delay = 0;
		this.rating = ratingObject;
		this.ratings.forEach(rating => {
			const { id } = rating;
			// add the delays
			const ratingLabel = this.el.querySelector(`[for="rating-${id}"]`);

			if (id > prevRatingID + 1 && id <= this.rating.id) {
				++delay;
				ratingLabel?.classList.add(`rating__label--delay${delay}`);
			}
		});
	}
}

Post a Comment

0Comments
Post a Comment (0)