SVG:是否可以使用随机或非静态值?

时间:2014-11-04 17:38:18

标签: animation svg svg-animate

我在SVG中设置多边形形状的动画(因此它可以用作CSS中的背景)。我很好奇是否有一种方法可以随机生成要使用的值,或者其他一些方式,因此每次加载时动画并不总是从相同的位置开始(不使用外部SVG库)?

这是当前的SVG:

<polygon style="stroke:rgb(255,0,0);fill:transparent;" points="0,0 121.5,150 600,0 ">
    <animate attributeName="points" dur="24s" values="0,20 121.5,150 600,0; 0,100 571.5,150 306.5,0; 0,20 121.5,150 600,0" repeatCount="indefinite" keyTimes="0; 0.5; 1" calcMode="spline" keySplines=".5 0 .5 1; .5 0 .5 1" />
</polygon>

2 个答案:

答案 0 :(得分:4)

我很好奇是否有一种方法可以随机产生一个要使用的值, 或其他方式,因此动画并非总是以相同的方式开始 每次加载时定位(无需使用外部SVG库 而不使用JavaScript)?

简短回答:否

在SVG中,如果没有JS,从理论上讲不可能满足您的条件,因为没有生成随机数的功能
同样,在SVG中,没有数组可以存储多边形的坐标并调用它们以随机方式进行渲染。

但是在SVG中,您可以创建随机运动的错觉,例如任何单词的字母。
SVG中的字母是矢量元素,因此每个字母都有自己的x y坐标
例如,如果您使用标签Stackoverflow

添加单词<text>

<text id="text1" x="200" y="500" font-size="90">Stackoverflow</text>

然后这个单词的每个字母都有自己的坐标,改变它们可以实现字母随机运动的错觉

看看代码,坐标就像数组一样写。如果启动坐标动画,则会创建字母随机运动的错觉。

在下面的示例中,动画将在单击后开始

<style>
 #text1 {

fill:#D0FF00;
}
 
</style>
<svg id="svg1" width="70%" height="70%" viewBox="0 0 1000 1000" 
  xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny"
  xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet">
 
    <title>Animation of text x and y attributes</title> 
    

<defs>
<linearGradient id="grad"
    x1="0" y1="0" x2="0" y2="100%"
    gradientUnits="userSpaceOnUse">
        <stop offset="2%" stop-color="#151515" />
          <stop offset="70%" stop-color="yellowgreen" />
    </linearGradient>
</defs> 
 <rect width="100%" height="100%" fill="url(#grad)" />
<text  x="200 " y="500" 
font-size="90" fill="#d3d3d3" stroke-width="1" stroke="#d3d3d3">Stackoverflow</text> 
<text id="text1" x="200" y="500"
font-size="90">Stackoverflow</text> 

<animate xlink:href="#text1" 
      attributeName="x" 
      attributeType="XML"
    values="200 233 266 299 332 365 400 431 464 497 530 563 596;
    100 600 200 365 700 465 465 563 530 398 431 850 900; 
    200 500 900 950 150 531 300 620 150 266 365 650 900;
    332 233 820 300 800 633 200 670 300 850 800 530 266;
    464 900 900 900 820 670 430 900 530 600 233 365 100;
    332 100 100 100 500 100 800 563 900 700 900 100 100;
    200 233 266 299 332 365 400 431 464 497 530 563 596"
    dur="4s"
    begin="svg1.click"
    repeatCount="2" />
<animate xlink:href="#text1"
      attributeName="y" 
      attributeType="XML"
    values="500 500 500 500 500 500 500 500 500 500 500 500 500;
    100 200 850 100 250 175 750 100 750 720 850 500 50; 
    100 600 600 250 200 450 50 200 520 550 300 300 750;
    500 100 650 650 600 150 550 50 150 550 200 550 400; 
    800 300 100 750 150 650 75 350 550 700 755 120 800;
    800 600 300 150 750 350 700 650 200 250 500 650 100;
    500 500 500 500 500 500 500 500 500 500 500 500 500"
        dur="3s"
      begin="svg1.click"
        repeatCount="2" />
