Reputation: 253
I am trying fill a simple circle SVG with an image in React. The sources I found have not been helpful, for they don't seem to apply to JSX.
Here is the code I currently have:
import React, {Component} from 'react';
import Anime from '../images/Anime.jpeg';
class Circle extends Component {
render() {
return (
<div>
<svg height="300" width="300">
<circle cx="150" cy="150" r="100" stroke="black" stroke-width="3" fill={Anime} />
</svg>
</div>
);
}
}
export default Circle;
My first instinct was to tweak the fill
attribute by either replacing the original color ="red"
with ={Anime}
or =url("../images/Anime.jpeg")
, but neither worked.
(I know the path to the Anime image is correct, after testing it by rendering <img src={Anime} alt={Anime}></img>
inside the div.
I see people using <defs>
and <pattern>
tags, as such (referring to this post):
<svg id="graph" width="100%" height="400px">
<!-- pattern -->
<defs>
<pattern id="image" x="0%" y="0%" height="100%" width="100%"
viewBox="0 0 512 512">
<image x="0%" y="0%" width="512" height="512" xlink:href="https://cdn3.iconfinder.com/data/icons/people-professions/512/Baby-512.png"></image>
</pattern>
</defs>
<circle id="sd" class="medium" cx="5%" cy="40%" r="5%" fill="url(#image)" stroke="lightblue" stroke-width="0.5%" />
</svg>
But these tags don't seem to work in React / JSX; I keep getting this error when I try to use them: Namespace tags are not supported by default. React's JSX doesn't support namespace tags. You can turn on the 'throwIfNamespace' flag to bypass this warning.
Is there a way around this? I want to be able to fit the following picture into a simple circle svg with a thick black border around it.
Upvotes: 2
Views: 3082
Reputation: 253
I figured out a way and wanted to post / share it, in case anyone is here, looking at this post and wondering what the (one of the) solution(s) is!
Here is my final code:
import React, {Component} from 'react';
import AnimeCropped from '../images/AnimeCropped.png';
class Circle extends Component {
render() {
return (
<div>
<svg height="670" width="670">
<circle cx="350" cy="350" r="300" stroke="black" stroke-width="5" fill="none" />
<image className='img-circle' xlinkHref={AnimeCropped} x='75.5' y="15" height="670" width="670"/>
</svg>
</div>
);
}
}
export default Circle;
Essentially what I did was:
Crop the photo to be a circle. I could have followed cubrr's recommendation above and clip-path'ed it (which is a great idea!), but instead - I just found and used a photo cropping tool online. I then named the newly-cropped picture "AnimeCropped" and saved it in the same directory.
Imported the picture into the component file and rendered via a <image>
tag after the <circle>
tag. It wasn't mentioned in my original question above, but I also hypothesized that inserting the image inside the circle might solve the problem. As such:
<svg height="670" width="670">
<circle cx="350" cy="350" r="300" stroke="black" stroke-width="5" fill="none">
<img src={AnimeCropped} alt={AnimeCropped}/>
</circle>
</svg>
But this didn't work.
In my final code, you'll see that the <image>
tag comes after the <circle>
tag, so technically, it's not really inside the circle, but just overlaying on top of it. Also note that I had to use <image>
, not <img>
. I'll have to do a bit of research on this, but <img>
was giving me an error message.
Also important: In React, xlink:href
won't work, but xlinkHref
will! This really tripped me off, but I found this helpful post.
Using classNames, I edited the size of the cropped picture in my App.css file.
Configured the x- and y- coordinates so that it somewhat fits perfectly in the middle of the circle.
That's it! Just wanted to post this for closure / help me review what I learned.
Upvotes: 2