Applying gradientTransform to linearGradient

I have a problem with applying all the transformations in an svg file. If the file contains only paths and without gradients, everything works fine. But after adding and applying gradientTransform to linearGradient, it causes rendering errors.

Algorithm:

  • multiply group and empty matrices
  • multiply path transformation with linearGradient gradientTransform binding
  • apply transform to path
  • apply gradientTransform to linearGradient

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 are the gradients different when the vectors are equal? And how can I fix this?

+4
source share
1 answer

Your algorithm is correct if your transformation matrix does not skew the gradient.

In your case, the final transformation applied to the gradient,

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

matrix(0.7363,-0.6113,0.9426,0.4775,-47.6376,74.0101)

which is equivalent

translate(-47.6376, 74.0101) rotate(-39.7) scale(0.957, 0.9695) skewX(23.4337)

If the latest skew(23.4337) were not there, everything should work as you wish.

This is rather complicated, or rather, I have to say that it is impossible to achieve a skew effect without using the gradientTransform attribute. According to SVG 1.1 specification :

gradientTransform contains the definition of an optional additional transformation from the gradient coordinate system to the target coordinate system (i.e. userSpaceOnUse or objectBoundingBox). This allows things like gradient skew.

It is designed to achieve a skew effect.

If you are still wondering why this is not possible, I made a simple example, shown in the image below.

oblique effect example

On the left, we have a horizontal linear gradient applied to the square. If we shift the gradient on the X axis by 20 degrees, the effect will look like a combination of two figures:

  • a triangle on the left side whose fill is a solid color
  • the same square filled with the same gradient, but the square itself is skewed by 20 degrees, and then tied to its original shape.

Now you canโ€™t just use the string to describe the gradient, so we need to use the gradientTransform attribute.

+1
source

Source: https://habr.com/ru/post/1487901/


All Articles