Note that there are some explanatory texts on larger screens.

plurals
  1. POCalculate new gradient positions after the polygon it fills changes dimensions
    primarykey
    data
    text
    <p><strong>What I want to do?</strong></p> <p>Updates to this question: 7/10/2012 - "gradientTransform not quite" Inspired by Duopixel 7/11/2012 - "SVG Code from the example" 7/16/2012 - "@dignifiedquire take on this problem"</p> <p>I'm trying to create a tool that let's the user dynamically resize polygons. Most of the polygons are filled with gradients <code>fill="url(#top_surface_1_gradient)"</code>. The way I go about this is a simple JavaScript script that:</p> <ol> <li>looks for mousemove &amp; click events over a certain polygon</li> <li>measures the amount of movement</li> <li>changes half of the coordinates of the polygon (in order to have the effect of stretching) using this algorithm to define new coordinates: <code>x = x_movement</code>, <code>y = x_movement * Math.tan( 31 * (Math.PI/180) )</code></li> <li>polygons that are filled with a single colour are OK</li> <li>polygons that are filled with a gradient are not, let me demonstrate:</li> </ol> <p><strong>Visually</strong></p> <p><img src="https://i.stack.imgur.com/1kheh.jpg" alt="step_1"></p> <p>So this is step one, no stretching has been done by the user.</p> <p><img src="https://i.stack.imgur.com/wTty4.jpg" alt="step_2"></p> <p>This is where the problem happens. Since I don't know how should I change the <code>x1, y1</code> and <code>x2, y2</code> coordinates for the gradient, it just stays hanging in it's old position while the polygon has been stretched. The result is a shape that fails to sustain the illusion of depth.</p> <p><img src="https://i.stack.imgur.com/Z4eB7.jpg" alt="step_3"></p> <p>The end result I'm looking for. And bare in mind that the gradient might have a completely random angle from the get go. In this end result, that I'm looking for, both the <code>x1, y1</code> and <code>x2, y2</code> coordinates of the gradient have been changed. <strong>What algorithm should be used to calculate these positions?</strong> I'm looking for a solution that is <strong>completely blind to the angle of the gradient</strong>.</p> <p>Below is the SVG with all the appropriate coordinates that was used to generate these examples:</p> <p><strong>Using SVG code</strong></p> <p>Step1:</p> <pre><code>&lt;!-- Step 1 --&gt; &lt;linearGradient id="top_surface_1_gradient" gradientUnits="userSpaceOnUse" x1="165.3425" y1="39.7002" x2="-49.991" y2="43.0337"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.6687" style="stop-color:#CCCCCC"/&gt; &lt;stop offset="1" style="stop-color:#FFFFFF"/&gt; &lt;/linearGradient&gt; &lt;polygon id="top_surface_1" fill="url(#top_surface_1_gradient)" points="137.145,41.204 68.572,0 0,41.204 68.572,82.396"/&gt; </code></pre> <p>Step 2</p> <pre><code>&lt;!-- Step 2 --&gt; &lt;linearGradient id="top_surface_2_gradient" gradientUnits="userSpaceOnUse" x1="250.0491" y1="233.8115" x2="23.7637" y2="237.3146"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.6687" style="stop-color:#CCCCCC"/&gt; &lt;stop offset="1" style="stop-color:#FFFFFF"/&gt; &lt;/linearGradient&gt; &lt;polygon id="top_surface_2" fill="url(#top_surface_2_gradient)" points="205.788,215.557 137.215,174.354 0.078,256.629 68.649,297.823"/&gt; </code></pre> <p>Step 3</p> <pre><code>&lt;!-- Step 3 --&gt; &lt;linearGradient id="top_surface_3_gradient" gradientUnits="userSpaceOnUse" x1="248.4543" y1="454.5225" x2="-75.535" y2="459.5381"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.6687" style="stop-color:#CCCCCC"/&gt; &lt;stop offset="1" style="stop-color:#FFFFFF"/&gt; &lt;/linearGradient&gt; &lt;polygon id="top_surface_3" fill="url(#top_surface_3_gradient)" points="205.788,415.557 137.215,374.354 0.078,456.629 68.649,497.823"/&gt; </code></pre> <p>I've spent countless hours developing solutions for this problem and I just couldn't get my head around it. Any help would be greatly appreciated.</p> <p><strong>Update: gradientTransform not quite</strong></p> <p>Using the gradientTransform attribute and no x1,y1; x2,y2 coordinates for the gradient, we achieve results that fill the polygon in a way that is almost as needed (This solution can be found here: <a href="http://jsfiddle.net/hqXx2/" rel="nofollow noreferrer">http://jsfiddle.net/hqXx2/</a>). The only place where the solution breaks is when the polygon is filled with a gradient that starts outside of the polygon and/or ends somewhere outside/inside. Let me illustrate:</p> <p>This is what is achieved with the solution, that Duopixel is suggesting. <img src="https://i.stack.imgur.com/vgNBk.jpg" alt="step_4"></p> <p>This is the usage case that is impossible to achieve using the solution mentioned above. I changed the colouring in order to visibly amplify the angle and gradient stops. <img src="https://i.stack.imgur.com/oOU9P.jpg" alt="step_5"></p> <p><strong>SVG Code from the example</strong></p> <p>Here's the code for the larger, correctly expanded group of polygons:</p> <pre><code>&lt;g&gt; &lt;linearGradient id="surface_center_inside_bottom_1_" gradientUnits="userSpaceOnUse" x1="167.7629" y1="634.5986" x2="-72.9039" y2="599.2647"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.8528" style="stop-color:#CCCCCC"/&gt; &lt;stop offset="0.9954" style="stop-color:#CCCCCC"/&gt; &lt;/linearGradient&gt; &lt;polygon id="surface_center_inside_bottom_9_" fill="url(#surface_center_inside_bottom_1_)" points="137.145,620.04 68.572,578.837 0,620.04 68.572,661.233"/&gt; &lt;linearGradient id="surface_right_inside_side_1_" gradientUnits="userSpaceOnUse" x1="178.8889" y1="600.1787" x2="33.103" y2="517.9229"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.9816" style="stop-color:#A3A5A8"/&gt; &lt;/linearGradient&gt; &lt;polygon id="surface_right_inside_side_3_" fill="url(#surface_right_inside_side_1_)" points="136.526,620.374 68.359,578.501 68.572,493.837 137.358,535.37"/&gt; &lt;linearGradient id="surface_right_inside_side_2_" gradientUnits="userSpaceOnUse" x1="126.2664" y1="563.249" x2="-28.4" y2="621.916"&gt; &lt;stop offset="0" style="stop-color:#FF0000"/&gt; &lt;stop offset="0.6698" style="stop-color:#00FFFF"/&gt; &lt;stop offset="1" style="stop-color:#FF0000"/&gt; &lt;/linearGradient&gt; &lt;polygon id="surface_right_inside_side_5_" fill="url(#surface_right_inside_side_2_)" points="68.573,661.239 0,620.036 0,535.036 68.573,576.231"/&gt; &lt;linearGradient id="surface_center_outside_top_1_" gradientUnits="userSpaceOnUse" x1="167.3728" y1="533.5059" x2="-47.9608" y2="536.8394"&gt; &lt;stop offset="0.0016" style="stop-color:#FF0000"/&gt; &lt;stop offset="0.6735" style="stop-color:#00FFFF"/&gt; &lt;stop offset="1" style="stop-color:#FF0000"/&gt; &lt;/linearGradient&gt; &lt;polygon id="surface_center_outside_top_3_" fill="url(#surface_center_outside_top_1_)" points="137.145,535.041 68.572,493.837 0,535.041 68.572,576.233"/&gt; &lt;/g&gt; </code></pre> <p>And here's the SVG code for the smaller one, which I need to expand:</p> <pre><code>&lt;g&gt; &lt;linearGradient id="surface_right_inside_side_4_" gradientUnits="userSpaceOnUse" x1="273.4377" y1="319.251" x2="78.0696" y2="209.0197"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.9816" style="stop-color:#A3A5A8"/&gt; &lt;/linearGradient&gt; &lt;polygon id="surface_right_inside_side_9_" fill="url(#surface_right_inside_side_4_)" points="205.112,366.797 136.945,324.924 137.157,156.261 205.731,197.464"/&gt; &lt;linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="247.2952" y1="408.1992" x2="-103.1108" y2="356.7538"&gt; &lt;stop offset="0" style="stop-color:#FFFFFF"/&gt; &lt;stop offset="0.8528" style="stop-color:#CCCCCC"/&gt; &lt;stop offset="0.9954" style="stop-color:#CCCCCC"/&gt; &lt;/linearGradient&gt; &lt;polygon fill="url(#SVGID_1_)" points="205.731,366.465 137.157,325.262 0.021,407.536 68.592,448.729"/&gt; &lt;linearGradient id="surface_right_inside_side_7_" gradientUnits="userSpaceOnUse" x1="160.3313" y1="296.623" x2="-52.0119" y2="377.1676"&gt; &lt;stop offset="0" style="stop-color:#FF0000"/&gt; &lt;stop offset="0.6698" style="stop-color:#00FFFF"/&gt; &lt;stop offset="1" style="stop-color:#FF0000"/&gt; &lt;/linearGradient&gt; &lt;polygon id="surface_right_inside_side_6_" fill="url(#surface_right_inside_side_7_)" points="68.532,448.767 0,407.497 0.021,238.536 68.592,279.729"/&gt; &lt;linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="248.4749" y1="215.7417" x2="-75.5139" y2="220.7572"&gt; &lt;stop offset="0.0016" style="stop-color:#FF0000"/&gt; &lt;stop offset="0.6735" style="stop-color:#00FFFF"/&gt; &lt;stop offset="1" style="stop-color:#FF0000"/&gt; &lt;/linearGradient&gt; &lt;polygon fill="url(#SVGID_2_)" points="205.731,197.464 137.157,156.261 68.592,197.333 0.021,238.536 68.592,279.729"/&gt; &lt;/g&gt; </code></pre> <p><strong>@dignifiedquire take on this problem</strong></p> <p>I've implemented @dignifiedquire suggested algo in a test site: <a href="http://9ball.me/svg_update/svg_version.php" rel="nofollow noreferrer">Here's the test link</a>. I did the absolute to relative conversion on my own and it just shows the same result I would have normally adding the same polygon x and y change values to the gradient x and y. That is the main issue - how to translate those values into such value, that transform the gradient as in my examples above?</p> <p>More help is needed.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload