SVG stroke not showing inside of clipPath - reactjs

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>

Related

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>

How to style an SVG using React styled components by passing the SVG as prop?

I have this SVG, imported from figma:
import React from 'react';
function CloseIcon() {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clip-path="url(#clip0_5301_20199)">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M19.8539 4.85394C20.0491 4.65868 20.0491 4.3421 19.8539 4.14683C19.6586 3.95157 19.342 3.95157 19.1468 4.14683L12.0007 11.2929L4.85372 4.14634C4.65845 3.95108 4.34187 3.95109 4.14661 4.14636C3.95136 4.34162 3.95136 4.65821 4.14663 4.85346L11.2936 12L4.14688 19.1467C3.95162 19.342 3.95162 19.6586 4.14688 19.8538C4.34214 20.0491 4.65873 20.0491 4.85399 19.8538L12.0007 12.7071L19.1467 19.8529C19.342 20.0481 19.6586 20.0481 19.8539 19.8528C20.0491 19.6576 20.0491 19.341 19.8538 19.1457L12.7078 12L19.8539 4.85394Z"
fill="#00A989"
/>
</g>
<defs>
<clipPath id="clip0_5301_20199">
<rect width="24" height="24" fill="white" />
</clipPath>
</defs>
</svg>
);
}
export default CloseIcon;
The SVG is then imported in my component, rendered correctly on the screen as the original style coming from Figma. But when I do style it with styled components, any style is not applied. What is the problem?
import CloseIcon from '../../../Icons/CloseIcon';
import styled from 'styled-components';
<ClosingIcon
aria-label="Close Modal"
onClick={() => setShowModal((prev) => !prev)}
/>
const ClosingIcon = styled(CloseIcon)`
cursor: pointer;
position: absolute;
top: 14px;
right: 32px;
/* width: 32px;
height: 32px; */
padding: 0;
z-index: 10;
`;
you need to pass classname prop to the child component,
function CloseIcon({ className }) {
return (
<svg
className={className} --> like this
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<g clipPath="url(#clip0_5301_20199)">
<path
fillRule="evenodd"
clipRule="evenodd"
d="M19.8539 4.85394C20.0491 4.65868 20.0491 4.3421 19.8539 4.14683C19.6586 3.95157 19.342 3.95157 19.1468 4.14683L12.0007 11.2929L4.85372 4.14634C4.65845 3.95108 4.34187 3.95109 4.14661 4.14636C3.95136 4.34162 3.95136 4.65821 4.14663 4.85346L11.2936 12L4.14688 19.1467C3.95162 19.342 3.95162 19.6586 4.14688 19.8538C4.34214 20.0491 4.65873 20.0491 4.85399 19.8538L12.0007 12.7071L19.1467 19.8529C19.342 20.0481 19.6586 20.0481 19.8539 19.8528C20.0491 19.6576 20.0491 19.341 19.8538 19.1457L12.7078 12L19.8539 4.85394Z"
fill="#00A989"
/>
</g>
<defs>
<clipPath id="clip0_5301_20199">
<rect width="24" height="24" fill="white" />
</clipPath>
</defs>
</svg>
);
}
reference : https://styled-components.com/docs/advanced#existing-css

How to make SVG element clickable?

Angular 1.6
I want to make the following SVG element clickable:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 30.2 34.1"
style="enable-background:new 0 0 30.2 34.1;" xml:space="preserve">
<rect x="19.4" y="0" width="10.8" height="5.4"/>
<rect x="19.4" y="14.3" width="10.8" height="5.4"/>
<rect x="19.4" y="28.7" width="10.8" height="5.4"/>
<rect x="0.2" y="0" width="10.8" height="5.4"/>
<rect x="0.2" y="14.3" width="10.8" height="5.4"/>
<rect x="0.2" y="28.7" width="10.8" height="5.4"/>
</svg>
If not Angular it works by simply enclosing it like this <svg>...</svg>. But the svg graphics simply dissapears if I do the same in Angular.
Also I tried <use> with no success:
<svg ...>
<use xlink:href="" ng-attr-xlink:href="{{$ctrl.menu.channels}}" />
...
</svg>
How to make my svg element clickable attaching a link to it?
Your first approach was OK, you just need a bit of additional CSS:
<a href="#" class="svg">
<svg version="1.1" id="Layer_1">...</svg>
</a>
And in your css:
a.svg:after {
content: "";
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}

Multiple setInterval() using array

I want to animate all three circles using this one script.
But to achieve this, I need to create 3 variables like 'c1' right?
I got the code to work by duplicating everything:
http://jsfiddle.net/JwkYm/339/
It has to be easier then this. Thanks for your help in advance.
(function () {
// math trick 2*pi*57 = 358, must be less than 360 degree
var circleArr = ['orange-halo','orange-halo2','orange-halo3'];
var myTimerArr = ['myTimer','myTimer2','myTimer3'];
var interval = 30;
var angle = [0,0,0];
var angle_increment = 6;
var c1 = setInterval(function () {
var x = 0;
while(x >= 2)
{
document.getElementById(circleArr[x]).setAttribute("stroke-dasharray", angle[x] + ", 20000");
document.getElementById(myTimerArr[x]).innerHTML = parseInt(angle[x]/360*100) + '%';
if (angle[x] >= 270)
{
c1.clearInterval(c1.timer);
}
angle[x] += angle_increment;
x++;
}
}.bind(this), interval);
#myTimer, #myTimer2, #myTimer3 {
fill: #000099;
font-size: 40px;
font-family: Myriad light;
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 300 300" preserveAspectRatio="none" style="width:300; height:300; top:0; left:0;">
<circle cx="100" cy="100" r="73" id="blue-halo" fill="none" stroke="#000099" stroke-width="30" />
<circle cx="100" cy="100" r="73" id="orange-halo" fill="none" stroke="#FD6400" stroke-width="31" stroke-dasharray="0,20000" transform="rotate(-90,100,100)" />
<text id="myTimer" text-anchor="middle" x="100" y="110">0%</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 300 300" preserveAspectRatio="none" style="width:300; height:300; top:0; left:0;">
<circle cx="100" cy="100" r="73" id="blue-halo2" fill="none" stroke="#000099" stroke-width="30" />
<circle cx="100" cy="100" r="73" id="orange-halo2" fill="none" stroke="#FD6400" stroke-width="31" stroke-dasharray="0,20000" transform="rotate(-90,100,100)" />
<text id="myTimer2" text-anchor="middle" x="100" y="110">0%</text>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 300 300" preserveAspectRatio="none" style="width:300; height:300; top:0; left:0;">
<circle cx="100" cy="100" r="73" id="blue-halo2" fill="none" stroke="#000099" stroke-width="30" />
<circle cx="100" cy="100" r="73" id="orange-halo2" fill="none" stroke="#FD6400" stroke-width="31" stroke-dasharray="0,20000" transform="rotate(-90,100,100)" />
<text id="myTimer3" text-anchor="middle" x="100" y="110">0%</text>
</svg>
http://jsfiddle.net/JwkYm/341/

Resources