CSS3 rotation animation - begins to rotate and then halts at a specific angle

I attempted to develop a function that initiates a spin, replaces an image, and then stops the spin.

However, when I remove the spin class, it jerks abruptly. How can I halt the spinning smoothly at a specific frame?

setTimeout(function() {
  $('.image').addClass("spinner");
}, 400);
setTimeout(function() {
  $('.image').removeClass("spinner");
}, 1500);
.image {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
}

.spinner {
  -webkit-animation: spin 1s linear infinite;
  -moz-animation: spin 1s linear infinite;
  animation: spin 1s linear infinite;
  -webkit-animation-fill-mode: forwards;
  /* Safari 4.0 - 8.0 */
  animation-fill-mode: forwards;
}

@-moz-keyframes spin {
  100% {
    -moz-transform: rotate(360deg);
  }
}

@-webkit-keyframes spin {
  100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes spin {
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="image" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">

original code http://jsfiddle.net/m6z4jgdq/

updated example http://jsfiddle.net/m6z4jgdq/2/

Answer №1

To make your image rotate just once, simply remove the infinite iteration count from your CSS animation:

.spinner {
  -webkit-animation: spin 1s linear;
  -moz-animation: spin 1s linear;
  animation: spin 1s linear;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards; 
  animation-delay: 400ms; /* start after 400ms */
}

This adjustment allows the spinning image to naturally stop at 360° without any abrupt changes. Plus, you can set an animation-delay of 400ms if you prefer starting the rotation with a delay instead of using JavaScript and setTimeout:

.image {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
}

.spinner {
  -webkit-animation: spin 1s linear;
  -moz-animation: spin 1s linear;
  animation: spin 1s linear;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  animation-delay: 400ms;
}

@-moz-keyframes spin {
  100% {
    -moz-transform: rotate(360deg);
  }
}

@-webkit-keyframes spin {
  100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes spin {
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="image spinner" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">

To specify how many times the animation should repeat, include the count in the animate CSS style. For example, to have it spin three times:

animation: spin 1s linear 3;

.image {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
}

.spinner {
  -webkit-animation: spin 1s linear 3;
  -moz-animation: spin 1s linear 3;
  animation: spin 1s linear 3;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  animation-delay: 400ms;
}

@-moz-keyframes spin {
  100% {
    -moz-transform: rotate(360deg);
  }
}

@-webkit-keyframes spin {
  100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes spin {
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="image spinner" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">

If you desire a delay between each spin, define keyframes that pause the rotation and adjust the animation duration accordingly:

.image {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 120px;
  height: 120px;
  margin: -60px 0 0 -60px;
}

.spinner {
  -webkit-animation: spin 2s linear 3;
  -moz-animation: spin 2s linear 3;
  animation: spin 2s linear 3;
  -webkit-animation-fill-mode: forwards;
  animation-fill-mode: forwards;
  animation-delay: 400ms;
}

@-moz-keyframes spin {
  50%, 100% {
    -moz-transform: rotate(360deg);
  }
}

@-webkit-keyframes spin {
  50%, 100% {
    -webkit-transform: rotate(360deg);
  }
}

@keyframes spin {
  50%, 100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img class="image spinner" src="http://makeameme.org/media/templates/120/grumpy_cat.jpg" alt="" width="120" height="120">

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Display an image on click using jQuery and smoothly fade it in once it has fully loaded

I'm curious if there's a way to achieve this. Currently, the fadeIn effect doesn't seem to work when I run the test. It seems like it triggers as soon as the image tag is in the document, but only actually displays once the entire image has ...

Reducing the amount of text displayed on ion-text to a minimum

HTML: <ion-list *ngFor="let message of messages"> <ion-item lines="none" type="button" button="true"> <ion-grid> <ion-row> <ion-col class="message"> <ion-text> ...

What could be causing the alignment issue with this html photo gallery?

Struggling to center a photo library on my webpage is really frustrating me. Does anyone have any tips? I've experimented with different ways to center it in the code, but nothing seems to do the trick :/ HTML: <div style="display: inline-block; ...

Can someone explain how to replicate the jQuery .css function using native JavaScript?

When referencing an external CSS file, the code may look something like this: #externalClass { font-family: arial; } Within the HTML file, you would use it like so: <a href="#" id="externalClass">Link</a> In the JavaScript file, you can ret ...

The error code 13:5 indicates that the "Home" component has been registered in the Vue application but is not being used, leading to the error message "vue/no-unused-components"

I encountered this issue while working with Vue for the first time. I was attempting to construct a website using Vue/CLI by reorganizing and building from the inside out. However, I am unfamiliar with Vue and unsure how to resolve this error. The changes ...

Tips for resizing a browser window using an HTML element

I decided to add a unique feature to my website - a handle in the bottom right corner that users can grab and drag to the left to see how the design adapts to different browser window sizes (Responsive Design). To implement this, I included the following ...

How should HTML5 type "month" be stored in a Django model's database using which data type?

My HTML form includes a field for inputting a month <input type='month' name="last_appraisal" id='txtLastAppraisal' value='2013-12' /> In the Django model, I have defined this field as last_appraisal = models.DateFie ...

Creating a Dual Linear Gradient Background with Tailwind: Step-by-Step Guide

Can you use two linear backgrounds on a single element in Tailwind CSS? I found this CSS code that seems to achieve it: background-image: linear-gradient(to right, #f8fafb 50%, #161616 50%), linear-gradient(to right, #161616 50%, #f8fafb 50%); I att ...

Tips for efficiently obtaining JSON Ajax data, saving it to local storage, and presenting it in a jQuery Mobile list view

Upon calling ajax to my server, I receive 1000 units of data which I then store in my local storage before displaying it on a jQuery mobile list-view. However, this process takes around 50-60 seconds to complete. Is there a way to optimize this and make it ...

The validation of the form does not seem to be functioning properly when the 'required' rule is used

I have implemented the Required form validation in my input fields to prevent submission with empty data. However, it seems like my required validation is not functioning as expected. function AddCar() { const [chasis, setChasis] = useState("" ...

Why do the checkbox values consistently appear as null after sending a post request with Ajax to a Controller?

When making an Ajax call to send data to a controller in my ASP.NET Core application, the function grabs a value from an input box and iterates through a div to collect the values of checked checkboxes into an array. The issue arises when the data is sent ...

Switching iframe content based on screen size

I'm attempting to use jQuery to dynamically change the source, width, and height of an iframe based on the viewport width. Here is the code I currently have: <head> <script type="text/javascript"> $(document).ready(function() ...

The AppBar is consuming space and obstructing other elements on the

As I dive into React/Material-UI and learn the ropes of CSS, I've come across a challenge with my simple page layout featuring an AppBar. Unfortunately, this AppBar is overlapping the elements that should be positioned below it. In my quest for a sol ...

Having difficulty initializing jQuery DataTables upon button click with an Ajax request

I have a piece of HTML code that represents a partial view: <table id="table_id" class="table table-inverse"> <thead class="thead-inverse"> <tr> <th>Select</th> ...

What is the best way to apply an outer border to a table using CKEDITOR?

Is there a way to only add an outer border to an HTML table in CKEDITOR? I've attempted to remove the inner borders using the advanced options in CKEDITOR, but it doesn't seem to be working. <table border="1" cellpadding="1" cellspacing="1" ...

Issue with Material-UI's DataGrid scrollbar not displaying on the screen

I have a DataGrid set up with at least 20 rows. My goal is to limit its height and allow users to navigate through the remaining rows using the scroll bar within the component. However, I'm facing an issue as the scrollbar for the DataGrid itself is n ...

Consolidate HTML project into a unified HTML file

In my current project, I am working with a static HTML report that is organized in the structure outlined below: 1.css 2.font 3.js 4.pages 5.attachments 6.index.html I would like to know how I can combine all these elements to create a unified 'repor ...

closing the space between rows at the top

Having trouble adjusting the top margin to match the left and right margins between items. How can I narrow the top gap so it aligns with the spacing of each bootstrap button? https://i.stack.imgur.com/1dZEC.jpg html <div ng-controller="RecipeCo ...

Issues with ng-bind-html in AngularJS and JavaScript are preventing it from functioning

I am experimenting with creating a dynamic webpage that can change its contents without being limited to predefined templates (potentially offering infinite template options). Below is the code I am currently testing: <!DOCTYPE html> <html lang= ...

What is the best way to verify HTML using RSS?

Looking to improve my skills in HTML/CSS/PHP development, I'm faced with a challenge when it comes to validating code that contains content beyond my control, such as an RSS feed. For instance, on my home page, which is a .php document containing bot ...