使用 css 动画使 div 元素移动到页面的每个角落

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

我想知道如何使用css动画让一个圆圈div元素到达页面的每个角落。我已经尝试这样做但无济于事。

很基本的问题,但它会帮助我理解。

<!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> 

CSS 变化

.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>

在我的解决方案中,我使用规则 transform: translate() translateY() 防止 动画对象创建 溢出

在此解决方案中,删除了名称为 myAnimation2 的第二个 @keyframes,因为此代码没有意义。

此外,我减小了动画元素的大小,以便在我的示例中更好地视觉感知动画。

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>

使用没有复杂关键帧的背景更简单:

.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>

考虑使用 SMIL SVG
在我看来,SMIL 是一个功能强大且灵活的动画平台,易于定制并且不需要像 CSS 动画那样在应用程序逻辑发生变化时重新计算时间。

smil 的灵活性在于,它足以改变决定动画顺序的逻辑链,这将使完全重建应用程序成为可能,而无需花费大量精力重新计算时间。

#1。一个球移动到页面角落的问题示例的解决方案

点击后开始动画

<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. 增加球到达角球时的暂停

通过重复 values 属性中的值实现暂停

<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。两个球的动画

第二个动画(红球)的开始由逻辑链控制

begin="anBlue.begin+3s"

换句话说,红球的动画会在蓝球的动画开始后3秒开始

<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>     

[奖金]

#4。从禁区两侧乱弹球的选项

<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>