RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1605775
Accepted
Alexandr_TT
Alexandr_TT
Asked:2025-01-28 22:41:54 +0000 UTC2025-01-28 22:41:54 +0000 UTC 2025-01-28 22:41:54 +0000 UTC

如何使 SVG 和 CSS 动画正确协同工作?

  • 772

尝试弄清楚 CSS 和 SVG 动画如何交互。为此,我采用了最简单的场景:

  1. 角色从右向左移动,同时上下移动(svg)
  2. 旋转 180 度 (css) 并
  3. 向后移动至左右 (css)

以下是代码:

body { perspective: 1000px;}

  .container{
  width:80vw;
  height:80vh;
}  
#SnowMaiden {
transform-box:fill-box;
transform-origin: center center;
animation: Maiden_rotate 2s linear 8s  forwards, Maiden_translate 14s linear 16s forwards;
}
@keyframes Maiden_rotate {
0%{ transform:  rotate3d(0,1,0,20deg);}
50%{ transform:  rotate3d(0,1,0,80deg);}
100%{ transform:  rotate3d(0,1,0,180deg);}
}
@keyframes Maiden_translate {
0%{ transform:  translate3d(300px,10px,10px);}
50%{ transform:  translate3d(800px,10px,10px);}
100%{ transform:  translate3d(1400px,10px,10px);}
}
<svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink"
            viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" > 

       <!-- Фон с ёлочкой -->
    <image id="img1" xlink:href="https://isstatic.askoverflow.dev/PBRad.jpg" width="100%" height="100%" opacity="1"   />  
    
    <image  id="SnowMaiden" x="1400" y="650"  xlink:href="https://isstatic.askoverflow.dev/LU3Bvfdr.png" opacity="0">
                  <!-- Анимация появления девочки с корзинкой -->
   <animate id="op1_Maidan" attributeName="opacity"   values="0; 1" dur="2s" begin="svg1.click"  repeatCount="1" fill="freeze" restart="whenNotActive" />   
                            <!-- Перемещение  по горизонтали -->
  <animate id="Go_Maidan" attributeName="x"   values="1400;1300;1200;1100;1000;900;800;700;600;500;400;300" dur="5s" begin="op1_Maidan.end"  repeatCount="indefinity" fill="freeze"  restart="whenNotActive"  />   
                         <!-- Перемещение по вертикали -->    
   <animate id="Go_Maidan_y" attributeName="y"   values="650;670;650;630;650;670;650;630;650;670;650;630" dur="5s" begin="op1_Maidan.end"  repeatCount="indefinity" fill="freeze"   restart="whenNotActive"  />  
</image>  
</svg>

从代码片段的结果可以看出:
180 度旋转之前的 SVG 动画阶段一切正常。故障在转弯后开始。看起来 CSS 动画与之前的 SVG 动画冲突,这就是 CSS 运动结果不可见的原因。
当然,您可以纯粹用 SVG 或仅使用 CSS 来实现动画。
我有一个问题,如何让 SVG 和 CSS 动画正确协同工作?

html
  • 2 2 个回答
  • 91 Views

