SVG clipping mask disappear when changing angular states (Safari / Chrome) - angularjs

I'm making a logo out of an SVG. Below is the code I am using to construct that logo. It works well and good, with three stacked rectangles and a clipping mask I define.
What is super strange is that whenever I change states in my angular app the clipping mask disappears and I am left with just the rectangles. In Chrome the clipping mask disappears when I zoom also.
Any input appreciated.
<svg style="display:none;" class="gp-ui">
<defs>
<g id="gp_logo-text">
<g class="gp_logo-global">
<path fill="#fff" d="M568.7,485.5c4.6,19.3,23.5,28.5,41.7,28.5c12.9,0,24.8-4.2,34.1-13.5c10-10.2,10.9-20.8,10.9-34.5v-58.2h11.3v-19h-29.6v13c-6.5-10.3-17.3-14.5-29.1-14.5c-24.2,0-44.3,21.3-44.3,45.8c0,24.8,19.3,46,44.1,46c11.8,0,21.7-4.5,27.9-14.8v3.3c0,8.4-0.5,14-6,20.7c-4.4,5.2-11.6,8.2-18.5,8.2c-7.7,0-16.2-3.5-19.6-11L568.7,485.5L568.7,485.5L568.7,485.5z M584.2,433c0-14.8,11.9-27,26.5-27c14.5,0,26.6,12,26.6,26.8c0,15-11.4,27.5-26.5,27.5C596,460.4,584.2,448.2,584.2,433L584.2,433z" />
<polygon fill="#fff" points="694.6,358.8 663.5,358.8 663.5,377.8 674.7,377.8 674.7,458.9 662.6,458.9 662.6,477.9 705.9,477.9 705.9,458.9 694.6,458.9 " />
<path fill="#fff" d="M749.9,480.2c25.6,0,45.9-21.3,45.9-47.4c0-25.3-20.3-46.7-45.4-46.7c-25.3,0-46.1,20.8-46.1,46.9C704.3,458.7,724.4,480.2,749.9,480.2L749.9,480.2z M749.9,460.2c-14.9,0-26-12.7-26-27.4c0-14.8,12.1-26.7,26.5-26.7c14.5,0,25.8,12.7,25.8,27.2C776.1,448.2,764.4,460.2,749.9,460.2L749.9,460.2z" />
<path fill="#fff" d="M824.5,358.8h-31.2v19h11.3v81h-11.3v19h31.2v-13.3c6.7,9.7,17.6,14.7,29.2,14.7c11.4,0,23.2-5.8,30.9-14.5c7.7-8.5,11.8-19.8,11.8-31.3c0-25.2-20.3-45.9-44.9-45.9c-11.1,0-20.7,4.8-26.9,14.2L824.5,358.8L824.5,358.8L824.5,358.8zM850.1,406c14.5,0,26.4,12.2,26.4,27c0,14.5-11.3,27.3-26,27.3c-15,0-26.9-12-26.9-27.5C823.7,418,835.6,406,850.1,406L850.1,406z" />
<path fill="#fff" d="M973.1,477.9h31.2v-19h-10.9v-51h10.9v-19h-31.2v12.7c-6-9.7-15.8-15-27.1-15c-25.5,0-45.7,21.5-45.7,47.4c0,25.2,19.8,46.3,44.8,46.3c11.4,0,21.7-4.5,28.1-14.3L973.1,477.9L973.1,477.9z M946.8,460.4c-14.1,0-26-12-26-26.5c0-15,11.4-27.5,26.3-27.5c14.4,0,26.3,11.8,26.3,26.5C973.4,448,961.8,460.4,946.8,460.4L946.8,460.4z" />
<polygon fill="#fff" points="1040.9,358.8 1009.7,358.8 1009.7,377.8 1020.9,377.8 1020.9,458.9 1008.8,458.9 1008.8,477.9 1052.1,477.9 1052.1,458.9 1040.9,458.9 " />
</g>
<g class="gp_logo-post">
<path fill="#E62100" d="M1072.2,491.4h-11.1v19h42.5v-19h-11.3v-26c7,9.3,18.1,13.8,29.6,13.8c24.2,0,43.4-21.2,43.4-45.5c0-25.2-19.8-45.9-44.4-45.9c-11.8,0-22.2,4.8-28.6,15v-14h-31.2v19h11.1L1072.2,491.4L1072.2,491.4L1072.2,491.4z M1118.4,460.4c-14.5,0-26.3-12-26.3-26.8c0-15.3,12.1-27,26.8-27c14.5,0,25.8,12.7,25.8,27.2C1144.7,448.4,1132.8,460.4,1118.4,460.4L1118.4,460.4z" />
<path fill="#E62100" d="M1213.7,480.2c25.7,0,45.9-21.3,45.9-47.4c0-25.3-20.2-46.7-45.4-46.7c-25.3,0-46.1,20.8-46.1,46.9C1168.1,458.7,1188.2,480.2,1213.7,480.2L1213.7,480.2z M1213.7,460.2c-14.9,0-26-12.7-26-27.4c0-14.8,12.1-26.7,26.5-26.7c14.5,0,25.8,12.7,25.8,27.2C1240,448.2,1228.2,460.2,1213.7,460.2L1213.7,460.2z" />
<path fill="#E62100" d="M1263.3,452v25.8h15.2v-7.3c5.7,6.8,13.7,9.7,22.5,9.7c16.3,0,31.2-10,31.2-28c0-20-16.8-25-32.5-28.7c-6.4-1.5-14.4-3.3-14.4-11.7c0-6.2,5.7-9.3,11.1-9.3c6.2,0,11,4.2,11.3,10.5h19.3v-24.2h-14.7v6.2c-4.9-6.3-11.9-8-19.8-8c-15.5,0-29.6,9.8-29.6,26.8c0,19.5,16.7,24.4,31.8,28.4c6.7,1.8,14.9,3.3,14.9,12.2c0,6.7-5.9,11-11.9,11c-8.2,0-13.4-5.3-14.1-13.3L1263.3,452L1263.3,452L1263.3,452z" />
<polygon fill="#E62100" points="1368.3,407.8 1383.2,407.8 1383.2,388.8 1368.3,388.8 1368.3,358.8 1348.4,358.8 1348.4,388.8 1334.7,388.8 1334.7,407.8 1348.4,407.8 1348.4,477.9 1384.2,477.9 1384.2,458.9 1368.3,458.9 " />
</g>
</g>
<path id="gp_logo-swoosh-path" d="M565.9,316v21c64.4-24.4,147.2-39.3,237.5-39.2c90.2,0,173,14.8,237.5,39.2v-21
c-66-23.9-148.2-38-237.5-38C714.1,278,631.9,292.1,565.9,316" />
</defs>
</svg>
<svg id="globalpost_logo" width="100%" height="100%" viewBox="563.8 277.9 820.4 236.1" xml:space="preserve">
<g id="gp_logo-swoosh" ng-class="{'gp_logo-loading': uiCtrl.loadingState}" clip-path="url(#gp_logo-clip-path)">
<clipPath id="gp_logo-clip-path" >
<use xlink:href="#gp_logo-swoosh-path" />
</clipPath>
<g id="gp_logo-swoosh">
<rect id="gp_logo-swoosh-lead-rect" class="active" x="565.9" y="277.9" fill=" rgba(69, 125, 222, 0)" width="1em" height="59" />
<rect id="gp_logo-swoosh-fill-rect" x="565.9" y="277.9" fill=" rgba(69, 125, 222, 0)" width="1em" height="59" />
<rect id="gp_logo-swoosh-full-rect" x="565.9" y="277.9" fill=" rgba(69, 125, 222, 1)" width="1em" height="59" />
</g>
</g>
<use xlink:href="#gp_logo-text" />
</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>

