I am animating a polygon shape all within an SVG (so it can be used as a background in CSS). I am curious if there is a way to randomly generate a value to use, or some other way so the animation does not always start at the same position each time it is loaded (without using an external SVG library and without using JavaScript)?
Here is the current 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>
Elements cannot act randomly in CSS because we have no random function to control them with, but elements can still appear to act randomly by using an intricate form of animation.
SVG supports the ability to change vector graphics over time, to create animated effects. SVG content can be animated in the following ways: Using SVG's animation elements [svg-animation]. SVG document fragments can describe time-based modifications to the document's elements.
random in sass is like randomly choosing the name of a main character in a story. it's only random when written. it doesn't change. In other words, as soon as the CSS is processed, randomization is over.
I am curious if there is a way to randomly generate a value to use, or some other way so the animation does not always start at the same position each time it is loaded (without using an external SVG library and without using JavaScript)?
Short answer: No
It is theoretically impossible to fulfill your condition without JS in SVG since there is no function for generating random numbers
Also in SVG there are no arrays where you could store the coordinates of polygons and call them for rendering in a random way.
But in SVG, you can create the illusion of random movement, for example, the letters of any word.
Letters in SVG are vector elements, so each letter has its own x
and y
coordinates
If you add for example the word Stackoverflow
using the tag<text>
<text id="text1" x="200" y="500" font-size="90">Stackoverflow</text>
Then each letter of this word will have its own coordinates, changing which you can achieve the illusion of random movement of letters
Look at the code, the coordinates are written like an array. If you start the animation of coordinates, then the illusion of random movement of letters will be created.
In the example below, the animation will start after clicking
<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>
One more example
<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>
Example with animation of billiard balls
<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>
Here, the illusion of random bouncing balls is achieved by changing the coordinates as a percentage of each other. In addition, different animation times are set for each ball.
<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>
You may add a negative begin
to the animation. The value used may be random.
In the next example I'm using the same polygon and the same animation. The only different thing is the value used for the 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>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With