06-14-2018 10:48
06-14-2018 10:48
Please bear with me if my terminology is not correct. Very new to this.
I'm creating a mask of a text element
<svg> <mask id="TextMask"> <text id="TextMask" class="Text-Mask" x="10" y="193">Some Text to Mask</text> </mask>
The Class Text-Mask just contains font/anchor/font size, nothing special.
I then want to apply a gradient coloring to this text and only this text. I have created a gradientRect element to apply to the text.
<svg mask="#TextMask" width="100%" height="100%"> <gradientRect width="100%" height="100%" gradient-type="linear" gradient-x1="0" gradient-y1="50" gradient-x2="0" gradient-y2="100%-50" gradient-color1="red" gradient-color2="yellow" /> </svg> </svg>
Now this works fine, but it isn't the effect I was hoping for.
From my understanding when I created this gradientRect element, I'm creating it over the background of the entire screen.
What I want is for the entire gradientRect to only cover the area that the text takes up. (Ex. The very top of the text is red and then it becomes gradient to the bottom of the text to yellow). As of right now how I currently have it, the text is in an orange/yellow area of the gradientRect.
I'm not sure how I can accomplish this with the gradient-y1 y2. I also do not believe that I can make my gradientRect a <def> of any sort and use fill="url(#grad1)" or anything of that sort.
Am I able to get the size (and position) of the text (regardless if the font size changes or placement of the text somewhere else on the screen) and apply this easily, or will I have to brute force it and hard code it to fit around only the text area?
Thanks!
Answered! Go to the Best Answer.
06-15-2018 02:19
06-15-2018 02:19
I have done the same thing during my experimenting, and you need to resize and position the gradient fill to where you want it to be. i.e. precisely where your text is going to be rendered. In your example (and also in mine) you are setting a width and height of the fill to 100%. This is specifying 100% of the container. However, the container for the fill is not the text, it's the whole screen, meaning that the fill is the size of the whole screen.
You could create a smaller sub-container and add the text mask and fill to that, but you'd still need to know how big to make that smaller container, so you have the same issue.
I don't think there is a way of measuring a piece of text in order to calculate this at runtime, leaving you with having to hard-code the position and size of the fill.
06-15-2018 02:19
06-15-2018 02:19
I have done the same thing during my experimenting, and you need to resize and position the gradient fill to where you want it to be. i.e. precisely where your text is going to be rendered. In your example (and also in mine) you are setting a width and height of the fill to 100%. This is specifying 100% of the container. However, the container for the fill is not the text, it's the whole screen, meaning that the fill is the size of the whole screen.
You could create a smaller sub-container and add the text mask and fill to that, but you'd still need to know how big to make that smaller container, so you have the same issue.
I don't think there is a way of measuring a piece of text in order to calculate this at runtime, leaving you with having to hard-code the position and size of the fill.
06-15-2018 05:16
06-15-2018 05:16
Thanks Mark! That's exactly what I ended up doing (kinda) where gradientRect was basically my sub container. It was a guess and compile type of thing for me until I got it perfectly around the text. For anyone to reference my final code looked something like this.
<svg mask="#TextToMask" width="100%" height="100%"> <gradientRect width="100%" height="40" y="154" gradient-type="linear" gradient-x1="0" gradient-y1="0" gradient-x2="0" gradient-y2="25" gradient-color1="red" gradient-color2="yellow" /> </svg>
Where the Height and y were the only values I needed to adjust. The y to move it up or down the screen and the height to match the height of the text. Seems a little hanky janky, but it's the best I could do with my knowledge. I'll be curious to see if anyone came up with a creative solution to this.