Why isn't this transform scale animating? - css

I am trying to animate a circle from scale(0) to scale(1) but it does not animate even though opacity animates.
https://codepen.io/labeeb/pen/rJaNdN
setInterval(function() {
TweenMax.to($("circle"), 1, {
css: {
opacity: 1
},
scale: 1
});
}, 1000);
circle {
transform: scale(0);
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<svg width="500" height="500">
<g>
<circle cx="30" cy="30" r="50" fill red></circle>
</g>
</svg>

I edited your post and put the code into a code-snippet.
While doing that, the error TweenMax is not defined was visible in the console.
You really did not define TweenMax.
You forgot to add some code.

Related

how to create an Angular circular progress bar using SVG

I have created a design for angular circular progress bar. The issue is that i want to give the percentage value dynamic . I have got the dynamic value from API but i have no idea how should i implement it to create a circular progress bar using SVG. I'll share my html skeleton and the css i use.
.track,
.filled {
stroke-width: 10;
fill: none;
}
.track {
stroke: rgba(160, 215, 231, 0.85);
}
.filled {
stroke: blue;
stroke-dashoffset: 202;
stroke-dasharray: 440;
}
<div class="col-lg-3">
<div class="iconbox-singleD7 dashboard-height">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-35 0 190 190" class="mw">
<circle class="track" cx="60" cy="60" r="55" />
<text x="40" y="60" fill="#fff">Patients</text>
<text x="50" y="75" fill="#fff">{{totalPatient}}</text>
<circle class="filled" cx="60" cy="60" r="55" />
<circle cx="30" cy="136" r="5" stroke="blue" stroke-width="3" fill="blue" /><text x="40" y="140" fill="#fff">Male {{malePercentage}}%</text>
<circle cx="30" cy="152" r="5" stroke="rgba(160, 215, 231, 0.85)" stroke-width="3" fill="rgba(160, 215, 231, 0.85)" /><text x="40" y="155" fill="#fff">Female {{femalePercentage}}%</text>
</svg>
</div>
</div>
What i want is that. Lets say i get a male percentage = 70% or any value from an API i want to set the progress bar according to the percentage i get from API. How can i achieve that .i'm not familier with SVG. So any help will be appreciated. Thanks
Hello here is the code pen: https://codepen.io/Echyzen/pen/LYBraGB
var percentage = 75;
var a = -3.46;
var b = 440;
function changePer() {
const finalOffset = Math.round(a*percentage+b)
const concernedCircle = document.getElementsByClassName('filled')[0];
concernedCircle.style.strokeDashoffset = finalOffset;
}
which extract the a and b of the affine function.
You have to click on the button to execute the 75% percentage.
Or using querySelector:
var percentage = 70;
var a = -3.46;
var b = 440;
function changePer() {
const finalOffset = Math.round(a*percentage+b)
const concernedCircle = document.querySelector('.filled');
concernedCircle.style.strokeDashoffset = finalOffset;
}
Start with the <progress-circle> native Web Component I built : https://pie-meister.github.io/
It is unlicensed Open Source code; do with it whatever your want. Documentation at Dev.to
<progress-circle value="100%">Web Components</progress-circle>
<progress-circle value="71%" stroke="red">React</progress-circle>
<progress-circle value="90%" stroke="orange">Others</progress-circle>
<script src="https://pie-meister.github.io/PieMeister-with-Progress.min.js"></script>
<style>
progress-circle {
font-family: Arial;
width: 180px; /* StackOverflow viewport */
}
progress-circle::part(label) {
font-size:70px;
}
</style>

Trying to "transform: rotate()" a <circle> element using styled-components

CodeSandbox with example:
https://codesandbox.io/s/floral-surf-l7m0x
I'm trying to rotate 180º a circle element inside an SVG. I'm being able to do it with the regular <circle> tag, but I'm not being able to do it with the styled component styled.circle
LS.Svg_SVG = styled.svg`
border: 1px dotted silver;
width: 100px;
height: 100px;
`;
LS.Circle_CIRCLE = styled.circle`
stroke-dasharray: 289.0272;
stroke-dashoffset: -144.5136;
transform: rotate(180 50 50); /* <------------ IT DOES NOT WORK */
`;
export default function App() {
return (
<React.Fragment>
<LS.Container_DIV>
<LS.Svg_SVG viewBox="100 100">
<circle /* USING REGULAR <circle> */
cx="50"
cy="50"
r="46"
stroke="black"
strokeWidth="8px"
fill="none"
strokeDasharray="289.0272"
strokeDashoffset="-144.5136"
transform="rotate(180 50 50)" /* <----------------- IT WORKS */
/>
</LS.Svg_SVG>
</LS.Container_DIV>
<LS.Container_DIV>
<LS.Svg_SVG viewBox="100 100">
<LS.Circle_CIRCLE /* USING STYLED COMPONENTS */
cx="50"
cy="50"
r="46"
stroke="black"
strokeWidth="8px"
fill="none"
/>
</LS.Svg_SVG>
</LS.Container_DIV>
</React.Fragment>
);
}
The result I'm getting:
They both should be the same. The first one is rotated (using regular <circle>). The second one is not rotated (using styled-components). Even though I'm setting transform: rotate(-180 50 50); in the styled component.
In CSS, units are required (ie. 180deg, 50px)
The SVG-specific version of rotate: rotate(angle, cx, cy), is not supported in the CSS version of transform. You'll need to use transform-origin.
LS.Circle_CIRCLE = styled.circle`
stroke-dasharray: 289.0272;
stroke-dashoffset: -144.5136;
transform: rotate(180deg);
transform-origin: 50px 50px;
`;

Animate dashed SVG line

I would like to animate a dashed line in a SVG-file. The line should »grow« from 0 length to full length. All the methods I found are not suitable for me.
Does anyone have an idea, how to solve this?
That's the path in my svg file:
<path class="path" fill="none" stroke="#FFFFFF" stroke-miterlimit="10" d="M234.3,119
c-31-0.7-95,9-128.7,50.8"/>
To animate the line as straight line i did:
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
Of course, this is not working, when I want the line to be dashed.
Is there anybody who has an idea how to solve this?
That's my codepen: http://codepen.io/anon/pen/WpZNJY
PS: I can't use two paths over each other to hide the path underneath because I'm having a coloured background.
You can also do this just using masks as so:
.paths {
fill: none;
stroke: black;
stroke-dasharray: 5;
}
.mask {
fill: none;
stroke: white;
stroke-width: 10;
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 830 500" >
<defs>
<path id="first" d="M234.3,119c-31-0.7-95,9-128.7,50.8"/>
<path id="vienna" d="M382.8,243.8c2.9-36.1,15.8-110.3,110.1-145.4"/>
<path id="budapest" d="M550.6,319.4c34-2.7,109-2.1,174.8,50.5"/>
<path id="salzburg" d="M265,323c21.5,12.1,57.2,39.5,60.7,85.1"/>
<path id="tyrol" d="M147.8,319.5c-27.1,7-79.7,31.3-92.8,74.2"/>
<mask id="first-mask"><use class="mask" xlink:href="#first" /></mask>
<mask id="vienna-mask"><use class="mask" xlink:href="#vienna" /></mask>
<mask id="budapest-mask"><use class="mask" xlink:href="#budapest" /></mask>
<mask id="salzburg-mask"><use class="mask" xlink:href="#salzburg" /></mask>
<mask id="tyrol-mask"><use class="mask" xlink:href="#tyrol" /></mask>
</defs>
<g class="paths">
<use xlink:href="#first" mask="url(#first-mask)" />
<use xlink:href="#vienna" mask="url(#vienna-mask)" />
<use xlink:href="#budapest" mask="url(#budapest-mask)" />
<use xlink:href="#salzburg" mask="url(#salzburg-mask)" />
<use xlink:href="#tyrol" mask="url(#tyrol-mask)" />
</g>
</svg>
This is also available as:
codepen of single dotted path
codepen of these plane tracks
Enjoy!
But note ... make sure you test your code cross-browser and fall back to animate tags or javascript if you have issues.
One of the ways to do this is with Javascript. It duplicates a path by creating a polyline.
Try the example below:
<!DOCTYPE HTML>
<html>
<head>
<style>
polyline{
stroke-dasharray:8;
stroke:black;
fill:none;
stroke-width:1;
}
</style>
</head>
<body >
This builds a smooth/dashed polylines that replicates your paths.<br>
<button onClick=animateDashPaths()>Animate Paths</button><br>
<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 830 500" enable-background="new 0 0 830 500" xml:space="preserve">
<path class="path" fill="none" stroke="#000000" stroke-miterlimit="10" d="M234.3,119
c-31-0.7-95,9-128.7,50.8"/>
<!-- Vienna Dash -->
<path id="pathVienna" display="none" stroke-miterlimit="10" d="M382.8,243.8
c2.9-36.1,15.8-110.3,110.1-145.4"/>
<!-- Budapest Dash -->
<path id="pathBudapest" display="none" stroke-miterlimit="10" d="M550.6,319.4
c34-2.7,109-2.1,174.8,50.5"/>
<!-- Salzburg Dash -->
<path id="pathSalzburg" display="none" stroke-miterlimit="10" d="M265,323
c21.5,12.1,57.2,39.5,60.7,85.1"/>
<!-- Tyrol Dash -->
<path id="pathTyrol" display="none" stroke-miterlimit="10" d="M147.8,319.5
c-27.1,7-79.7,31.3-92.8,74.2"/>
</svg>
<script>
//---button---
function animateDashPaths()
{
var NS="http://www.w3.org/2000/svg"
//----Vienna----------------
var endLengthVienna=pathVienna.getTotalLength()
var lengthDeltaVienna=endLengthVienna/200
var polylineVienna=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineVienna)
var pntListVienna=polylineVienna.points
var iTVienna=setInterval(drawPathVienna,5)
var cntVienna=0
function drawPathVienna()
{
var len=lengthDeltaVienna*cntVienna++
if(len<endLengthVienna)
{
var pnt=pathVienna.getPointAtLength(len)
pntListVienna.appendItem(pnt)
}
else
clearInterval(iTVienna)
}
//----Budapest----------------
var endLengthBudapest=pathBudapest.getTotalLength()
var lengthDeltaBudapest=endLengthBudapest/200
var polylineBudapest=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineBudapest)
var pntListBudapest=polylineBudapest.points
var iTBudapest=setInterval(drawPathBudapest,5)
var cntBudapest=0
function drawPathBudapest()
{
var len=lengthDeltaBudapest*cntBudapest++
if(len<endLengthBudapest)
{
var pnt=pathBudapest.getPointAtLength(len)
pntListBudapest.appendItem(pnt)
}
else
clearInterval(iTBudapest)
}
//----Salzburg----------------
var endLengthSalzburg=pathSalzburg.getTotalLength()
var lengthDeltaSalzburg=endLengthSalzburg/200
var polylineSalzburg=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineSalzburg)
var pntListSalzburg=polylineSalzburg.points
var iTSalzburg=setInterval(drawPathSalzburg,5)
var cntSalzburg=0
function drawPathSalzburg()
{
var len=lengthDeltaSalzburg*cntSalzburg++
if(len<endLengthSalzburg)
{
var pnt=pathSalzburg.getPointAtLength(len)
pntListSalzburg.appendItem(pnt)
}
else
clearInterval(iTSalzburg)
}
//----Tyrol----------------
var endLengthTyrol=pathTyrol.getTotalLength()
var lengthDeltaTyrol=endLengthTyrol/200
var polylineTyrol=document.createElementNS(NS,"polyline")
Layer_1.appendChild(polylineTyrol)
var pntListTyrol=polylineTyrol.points
var iTTyrol=setInterval(drawPathTyrol,5)
var cntTyrol=0
function drawPathTyrol()
{
var len=lengthDeltaTyrol*cntTyrol++
if(len<endLengthTyrol)
{
var pnt=pathTyrol.getPointAtLength(len)
pntListTyrol.appendItem(pnt)
}
else
clearInterval(iTTyrol)
}
}
</script>
</body>
</html>
I think you should just be able to add stroke-dasharray to your animation and lower the dash array in your css. An updated version of your codepen; http://codepen.io/harvey89/pen/NpaWBE
stroke-dashoffset: 1000;
stroke-dasharray: 10;
#keyframes dash {
to {
stroke-dashoffset: 0;
stroke-dasharray: 10;
}
}
You'll probably have to play around with numbers to get your desired effect though

Change SVG <circle> <rect> values through css

I have this SVG code
<pattern id="thirdPattern" x="0" y="5" width="40" height="40" patternUnits="userSpaceOnUse">
<circle r="10" cx="15" cy="10" />
</pattern>
Can I change r, cx & cy values through CSS, Just like this
#keyframes move {
25% {
cx: 50%;
cy: 50%;
r: 60;
}
}
or this
#thirdPattern {
cx: 25;
cy: 25;
r: 50;
}
This code works, But the code editor does show errors becuase of r cx cy are not CSS properties.
Not in SVG 1.1, but SVG 2 should support this. Browsers are gradually adding SVG 2 capabilities - your mileage may vary.

Change direction of SVG animation

I saw this SVG animation and I'm wondering how to alter the direction that the line is erased in; currently the line retracts from the last point it is drawn, however I want the reverse; for the line to erase itself from the point where it first started to draw (so that it looks more like a loading animation).
I see that the animation property on .path has a value of infinite, but I'm not sure how the direction is specified.
The HTML is
<div class="bg">
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236">
<path class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="300" stroke-dashoffset="300" fill="none" d="M343.6 75.9v20.3l23.1 21.8-23.1 21.8v20.3l44.6-42.1zM326.4 139.8l-23.1-21.8 23.1-21.8v-20.3l-44.6 42.1 44.6 42.1z"/>
<path class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="500" stroke-dashoffset="500" fill="none" d="M335 38.9c-43.7 0-79.1 35.4-79.1 79.1s35.4 79.1 79.1 79.1 79.1-35.4 79.1-79.1-35.4-79.1-79.1-79.1zM335 182.9c-35.8 0-64.9-29.1-64.9-64.9s29.1-64.9 64.9-64.9 64.9 29.1 64.9 64.9-29.1 64.9-64.9 64.9z"/>
</svg>
</div>
And the CSS is
body {
background-color: #fff;
}
.bg {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.path {
animation: draw 3.5s infinite;
}
#keyframes draw {
50% {
stroke-dashoffset: 0;
}
}
I like your idea of making this an loading animation:
CODEPEN
Now what i did:
changed the animation start stop point
#keyframes draw {
100% {
stroke-dashoffset: -500;
}
}
Why -500?
Because this is the value of the dash-array.
This is defined in the <svg>: dasharray="500"
Changed this value in the inner most path. It was only 300
I added a linear animation
animation: draw 5s infinite linear;
The default is ease. I found the animation has better consistency with a linear animation.
NOTE
dashoffset=500 <- makes the animation start without the dash/stroke
I used the negative value for stroke-dashoffset that Persijn recommended. This worked great in Chrome and FF, but it didn't work properly in Safari.
I've found that if you open the SVG in Illustrator, you can reverse the direction of the path, by opening the Attributes panel (you might have to click the "show more" in the top right) and literally clicking the "reverse path" button.
stroke-dasharray can be a list of white space separated dashes and gaps, so you could do something like this:
var svgPath = document.getElementById('svgPath');
var pathLength = svgPath.getTotalLength();
var offset = 0;
function offsetPath() {
requestAnimationFrame(offsetPath);
offset += 0.1;
var dasharray = 0 + ' ' + offset + ' ' + (pathLength - offset);
svgPath.setAttribute('stroke-dasharray', dasharray);
}
requestAnimationFrame(offsetPath);
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236">
<path id="svgPath" class="path" stroke="#4CADC1" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="100 100 100" fill="none" d="M343.6 75.9v20.3l23.1 21.8-23.1 21.8v20.3l44.6-42.1zM326.4 139.8l-23.1-21.8 23.1-21.8v-20.3l-44.6 42.1 44.6 42.1z"
/>
</svg>
Changing SVG Line Animation Direction
Add KeyFrames and Classes for Both Directions:
.dash {
stroke-dasharray : 10 5;
animation : dash 4s linear infinite;
}
.dash_reverse {
stroke-dasharray : 10 5;
animation : dash_reverse 4s linear infinite;
}
#keyframes dash {
to {
stroke-dashoffset: 100;
}
}
#keyframes dash_reverse {
to {
stroke-dashoffset: -100;
}
}
Use JavaScript to Toggle Animation:
function animate_line_forward(id) {
$("#" + id).removeClass("dash_reverse");
$("#" + id).addClass("dash");
}
function animate_line_reverse(id) {
$("#" + id).removeClass("dash");
$("#" + id).addClass("dash_reverse");
}
Call functions as needed (pass the SVG line id into the above functions:
Calling animate_line_forward:
Calling animate_line_reverse:

Resources