diff --git a/Example/src/examples/Path.tsx b/Example/src/examples/Path.tsx index 927c9637..e8ef10f2 100644 --- a/Example/src/examples/Path.tsx +++ b/Example/src/examples/Path.tsx @@ -6,7 +6,7 @@ class PathExample extends Component { render() { return ( - + - - + + diff --git a/Example/src/examples/Text.tsx b/Example/src/examples/Text.tsx index ed90199e..0223f948 100644 --- a/Example/src/examples/Text.tsx +++ b/Example/src/examples/Text.tsx @@ -144,7 +144,7 @@ class TSpanExample extends Component { render() { return ( - + tspan line 1 tspan line 2 @@ -163,7 +163,7 @@ class TSpanExample extends Component { 89a - + delta on text diff --git a/Example/src/examples/TouchEvents.tsx b/Example/src/examples/TouchEvents.tsx index a2014992..f8b70793 100644 --- a/Example/src/examples/TouchEvents.tsx +++ b/Example/src/examples/TouchEvents.tsx @@ -79,6 +79,7 @@ class GroupExample extends Component { Alert.alert('Pressed on G')} scale="1.4"> + + + + + + + + + + + {Platform.OS !== 'web' && ( )} diff --git a/FabricExample/src/App.tsx b/FabricExample/src/App.tsx index c55fe8c4..2f618af3 100644 --- a/FabricExample/src/App.tsx +++ b/FabricExample/src/App.tsx @@ -14,7 +14,6 @@ import { TouchableHighlight, TouchableOpacity, } from 'react-native'; -import {Modal} from 'react-native'; import {Svg, Circle, Line} from 'react-native-svg'; import * as examples from './examples'; diff --git a/FabricExample/src/examples/PanResponder.tsx b/FabricExample/src/examples/PanResponder.tsx index 9452673e..bd2c387a 100644 --- a/FabricExample/src/examples/PanResponder.tsx +++ b/FabricExample/src/examples/PanResponder.tsx @@ -1,20 +1,20 @@ import React, {PureComponent} from 'react'; import { - PanResponder, - View, Animated, + PanResponder, TouchableWithoutFeedback, + View, } from 'react-native'; -import {Svg, G, Text, Path, Polyline, Line} from 'react-native-svg'; +import {G, Line, Path, Polyline, Svg, Text} from 'react-native-svg'; const AnimatedSvg = Animated.createAnimatedComponent(Svg); const zeroDelta = {x: 0, y: 0}; class PanExample extends PureComponent { - static title = 'Bind PanResponder on the SVG Shape - It does not work on Fabric since it uses `setNativeProps`'; + static title = 'Bind PanResponder on the SVG Shape'; panXY: any; - constructor(props, context) { + constructor(props: {}, context: {}) { super(props, context); const xy = new Animated.ValueXY(); const {x: dx, y: dy} = xy; @@ -29,7 +29,9 @@ class PanExample extends PureComponent { xy.setOffset(offset); xy.setValue(zeroDelta); }, - onPanResponderMove: Animated.event([null, {dx, dy}]), + onPanResponderMove: Animated.event([null, {dx, dy}], { + useNativeDriver: false, + }), onPanResponderRelease: () => { xy.flattenOffset(); }, diff --git a/FabricExample/src/examples/Path.tsx b/FabricExample/src/examples/Path.tsx index 927c9637..9904432b 100644 --- a/FabricExample/src/examples/Path.tsx +++ b/FabricExample/src/examples/Path.tsx @@ -6,7 +6,7 @@ class PathExample extends Component { render() { return ( - + - + tspan line 1 tspan line 2 @@ -163,7 +163,7 @@ class TSpanExample extends Component { 89a - + delta on text diff --git a/FabricExample/src/examples/TouchEvents.tsx b/FabricExample/src/examples/TouchEvents.tsx index 507270f0..f8b70793 100644 --- a/FabricExample/src/examples/TouchEvents.tsx +++ b/FabricExample/src/examples/TouchEvents.tsx @@ -10,6 +10,7 @@ import { Defs, ClipPath, } from 'react-native-svg'; +import {Alert} from 'react-native'; class PressExample extends Component { static title = @@ -22,7 +23,7 @@ class PressExample extends Component { cy="50%" r="38%" fill="red" - onPress={() => alert('Press on Circle')} + onPress={() => Alert.alert('Press on Circle')} /> alert('Long press on Rect')} + onLongPress={() => Alert.alert('Long press on Rect')} /> @@ -75,14 +76,15 @@ class GroupExample extends Component { render() { return ( - alert('Pressed on G')} scale="1.4"> + Alert.alert('Pressed on G')} scale="1.4"> alert('Pressed on Text')}> + onPress={() => Alert.alert('Pressed on Text')}> H diff --git a/TestsExample/App.js b/TestsExample/App.js index e578a7e6..d7dd721f 100644 --- a/TestsExample/App.js +++ b/TestsExample/App.js @@ -2,6 +2,7 @@ import React from 'react'; import ColorTest from './src/ColorTest'; +import Test1374 from './src/Test1374'; import Test1718 from './src/Test1718'; import Test1813 from './src/Test1813'; import Test1845 from './src/Test1845'; diff --git a/TestsExample/src/Test1374.tsx b/TestsExample/src/Test1374.tsx new file mode 100644 index 00000000..07747597 --- /dev/null +++ b/TestsExample/src/Test1374.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { View } from 'react-native'; +import Svg, {Circle, SvgXml} from 'react-native-svg'; + +export default function App() { + const svgXmlWithTransform = ` + +`; + const svgXmlWithEmptyStyle = ` + +`; + +const svgg = ` + + + + +`; + + return ( + + + + + + + + + ); +} diff --git a/src/elements/Shape.tsx b/src/elements/Shape.tsx index ec19dbe2..ef293b2c 100644 --- a/src/elements/Shape.tsx +++ b/src/elements/Shape.tsx @@ -1,6 +1,7 @@ import { Component } from 'react'; import SvgTouchableMixin from '../lib/SvgTouchableMixin'; -import { findNodeHandle, NativeMethods } from 'react-native'; +import extractBrush from '../lib/extract/extractBrush'; +import { ColorValue, findNodeHandle, NativeMethods } from 'react-native'; import { ColumnMajorTransformMatrix, TransformProps, @@ -249,8 +250,13 @@ export default class Shape

extends Component

{ setNativeProps = ( props: Object & { matrix?: ColumnMajorTransformMatrix; + fill?: ColorValue; } & TransformProps, ) => { + if (props.fill) { + // @ts-ignore TODO: native `fill` prop differs from the one passed in props + props.fill = extractBrush(props.fill); + } this.root?.setNativeProps(props); }; /* diff --git a/src/elements/Svg.tsx b/src/elements/Svg.tsx index d94bc4ec..478abda7 100644 --- a/src/elements/Svg.tsx +++ b/src/elements/Svg.tsx @@ -115,6 +115,7 @@ export default class Svg extends Shape { width, height, focusable, + transform, // Inherited G properties font, @@ -182,10 +183,18 @@ export default class Svg extends Shape { props.onLayout = onLayout; } - // transform should not be passed down since it is already used in svgView - // and would be doubled in G causing double transformations const gStyle = Object.assign({}, style) as ViewStyle; - gStyle.transform = undefined; + // if transform prop is of RN style's kind, we want `SvgView` to handle it + // since it can be done here. Otherwise, if transform is of `svg` kind, e.g. string, + // we want G element to parse it since `Svg` does not include parsing of those custom transforms. + // It is problematic due to fact that we either move the `Svg` or just its `G` child, and in the + // second case, when the `G` leaves the area of `Svg`, it will just disappear. + if (Array.isArray(transform) && typeof transform[0] === 'object') { + gStyle.transform = undefined; + } else { + props.transform = undefined; + gStyle.transform = transform; + } const RNSVGSvg = Platform.OS === 'android' ? RNSVGSvgAndroid : RNSVGSvgIOS; diff --git a/src/lib/extract/extractFill.ts b/src/lib/extract/extractFill.ts index 78842ee8..3070ab82 100644 --- a/src/lib/extract/extractFill.ts +++ b/src/lib/extract/extractFill.ts @@ -8,7 +8,7 @@ const fillRules: { evenodd: number; nonzero: number } = { nonzero: 1, }; -const defaultFill = processColor('black'); +const defaultFill = { type: 0, payload: processColor('black') }; export default function extractFill( o: extractedProps,