can't get the SVG to my react component getting an error

I'm trying to add a SVG file but I'm getting an error tat says:
Compiled with problems:X
ERROR
[eslint]
src/svg/banner.jsx
Line 15:2: Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (15:2)
this is the svg:
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle
cx="50"
cy="50"
r="40"
stroke="blue"
fill="lightblue"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1921.641"
height="170.5"
viewBox="0 0 1921.641 170.5"
>
<defs>
<linearGradient
id="linear-gradient"
x1="-0.038"
y1="-1.902"
x2="1.1"
y2="2.41"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#4040be" />
<stop offset="0.36" stop-color="#4e67eb" />
<stop offset="1" stop-color="#31c3ac" />
</linearGradient>
</defs>
<path
id="Path_30"
data-name="Path 30"
d="M0,0H1921.641V170.5H0Z"
opacity="0.8"
fill="url(#linear-gradient)"
/>
</svg>
I'm trying to import it like this:
import { ReactComponent as Logo } from "../svg/banner.svg";
I've also tried to import it like this:
import banner from "../svg/banner.svg";
but it isn't working... any ideas?
using react and chakra UI
create js file export individual SVG data import file inside {} brace and inside importing an SVG file return SVG looks like
//This is my allsvg.js file
export const calender = <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-calendar" viewBox="0 0 16 16">
<path d="M3.5 0a.5.5 0 0 1 .5.5V1h8V.5a.5.5 0 0 1 1 0V1h1a2 2 0 0 1 2 2v11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V3a2 2 0 0 1 2-2h1V.5a.5.5 0 0 1 .5-.5zM1 4v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V4H1z" />
</svg>
//This is where i will import svg file
import { calender } = require("./Media/AllSvg");
return (<div>{calender}</div>)
If you want set the SVG as a react component, you should return one element. ( You can use react Fragment for that <> /* ...HTML code */ </>)
export default function Svg() {
return (
<>
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle
cx="50"
cy="50"
r="40"
stroke="blue"
fill="lightblue"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1921.641"
height="170.5"
viewBox="0 0 1921.641 170.5"
>
<defs>
<linearGradient
id="linear-gradient"
x1="-0.038"
y1="-1.902"
x2="1.1"
y2="2.41"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#4040be" />
<stop offset="0.36" stop-color="#4e67eb" />
<stop offset="1" stop-color="#31c3ac" />
</linearGradient>
</defs>
<path
id="Path_30"
data-name="Path 30"
d="M0,0H1921.641V170.5H0Z"
opacity="0.8"
fill="url(#linear-gradient)"
/>
</svg>
</>
)
}
JSX elements must be wrapped in an enclosing tag But Your component it's not wrapped . You can use Fragments to group all your svg tags without adding nodes to the DOM try it like this :
<> // shorter syntax you can use for declaring fragments
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
<circle
cx="50"
cy="50"
r="40"
stroke="blue"
fill="lightblue"
/>
</svg>
<svg
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1921.641"
height="170.5"
viewBox="0 0 1921.641 170.5"
>
<defs>
<linearGradient
id="linear-gradient"
x1="-0.038"
y1="-1.902"
x2="1.1"
y2="2.41"
gradientUnits="objectBoundingBox"
>
<stop offset="0" stop-color="#4040be" />
<stop offset="0.36" stop-color="#4e67eb" />
<stop offset="1" stop-color="#31c3ac" />
</linearGradient>
</defs>
<path
id="Path_30"
data-name="Path 30"
d="M0,0H1921.641V170.5H0Z"
opacity="0.8"
fill="url(#linear-gradient)"
/>
</svg>
</>

