I have trouble applying all transformations matrices in svg file. If file contains only paths, and without gradients - all works fine. But after adding and applying gradientTransform to linearGradient causes rendering errors.
Algorithm:
Input file:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="linearGradient3755">
<stop offset="0" />
<stop offset="1" stop-opacity="0" />
</linearGradient>
<linearGradient id="linearGradient3761" xlink:href="#linearGradient3755" x1="16.162441" y1="66.128159" x2="117.17769" y2="66.128159" gradientUnits="userSpaceOnUse" />
</defs>
<g transform="translate(0,-924.36218)">
<g transform="matrix(0.95516166,-0.46694301,0.71994792,0.61949768,-706.90347,408.6637)">
<path d="M 2.1428571,3 L 126.07143,3 L 126.07143,123 L 2.1428571,123 z" transform="translate(0,924.36218)" style="fill:#ff0000;fill-opacity:1;stroke:none" />
<path d="M 16.162441,21.428905 L 117.17769,21.428905 L 117.17769,110.8274 L 16.162441,110.8274 z" transform="matrix(0.96592583,-0.25881905,0.25881905,0.96592583,-17.36888,938.82017)" style="fill:url(#linearGradient3761);fill-opacity:1;stroke:none" />
</g>
</g>
</svg>
Output file:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="linearGradient3755">
<stop offset="0" />
<stop offset="1" stop-opacity="0" />
</linearGradient>
<linearGradient id="linearGradient3761" xlink:href="#linearGradient3755" y1="95.70844949469" x1="26.6443734054997" y2="33.95075671356" x2="101.020294143975" gradientUnits="userSpaceOnUse" />
</defs>
<path fill="#f00" d="M -37.2023,57.8018 C -37.2023,57.8018 81.1699,-.0654 81.1699,-.0654 81.1699,-.0654 167.5631,74.2746 167.5631,74.2746 167.5631,74.2746 49.1909,132.1418 49.1909,132.1418 z" />
<path fill="url(#linearGradient3761)" d="M -15.4903,74.3628 C -15.4903,74.3628 58.8856,12.6051 58.8856,12.6051 58.8856,12.6051 143.155,55.2964 143.155,55.2964 143.155,55.2964 68.7791,117.0541 68.7791,117.0541 z" />
</svg>
My question is why gradients are different, when vectors are equal? And how can I fix it?
Your algorithm is correct as long as your transform matrix doesn't skew the gradient.
In your case, the final transformation that is applied to the gradient is
translate(0,-924.36218) matrix(0.95516166,-0.46694301,0.71994792,0.61949768,-706.90347,408.6637) matrix(0.96592583,-0.25881905,0.25881905,0.96592583,-17.36888,938.82017)
which is the same as
matrix(0.7363,-0.6113,0.9426,0.4775,-47.6376,74.0101)
which is equivalent to
translate(-47.6376, 74.0101) rotate(-39.7) scale(0.957, 0.9695) skewX(23.4337)
If the last skew(23.4337)
weren't there, everything should work as you desired.
It's pretty hard, or more accurately I should say impossible, to achieve the skew effect without using gradientTransform
attribute. According to the SVG 1.1 Specification:
gradientTransform contains the definition of an optional additional transformation from the gradient coordinate system onto the target coordinate system (i.e., userSpaceOnUse or objectBoundingBox). This allows for things such as skewing the gradient.
It is designed to achieve the skew effect.
If you are still curious why it's impossible, I've made a simple example shown in the image below.
On the left, we have a horizontal linear gradient applied to a square. If we skew the gradient on X axis for 20 degrees, the effect is rendered like a combination of 2 shapes:
Now you can't simply use a line to describe the gradient, which is why we have to use gradientTransform
attribute.
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