</svg>

另一个例子

<style>
 #text1 {

fill:yellow;
}
 
</style>
<svg id="svg1" width="70%" height="70%" viewBox="0 0 1000 1000" 
  xmlns="http://www.w3.org/2000/svg" version="1.1" baseProfile="tiny"
  xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMinYMin meet">

<defs>
<linearGradient id="grad"
    x1="0" y1="0" x2="0" y2="100%"
    gradientUnits="userSpaceOnUse">
        <stop offset="2%" stop-color="black" />
        <stop offset="75%" stop-color="red" />
    </linearGradient>
</defs> 
 <rect width="100%" height="100%" fill="url(#grad)" />
<text  x="200 " y="500" 
font-size="90" fill="#E4E4E4" stroke-width="1" stroke="#E4E4E4">Stackoverflow</text> 
<text id="text1" x="200" y="500"
font-size="90">Stackoverflow</text> 

<animate xlink:href="#text1" 
    attributeName="x" 
    attributeType="XML"
        values="200 233 266 299 332 365 400 431 464 497 530 563 596;
    100 600 200 365 700 465 465 563 530 398 431 850 900; 
    200 500 900 950 150 531 300 620 150 266 365 650 900;
    332 233 820 300 800 633 200 670 300 850 800 530 266;
    464 900 900 900 820 670 430 900 530 600 233 365 100;
    332 100 100 100 500 100 800 563 900 700 900 100 100;
    200 233 266 299 332 365 400 431 464 497 530 563 596"
    dur="3s"
    begin="svg1.click"
    repeatCount="2" />
<animate xlink:href="#text1"
    attributeName="y" 
    attributeType="XML"
        values="500 500 500 500 500 500 500 500 500 500 500 500 500;
    100 200 850 100 250 175 750 100 750 720 850 500 50; 
    100 600 600 250 200 450 50 200 520 550 300 300 750;
    500 100 650 650 600 150 550 50 150 550 200 550 400; 
    800 300 100 750 150 650 75 350 550 700 755 120 800;
    800 600 300 150 750 350 700 650 200 250 500 650 100;
    500 500 500 500 500 500 500 500 500 500 500 500 500"
    dur="4s"
    begin="svg1.click"
    repeatCount="2" />


</svg>

台球动画示例

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

在这里,随机跳动球的错觉是通过将坐标彼此更改为百分比来实现的。 此外,每个球都设置了不同的动画时间。

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

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

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

</svg>

答案 1 :(得分:2)

您可以在动画中添加负数begin。使用的值可能是随机的。

在下一个示例中,我使用相同的多边形和相同的动画。唯一不同的是用于begin

的值

svg{border:solid;width:45%}
<svg viewBox="0 0 600 150">

  <polygon style="stroke:rgb(255,0,0);fill:transparent;" points="0,0 121.5,150 600,0 ">
    <animate attributeName="points" 
             dur="24s" 
             values="0,20 121.5,150 600,0; 
                     0,100 571.5,150 306.5,0; 
                     0,20 121.5,150 600,0" 
             repeatCount="indefinite" 
             keyTimes="0; 0.5; 1" 
             calcMode="spline" 
             keySplines=".5 0 .5 1; .5 0 .5 1"
             begin="-5s"/>
  </polygon>

  </svg>
<svg viewBox="0 0 600 150">

  <polygon style="stroke:rgb(255,0,0);fill:transparent;" points="0,0 121.5,150 600,0 ">
    <animate attributeName="points" 
             dur="24s" 
             values="0,20 121.5,150 600,0; 
                     0,100 571.5,150 306.5,0; 
                     0,20 121.5,150 600,0" 
             repeatCount="indefinite" 
             keyTimes="0; 0.5; 1" 
             calcMode="spline" 
             keySplines=".5 0 .5 1; .5 0 .5 1"
             begin="-15s"/>
  </polygon>

  </svg>