Related
I am trying to create an SVG loading placeholder and I want to place the 3 animated circles to the center vertically and horizontally in the rectangle without overlapping each other. I tried putting them in a g and applying width and margin using CSS but that did not work. Is there a way to achieve it?
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="200" viewBox="0 0 500 100">
<rect width="100%" height="100%" fill="#f3f3f3"/>
<circle fill="#2FC143" stroke="none" cx="6" cy="50" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 15 ; 0 -15; 0 15" repeatCount="indefinite" begin="0.1"></animateTransform>
</circle>
<circle fill="#2FC143" stroke="none" cx="30" cy="50" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 10 ; 0 -10; 0 10" repeatCount="indefinite" begin="0.2"></animateTransform>
</circle>
<circle fill="#2FC143" stroke="none" cx="54" cy="50" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 5 ; 0 -5; 0 5" repeatCount="indefinite" begin="0.3"></animateTransform>
</circle>
</svg>
I would simplify the SVG and use css to lay out where/how the SVG sits within its parent container.
Also, if you use currentColor in the SVG fill attributes, the color will be inherited.
body,
html {
margin: 0;
height: 100%;
}
.svg-wrapper {
background: #eee;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 300px;
}
svg {
width: 60px;
color: #2FC143;
}
.secondary {
background: #ddd;
height: 100px;
width: 300px;
}
.secondary svg {
color: lightcoral;
}
<div class="svg-wrapper">
<svg viewBox="0 0 60 42">
<circle fill="currentColor" stroke="none" cx="6" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 15 ; 0 -15; 0 15" repeatCount="indefinite" begin="0.1"></animateTransform>
</circle>
<circle fill="currentColor" stroke="none" cx="30" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 10 ; 0 -10; 0 10" repeatCount="indefinite" begin="0.2"></animateTransform>
</circle>
<circle fill="currentColor" stroke="none" cx="54" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 5 ; 0 -5; 0 5" repeatCount="indefinite" begin="0.3"></animateTransform>
</circle>
</svg>
</div>
<div class="svg-wrapper secondary">
<svg viewBox="0 0 60 42">
<circle fill="currentColor" stroke="none" cx="6" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 15 ; 0 -15; 0 15" repeatCount="indefinite" begin="0.1"></animateTransform>
</circle>
<circle fill="currentColor" stroke="none" cx="30" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 10 ; 0 -10; 0 10" repeatCount="indefinite" begin="0.2"></animateTransform>
</circle>
<circle fill="currentColor" stroke="none" cx="54" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 5 ; 0 -5; 0 5" repeatCount="indefinite" begin="0.3"></animateTransform>
</circle>
</svg>
</div>
Without CSS you can use preserveAspectRatio
<svg viewBox="0 0 60 42" preserveAspectRatio="xMidYMid meet" width="500" height="400">
<rect width="100%" height="100%" fill="#f3f3f3"/>
<circle fill="currentColor" stroke="none" cx="6" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 15 ; 0 -15; 0 15" repeatCount="indefinite" begin="0.1"></animateTransform>
</circle>
<circle fill="currentColor" stroke="none" cx="30" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 10 ; 0 -10; 0 10" repeatCount="indefinite" begin="0.2"></animateTransform>
</circle>
<circle fill="currentColor" stroke="none" cx="54" cy="21" r="6">
<animateTransform attributeName="transform" dur="1s" type="translate" values="0 5 ; 0 -5; 0 5" repeatCount="indefinite" begin="0.3"></animateTransform>
</circle>
</svg>
I'm able to make the pulse animation on the heart but on the second icon it's sliding, I don't understand why.
<svg>
<g transform="translate(50, 50)">
<path transform="translate(-50, -50)" d="M82.6,50L82.6,50c-0.2-8.1-6.9-15.2-15.1-15.2c-4.8,0-9,2.4-11.8,6c-2.8-3.6-7-6-11.8-6c-8.3,0-15,7.2-15.1,15.2h0c0,0,0,0.1,0,0.1c0,0,0,0.1,0,0.1c0,0.2,0.1,0.4,0.1,0.6c0.7,20.5,26.6,29,26.6,29s26.3-8.4,27.1-28.9c0-0.2,0.1-0.4,0.1-0.6c0,0,0-0.1,0-0.1C82.6,50.1,82.6,50.1,82.6,50z"/>
<animateTransform attributeType="XML" attributeName="transform" type="scale" values="1;1.5;1" additive="sum" begin="0s" dur="2s" repeatCount="indefinite"/>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1042.816 1297.406">
<g transform="translate(50, 50)">
<path transform="translate(-50, -50)" d="M698.467,114.89a10.209,10.209,0,0,1-3.787-.817c-13.05-5.219-51.65-19.04-65.74-21.65s-23.48-4.96-19.83-14.09,7.57-24.78,7.57-24.78,5.57-30.79,7.61-34.44c1.618-2.894,3.594-3.82,7.465-3.82,1.01,0,2.149.062,3.445.17,6.26.52,26.61,3.65,25.3,8.87s-2.6,7.92,8.87,10.09,49.374,13.388,51.457,18.084c2.47,5.567-3.977,24.786-8.147,35.217-3.732,9.321-4.754,27.166-14.213,27.166M628.979,10.6c-6.16,0-8.353,2.8-10.209,12.954-2.76,15.01-13.91,53.56-14.82,56.671a3.161,3.161,0,0,1-.14.4c-4.27,10.521,1.78,12.86,22,16.231,20.35,3.389,57.3,17,63.09,18.889,3.735,1.222,8.923,4.074,13.182,4.074,2.924,0,5.41-1.343,6.688-5.484,3.13-10.17,12.78-39.649,16.95-52.17s-4.95-18.79-17.74-21.92c-11.46-2.8-29.64-7.5-39.67-11.45a4.522,4.522,0,0,1-2.87-4.26c.14-8.97-6.28-9.83-22.41-12.2-6.227-.916-10.719-1.734-14.051-1.734" fill="#4cb5e3"/>
<animateTransform attributeType="XML" attributeName="transform" type="scale" values="1;1.5;1" additive="sum" begin="0s" dur="2s" repeatCount="indefinite"/>
</g>
</svg>
You will need to use a different transform like so:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1042.816 1297.406">
<g transform="translate(664.6295, 65.2095)">
<path transform="translate(-664.6295, -65.2095)" d="M698.467,114.89a10.209,10.209,0,0,1-3.787-.817c-13.05-5.219-51.65-19.04-65.74-21.65s-23.48-4.96-19.83-14.09,7.57-24.78,7.57-24.78,5.57-30.79,7.61-34.44c1.618-2.894,3.594-3.82,7.465-3.82,1.01,0,2.149.062,3.445.17,6.26.52,26.61,3.65,25.3,8.87s-2.6,7.92,8.87,10.09,49.374,13.388,51.457,18.084c2.47,5.567-3.977,24.786-8.147,35.217-3.732,9.321-4.754,27.166-14.213,27.166M628.979,10.6c-6.16,0-8.353,2.8-10.209,12.954-2.76,15.01-13.91,53.56-14.82,56.671a3.161,3.161,0,0,1-.14.4c-4.27,10.521,1.78,12.86,22,16.231,20.35,3.389,57.3,17,63.09,18.889,3.735,1.222,8.923,4.074,13.182,4.074,2.924,0,5.41-1.343,6.688-5.484,3.13-10.17,12.78-39.649,16.95-52.17s-4.95-18.79-17.74-21.92c-11.46-2.8-29.64-7.5-39.67-11.45a4.522,4.522,0,0,1-2.87-4.26c.14-8.97-6.28-9.83-22.41-12.2-6.227-.916-10.719-1.734-14.051-1.734" fill="#4cb5e3"/>
<animateTransform attributeType="XML" attributeName="transform" type="scale" values="1;1.5;1" additive="sum" begin="0s" dur="2s" repeatCount="indefinite"/>
</g>
</svg>
In order to get the new transformation I'm using getBBox() for the path. This is returning in this case SVGRect {x: 602.5171508789062, y: 10.600000381469727, width: 124.22491455078125, height: 109.21900939941406}
In order to get the transformation for the path:
x = 602.5171508789062 + 124.22491455078125/2
y = 10.600000381469727 + 109.21900939941406/2
This is my svg logo for my website. I want each tag to be opened wider while having the center brush stand up straight. I have been playing around with translate properties but I am not getting anywhere. So to summarize...
id of Tag_R needs to move to right in the same distance as id of Tag_L so it looks like it is opening a mouth. At the same time, I want the brush (id of Brush) to stand straight by pointing up.
svg {
width:350px;
text-align:center;
display:block;
margin:auto;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216 145"><defs><style>.cls-1{fill:black;}</style></defs><g id="Layer_2" data-name="Layer 2"><g id="Logo"><g id="Logo_1" data-name="Logo 1"><path id="Tag_R" class="cls-1" d="M160.91,48.19h0a5.18,5.18,0,0,0,1.69,3.9l40.5,38.6L162.62,129a5.14,5.14,0,0,0-1.71,3.92v.72c0,4.1,4.12,6.38,6.91,3.82l46.5-42.73a5.18,5.18,0,0,0,0-7.64l-46.5-42.72C165,41.81,160.91,44.09,160.91,48.19Z"/><path id="Tag_L" class="cls-1" d="M55.09,48.53h0a5.2,5.2,0,0,1-1.69,3.91L12.9,91l40.48,38.3a5.16,5.16,0,0,1,1.71,3.92V134c0,4.1-4.12,6.38-6.91,3.82L1.68,95.07a5.17,5.17,0,0,1,0-7.63l46.5-42.73C51,42.15,55.09,44.43,55.09,48.53Z"/><g id="Brush"><path class="cls-1" d="M115,44.12c.7,9.7,12.05,11,19.74,10.59,5.76-.32-38.44,72.41-50.48,89.72-.94,1.36-2.22.09-1.7-1.68C89.13,120.48,114.38,35.67,115,44.12Z"/><path class="cls-1" d="M121.67,24.62c6.79-7.1,23.19-16,25.94-24.62,0,0,1.9,50.74-15.16,51.3C119.81,51.71,109.72,37.09,121.67,24.62Z"/></g><path id="Eye_R" class="cls-1" d="M147.68,75c-4.74,0-8.59,4.31-8.59,9.61s3.85,9.61,8.59,9.61,8.58-4.3,8.58-9.61S152.42,75,147.68,75Zm0,13.6a4,4,0,1,1,3.56-4A3.79,3.79,0,0,1,147.68,88.61Z"/><path id="Eye_L" class="cls-1" d="M68.87,75c-4.74,0-8.59,4.31-8.59,9.61s3.85,9.61,8.59,9.61,8.58-4.3,8.58-9.61S73.61,75,68.87,75Zm0,13.6a4,4,0,1,1,3.56-4A3.8,3.8,0,0,1,68.87,88.61Z"/></g></g></g></svg>
After translating you need to change the viewBox of your svg element for a bigger icon. In order to get it right you may use Logo.getBBox(). This will return an object with the new size of your Logo. I hope it helps.
Also you need to find the center of the brush in order to be able to set the rotation center.
svg {
width: 350px;
text-align: center;
display: block;
margin: 1em auto;
border: 1px solid;
overflow: visible;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-21 -7 257 160"><defs><style>.cls-1{fill:black;}</style></defs>
<g id="Logo">
<path id="Tag_R" class="cls-1" d="M160.91,48.19h0a5.18,5.18,0,0,0,1.69,3.9l40.5,38.6L162.62,129a5.14,5.14,0,0,0-1.71,3.92v.72c0,4.1,4.12,6.38,6.91,3.82l46.5-42.73a5.18,5.18,0,0,0,0-7.64l-46.5-42.72C165,41.81,160.91,44.09,160.91,48.19Z" transform="translate(0,0)">
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
values="0,0; 20,0; 0,0"
begin="0s"
dur="2s"
repeatCount="indefinite" />
</path>
<path id="Tag_L" class="cls-1" d="M55.09,48.53h0a5.2,5.2,0,0,1-1.69,3.91L12.9,91l40.48,38.3a5.16,5.16,0,0,1,1.71,3.92V134c0,4.1-4.12,6.38-6.91,3.82L1.68,95.07a5.17,5.17,0,0,1,0-7.63l46.5-42.73C51,42.15,55.09,44.43,55.09,48.53Z" transform="translate(0,0)">
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
values="0,0; -20,0; 0,0"
begin="0s"
calcMode="linear"
dur="2s"
repeatCount="indefinite" />
</path>
<g id="Brush" >
<animateTransform
attributeType="XML"
attributeName="transform"
type="rotate"
values="0,115,71.5; -22,115,71.5; 0,115,71.5"
begin="0s"
calcMode="linear"
dur="2s"
repeatCount="indefinite" />
<path class="cls-1" d="M115,44.12c.7,9.7,12.05,11,19.74,10.59,5.76-.32-38.44,72.41-50.48,89.72-.94,1.36-2.22.09-1.7-1.68C89.13,120.48,114.38,35.67,115,44.12Z"/>
<path class="cls-1" d="M121.67,24.62c6.79-7.1,23.19-16,25.94-24.62,0,0,1.9,50.74-15.16,51.3C119.81,51.71,109.72,37.09,121.67,24.62Z"/>
</g>
<path id="Eye_R" class="cls-1" d="M147.68,75c-4.74,0-8.59,4.31-8.59,9.61s3.85,9.61,8.59,9.61,8.58-4.3,8.58-9.61S152.42,75,147.68,75Zm0,13.6a4,4,0,1,1,3.56-4A3.79,3.79,0,0,1,147.68,88.61Z"/><path id="Eye_L" class="cls-1" d="M68.87,75c-4.74,0-8.59,4.31-8.59,9.61s3.85,9.61,8.59,9.61,8.58-4.3,8.58-9.61S73.61,75,68.87,75Zm0,13.6a4,4,0,1,1,3.56-4A3.8,3.8,0,0,1,68.87,88.61Z"/>
<circle cx="115" cy="80" r="2" fill="red" />
</g></svg>
I am trying to make a SVG group follow a SVG path and transform animate the group. I am trying to make #moon transform with animateTransform but nothing seems to work.
Can anyone spot the problem?
<svg width="100%" height="100%" viewBox="0 0 570 594" preserveAspectRatio="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="padding: 0 10px 0 18px;fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:10;">
<path id="orbit" d="M146.719,183.637l-18.408,-7.796l-13.233,-6.252l-12.327,-6.302l-18.44,-9.379l-12.42,-11.695l-16.36,-10.421l-15.546,-10.511l-12.326,-12.281l-14.415,-14.728l-8.426,-16.45l-4.168,-14.276l2.084,-14.272l6.297,-11.239l8.019,-10.103l12.013,-6.302l16.682,-8.426l16.356,-4.169l22.804,-4.217l27.474,-4.168l22.03,0l21.75,1.042l24.881,1.042l20.524,1.042l26.875,3.126l27.917,5.211l41.477,9.293l37.047,10.702l41.159,12.782l35.33,14.012l19.808,8.426l25.874,12.554l18.86,11.423l18.578,11.556l18.815,14.105l17.777,16.951l12.233,16.718l8.345,17.187l1.091,27.64l-7.434,8.207l-11.194,10.466l-15.595,10.559l-24.221,7.844l-22.609,5.211l-30.925,3.265l-43.658,0l-32.546,-2.085" style="fill:none;stroke-width:0px;stroke:#ff6060;"/>
<g id="moon" style="transform: translateY(-130px) translateX(-53px);">
<path d="M77.39,295.34c0,-10.683 -8.658,-19.343 -19.342,-19.343c-10.683,0 -19.344,8.66 -19.344,19.343c0,10.683 8.661,19.343 19.344,19.343c10.684,0 19.342,-8.66 19.342,-19.343" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M61.54,304.476c0,-2.967 -2.404,-5.373 -5.371,-5.373c-2.969,0 -5.373,2.406 -5.373,5.373c0,2.967 2.404,5.373 5.373,5.373c2.967,0 5.371,-2.406 5.371,-5.373" style="fill:#878787;fill-opacity:0.199997;fill-rule:nonzero;"/>
<animateMotion dur="6s" repeatCount="indefinite">
<mpath xlink:href="#orbit" />
</animateMotion>
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0 60 70"
to="360 60 70"
dur="10s"
repeatCount="indefinite"/>
</g>
</svg>
You're mixing a CSS transform with the SMIL animation of a transform attribute. Although SVG 2 suggests they should be the same thing, SVG 1.1 has them as different things. Until the SVG 2 specification and UAs implementation of SVG 2 gets closer to completion it's best not to mix these things.
I've converted the g element's transform to an attribute transform and the animations certainly seem to do something for me now on Firefox.
<svg width="100%" height="100%" viewBox="0 0 570 594" preserveAspectRatio="true" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="padding: 0 10px 0 18px;fill-rule:evenodd;clip-rule:evenodd;stroke-miterlimit:10;">
<path id="orbit" d="M146.719,183.637l-18.408,-7.796l-13.233,-6.252l-12.327,-6.302l-18.44,-9.379l-12.42,-11.695l-16.36,-10.421l-15.546,-10.511l-12.326,-12.281l-14.415,-14.728l-8.426,-16.45l-4.168,-14.276l2.084,-14.272l6.297,-11.239l8.019,-10.103l12.013,-6.302l16.682,-8.426l16.356,-4.169l22.804,-4.217l27.474,-4.168l22.03,0l21.75,1.042l24.881,1.042l20.524,1.042l26.875,3.126l27.917,5.211l41.477,9.293l37.047,10.702l41.159,12.782l35.33,14.012l19.808,8.426l25.874,12.554l18.86,11.423l18.578,11.556l18.815,14.105l17.777,16.951l12.233,16.718l8.345,17.187l1.091,27.64l-7.434,8.207l-11.194,10.466l-15.595,10.559l-24.221,7.844l-22.609,5.211l-30.925,3.265l-43.658,0l-32.546,-2.085" style="fill:none;stroke-width:0px;stroke:#ff6060;"/>
<g id="moon" transform="translate(-53, -130)">
<path d="M77.39,295.34c0,-10.683 -8.658,-19.343 -19.342,-19.343c-10.683,0 -19.344,8.66 -19.344,19.343c0,10.683 8.661,19.343 19.344,19.343c10.684,0 19.342,-8.66 19.342,-19.343" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M61.54,304.476c0,-2.967 -2.404,-5.373 -5.371,-5.373c-2.969,0 -5.373,2.406 -5.373,5.373c0,2.967 2.404,5.373 5.373,5.373c2.967,0 5.371,-2.406 5.371,-5.373" style="fill:#878787;fill-opacity:0.199997;fill-rule:nonzero;"/>
<animateMotion dur="6s" repeatCount="indefinite">
<mpath xlink:href="#orbit" />
</animateMotion>
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0 60 70"
to="360 60 70"
dur="10s"
repeatCount="indefinite"/>
</g>
</svg>
Easy !
AnimateTransform tag has to be within
AnimateMotion tag, completely enclosed, not following.
Precessing Orbit:
<?xml version="1.0"?>
<svg width="940" height="360" viewBox="0 0 350 350"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- Here is a red circle which will be moved along the motion path. -->
<g>
<path d="M10,110 A120,120 -45 0,1 110 10 A120,120 -45 0,1 10,110"
stroke="lightgrey" stroke-width="2"
fill="none" id="theMotionPath"/
<circle cx="470" cy="180" r="160" fill="paleblue" />
<circle cx="10" cy="110" r="3" fill="lightgrey" />
<circle cx="110" cy="10" r="3" fill="lightgrey" />
<circle cx="" cy="" r="10" fill="red">
<!-- Define the motion path animation -->
<animateMotion dur="6s" repeatCount="indefinite">
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0 440 190"
to="360 440 190"
dur="6s"
repeatCount="indefinite"/>
<mpath xlink:href="#theMotionPath"/>
</animateMotion>
</circle>
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0 60 70"
to="360 60 70"
dur="10s"
repeatCount="indefinite"/>
</g>
</svg>
Copy, paste, edit to your liking.
<!DOCTYPE html>
<div width="100%">
<svg style="background:plum" width="240px" height="120px"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" >
<polygon points="60,30 90,90 30,90">
<animateTransform attributeName="transform"
attributeType="XML"
type="rotate"
from="0 60 70"
to="360 60 70"
dur="10s"
repeatCount="indefinite"/>
</polygon>
</svg>
</div>
I'm trying to animate scale transformation around the object's center using SMIL, it works in Firefox 38, but not in Chrome 43, in Chrome the CSS transform-origin property seems ignored for some reason
Original
document.querySelector("#trigger").addEventListener("click", function(e){
if (e.ctrlKey)
document.querySelector("#triggerScaleOut").beginElement();
else
document.querySelector("#triggerScaleIn").beginElement();
}, false);
<svg version="1.1" width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="triggerContainer" transform="scale(1)" style="transform-origin: 150px 150px 0;">
<circle id="trigger" cx="150" cy="150" r="25" />
<animateTransform id="triggerScaleIn" begin="indefinite" values="1; 2" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"/>
<animateTransform id="triggerScaleOut" begin="indefinite" values="2; 1" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"/>
</g>
</svg>
I need this method to work in Chrome since its the cleanest/easiest.
I have tried other things that work like this:
Trial#1
document.querySelector("#trigger").addEventListener("click", function(e){
if ( e.ctrlKey )
document.querySelector("#triggerScaleOut").beginElement();
else
document.querySelector("#triggerScaleIn").beginElement();
}, false);
<svg version="1.1" width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="triggerContainerFix" transform="translate(150,150)">
<g id="triggerContainer" transform="scale(1)">
<circle id="trigger" cx="150" cy="150" r="25" transform="translate(-150,-150)"/>
<animateTransform id="triggerScaleIn" begin="indefinite" values="1; 2" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"/>
<animateTransform id="triggerScaleOut" begin="indefinite" values="2; 1" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"/>
</g>
</g>
</svg>
But it's a bit hacky, and i don't prefer it.
I also tried additive animations, but it is problematic (probably my fault)
Trial#2
document.querySelector("#trigger").addEventListener("click", function(e){
if (e.ctrlKey){
document.querySelector("#triggerScaleOut").beginElement();
document.querySelector("#triggerTranslateOut").beginElement();
}
else{
document.querySelector("#triggerScaleIn").beginElement();
document.querySelector("#triggerTranslateIn").beginElement();
}
}, false);
<svg version="1.1" width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="triggerContainer" transform="scale(1)">
<circle id="trigger" class="button" cx="150" cy="150" r="25" />
<animateTransform id="triggerTranslateIn" begin="indefinite" values="0,0; -150,-150" dur="0.5s"
type="translate"
attributeName="transform"
fill="freeze"
additive="sum"/>
<animateTransform id="triggerScaleIn" begin="indefinite" values="1; 2" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"
additive="sum"/>
<animateTransform id="triggerTranslateOut" begin="indefinite" values="-150,-150; 0,0" dur="0.5s"
type="translate"
attributeName="transform"
fill="freeze"
additive="sum"/>
<animateTransform id="triggerScaleOut" begin="indefinite" values="2; 1" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"
additive="sum"/>
</g>
</svg>
Any ideas? Thanks.
As you have discovered transform-origin has only recently become supported in browsers. So you probably shouldn't try to rely on it just yet.
Both of your "Trial" approaches are commonly used. IMO, the simplest approach is your "Trial #1" version. It's what I most commonly use. The idea is to apply the animation in a coordinate space where the element being scaled sits at the origin.
Here's a slightly simplified version of your sample.
document.querySelector("#trigger").addEventListener("click", function(e){
if ( e.ctrlKey )
document.querySelector("#triggerScaleOut").beginElement();
else
document.querySelector("#triggerScaleIn").beginElement();
}, false);
<svg version="1.1" width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="triggerContainer" transform="translate(150,150)">
<circle id="trigger" cx="0" cy="0" r="25">
<animateTransform id="triggerScaleIn" begin="indefinite" values="1; 2" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"/>
<animateTransform id="triggerScaleOut" begin="indefinite" values="2; 1" dur="0.5s"
type="scale"
attributeName="transform"
fill="freeze"/>
</circle>
</g>
</svg>
I don't consider it hacky at all.