SVG: можно ли использовать случайные или нестатические значения?

Я анимирую форму многоугольника внутри SVG (поэтому ее можно использовать в качестве фона в CSS). Мне любопытно, есть ли способ случайным образом сгенерировать значение для использования или какой-либо другой способ, чтобы анимация не всегда начиналась с одной и той же позиции при каждой загрузке (без использования внешней библиотеки SVG и без использования JavaScript)?

Вот текущий 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>

person gokujou    schedule 04.11.2014    source источник
comment
Нет, если вы собираетесь использовать его в качестве фона, потому что javascript будет отключен, если только вы не сгенерируете весь фон динамически как URL-адрес данных в основном документе.   -  person Robert Longson    schedule 04.11.2014
comment
Итак, SVG не хватает функциональности для этого... :(   -  person gokujou    schedule 04.11.2014
comment
Хорошо, если это не фон, вы можете генерировать случайные числа и создавать элементы с помощью javascript. Если вы ограничены разметкой и SMIL, то нет никакого способа получить случайность.   -  person Robert Longson    schedule 04.11.2014


Ответы (2)


Мне любопытно, есть ли способ случайным образом сгенерировать значение для использования или какой-либо другой способ, чтобы анимация не всегда начиналась с одной и той же позиции при каждой загрузке (без использования внешней библиотеки SVG и без использования JavaScript)?

Краткий ответ: нет

Теоретически невозможно выполнить ваше условие без JS в SVG, так как нет функции генерации случайных чисел
Также в 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>

person Alexandr_TT    schedule 26.10.2020

Вы можете добавить минус 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>

person enxaneta    schedule 25.10.2020