Here is the rewritten article:
—
Time for part two! This time, we will explore how to start and stop infinite animations smoothly. The goal is to achieve a natural and realistic effect. As in the previous article, we will examine the effects using rotation and then move on to additional examples.
## Smooth Starts
Hover over the element in the demo below. The element begins rotating slowly, then reaches a constant speed. When you unhover, it stops slowly as well. Cool, right? It’s even more satisfying if you keep hovering and unhovering.
This effect is achieved as follows:
“`css
.box {
animation: rotate 2s linear infinite paused;
transition: transform 1s ease-out;
}
.box:hover {
animation-play-state: running;
transform: rotate(-.2turn);
}
@keyframes rotate {
to { transform: rotate(1turn); }
}
“`
The technique involves using an animation and a transition. On hover, the infinite linear animation starts playing (it’s initially paused), and a transition is triggered.
During the first second, the transition creates a “brake” effect on the animation, then the linear behavior of the animation takes over, resulting in a constant speed rotation. Upon unhovering, the animation pauses, and the transition smoothly stops the element. Picking the right values is crucial for the illusion to work.
The same code can be modified to have the animation running initially and then smoothly stop on hover:
“`css
.box {
animation: rotate 2s linear infinite paused;
transition: transform 1s ease-out;
}
.box:not(:hover) {
animation-play-state: running;
transform: rotate(-.2turn);
}
@keyframes rotate {
to { transform: rotate(1turn); }
}
“`
Or you can write it this way:
“`css
.box {
animation: rotate 2s linear infinite;
transition: transform 1s ease-out;
}
.box:hover {
animation-play-state: paused;
transform: rotate(.2turn);
}
@keyframes rotate {
to { transform: rotate(1turn); }
}
“`
## More Examples
The main trick relies on defining rotation using two properties (transform and rotate). We can find alternatives for other properties, such as using an infinite marquee animation. Hover to start the animation.
“`css
img {
animation: x linear infinite var(–d) calc(-1*sibling-index()*var(–d)/sibling-count()) paused;
transition: translate .8s ease-out;
}
.container:hover img {
animation-play-state: running;
translate: -50px;
}
@keyframes x {
to { offset-distance: 100%; }
}
“`
For a glowing border, CSS variables are used:
“`css
img {
mask:
conic-gradient(#000 0 0) content-box,
linear-gradient(calc(45deg + var(–a) + var(–b)), #0000 30%,#000 40% 60%,#0000 70%) subtract,
conic-gradient(#000 0 0) padding-box;
animation: rotation 2s linear infinite paused;
transition: –b .8s ease-out;
}
img:hover {
animation-play-state: running;
–b: -.2turn;
}
@keyframes rotation {
to {–a: 1turn}
}
“`
Variables `–a` and `–b` are summed to change the angle of the gradient, achieving the “additive effect.”
## Stop There!
We can control the speed of infinite animations and smooth their stopping and starting. To control the stop position, define an infinite animation using `@starting-style`.
“`css
@property –a {
syntax: “”;
inherits: false;
initial-value: -100turn;
}
.box {
rotate: var(–a);
transition: –a 200s linear;
@starting-style {
–a: 0turn;
}
}
“`
The large values create the illusion of an infinite animation. Upon hover, the element will always return to the same position. On unhover, the animation resumes.
We introduce a new variable:
“`css
@property –a {
syntax: “”;
inherits: false;
initial-value: -100turn;
}
@property –i {
syntax: “”;
inherits: false;
initial-value: 1;
}
.box {
rotate: calc(mod(var(–a),1turn)*var(–i));
transition: –i 0s, –a 200s linear;
@starting-style {
–a: 0turn;
}
}
.box:hover {
–i: 0;
–a: 0turn;
transition: —
