-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Question: draw circular text around an image #972
Comments
How about something like this: https://snack.expo.io/@msand/text-on-a-circle-path import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Constants, Svg } from 'expo';
const { Circle, Text, TextPath, TSpan, G, Path } = Svg;
const SvgComponent = props => (
<Svg height="100%" width="100%" viewBox="0 0 300 300" {...props}>
<G id="circle">
<Circle
r={100}
x={150}
y={150}
fill="none"
stroke="#00008b"
strokeWidth={14}
/>
</G>
<G id="webCompatible">
<Path
d="M 64,0 A 64,64 0 0 1 -64,0 A 64,64 0 0 1 64,0"
transform="translate(150,150)"
stroke="darkblue"
fill="none"
/>
</G>
<Text fill="#000" fontSize="14">
<TextPath href="#circle">
<TSpan dy={-14}>
Text along a curved path... Text along a curved path... Text along a
curved path...
</TSpan>
</TextPath>
</Text>
<Text fill="#000" fontSize="10">
<TextPath href="#webCompatible">
<TSpan>
Text along a curved path... Text along a curved path... Text along a
curved path...
</TSpan>
</TextPath>
</Text>
</Svg>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<SvgComponent />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
}); |
@msnad Thanks a lot!
|
Try using a rotate transform: import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Constants, Svg } from 'expo';
const { Circle, Text, TextPath, TSpan, G, Path } = Svg;
const SvgComponent = props => (
<Svg height="100%" width="100%" viewBox="0 0 300 300" {...props}>
<G id="circle">
<Circle
r={100}
x={150}
y={150}
fill="none"
stroke="#00008b"
strokeWidth={14}
transform="rotate(-90)"
/>
</G>
<G id="webCompatible">
<Path
d="M 64,0 A 64,64 0 0 1 -64,0 A 64,64 0 0 1 64,0"
transform="translate(150,150)rotate(-90)"
stroke="darkblue"
fill="none"
/>
</G>
<Text fill="#000" fontSize="14">
<TextPath href="#circle">
<TSpan dx="0" dy={-14}>
Text along a curved path...
</TSpan>
</TextPath>
</Text>
<Text fill="#000" fontSize="10">
<TextPath href="#webCompatible">
<TSpan>
Text along a curved path...
</TSpan>
</TextPath>
</Text>
</Svg>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<SvgComponent />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
}); |
Thanks @msand Also, any idea why the following happens? This is the code:
|
You should use the image component from react-native-svg rather than react-native: import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Circle, Text, TextPath, TSpan, G, Path, Svg, Image } from 'react-native-svg';
const SvgComponent = props => (
<Svg height="100%" width="100%" viewBox="0 0 300 300" {...props}>
<G id="circle">
<Circle
r={100}
x={150}
y={150}
fill="none"
stroke="#00008b"
strokeWidth={14}
transform="rotate(-90)"
/>
</G>
<G id="webCompatible">
<Path
d="M 64,0 A 64,64 0 0 1 -64,0 A 64,64 0 0 1 64,0"
transform="translate(150,150)rotate(-90)"
stroke="darkblue"
fill="none"
/>
</G>
<Image href="https://facebook.github.io/react/logo-og.png" x={100} y={100} width={100} height={100} />
<Text fill="#000" fontSize="14">
<TextPath href="#circle">
<TSpan dx="0" dy={-14}>
Text along a curved path...
</TSpan>
</TextPath>
</Text>
<Text fill="#000" fontSize="10">
<TextPath href="#webCompatible">
<TSpan>
Text along a curved path...
</TSpan>
</TextPath>
</Text>
</Svg>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<SvgComponent />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: 50,
backgroundColor: '#ecf0f1',
padding: 8,
},
}); |
I would recommend reading the svg spec, it's relatively well written. And then just google for specific tutorials/working examples if you get stuck. |
Thanks @msand , it works. Is it possible to display a circular image as in the following React-Native image?
One more thing that I don't understand: why with expo I can embed a react-native Image within an SVG component, and without expo I can't? Expo is using react-native-svg, right? |
Since react-native-svg probably doesn't support circular images at this point, the following can be a possible solution:
|
How about the example from the readme? https://github.com/react-native-community/react-native-svg#image import * as React from 'react';
import { Text, View, StyleSheet } from 'react-native';
import { Constants, Svg } from 'expo';
const { Defs, ClipPath, Circle, Image } = Svg;
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Svg height="100%" width="100%" viewBox="0 0 100 100">
<Defs>
<ClipPath id="clip">
<Circle cx="50" cy="50" r="50" />
</ClipPath>
</Defs>
<Image
x="0"
y="0"
width="100"
height="100"
opacity="0.5"
preserveAspectRatio="xMidYMid slice"
href={require('./assets/snack-icon.png')}
clipPath="url(#clip)"
/>
</Svg>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
}); With regards to using react-native View/Text/Image components, we don't have any official support for that, it would require implementing foreignObject, which shouldn't be too much work if you have a significant need for it, I can probably describe the changes you would need to make if you're interested in working on it. |
@msand |
You're welcome! Happy I could help |
If you want to center the text along the middle of a path, you can use this: https://snack.expo.io/@msand/text-on-a-circle-path import * as React from 'react';
import { View, StyleSheet } from 'react-native';
import { Constants, Svg } from 'expo';
const { Circle, Text, TextPath, TSpan, G, Path, Defs, ClipPath, Image } = Svg;
const SvgComponent = props => (
<Svg height="100%" width="100%" viewBox="0 0 300 300" {...props}>
<G id="circle">
<Circle
r={100}
x={150}
y={150}
fill="none"
stroke="#00008b"
strokeWidth={14}
transform="rotate(+90)"
/>
</G>
<G id="webCompatible">
<Path
d="M 64,0 A 64,64 0 0 1 -64,0 A 64,64 0 0 1 64,0"
transform="translate(150,150)rotate(+90)"
stroke="darkblue"
fill="none"
/>
</G>
<Text fill="#000" fontSize="14">
<TextPath href="#circle" startOffset="50%">
<TSpan textAnchor="middle" dy={-14}>
Text along a curved path...
</TSpan>
</TextPath>
</Text>
<Text fill="#000" fontSize="10">
<TextPath href="#webCompatible" startOffset="50%">
<TSpan textAnchor="middle">Text along a curved path...</TSpan>
</TextPath>
</Text>
<Defs>
<ClipPath id="clip">
<Circle cx="50" cy="50" r="64" />
</ClipPath>
</Defs>
<G transform="translate(100,100)">
<Image
x="3.5"
y="7"
width="100"
height="100"
opacity="0.5"
preserveAspectRatio="xMidYMid slice"
href={require('./assets/snack-icon.png')}
clipPath="url(#clip)"
/>
</G>
</Svg>
);
export default class App extends React.Component {
render() {
return (
<View style={styles.container}>
<SvgComponent />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingTop: Constants.statusBarHeight,
backgroundColor: '#ecf0f1',
padding: 8,
},
}); |
Wow, Mikael! Thanks much, it works! (I deleted my question but you saw it... I decided that I shouldn't bother you with that...) |
Hey @msand ; In all my tests I used version 5.5.1 of react-native-svg (I am using version 0.55.3 of react-native) and the code seemed to work fine. When I tried to rebuild the repo, however, the circular text is not displayed at all. Any idea? |
Hmm, are you using the one with circle or the web compatible? I think the web-compatible version might work in v5, but text on a path with the other geometric primitives rather than just paths came later, not exactly sure what version right now. Latest version should work fine. Can you make a reproducible git repo using a clean project? |
It will take me some time creating a repo, since I have some urgent tasks for today and tomorrow. Meanwhile, here is the code I am using:
|
This seems to work just fine for me in the latest version / development branch at least: import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native'
import Svg, { G, Text, TextPath, TSpan, Circle } from 'react-native-svg';
const SvgComponent = () => (
<Svg position="absolute" height="200" width="200" viewBox="0 0 300 300">
<G id="circle">
<Circle r={75} x={150} y={140}
fill="none" stroke="#fff" strokeWidth={14}
transform="rotate(+90)"
/>
</G>
<Text fill="#000" fontSize="20" fontFamily="Quicksand-Regular">
<TextPath href="#circle" startOffset="50%">
<TSpan dx="0" dy={-20} textAnchor="middle">
testing
</TSpan>
</TextPath>
</Text>
</Svg>
);
export default class App extends Component {
render() {
return (
<View style={styles.container}>
<SvgComponent />
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: 'gray',
flex: 1
}
}); |
Seems identical to my version... Did you change anything? |
Only the imports / component names. |
I believe that this should not make any difference... |
react: 16.8.3 |
That's what you wrote in package.json? |
I would recommend upgrading to the latest version of both react-native and react-native-svg. I'm just using the latest code I wrote when I pushed to the develop branch, you can check for specific commits from here: https://github.com/react-native-community/react-native-svg/tree/develop npm i react-native-svg@react-native-community/react-native-svg#9321aa5 or yarn add react-native-svg@react-native-community/react-native-svg#9321aa5 |
It is a large project. Upgrading may be a long process. |
@msand your snack was out of date so I updated it with respect to Expo SDK 47 https://snack.expo.dev/@danstepanov/text-on-a-circle-path?platform=ios |
Can anybody post an example of how to draw text around a circular image?
Something like the following:
Thanks in advance :)
The text was updated successfully, but these errors were encountered: