DEV Community

Cover image for Create Dynamic Spinners only using CSS
Tapajyoti Bose
Tapajyoti Bose

Posted on

Create Dynamic Spinners only using CSS

In this blog we will be creating the Pizza Spinner depicted in the Cover Image.

Getting Started

We would be using the following image of a Pizza Slice to generate the entire pizza.

Pizza Slice

The shell of the HTML would be

<div class="spinner">
  <img src="<link to image>" class="pizza-part pizza-part-1" />
  <img src="<link to image>" class="pizza-part pizza-part-2" />
  <img src="<link to image>" class="pizza-part pizza-part-3" />
  <img src="<link to image>" class="pizza-part pizza-part-4" />
</div>
Enter fullscreen mode Exit fullscreen mode

Breaking Down the Animation

Any complex animation can be broken down into a series of simple animations. Let's breaking down the animation into the corresponding components:

  • Each of the pizza slice uses opacity to make the impression of fading in & out
  • Each of the pizza slice also uses transform to rotate (to the required position to generate the appearance of a complete pizza) and translate (to generate the animation of picking the slice off the pizza)
  • The main container spins about its center making it look even more dynamic

The CSS for the spinner would be

.spinner {
  width: 160px;
  height: 160px;
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  animation: spin 4s linear infinite;
}

.pizza-part {
  width: 80px;
  height: 80px;
}

.pizza-part-1 {
  animation: pizza1 2s ease-in-out infinite;
}

.pizza-part-2 {
  animation: pizza2 2s ease-in-out infinite;
}

.pizza-part-3 {
  animation: pizza4 2s ease-in-out infinite;
}

.pizza-part-4 {
  animation: pizza3 2s ease-in-out infinite;
}

/* animations */
@keyframes spin {
  0% {
    transform: rotateZ(0deg);
  }
  100% {
    transform: rotateZ(360deg);
  }
}

@keyframes pizza1 {
  0% {
    transform: translate(-20%, -20%);
    opacity: 0;
  }
  10% {
    transform: translate(0%, 0%);
    opacity: 1;
  }
  50% {
    transform: translate(0%, 0%);
    opacity: 1;
  }
  60% {
    transform: translate(-20%, -20%);
    opacity: 0;
  }
  100% {
    transform: translate(-20%, -20%);
    opacity: 0;
  }
}

@keyframes pizza2 {
  0% {
    transform: translate(20%, -20%) rotateZ(90deg);
    opacity: 0;
  }
  10% {
    transform: translate(20%, -20%) rotateZ(90deg);
    opacity: 0;
  }
  20% {
    transform: translate(0%, 0%) rotateZ(90deg);
    opacity: 1;
  }
  60% {
    transform: translate(0%, 0%) rotateZ(90deg);
    opacity: 1;
  }
  70% {
    transform: translate(20%, -20%) rotateZ(90deg);
    opacity: 0;
  }
  100% {
    transform: translate(20%, -20%) rotateZ(90deg);
    opacity: 0;
  }
}

@keyframes pizza3 {
  0% {
    transform: translate(20%, 20%) rotateZ(180deg);
    opacity: 0;
  }
  20% {
    transform: translate(20%, 20%) rotateZ(180deg);
    opacity: 0;
  }
  30% {
    transform: translate(0%, 0%) rotateZ(180deg);
    opacity: 1;
  }
  70% {
    transform: translate(0%, 0%) rotateZ(180deg);
    opacity: 1;
  }
  80% {
    transform: translate(20%, 20%) rotateZ(180deg);
    opacity: 0;
  }
  100% {
    transform: translate(20%, 20%) rotateZ(180deg);
    opacity: 0;
  }
}

@keyframes pizza4 {
  0% {
    transform: translate(-20%, 20%) rotateZ(-90deg);
    opacity: 0;
  }
  30% {
    transform: translate(-20%, 20%) rotateZ(-90deg);
    opacity: 0;
  }
  40% {
    transform: translate(0%, 0%) rotateZ(-90deg);
    opacity: 1;
  }
  80% {
    transform: translate(0%, 0%) rotateZ(-90deg);
    opacity: 1;
  }
  90% {
    transform: translate(-20%, 20%) rotateZ(-90deg);
    opacity: 0;
  }
  100% {
    transform: translate(-20%, 20%) rotateZ(-90deg);
    opacity: 0;
  }
}
Enter fullscreen mode Exit fullscreen mode

Demo

Project using this Implementation

Pizza Man

Web-app: http://pizza-man-61510.firebaseapp.com/

GitHub logo ruppysuppy / Pizza-Man

πŸ•πŸ›’ An e-commerce website to order pizza online

Pizza Man Project

An E-Commerce website for ordering Pizza Online

Demo

NOTE: The features shown in the demo is not exhaustive. Only the core features are showcased in the demo.

Tools used

  1. React: To create the Single Page App
  2. React-Router: For Routing
  3. Redux: For State Management
  4. Firebase: As a DataBase

Firebase Setup

You need to create a firebase configeration file holding the firebase settings in the path /src/firebase/config.js. The required format is:

const firebaseConfig = {
    apiKey: "API-KEY",
    authDomain: "AUTH-DOMAIN.firebaseapp.com",
    databaseURL: "DATABASE-URL.firebaseio.com",
    projectId: "PROJECT-ID",
    storageBucket: "STORAGE-BUCKET.appspot.com",
    messagingSenderId: "MESSAGING-SENDER-ID",
    appId: "APP-ID",
    measurementId: "MEASUREMENT-ID",
};

export default firebaseConfig;
Enter fullscreen mode Exit fullscreen mode

Data needs to be stored in the following format:

[
    {
        name: "CATEGORY NAME",
        items: [
            {
                desc: "PIZZA DESCRIPTION",
                id: "ID",
                img: "IMAGE LINK",
                name
…
Enter fullscreen mode Exit fullscreen mode

Thanks for reading

Reach out to me on:

Discussion (9)

Collapse
maureento8888 profile image
Maureen T'O

Adorable spinner! Definitely going to play around with these in my next side projects πŸ‘πŸΌ

Collapse
ruppysuppy profile image
Tapajyoti Bose Author • Edited on

A small suggestion, use svg instead of png (unlike what's done here as dev.to doesn't support svg images in blogs), its smaller in size & scales as well

Collapse
maureento8888 profile image
Maureen T'O

Ahh yes thank you! SVGs are the win for icons and don’t lose resolution ❀️

Collapse
fernandoboza profile image
Fernando Boza

i love it, it's so cute

Collapse
ruppysuppy profile image
Tapajyoti Bose Author

Thanks!

Collapse
georgedoescode profile image
George Francis

So good!

Collapse
ruppysuppy profile image
Tapajyoti Bose Author

Thankyou! :)

Collapse
arvindsridharan profile image
arvindsridharan

Hey Tap! That's a cool post. Amazing.

Collapse
ruppysuppy profile image
Tapajyoti Bose Author

Thanks a lot! :)