Related
The bounty expires in 5 days. Answers to this question are eligible for a +50 reputation bounty.
Qoomit is looking for an answer from a reputable source.
I'm trying to accomplish this... in this example the green stroke is filled when the people selected (1), and the gray ones are the total of people (6)
other example is green stroke is filled (3) and total (6)
what I accomplished by now, it doesn't fill correctly,
const [personQuantity, setPersonQuantity] = useState(2)
const [payingFor, setPayingFor] = useState(1)
useEffect(() => {
let amountPerPerson = subtotal / personQuantity
let perPerson = amountPerPerson * payingFor
setPerPerson(perPerson)
if (personQuantity >= payingFor && personQuantity > 2) {
setActivate(true)
} else {
setActivate(false)
}
}, [personQuantity, payingFor])
const fillPercentage = (payingFor / personQuantity) * 100
return (
<>
<div className="h-20 w-20 ">
<svg className="circular-chart " viewBox="0 0 36 36">
<path
fill="none"
strokeWidth="4"
strokeDasharray={`${fillPercentage + 1},1`}
className="circle-bg bg-DARK_1 stroke-2 stroke-white"
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
/>
<path
strokeWidth="4"
strokeLinecap="round"
fill="none"
className="circle stroke-LIGHT_GREEN_1 transition-opacity delay-150 ease-in-out"
strokeDasharray={`${fillPercentage}, 100`}
d="M18 2.0845
a 15.9155 15.9155 0 0 1 0 31.831
a 15.9155 15.9155 0 0 1 0 -31.831"
/>
</svg>
</div>
as stated by enxaneta, you use path of 100 percent, so you should make the math so that the white draws the person's number separated by a gap percent space and the green fills the number of slots including intermediate spaces.
So assuming subtotal is the total number of persons and payingFor is the number of persons that should be green, we have :
let pathSize = 100
let gapSize = 1
let percentForOne = (pathSize / subtotal)
let greenedPercent = (percentForOne * payingFor) - gapSize
let notGreenedPercent = (percentForOne * (subtotal - payingFor)) + gapSize
so for white :
strokeDasharray={`${percentForOne} - ${gapSize},${gapSize}`}
then for green :
strokeDasharray={`${greenedPercent},${notGreenedPercent}`}
Please note that it will be incorrect with more than 100 persons because these would imply more than 100 gaps of 1 percent and negative space between them, so you should probably put the gapSize to 0 when subtotal is more than ~40 (esthetic value)
As a second note, while using a path to approximate a circle do work, I recommend using <circle cx="18" cy="18" r="15.9155" pathlength=100> and in both case you will need to rotate the figure by -90deg to achieve the vertical origin of the drawing transform: rotate(-90deg)
I did a demo on this codepen (with fixed values)
I'm working in WPF, but SVG would probably be the same so I've tagged it. I have some paths that I am rotating/translating multiple times and in it's final rendered position, I would like to take the path and "unrotate" at that position. The issue is that I can't find the right CenterX/CenterY for this (renderTransformOrigin="0.5, 0.5" doesn't work because the final rendered path has been translated). Finding the boundingbox of the final rendered shape also doesn't not work to rotate it back.
Here's what the non-rotated paths look like:
And here's what they look like when rotated:
To get this, here's my XAML.
<Canvas>
<Rectangle Fill="DarkGray" Opacity=".3" Canvas.Left="168.48" Width="100.08" Height="200.16" Canvas.Top="164.88"/>
<!-- ////////////////// -->
<!-- ///shape/// -->
<Path Stroke="Purple" x:Name="purpleShape" Data="M0,150 25,150 25,0 75,0 75,150 100,150 50,200 Z" StrokeThickness="2">
<Path.RenderTransform >
<TransformGroup>
<!--shape transforms-->
<RotateTransform Angle="30" CenterX="50" CenterY="100"/>
<TranslateTransform X="46.08" Y="0"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
<!-- ///childGroup/// -->
<!-- ///childGroup.shape/// -->
<Path Stroke="Green" x:Name="greenShape" Data="M0,25 150,25 150,0 200,50 150,100 150,75 0,75 Z" StrokeThickness="2">
<Path.RenderTransform >
<TransformGroup>
<!--shape transforms-->
<RotateTransform Angle="330" CenterX="100" CenterY="50"/>
<TranslateTransform X="50" Y="200" />
<!--childgroup transforms-->
<RotateTransform Angle="60" CenterX="150" CenterY="150"/>
<TranslateTransform X="0" Y="96.46" />
</TransformGroup>
</Path.RenderTransform>
</Path>
<!-- ///childGroup.shape/// -->
<Path Stroke="Red" x:Name="redShape" Data="M0,150 25,150 25,0 75,0 75,150 100,150 50,200 Z " StrokeThickness="2">
<Path.RenderTransform >
<TransformGroup>
<!--shape transforms-->
<RotateTransform Angle="330" CenterX="50" CenterY="100"/>
<TranslateTransform X="150" Y="0" />
<!--childgroup transforms-->
<RotateTransform Angle="60" CenterX="150" CenterY="150"/>
<TranslateTransform X="0" Y="96.46"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
Notice in this code <Rectangle Fill="DarkGray" .... as the first element. This is where I am hoping to "unrotate" the red path to, so that it fits in this bounding box (the size of this is the size of the non-rotated bounding box).
Here's what this looks like:
The final render path of the red shape is: Data="M150,283.064 171.651,295.564 246.651,165.66 289.952,190.66 214.952,320.564 236.603,333.064 168.301,351.365 Z " and now I want to unrotate that (-30 degrees) so that it is pointing down again - again, at this same exact location. (again, getting the bounding box of the red shape doesn't work as it has a different center x/y than I need in order to unrotate).
So using another shape (orange shape) and the path data above, I place it on the red shape and try to rotate it back (i.e. so it doesn't appear rotated).
<Path RenderTransformOrigin="0.5,0.5" Stroke="Orange" x:Name="unrotatedShape" Data="M150,283.064 171.651,295.564 246.651,165.66 289.952,190.66 214.952,320.564 236.603,333.064 168.301,351.365 Z " StrokeThickness="4">
<Path.RenderTransform >
<TransformGroup>
<RotateTransform Angle="-30" CenterX="0.5" CenterY="0.5"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
And this is the result:
This is obviously getting rotated from the path as it is both rotated and translated (e.g. Data="M150,283.064...). It's that 150,283.064 that are causing the issue.
So I'm asking for solutions that allow me to "unrotate" the "red shape" (the rendering of which is the "orange shape") at the same position so that it looks like the following (blue shape).
Caveat
Your grey rectangle is not the same size as the red arrow. I'll place the center of the red arrow on the center of the grey box.
Setup
Rotating around some point, P, is equivalent to translating P to the origin, rotating around the origin, and then translating the origin back to P again.
Define a function which does that, and check how it modifies the individual coordinates. (Below is Mathematica.)
In[1] :=
RotateVAroundP[V_, \[Theta]_, Px_, Py_] := {{Cos[\[Theta]], -Sin[\[Theta]]}, {Sin[\[Theta]], Cos[\[Theta]]}} . (V - {{Px}, {Py}}) + {{Px}, {Py}}
MatrixForm[Simplify[RotateVAroundP[{{x}, {y}}, \[Theta], Px, Py]]]
Out[2]//MatrixForm =
MatrixForm[{{Px + (-Px + x)*Cos[\[Theta]] + (Py - y)*Sin[\[Theta]]}, {Py + (-Py + y)*Cos[\[Theta]] + (-Px + x)*Sin[\[Theta]]}}]
Testing
Rotate the point (1,0), 90 degrees around the point (1,1) to (2,1).
In[3] :=
MatrixForm[RotateVAroundP[{{1}, {0}}, 90*Degree, 1, 1]]
Out[3]//MatrixForm =
MatrixForm[{{2}, {1}}]
Solving
Start with the center of the original red arrow: V1 = (50, 100). Apply all the transformations. The final transformation has the desired -30 degrees, around an unknown point (x,y). This final rotation needs to place the center of the arrow on the center of the box, which is (168.48 + 100.08/2, 164.88 + 200.16/2).
In[5] :=
V1 = {{50}, {100}};
V2 = RotateVAroundP[V1, 330*Degree, 50, 100];
V3 = V2 + {{150}, {0}};
V4 = RotateVAroundP[V3, 60*Degree, 150, 150];
V5 = FullSimplify[V4 + {{0}, {96.46}}];
Solve[RotateVAroundP[V5, -30*Degree, x, y] == {{168.48 + 100.08/2}, {164.88 + 200.16/2}}]
Out[10] =
{{x -> 218.78146997001204, y -> 264.4524797111341}}
Verifying
I don't know anything about WPF, but I dabble in SVG. Working from the initial opaque arrow to the transparent one, the subsequent transformations in each element are applied from right to left.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="https://www.w3.org/1999/xlink" viewBox="-25 -25 350 425" width="560" height="680">
<rect xmlns="http://www.w3.org/2000/svg" fill="none" stroke="black" x="0" y="0" width="300" height="375"/>
<rect fill="darkgray" fill-opacity=".3" x="168.48" width="100.08" height="200.16" y="164.88"/>
<path stroke="red" id="redShape" d="M0,150 25,150 25,0 75,0 75,150 100,150 50,200 Z " stroke-width="2" fill=" red"/>
<use href="#redShape" transform="rotate(330, 50, 100)" fill-opacity=".8"/>
<use href="#redShape" transform="translate(150,0) rotate(330, 50, 100)" fill-opacity=".6"/>
<use href="#redShape" transform="rotate(60,150,150) translate(150,0) rotate(330, 50, 100)" fill-opacity=".4"/>
<use href="#redShape" transform="translate(0,96.46) rotate(60,150,150) translate(150,0) rotate(330, 50, 100)" fill-opacity=".2"/>
<use href="#redShape" transform="rotate(-30, 218.781, 264.452) translate(0,96.46) rotate(60,150,150) translate(150,0) rotate(330, 50, 100)" fill-opacity="0"/>
</svg>
Generalizing
If you want to rotate the point V to the point W by applying a rotation θ around a point P, the coordinates for P are the expressions below.
In[11] :=
FullSimplify[Solve[RotateVAroundP[{{Vx}, {Vy}}, \[Theta], Px, Py] == {{Wx}, {Wy}}, {Px, Py}]]
Out[11] =
{{Px -> (1/2)*(Vx + Wx + (Vy - Wy)*Cot[\[Theta]/2]), Py -> (1/2)*(Vy + Wy + (-Vx + Wx)*Cot[\[Theta]/2])}}
i made a wave svg from bgjar.com and i need to fill inside the wave a gradient color or atleast a light red color similar to the output picture
what i have
what i need
raw svg code
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" width="320" height="270" preserveAspectRatio="none" viewBox="0 0 320 270">
<g mask="url("#SvgjsMask1038")" fill="none">
<path d="M -58.93643021614276,150 C -52.94,134.6 -40.94,68 -28.93643021614276,73 C -16.94,78 -10.94,164.8 1.0635697838572398,175 C 13.06,185.2 19.06,117.6 31.06356978385724,124 C 43.06,130.4 49.06,219 61.06356978385724,207 C 73.06,195 79.06,67.6 91.06356978385725,64 C 103.06,60.4 109.06,183.4 121.06356978385725,189 C 133.06,194.6 139.06,101 151.06356978385725,92 C 163.06,83 169.06,147.2 181.06356978385725,144 C 193.06,140.8 199.06,73.2 211.06356978385725,76 C 223.06,78.8 229.06,153 241.06356978385725,158 C 253.06,163 259.06,95.4 271.06356978385725,101 C 283.06,106.6 291.28,182.6 301.06356978385725,186 C 310.85,189.4 316.21,131.6 320,118" stroke="rgba(255, 22, 102, 1)" stroke-width="2"></path>
</g>
<defs>
<mask id="SvgjsMask1038">
<rect width="320" height="270" fill="#ffffff"></rect>
</mask>
</defs>
</svg>
You can modify this one...
<svg
id="chart"
width="1000"
height="500"
viewBox="0 0 1000 500"
xmlns="http://www.w3.org/2000/svg"
>
<path d="M 0,271.24815576685774 C 10.599999999999996,240.48688897649592 31.800000000000004,158.67494027213138 53,117.44182181504868 C 74.2,76.20870335796599 84.80000000000001,75.17380226445499 106,65.08256348144425 C 127.2,54.99132469843352 137.8,2.3375166629619457 159,66.98562789999504 C 180.2,131.63373913702813 190.79999999999998,367.39699461622166 212,388.3231196666097 C 233.2,409.24924471699785 243.8,230.5326737765239 265,171.6162531519355 C 286.2,112.69983252734713 296.8,88.54554102750788 318,93.74101654366785 C 339.2,98.93649205982783 349.8,186.35380781584786 371,197.5936307327354 C 392.2,208.83345364962292 402.8,173.57178815030994 424,149.94013112810546 C 445.2,126.30847410590097 455.8,86.12464938994711 477,79.43534562171294 C 498.2,72.74604185347877 508.8,102.00812370837183 530,116.49361228693465 C 551.2,130.97910086549746 561.8,146.70996863245625 583,151.86278851452704 C 604.2,157.01560839659783 614.8,105.06597744397455 636,142.25771169728864 C 657.2,179.44944595060275 667.8,352.8024986694471 689,337.8214597810976 C 710.2,322.84042089274806 720.8,103.54739853063538 742,67.35251725554093 C 763.2,31.157635980446486 773.8,130.46694719017148 795,156.84705340562533 C 816.2,183.2271596210792 826.8,166.55203838147713 848,199.2530483328103 C 869.2,231.95405828414346 879.8,290.7332238327917 901,320.3521031622911 C 922.2,349.9709824917905 932.8,334.22449767297155 954,347.3474449803073 C 975.2,360.470392287643 996.4,378.2429607552373 1007,385.9668396989698,L 1000 500,L 0 500Z" fill="#321834" />
<path d="M 0,271.24815576685774 C 10.599999999999996,240.48688897649592 31.800000000000004,158.67494027213138 53,117.44182181504868 C 74.2,76.20870335796599 84.80000000000001,75.17380226445499 106,65.08256348144425 C 127.2,54.99132469843352 137.8,2.3375166629619457 159,66.98562789999504 C 180.2,131.63373913702813 190.79999999999998,367.39699461622166 212,388.3231196666097 C 233.2,409.24924471699785 243.8,230.5326737765239 265,171.6162531519355 C 286.2,112.69983252734713 296.8,88.54554102750788 318,93.74101654366785 C 339.2,98.93649205982783 349.8,186.35380781584786 371,197.5936307327354 C 392.2,208.83345364962292 402.8,173.57178815030994 424,149.94013112810546 C 445.2,126.30847410590097 455.8,86.12464938994711 477,79.43534562171294 C 498.2,72.74604185347877 508.8,102.00812370837183 530,116.49361228693465 C 551.2,130.97910086549746 561.8,146.70996863245625 583,151.86278851452704 C 604.2,157.01560839659783 614.8,105.06597744397455 636,142.25771169728864 C 657.2,179.44944595060275 667.8,352.8024986694471 689,337.8214597810976 C 710.2,322.84042089274806 720.8,103.54739853063538 742,67.35251725554093 C 763.2,31.157635980446486 773.8,130.46694719017148 795,156.84705340562533 C 816.2,183.2271596210792 826.8,166.55203838147713 848,199.2530483328103 C 869.2,231.95405828414346 879.8,290.7332238327917 901,320.3521031622911 C 922.2,349.9709824917905 932.8,334.22449767297155 954,347.3474449803073 C 975.2,360.470392287643 996.4,378.2429607552373 1007,385.9668396989698" fill="none" stroke="#FF1666" stroke-width="4px" />
</svg>
I've been hit by this iframe that breaks all my clicks and after adding { force: true } to it, it just moves to break should() assertions.
I don't know what this iframe is and it's not visible in the html when you are using the app. Is there a solution for this?
HTML of this button:
<button class="MuiButtonBase-root makeStyles-root-1080 makeStyles-sm-1082 makeStyles-sm-1303 makeStyles-ghost-1088 makeStyles-ghost-1308 makeStyles-button-1161 makeStyles-defaultState-1163 makeStyles-defaultState-1298" tabindex="0" type="button" aria-label="Lobby" data-cy="lobby-button" color="dark"><div class="makeStyles-contentWrapper-1093"><div class="makeStyles-content-1094 makeStyles-content-1310 makeStyles-content-1167"><span class="MuiBadge-root"><svg width="34" height="34" viewBox="0 0 34 34" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21.7273 15.8571C23.6891 15.8571 25.2609 14.3257 25.2609 12.4286C25.2609 10.5314 23.6891 9 21.7273 9C19.7655 9 18.1818 10.5314 18.1818 12.4286C18.1818 14.3257 19.7655 15.8571 21.7273 15.8571ZM12.2727 15.8571C14.2345 15.8571 15.8064 14.3257 15.8064 12.4286C15.8064 10.5314 14.2345 9 12.2727 9C10.3109 9 8.72727 10.5314 8.72727 12.4286C8.72727 14.3257 10.3109 15.8571 12.2727 15.8571ZM12.2727 18.1429C9.51909 18.1429 4 19.48 4 22.1429V23.8571C4 24.4857 4.53182 25 5.18182 25H19.3636C20.0136 25 20.5455 24.4857 20.5455 23.8571V22.1429C20.5455 19.48 15.0264 18.1429 12.2727 18.1429ZM21.7273 18.1429C21.3845 18.1429 20.9945 18.1657 20.5809 18.2C20.6045 18.2114 20.6164 18.2343 20.6282 18.2457C21.9755 19.1943 22.9091 20.4629 22.9091 22.1429V23.8571C22.9091 24.2571 22.8264 24.6457 22.6964 25H28.8182C29.4682 25 30 24.4857 30 23.8571V22.1429C30 19.48 24.4809 18.1429 21.7273 18.1429Z" fill="currentColor"></path></svg><span class="MuiBadge-badge MuiBadge-anchorOriginTopRightRectangle MuiBadge-colorError MuiBadge-invisible">0</span></span></div></div><span class="MuiTouchRipple-root"></span></button>
And click is like this
cy.get('[data-cy="lobby-button"]').click();
This went away (was fixed) after commenting out
new ReactRefreshWebpackPlugin()
from webpack.config.js
In my XAML, I have a button like this:
<Button Name="btnName" Width="194" TabIndex="3514" Click="btnName_Click" Margin="5,10,0,10" >
<StackPanel Orientation="Horizontal">
<ContentControl Width="16" Height="16" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="{StaticResource iconFolderOpen}" />
<Label>Click Me</Label>
</StackPanel>
</Button>
In my resource dictionary, I have a style defined to draw out the icon:
<Viewbox x:Key="iconFolderOpen" x:Shared="False" Stretch="Uniform">
<Path Fill="#ff2d66b0" Data="F1 M 15.736,7.579 L 12.875,10.950 C 12.381,11.530 11.377,11.990 10.627,11.990 L 1.362,11.990 C 1.056,11.990 0.622,11.896 0.622,11.513 C 0.622,11.308 0.750,11.104 0.885,10.950 L 3.747,7.579 C 4.241,6.999 5.245,6.540 5.995,6.540 L 15.259,6.540 C 15.566,6.540 16.000,6.634 16.000,7.016 C 16.000,7.221 15.872,7.426 15.736,7.579 Z M 13.079,5.450 L 5.995,5.450 C 4.931,5.450 3.610,6.054 2.921,6.872 L 0.051,10.244 L 0.009,10.295 C 0.009,10.227 0.000,10.150 0.000,10.082 L 0.000,1.907 C 0.000,0.860 0.860,0.000 1.907,0.000 L 4.632,0.000 C 5.679,0.000 6.540,0.860 6.540,1.907 L 6.540,2.180 L 11.172,2.180 C 12.219,2.180 13.079,3.040 13.079,4.087 L 13.079,5.450 Z"/>
</Viewbox>
Now, you'll notice on the icon above, I have a Fill="#ff2d66b0"
Is there a way I can get to this attribute directly in my XAML code? Reason being, I would obviously like to control the fill color for different designs. I can obviously make an iconFolderOpenBlue, iconFolderOpenRed, and so on, but that does not seem very efficient.
Any thoughts? Thanks!
You can change the Path.Fill property by binding it to the ContentControl's Background property for example, by using a RelativeSource binding :
<Viewbox x:Key="iconFolderOpen" x:Shared="False" Stretch="Uniform">
<Path Fill="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContentControl}},Path=Background}" Data="F1 M 15.736,7.579 L 12.875,10.950 C 12.381,11.530 11.377,11.990 10.627,11.990 L 1.362,11.990 C 1.056,11.990 0.622,11.896 0.622,11.513 C 0.622,11.308 0.750,11.104 0.885,10.950 L 3.747,7.579 C 4.241,6.999 5.245,6.540 5.995,6.540 L 15.259,6.540 C 15.566,6.540 16.000,6.634 16.000,7.016 C 16.000,7.221 15.872,7.426 15.736,7.579 Z M 13.079,5.450 L 5.995,5.450 C 4.931,5.450 3.610,6.054 2.921,6.872 L 0.051,10.244 L 0.009,10.295 C 0.009,10.227 0.000,10.150 0.000,10.082 L 0.000,1.907 C 0.000,0.860 0.860,0.000 1.907,0.000 L 4.632,0.000 C 5.679,0.000 6.540,0.860 6.540,1.907 L 6.540,2.180 L 11.172,2.180 C 12.219,2.180 13.079,3.040 13.079,4.087 L 13.079,5.450 Z"/>
</Viewbox>
and to change the fill just set the ContentControl Background
<Button Name="btnName" Width="194" TabIndex="3514" Click="btnName_Click" Margin="5,10,0,10" >
<StackPanel Orientation="Horizontal">
<ContentControl Width="16" Background="Red" Height="16" VerticalAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Content="{StaticResource iconFolderOpen}" />
<Label>Click Me</Label>
</StackPanel>
</Button>