ZoomableSvg
Pinch to pan-n-zoom react-native-svg components using a render prop.
Advanced Example: InfiniDraw Universal svg drawing with pan and zoom. Builds on Next.js and react-native-web for the web version, and react-native for native apps. Uses react-native-svg on native, svgs for the web, and zoomable-svg in both.
import React Component from 'react';import View StyleSheet Dimensions Animated from 'react-native';import Svg from 'expo'; import ZoomableSvg from 'zoomable-svg'; const G Circle Path Rect = Svg; const width height = Dimensions;const AnimatedRect = Animated; const colors = 'red' 'green' 'blue' 'yellow' 'brown'; state = color: 'red' initAnim: 0 ; { Animated; } { this; const onToggle = thisprops; if onToggle ; }; { const initAnim color = thisstate; let translateRectY = initAnim; const transform = thisprops; return <Svg = => <G => <AnimatedRect = ="5" ="90" ="90" ="rgb(0,0,255)" ="3" ="rgb(0,0,0)" /> <Rect ="5" ="5" ="55" ="55" ="white" /> <Circle ="32" ="32" ="4.167" = = /> <Path ="M55.192 27.87l-5.825-1.092a17.98 17.98 0 0 0-1.392-3.37l3.37-4.928c.312-.456.248-1.142-.143-1.532l-4.155-4.156c-.39-.39-1.076-.454-1.532-.143l-4.928 3.37a18.023 18.023 0 0 0-3.473-1.42l-1.086-5.793c-.103-.543-.632-.983-1.185-.983h-5.877c-.553 0-1.082.44-1.185.983l-1.096 5.85a17.96 17.96 0 0 0-3.334 1.393l-4.866-3.33c-.456-.31-1.142-.247-1.532.144l-4.156 4.156c-.39.39-.454 1.076-.143 1.532l3.35 4.896a18.055 18.055 0 0 0-1.37 3.33L8.807 27.87c-.542.103-.982.632-.982 1.185v5.877c0 .553.44 1.082.982 1.185l5.82 1.09a18.013 18.013 0 0 0 1.4 3.4l-3.31 4.842c-.313.455-.25 1.14.142 1.53l4.155 4.157c.39.39 1.076.454 1.532.143l4.84-3.313c1.04.563 2.146 1.02 3.3 1.375l1.096 5.852c.103.542.632.982 1.185.982h5.877c.553 0 1.082-.44 1.185-.982l1.086-5.796c1.2-.354 2.354-.82 3.438-1.4l4.902 3.353c.456.313 1.142.25 1.532-.142l4.155-4.154c.39-.39.454-1.076.143-1.532l-3.335-4.874a18.016 18.016 0 0 0 1.424-3.44l5.82-1.09c.54-.104.98-.633.98-1.186v-5.877c0-.553-.44-1.082-.982-1.185zM32 42.085c-5.568 0-10.083-4.515-10.083-10.086 0-5.568 4.515-10.084 10.083-10.084 5.57 0 10.086 4.516 10.086 10.083 0 5.57-4.517 10.085-10.086 10.085z" ="blue" /> </G> </Svg> ; } const constraintCombinations = 'none' 'dynamic' 'static' 'union' 'intersect'; state = type: 1 constrain: true constraints: combine: 'dynamic' scaleExtent: width / height 5 translateExtent: 0 0 100 100 ; this; childProps = onToggle: thisonToggle ; { const constrain constraints = thisstate; return <View => <ZoomableSvg ="mid" = = = = = = = = ="meet" = = = /> </View> ; } const styles = StyleSheet;
import React Component from 'react';import View StyleSheet Dimensions PanResponder TouchableOpacity Text from 'react-native';import Svg from 'expo'; import ZoomableSvg from 'zoomable-svg'; const G Path Rect = Svg; const width height = Dimensions; state = paths: currentPath: null ; { const transform = thisprops; const currentPath = thisstate; const translateX translateY scaleX scaleY = transform; const x = sx - translateX / scaleX; const y = sy - translateY / scaleY; if !currentPath this; else this; }; { const noop = ; const yes = true; const shouldRespond = return thispropsdrawing; ; this_panResponder = PanResponder; } { const paths currentPath = thisstate; const transform = thisprops; return <View > <Svg = = => <G => <Rect ="0" ="0" ="100" ="100" ="white" /> paths </G> </Svg> <Svg = = => <G => currentPath ? <Path = ="black" ="1" ="none" /> : null </G> </Svg> </View> ; } const constraints = combine: 'dynamic' scaleExtent: width / height 5 translateExtent: 0 0 100 100; state = drawing: false ; { this; }; { const drawing = thisstate; return <View => <ZoomableSvg ="mid" = = = = = = = = ="meet" = = = = /> <TouchableOpacity = => <Text>drawing ? 'Move' : 'Draw'</Text> </TouchableOpacity> </View> ; } const styles = StyleSheet;