Rebuilding the entire image from the serialized URL data is too time-consuming. A more efficient approach is to manually create the SVG code and animate the gradientTransform
attribute. The code snippet below demonstrates rendering the <svg>
element directly within the <body>
tag of an HTML page.
There are two ways to declaratively implement the animation, both with their compatibility issues:
- A SMIL animation using the
<animateTransform>
element will not function on Edge/IE browsers.
- A CSS animation necessitates the utilization of the
gradientTransform
attribute defined as a presentation attribute, a feature introduced in SVG 2 that is not universally supported by all browsers (it is currently not functional on Firefox).
Thus, the scripted version is the optimal approach. It is advised to utilize the window.requestAnimationFrame()
method to ensure smooth execution of the animation based on the browser's capability.
let start = null;
const gradient = document.querySelector('#a');
function step(timestamp) {
if (!start) start = timestamp;
const degree = (timestamp - start) / 30 % 360;
gradient.setAttribute('gradientTransform', `rotate(${degree},814,458)`);
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
body { height: 100vh; margin: 0; }
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
<defs>
<linearGradient id="a" gradientUnits="userSpaceOnUse" x1="0" x2="0" y1="0" y2="100%" gradientTransform="rotate(0,814,458)">
<stop offset="0" stop-color="#0f63ff"/>
<stop offset="1" stop-color="#d90fff"/>
</linearGradient>
<pattern patternUnits="userSpaceOnUse" id="b" width="504" height="420" x="0" y="0" viewBox="0 0 1080 900">
<g fill-opacity="0.15">
<polygon fill="#444" points="90 150 0 300 180 300"/>
<polygon points="90 150 180 0 0 0"/>
<polygon fill="#AAA" points="270 150 360 0 180 0"/>
<polygon fill="#DDD" points="450 150 360 300 540 300"/>
<polygon fill="#999" points="450 150 540 0 360 0"/>
<polygon points="630 150 540 300 720 300"/>
<polygon fill="#DDD" points="630 150 720 0 540 0"/>
<polygon fill="#444" points="810 150 720 300 900 300"/>
<polygon fill="#FFF" points="810 150 900 0 720 0"/>
<polygon fill="#DDD" points="990 150 900 300 1080 300"/>
...
<polygon fill="#DDD" points="1080 900 1170 750 990 750"/>
</g>
</pattern>
</defs>
<rect x="0" y="0" fill="url(#a)" width="100%" height="100%"/>
<rect x="0" y="0" fill="url(#b)" width="100%" height="100%"/>
</svg>