SVG icon doesn`t load

Some svg icons in my project are displayed and some dont. Heres an example of one that has issue
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" id="windows">
<defs>
<linearGradient id="windows_svg__b" x1="0%" x2="100%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#FFF" stop-opacity="0.1"></stop>
<stop offset="100%" stop-color="#0087C7"></stop>
</linearGradient>
<path id="windows_svg__a"
d="M6.5 14.62l-5.656-.892A1 1 0 010 12.74V8.288h6.5v6.333zm1 .159V8.288H16v6.662a1 1 0 01-1.156.988L7.5 14.778zm-1-13.367v5.876H0V3.241a1 1 0 01.853-.989l5.647-.84zm1-.148L14.853.17A1 1 0 0116 1.16v6.128H7.5V1.264z">
</path>
</defs>
<g fill="none" fill-rule="evenodd">
<use fill="#0087C7" xlink:href="#windows_svg__a"></use>
<use fill="url(#windows_svg__b)" fill-opacity="0.8" xlink:href="#windows_svg__a"></use>
</g>
</svg>
https://codesandbox.io/s/practical-satoshi-o68rnt
I guess that`s something with tags but not sure and have no idea how to fix it
There are 2 issues with your code first issue is with your SVG have some issues please use the below one.
`<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" id="windows">
<defs>
<linearGradient id="windows_svg__b" x1="0%" x2="100%" y1="0%" y2="100%">
<stop offset="0%" stop-color="#FFF" stop-opacity="0.1"></stop>
<stop offset="100%" stop-color="#0087C7"></stop>
</linearGradient>
<path id="windows_svg__a"
d="M6.5 14.62l-5.656-.892A1 1 0 010 12.74V8.288h6.5v6.333zm1 .159V8.288H16v6.662a1 1 0 01-1.156.988L7.5 14.778zm-1-13.367v5.876H0V3.241a1 1 0 01.853-.989l5.647-.84zm1-.148L14.853.17A1 1 0 0116 1.16v6.128H7.5V1.264z">
</path>
</defs>
<g fill="none" fill-rule="evenodd">
<use fill="#0087C7" href="#windows_svg__a"></use>
<use fill="url(#windows_svg__b)" fill-opacity="0.8" href="#windows_svg__a"></use>
</g>
</svg>`
Second, you have to import that image first, and then you can use it in your code.
import "./styles.css";
import icon from"../public/icons/icon.svg";
export default function App() {
return (
<div className="App">
<img src={icon} alt="sorry" />
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
Try to use
import { ReactComponent as Icon } from "path/icon.svg";
And then you can use it as component in React
<div>
<Icon />
</div>

SVG stroke not showing inside of clipPath

I have the following Codepen, where I'm trying to animate a stroke of a circle around an image.
So far, I've got a circle SVG which is clipping an image, but it doesn't show the stroke inside of clipPath.
How do I get the border to show?
class App extends React.Component {
render() {
return (
<svg width='48' height='48'>
<defs>
<clipPath id='circleView'>
<circle cx='24' cy='24' r='23' fill='none' stroke='red' strokeWidth='2' />
</clipPath>
</defs>
<image width='48' height='48' xlinkHref={'https://source.unsplash.com/random'} clipPath='url(#circleView)' />
</svg>
)
}
}
As Robert said, the child SVG figures in the clip-path line are not displayed.
Therefore, for the animation you need to add another circle outside the clip-path
<circle cx="25" cy="24" r="14" fill="none" stroke="red" strokeWidth="2" />
.container {
width:25%;
height:25%;
}
<div class="container">
<svg viewBox="0 0 48 48" >
<defs>
<clipPath id='circleView'>
<circle cx='24' cy='22' r='16' fill='none' stroke='red' stroke-width='2' />
</clipPath>
</defs>
<image width="100%" height="100%" xlink:href='https://i.stack.imgur.com/O9eO8.jpg'
clip-path='url(#circleView)' />
<circle cx='24' cy='22' r='16' fill='none' stroke='red' strokeWidth='2' />
</svg>
</div>
To animate a circle, use the change in the stroke-dashoffset attribute from maximum to zero. values="(100.48;0)"
Animation starts after click
.container {
width:25%;
height:25%;
}
<div class="container">
<svg id="svg1" viewBox="0 0 48 48">
<defs>
<clipPath id='circleView'>
<circle cx='24' cy='22' r='16' fill='none' stroke='red' stroke-width='2' />
</clipPath>
</defs>
<image width="100%" height="100%" xlink:href='https://i.stack.imgur.com/O9eO8.jpg' clip-path='url(#circleView)' />
<circle transform="rotate(-90 24 22)" cx="24" cy="22" r="16" fill='none' stroke='red' strokeWidth='2'
stroke-dasharray="100.48" stroke-dashoffset="100.48" >
<animate
attributeName="stroke-dashoffset"
dur="1s"
begin="svg1.click"
values="100.48;0"
fill="freeze"/>
</circle>
</svg>
</div>
Variant of animation with CSS
I added transparency animation to the circle animation.
The animation begins when you hover the mouse cursor.
.container {
width:25%;
height:25%;
}
#crc1 {
fill:skyblue;
stroke-width:1;
stroke:red;
stroke-dasharray:100.48;
stroke-dashoffset:100.48;
fill-opacity:0.9;
}
#crc1:hover {
animation: dash 1.5s ease-out forwards;
}
#keyframes dash {
0% { stroke-dashoffset: 100.48; fill-opacity:0.9; }
50% { fill-opacity:0.45;}
100% { stroke-dashoffset: 0; fill-opacity:0; }
}
#img1 {
clip-path: url(#circleView);
}
<div class="container">
<svg id="svg1" viewBox="0 0 48 48">
<defs>
<clipPath id='circleView'>
<circle cx='24' cy='22' r='16'/>
</clipPath>
</defs>
<image width="100%" height="100%" xlink:href='https://i.stack.imgur.com/O9eO8.jpg'
clip-path='url(#circleView)' />
<circle id="crc1" cx="24" cy="22" r="16" />
</svg>
</div>

select SVG element's attribute "id" in React

How I can select the SVG element's "g" attribute "id" : as mentioned below "SvgElement" in react
like :
<svg id="L_1" data-name="L 1" xmlns="http://www.w3.org/2000/svg" width="1920" height="720" viewBox="0 0 920 420">
<rect id="Background" width="1920" height="720" fill="none"/>
<g id="SvgElement">
<circle cx="200" cy="100" r="50"/>
</g>
</svg>

Resources