mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-03 07:06:04 +00:00
fix: radialGradient r={0} (#2271)
# Summary
* Fixed crash on Android when `<RadialGradient r={0}>`.
* Fixed render issue on Android and iOS when radius is zero. According
to [MDN
Docs](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/r#radialgradient)
> A value of lower or equal to zero will cause the area to be painted as
a single color using the color and opacity of the last gradient
`<stop>`.
## Test Plan
Test is available in `TestsExample` as `Test2170`
## Compatibility
| OS | Implemented |
| ------- | :---------: |
| iOS | ✅ |
| Android | ✅ |
Fixes #2170
This commit is contained in:
@@ -0,0 +1,65 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import {View} from 'react-native';
|
||||||
|
import {
|
||||||
|
Circle,
|
||||||
|
RadialGradient,
|
||||||
|
Rect,
|
||||||
|
Stop,
|
||||||
|
Svg,
|
||||||
|
SvgXml,
|
||||||
|
} from 'react-native-svg';
|
||||||
|
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/r#example
|
||||||
|
const svgXml = `
|
||||||
|
<svg viewBox="0 0 300 200" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<radialGradient r="0" id="myGradient000">
|
||||||
|
<stop offset="0" stop-color="white" />
|
||||||
|
<stop offset="100%" stop-color="black" />
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient r="50%" id="myGradient050">
|
||||||
|
<stop offset="0" stop-color="white" />
|
||||||
|
<stop offset="100%" stop-color="black" />
|
||||||
|
</radialGradient>
|
||||||
|
<radialGradient r="100%" id="myGradient100">
|
||||||
|
<stop offset="0" stop-color="white" />
|
||||||
|
<stop offset="100%" stop-color="black" />
|
||||||
|
</radialGradient>
|
||||||
|
|
||||||
|
<circle cx="50" cy="50" r="0" />
|
||||||
|
<circle cx="150" cy="50" r="25" />
|
||||||
|
<circle cx="250" cy="50" r="50" />
|
||||||
|
|
||||||
|
<rect x="20" y="120" width="60" height="60" fill="url(#myGradient000)" />
|
||||||
|
<rect x="120" y="120" width="60" height="60" fill="url(#myGradient050)" />
|
||||||
|
<rect x="220" y="120" width="60" height="60" fill="url(#myGradient100)" />
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return (
|
||||||
|
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
||||||
|
<SvgXml width={400} height={300} xml={svgXml} />
|
||||||
|
<Svg width={400} height={300}>
|
||||||
|
<RadialGradient id="a" r={0}>
|
||||||
|
<Stop offset={0} stopColor="#f00" />
|
||||||
|
<Stop offset="50%" stopColor="#0f0" />
|
||||||
|
<Stop offset="100%" stopColor="#00f" />
|
||||||
|
</RadialGradient>
|
||||||
|
<RadialGradient id="b" r="50%">
|
||||||
|
<Stop offset={0} stopColor="#f00" />
|
||||||
|
<Stop offset="100%" stopColor="#00f" />
|
||||||
|
</RadialGradient>
|
||||||
|
<RadialGradient id="c" r="100%">
|
||||||
|
<Stop offset={0} stopColor="#f00" />
|
||||||
|
<Stop offset="100%" stopColor="#00f" />
|
||||||
|
</RadialGradient>
|
||||||
|
<Rect x={0} y={100} width={100} height={100} fill="url(#a)" />
|
||||||
|
<Rect x={150} y={100} width={100} height={100} fill="url(#b)" />
|
||||||
|
<Rect x={300} y={100} width={100} height={100} fill="url(#c)" />
|
||||||
|
<Circle cx={50} cy={250} r={50} fill="url(#a)" />
|
||||||
|
<Circle cx={200} cy={250} r={50} fill="url(#b)" />
|
||||||
|
<Circle cx={350} cy={250} r={50} fill="url(#c)" />
|
||||||
|
</Svg>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -204,6 +204,14 @@ class Brush {
|
|||||||
double rx = getVal(mPoints[2], width, scale, textSize);
|
double rx = getVal(mPoints[2], width, scale, textSize);
|
||||||
double ry = getVal(mPoints[3], height, scale, textSize);
|
double ry = getVal(mPoints[3], height, scale, textSize);
|
||||||
|
|
||||||
|
if (rx <= 0 || ry <= 0) {
|
||||||
|
// Gradient with radius = 0 should be rendered as solid color of the last stop
|
||||||
|
rx = width;
|
||||||
|
ry = height;
|
||||||
|
stops = new float[] {stops[0], stops[stops.length - 1]};
|
||||||
|
stopsColors =
|
||||||
|
new int[] {stopsColors[stopsColors.length - 1], stopsColors[stopsColors.length - 1]};
|
||||||
|
}
|
||||||
double ratio = ry / rx;
|
double ratio = ry / rx;
|
||||||
|
|
||||||
double cx = getVal(mPoints[4], width, scale, textSize) + offsetX;
|
double cx = getVal(mPoints[4], width, scale, textSize) + offsetX;
|
||||||
|
|||||||
@@ -232,6 +232,15 @@ void PatternFunction(void *info, CGContextRef context)
|
|||||||
CGFloat rx = [self getVal:[_points objectAtIndex:2] relative:width];
|
CGFloat rx = [self getVal:[_points objectAtIndex:2] relative:width];
|
||||||
CGFloat ry = [self getVal:[_points objectAtIndex:3] relative:height];
|
CGFloat ry = [self getVal:[_points objectAtIndex:3] relative:height];
|
||||||
|
|
||||||
|
if (rx <= 0 || ry <= 0) {
|
||||||
|
// Gradient with radius = 0 should be rendered as solid color of the last stop
|
||||||
|
rx = width;
|
||||||
|
ry = height;
|
||||||
|
CGGradientRelease(gradient);
|
||||||
|
NSArray<NSNumber *> *gradientArray = @[_colors.firstObject, _colors.lastObject, _colors[_colors.count-2], _colors.lastObject];
|
||||||
|
gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:gradientArray]);
|
||||||
|
}
|
||||||
|
|
||||||
double ratio = ry / rx;
|
double ratio = ry / rx;
|
||||||
|
|
||||||
CGFloat fx = [self getVal:[_points objectAtIndex:0] relative:width] + offsetX;
|
CGFloat fx = [self getVal:[_points objectAtIndex:0] relative:width] + offsetX;
|
||||||
|
|||||||
Reference in New Issue
Block a user