Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using css animation to make a div element move to each corner of the page

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> 
like image 638
Stefan Avatar asked Mar 26 '21 07:03

Stefan


People also ask

Can you animate a div in CSS?

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.

Can you animate position CSS?

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 .


Video Answer


4 Answers

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>
like image 179
Lalji Tadhani Avatar answered Oct 26 '22 23:10

Lalji Tadhani


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>
like image 21
s.kuznetsov Avatar answered Oct 26 '22 23:10

s.kuznetsov


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>
like image 26
Alexandr_TT Avatar answered Oct 27 '22 00:10

Alexandr_TT


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>
like image 41
Temani Afif Avatar answered Oct 26 '22 23:10

Temani Afif