Google maps Api SVG is not displayed in icons - reactjs

SVG is not displayed in icons
Referenced sites
Add a background image (.png) to a SVG circle shape
https://codesandbox.io/s/react-google-maps-api-forked-pcup77?file=/src/index.js
source code
<LoadScript googleMapsApiKey="">
<GoogleMap
mapContainerStyle={containerStyle}
center={position}
zoom={17}
>
<Marker
position={position}
icon={{
url:
"data:image/svg+xml;utf-8, " +
'<svg width="100" height="100">' +
"<defs>" +
'<pattern id="image" patternUnits="userSpaceOnUse" height="100" width="100">' +
'<image x="0" y="0" height="100" width="100" xlink:href="http://i.imgur.com/7Nlcay7.jpg"></image>' +
"</pattern>" +
"</defs>" +
'<circle id="top" cx="50" cy="50" r="50" fill="url(#image)"/>' +
"</svg>",
}}
/>
</GoogleMap>
</LoadScript>
Is there a problem with SVG?
How to solve this problem?
I want to be able to display what I have created in SVG.

Related

How to add images to svg to map each pie in the circle

How can I add an image to the path in my SVG and also rotate the text inside the path and make it closer to the edges of the path?
I am currently using the following code in my React application to create a roulette wheel with multiple sections. Each section is represented by a path that is filled with a specific color. I would like to add an image inside each path and also rotate the text inside the path and make it closer to the edges of the path.
const RouletteWheel = () => {
const items = ["item1", "item2", "item3", "item4"];
const colors = ["blue", "red", "green", "yellow", "brown", "purple"];
const numItems = items.length;
const angle = items.length === 1 ? 0 : 360 / numItems;
return (
<svg viewBox="0 0 100 100" className="svg-wheel">
{items.length > 1 ? (
items.map((item, index) => {
const x1 = 50 + 45 * Math.cos(angle * index * (Math.PI / 180));
const y1 = 50 + 45 * Math.sin(angle * index * (Math.PI / 180));
const x2 = 50 + 45 * Math.cos(angle * (index + 1) * (Math.PI / 180));
const y2 = 50 + 45 * Math.sin(angle * (index + 1) * (Math.PI / 180));
return (
<React.Fragment>
<defs>
<path
id="text-path"
d={`M 50 50 L ${x1} ${y1} A 45 45 0 0 1 ${x2} ${y2} Z`}
/>
</defs>
<path
key={`path-${index}`}
id={`path-${index}`}
d={`M 50 50 L ${x1} ${y1} A 45 45 0 0 1 ${x2} ${y2} Z`}
fill={`${colors[index]}`}
></path>
<text
x={20}
dy={25}
fill="white"
textAnchor="middle"
fontSize={4}
>
<textPath transform={`rotate(100)`} xlinkHref={`#path-${index}`}>{item}</textPath>
</text>
</React.Fragment>
);
})
) : (
<circle key={"circle"} cx="50" cy="50" r="45" fill="url(#pattern1)" />
)}
</svg>
);
};
ReactDOM.render(
RouletteWheel(),
document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="container"></div>
The following examples in plain SVG. In the first example I just implemented a solid color using the stroke of a circle (#c1).
In the second example I replaced the solid colors with images. Here the circle (#c1) acts as mask for the image. The tricky part is to place the image in the right angle together with the mask. In general all the rotations are calculated from a circle (360) split in 5 items. So 72 degrees each.
In both examples the text is placed along a circle (#c2) using a textpath element and the attribute startOffset. The dominant-baseline of the text is "hanging" -- so the text is place "under" the circle/arc. The placement of the text can be adjusted with the radius of circle (#c2).
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="300">
<defs>
<circle id="c1" r="23" fill="none" stroke-width="46"
stroke-dasharray="72 360" pathLength="360" />
<circle id="c2" r="45" fill="none" pathLength="360" />
</defs>
<g transform="translate(50 50)">
<use href="#c1" stroke="blue" transform="rotate(0)" />
<use href="#c1" stroke="red" transform="rotate(72)" />
<use href="#c1" stroke="green" transform="rotate(144)" />
<use href="#c1" stroke="yellow" transform="rotate(216)" />
<use href="#c1" stroke="brown" transform="rotate(288)" />
<text font-size="6" fill="white" text-anchor="middle"
dominant-baseline="hanging">
<textPath href="#c2" startOffset="36">item 1</textPath>
<textPath href="#c2" startOffset="108">item 2</textPath>
<textPath href="#c2" startOffset="180">item 3</textPath>
<textPath href="#c2" startOffset="252">item 4</textPath>
<textPath href="#c2" startOffset="324">item 5</textPath>
</text>
</g>
</svg>
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" width="300">
<defs>
<mask id="m1">
<circle r="23" fill="none" stroke="white" stroke-width="46"
stroke-dasharray="72 360" pathLength="360" />
</mask>
<circle id="c2" r="45" fill="none" pathLength="360" />
</defs>
<g transform="translate(50 50)">
<g mask="url(#m1)">
<image href="https://via.placeholder.com/300/09f/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(72)">
<image href="https://via.placeholder.com/300/080/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(144)">
<image href="https://via.placeholder.com/300/800/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(216)">
<image href="https://via.placeholder.com/300/f0f/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<g mask="url(#m1)" transform="rotate(288)">
<image href="https://via.placeholder.com/300/022/fff.png" width="60"
x="-30" y="-60" transform="rotate(126)" />
</g>
<text font-size="6" fill="white" text-anchor="middle"
dominant-baseline="hanging">
<textPath href="#c2" startOffset="36">item 1</textPath>
<textPath href="#c2" startOffset="108">item 2</textPath>
<textPath href="#c2" startOffset="180">item 3</textPath>
<textPath href="#c2" startOffset="252">item 4</textPath>
<textPath href="#c2" startOffset="324">item 5</textPath>
</text>
</g>
</svg>

How to use Next.js Image component with MaterialUI?

I am able to use the <img> tag no problem, but when I try to use the <Image> component, all that displays is an empty square the size of the image. The only way I have been able to get the image to display without using <img> is with the <Avatar> component. It's just a small brand image so it's not a huge deal, but I would like to use the built-in Next.js image optimization. And using <Avatar> does not feel very semantic as well.
It is being displayed inside of a ListItem component like this:
<Drawer variant="permanent" {...other}>
<List disablePadding>
<ListItem
sx={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<Avatar
src="images/icons/agreement2.png"
alt="Scales of Justice Brand Image"
sx={{ width: 50, height: 50 }}
/>
</ListItem>
This is what I have tried so far:
I created a separate component for the image
import Image from 'next/image'
import brandImage from '../public/images/icons/law.png'
export default function Brand() {
return <Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
}
and displaying <Brand /> inside of the <ListItem> in place of the current <Avatar> component.
I tried to import the .png file and use
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
inside of the <ListItem>. And then I tried without importing the image and just using the full file path.
I tried placing <Image> inside of the <Avatar> component.
<Avatar>
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
</Avatar>
I also tried adding in the layout prop with all of the options.
I am using Next.js v12.0.9 and MUI v5.4.2
I recommend creating a parent element with a position responsive and setting the image like this:
<Box sx={{position:'relative'}}>
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
</Box>
You also may set it like:
<Box sx={{position:'relative', height:'50px', width:'50px'}}>
<Image src={brandImage} layout="fill" objectFit="cover" alt="Brand Logo" />
</Box>
This seem to work for me.
<Stack
sx={{
height: "500px",
}}
>
<Image
src={image.data.attributes.url}
alt={image.data.attributes.alternativeText}
width={image.data.attributes.width}
height={image.data.attributes.height}
objectFit="cover"
priority
/>
</Stack>
Using Stack seems to expand the image full width without using width: 100%

React Native svg clip path on image not working

Trying to clip an Image component with an svg ClipPath is proving problematic. I can clip a Rect no problem, but when I replace the Rect with an Image, nothing shows up.
octogon.points = "80,0.3 23.6,23.6 0.3,80 23.6,136.4 80,159.7 136.4,136.4 159.7,80 136.4,2 3.6";
props.photoUri = "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Fhalt-c46ef35c-1897-441e-840e-28147c0de5a9/ImagePicker/d68a7ddd-807e-4d26-95c2-bd47ddca803e.jpg"
<View style={styles.container}>
<Svg width={160} height={160} viewBox={`0 0 160 160`}>
<Defs>
<ClipPath id="clip">
<Polygon points={octogon.points} />
</ClipPath>
</Defs>
{/* <Rect x="0" y="0" width="160" height="160" fill="red" clipPath="#clip" /> */}
<Image x="0" y="0" width="160" height="160" source={{ uri: props.photoUri }} clipPath="#clip" />
</Svg>
</View>
The commented out Rect worked as intended and creates a red octogon. The Image returns blank.
I feel like I'm overlooking something simple. Any help is appreciated.
Answering my own question because I'm an idiot and hopefully it will help someone in the future. Be mindful of which components you are importing. I was using Image from 'react-native' instead of Image from 'react-native-svg'.
Once I swapped it over and changed source={{ uri: props.photoUri }} to href={{ uri: props.photoUri }}, it started working.

React FabricJS Grouping (JSX)

NPM Package: https://www.npmjs.com/package/react-fabricjs
I'm using react-fabricjs and have a canvas with some icons showing. I'm now trying to get Grouping to work but I can't work out the syntax. Essentially I want to create this effect but using React JSX Code:
http://jsfiddle.net/anwjhs2o/1/
This is the code I have:
import React from 'react';
import {Canvas, Circle, Image, Path, Text, Rect, Ellipse, Triangle, Group} from 'react-fabricjs';
export default class CanvasFabric extends React.Component {
render() {
return (
<Canvas
ref="canvas"
width="556"
height="371"
>
<Circle
ref="circle"
radius={20}
left={100}
top={50}
stroke="green"
fill="blue"
blur={100}
color="rgba(0,0,0,0.6)"
/>
<Image
src="https://cloudinary-a.akamaihd.net/bountysource/image/twitter_name/d_noaoqqwxegvmulwus0un.png,c_pad,w_200,h_200,b_white/fabricjs.png"
width={64}
height={48}
left={10}
top={50}
/>
<Rect
ref="rect1"
width={50}
height={50}
left={150}
top={150}
fill="orange"
shadow="rgba(0,0,0,0.3) 5px 5px 5px"
/>
<Rect
ref="rect2"
width={60}
height={60}
left={145}
top={145}
stroke="purple"
strokeWidth={2}
blur={20}
/>
<Ellipse
ref="ellipse"
width={20}
height={100}
offsetX={350}
offsetY={250}
stroke="orange"
strokeWidth={2}
fill="yellow"
/>
<Triangle
ref="tri"
width={20}
height={20}
left={350}
top={250}
stroke="orange"
strokeWidth={1}
fill="black"
opacity={0.3}
/>
<Text text="Edit me"
top={300}
left={10}
shadow="rgba(0,0,0,0.3) 5px 5px 5px"
stroke="#ff1318"
strokeWidth={1}
fontStyle="italic"
fontFamily="Hoefler Text"
/>
</Canvas>
)
}
}
How could I say group the 2 Rect's - so they can be rotated/scaled etc together?
thankyou
Adam
** Extra Note: I'm no React Expert but I get the feeling the Fabric React Package is far from completed and this is why core functionality doesn't work.
I tried to check the lib, i did not get how to use the group.
The main point is you should just use fabricJS in a normal way even if you are using reactJS. Binding a fabricjs render to a react render may be slow or just unnecessary.
The group code is using:
While the Group constructor in fabric is different.
You can try 2 approaches, the only 2 that makes sense in react:
<Group>
<Rect
ref="rect1"
width={50}
height={50}
left={150}
top={150}
fill="orange"
shadow="rgba(0,0,0,0.3) 5px 5px 5px"
/>
<Rect
ref="rect2"
width={60}
height={60}
left={145}
top={145}
stroke="purple"
strokeWidth={2}
blur={20}
/>
</Group>
OR
<Group
objects={[<Rect
ref="rect1"
width={50}
height={50}
left={150}
top={150}
fill="orange"
shadow="rgba(0,0,0,0.3) 5px 5px 5px"
/>,
<Rect
ref="rect2"
width={60}
height={60}
left={145}
top={145}
stroke="purple"
strokeWidth={2}
blur={20}
/>]}
/>

Defs pattern with css module - modify point in c3.js line chart to have an image inside

I am using c3.js and my components are using CSS Modules. I wanted to modify the fill of points in the line chart with an image. For that in the render method I had added defs-pattern -
render(){
return (
<div>
<defs>
<pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1">
<image x="0" y="0" src="http://dummyimage.com/20x20/faf2fa/0011ff.png&text=x" />
</pattern>
</defs>
<C3Chart {...this.getConfig()}/>
</div>
);
}
In the styles css file I had added -
container :global(.c3-target-subscriber .c3-circle-5) {
fill: url(#image) !important;
}
But nothing happens. I just want to show an image inside the point of the line chart.
Any help is highly appreciated.
A <defs> element must have a parent that is a SVG element and not a HTML element. You need something like this:
<svg>
<defs>
<pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="1" width="1">
<image x="0" y="0" src="http://dummyimage.com/20x20/faf2fa/0011ff.png&text=x" />
</pattern>
</defs>
<svg>
Also your CSS points to something with a id of gradient but your pattern's id is image.

Resources