2 个回答

  • Voted
  1. Best Answer
    puffleeck
    2025-01-29T05:16:13Z2025-01-29T05:16:13Z

    这与SMILvs无关。CSS只是所选的属性没有完全满足要求。

    body {perspective: 1000px}
    
    #girl {
      transform-box:fill-box;
      transform-origin: center center;
      animation: 
        mR 2s linear 9.5s forwards,
        mT 5s linear 12s forwards,
        mR 2s linear 17s reverse forwards;
    }
    @keyframes mR {
      0%    {transform: rotate3d(0,1,0,20deg)}
      50%   {transform: rotate3d(0,1,0,80deg)}
      100%  {transform: rotate3d(0,1,0,180deg)}
    }
    @keyframes mT {
    /* transform: translate не меняет исходные координаты,
    а смещает от них(300px+300px = 600px) */
      0%  {x: 300px;  y: 630px}
      10% {x: 410px;  y: 650px}
      20% {x: 520px;  y: 670px}
      30% {x: 630px;  y: 650px}
      40% {x: 740px;  y: 630px}
      50% {x: 850px;  y: 650px}
      60% {x: 960px;  y: 670px}
      70% {x: 1070px; y: 650px}
      80% {x: 1180px; y: 630px}
      90% {x: 1290px; y: 650px}
      100%{x: 1400px; y: 670px}
    }
    <svg id="xyz" version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1680 1050"
    xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet" > 
      <image width="100%" height="100%" xlink:href="https://isstatic.askoverflow.dev/PBRad.jpg"/>
      <image id="girl" x="1400" y="650" opacity="0"
        xlink:href="https://isstatic.askoverflow.dev/LU3Bvfdr.png">
    
        <animate id="spawn"
          attributeName="opacity"
          begin="xyz.click" values="0; 1"
          dur="2s" repeatCount="1" fill="freeze" restart="whenNotActive" />
    
        <animate
          attributeName="x"
          begin="spawn.end"
          values="1400;1300;1200;1100;1000;900;800;700;600;500;400;300"
          dur="5s" repeatCount="indefinity" fill="freeze" restart="whenNotActive"/>
    
        <animate
          attributeName="y"
          begin="spawn.end"
          values="650;670;650;630;650;670;650;630;650;670;650;630"
          dur="5s" repeatCount="indefinity" fill="freeze" restart="whenNotActive"/>
      </image>  
    </svg>

    • 3
  2. Alexandr_TT
    2025-02-03T00:06:43Z2025-02-03T00:06:43Z

    SVG解决方案

    增加动画包的循环:运动+旋转。
    循环是通过以下条件实现的:
    begin="op1_Maidan.end;scale_M2.end",其中
    scale_M2.end"是第一次循环后角色在起点处转动的动画的结束位置。

    .container{
      width:80vw;
      height:80vh;
    }  
    #SnowMaiden {
    transform-box:fill-box;
    transform-origin: center center;
    }
    <svg id="svg1" version="1.1" xmlns="http://www.w3.org/2000/svg" 
            xmlns:xlink="http://www.w3.org/1999/xlink"
                viewBox="0 0 1680 1050" preserveAspectRatio="xMinYMin meet" > 
    
           <!-- Фон с ёлочкой -->
        <image id="img1" xlink:href="https://isstatic.askoverflow.dev/PBRad.jpg" width="100%" height="100%" opacity="1"   />  
        
        <image  id="SnowMaiden" x="1400" y="650"  xlink:href="https://isstatic.askoverflow.dev/LU3Bvfdr.png" opacity="0">
                      <!-- Анимация появления девочки с корзинкой -->
       <animate id="op1_Maidan" attributeName="opacity"   values="0; 1" dur="2s" begin="svg1.click"  repeatCount="1" fill="freeze" restart="whenNotActive" />   
                                <!-- Перемещение  по горизонтали -->
       <animate id="Go_Maidan" attributeName="x"   values="1400;1300;1200;1100;1000;900;800;700;600;500;400;300" dur="5s" begin="op1_Maidan.end;scale_M2.end"  repeatCount="1" fill="freeze"  restart="whenNotActive"  />   
                             <!-- Перемещение по вертикали -->    
        <animate id="Go_Maidan_y" attributeName="y"   values="650;670;650;630;650;670;650;630;650;670;650;630" dur="5s" begin="Go_Maidan.begin"  repeatCount="1" fill="freeze"   restart="whenNotActive"  />  
                                  <!-- Поворот -->
          <animateTransform id="scale_M" attributeName="transform" type="scale" values="-1 1" begin="Go_Maidan_y.end" dur="0.1s" fill="freeze" />  
                                   <!-- Назад по Х     -->
        <animate id="Go_back_x" attributeName="x"   values="300;400;500;600;700;800;900;1000;1100;1200;1300;1400" dur="5s" begin="scale_M.end"  repeatCount="1" fill="freeze"  restart="whenNotActive"  />    
                                        <!-- Назад по Y -->
         <animate id="Go_back_y" attributeName="y"   values="650;670;650;630;650;670;650;630;650;670;650;630" dur="5s" begin="scale_M.end"  repeatCount="1" fill="freeze"   restart="whenNotActive"  />
         
                                 <!-- Поворот -->
          <animateTransform id="scale_M2" attributeName="transform" type="scale" values="1 1" begin="Go_back_y.end" dur="0.1s" fill="freeze" />  
        
    </image>  
    </svg>

    • 0

相关问题

  • 具有非均匀背景的块内的渐变边框

  • 离开页脚

  • 如何将三个字段的数据收集到一封电子邮件中?

  • Html 元素刚从父元素中出来

  • 如何在css中制作这个背景?

  • 如何制作带有斜条纹的背景?

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5