I would like to know how to use css animation to make a circle div element go to each corner of the page. I have attempted to do this to no avail.
Quite a basic question, but It will help me to understand.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CSS 201</title>
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
<style>
.box {
width: 300px;
height: 300px;
border: 10px solid black;
background-color: black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
animation: myAnimation 4s infinite alternate,myAnimation2 4s infinite alternate;
}
@keyframes myAnimation {
0% { top: 0; left: 0; }
30% { top: 3000px; }
68%, 72% { left: 50px; }
100% { top: 3000px; left: 90%; }
}
@keyframes myAnimation2{
0% { bottom: 0; right: 0; }
30% { top: 3000px; }
68%, 72% { left: 50px; }
100% { top: 3000px; left: 90%; }
}
}
</style>
</head>
<body>
<div class="box"></div>
</body>
</html>
To create a CSS animation sequence, you style the element you want to animate with the animation property or its sub-properties. This lets you configure the timing, duration, and other details of how the animation sequence should progress.
you have to declare your keyframe outside the css selector, as well as animate an absolutely positioned element. Show activity on this post. To animate with left , top , bottom or right , you either have to have a absolutely positioned or floated element. SO, Change the position to absolute .
CSS Changes
.box {
width: 300px;
height: 300px;
border: 10px solid black;
background-color: black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
animation: myAnimation 4s infinite;
}
@keyframes myAnimation {
5% { top: 0; left: 0; }
25% { top: 200px; left: 0px; }
50% { top: 200px; left: calc(100% - 320px); }
75% { top: 0px; left: calc(100% - 320px); }
100% { top: 0px; left: 0; }
}
<div class="box"></div>
In my solution, I used rule transform: translate() translateY()
to prevent an animated object from creating an overflow.
In this solution, the second @keyframes
with the name myAnimation2
was removed, since there was no point in this code.
Also, I reduced the size of the animated element for a better visual perception of the animation in my example.
body {
margin: 0;
}
.box {
width: 100px;
height: 100px;
border: 10px solid black;
background-color: black;
border-radius: 50%;
position: absolute;
top: 0;
left: 0;
animation: myAnimation 4s infinite;
}
@keyframes myAnimation {
0% {
top: 0;
left: 0;
transform: translate(0) translateY(0);
}
25% {
top: 100%;
left: 0;
transform: translateX(0) translateY(-100%);
}
50% {
top: 100%;
left: 100%;
transform: translateX(-100%) translateY(-100%);
}
75% {
top: 0;
left: 100%;
transform: translateX(-100%) translateY(0);
}
100% {
top: 0;
left: 0;
transform: translateX(0) translateY(0);
}
}
<div class="box"></div>
Consider using SMIL SVG
In my opinion, SMIL is a powerful and flexible animation platform that is easily customizable and does not require, like CSS animation, recalculation of timings when the application logic changes.
The flexibility of smil lies in the fact that it is enough to change the logical chains that determine the sequence of animations and this will make it possible to completely rebuild the application without spending significant effort in recalculating timings.
#1. Solution of the example from the question one ball moves to the corners of the page
Animation starts after click
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100vw" height="95vh" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet" >
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="380" height="380" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="30" cy="30" r="3%" fill="url(#gradB)" >
<animateTransform
attributeName="transform"
type="translate"
begin="svg1.click"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,340;
0,340;
0,0;
0,0" />
</circle>
</svg>
# 2. Added pauses when the ball arrives at the corners
Pauses are implemented by repeating values in the values
attribute
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100vw" height="95vh" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet" >
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="380" height="380" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="30" cy="30" r="3%" fill="url(#gradB)" >
<animateTransform
attributeName="transform"
type="translate"
begin="svg1.click"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
</circle>
</svg>
#3. Animation of two balls
The start of the second animation (red ball) is controlled by a logical chain
begin="anBlue.begin+3s"
In words, we can say that the animation of the red ball will start 3s after the start of the animation of the blue ball
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
width="100vw" height="95vh" viewBox="0 0 400 400" preserveAspectRatio="xMinYMin meet" >
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
<radialGradient id="gradR" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="red" offset="25%"/>
<stop stop-color="rgb(192,0,0)" offset="50%"/>
<stop stop-color="rgb(127,0,0)" offset="70%"/>
<stop stop-color="rgb(64,0,0)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect x="10" y="10" width="380" height="380" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<!-- Red ball -->
<circle cx="30" cy="30" r="3%" fill="url(#gradR)" >
<!-- Red ball animation -->
<animateTransform id="anRed"
attributeName="transform"
type="translate"
begin="anBlue.begin+3s"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
</circle>
<!-- Blue ball -->
<circle cx="30" cy="30" r="3%" fill="url(#gradB)" >
<!-- Blue ball animation -->
<animateTransform id="anBlue"
attributeName="transform"
type="translate"
begin="svg1.click"
dur="9s"
restart="whenNotActive"
repeatCount="indefinite"
fill="freeze"
values="
0,0;
340,0;
340,0;
340,340;
340,340;
0,340;
0,340;
0,0;
0,0" />
</circle>
</svg>
[BONUS]
#4. Option with a chaotic rebound of balls from the sides of the box
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" height="100vh" viewBox="0 0 400 400">
<defs>
<radialGradient id="gradB" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="blue" offset="25%"/>
<stop stop-color="rgb(0,0,192)" offset="50%"/>
<stop stop-color="rgb(0,0,127)" offset="70%"/>
<stop stop-color="rgb(0,0,64)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
<radialGradient id="gradR" cx="20%" cy="20%" r="100%" fx="30%" fy="30%">
<stop stop-color="white" offset="0"/>
<stop stop-color="red" offset="25%"/>
<stop stop-color="rgb(192,0,0)" offset="50%"/>
<stop stop-color="rgb(127,0,0)" offset="70%"/>
<stop stop-color="rgb(64,0,0)" offset="85%"/>
<stop stop-color="rgb(0,0,0)" offset="100%"/>
</radialGradient>
</defs>
<rect width="100%" height="100%" rx="25" fill="green" stroke="#9D8500" stroke-width="15"/>
<circle cx="50%" cy="20%" r="3%" fill="url(#gradB)" >
<animate attributeName="cx" dur="3" values="3%;97%;3%"
repeatCount="indefinite" />
<animate attributeName="cy" dur="2.8" values="3%;97%;3%"
repeatCount="indefinite" />
</circle>
<circle cx="30%" cy="70%" r="3%" fill="url(#gradR)" >
<animate attributeName="cx" dur="2.7" values="97%;3%;97%"
repeatCount="indefinite" />
<animate attributeName="cy" dur="3.1" values="3%;97%;3%"
repeatCount="indefinite" />
</circle>
</svg>
Easier idea using background with no complex keyframes:
.box {
background:
radial-gradient(farthest-side,black 97%,transparent)
top left/100px 100px /* simply adjust the values here to control the size of the circle */
no-repeat;
position: fixed;
top: 0;
left: 0;
right:0;
bottom:0;
animation: move 4s infinite;
}
@keyframes move {
25% { background-position: bottom left }
50% { background-position: bottom right }
75% { background-position: top right }
}
<div class="box"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With