8

This question can already be said not relevant Microsoft Edge-Chromium Insider

Colleagues, I know two ways of animation. Both options work in all browsers that I can access; I did not check only Safari.

The first is using the function elem.beginElement ();

var wrapper_svg_1 = document.getElementById("wrapper_svg_1"),
  close = document.getElementById('close'),
  open = document.getElementById("open");

let flag = true;

wrapper_svg_1.addEventListener('click', function() {
  if (flag == true) {
    close.beginElement();
    flag = false;
  } else {
    open.beginElement();
    flag = true;
  }
});
* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100vw;
  height: 100vh;
  background: #272727;
  font-size: 20px;
}

#wrapper {
  width: 100vw;
  height: 100vh;
  background: transparent;
}
<div id="wrapper">
  <svg id="wrapper_svg_1" viewBox="0 0 301 301" width="301" height="301">
  
 <path fill="none" id="icon-active" stroke="white" stroke-width="5" d="M100 65, 160 5, 195 40, 135 100, 195 160, 160 195, 100 135, 40 195, 5 160,  65 100, 5 40, 40 5z">
 
  <animate id="close" begin="indefinite" fill="freeze" attributeName="d" dur="0.2s" 
     to="M5 5, 195 5, 195 195, 145 195, 145 40, 125 40, 125 195, 75 195, 75 40, 55 40, 55 195, 5 195z"></animate>
       <animate id="open" begin="indefinite" fill="freeze" attributeName="d" dur="0.2s" 
     to="M100 65, 160 5, 195 40, 135 100, 195 160, 160 195, 100 135, 40 195, 5 160,  65 100, 5 40, 40 5z"></animate>
</path>
 </svg>

</div>
<div id="wrapper">
  <svg id="menu-icon" viewBox="0 0 200 200" width="100%" height="100%" ng-click="iconActive = !iconActive">


        </svg>
</div>

Option two, you can implement by changing the class element

let wrapper = document.getElementById("wrapper"),
  iconActive = document.getElementById("icon-active");
wrapper.addEventListener('click', function() {
  iconActive.classList.toggle('icon-active');
});
* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100vw;
  height: 100vh;
  background: #272727;
  font-size: 20px;
}

#wrapper {
  width: 100vw;
  height: 100vh;
  background: transparent;
}
<div id="wrapper">
  <svg id="menu-icon" viewBox="0 0 200 200" width="100%" height="100%" ng-click="iconActive = !iconActive">
            <style>
            #menu-icon {
                background: grey;
            }

            #icon-active {
                transition: all .3s;
                
            }
            .icon-active {
                d: path("M5 5, 195 5, 195 195, 145 195, 145 40, 125 40, 125 195, 75 195, 75 40, 55 40, 55 195, 5 195z");
                transition: all .3s;
            }
            </style>
            <path fill="none" id="icon-active" stroke="white" stroke-width="5" d="M100 65, 160 5, 195 40, 135 100, 195 160, 160 195, 100 135, 40 195, 5 160,  65 100, 5 40, 40 5z">
            </path>
        </svg>
</div>

In the first example, Edge does not support the function elem.beginElement ();

Is there an analog for Microsoft Edge & IE?

And in the second variant, the main thing is that class to the left element is added and removed, but does not work. How can I fix that?

Mainly, we need to solve the problem with Edge; IE - not necessarily, but for general information and you can give an example solution for this browser

Air
  • 181
  • 3
  • 15
  • You can add SMIL support on IE and Edge using a polyfill like [FakeSmile](https://leunen.me/fakesmile/) For your second snippet you are using some SVG2 only syntax, only Chrome will currently be able to interpret it, all others will fail. – Kaiido Jun 26 '18 at 08:12
  • 1
    @Kaiido, FakeSmile doesn't work in Edge. On the official website too. – Arthur Jun 26 '18 at 15:45
  • F̶o̶r̶ ̶y̶o̶u̶r̶ ̶s̶e̶c̶o̶n̶d̶ ̶v̶a̶r̶i̶a̶n̶t̶ ̶y̶o̶u̶ ̶n̶e̶e̶d̶ ̶t̶o̶ ̶p̶o̶l̶y̶f̶i̶l̶l̶ ̶c̶l̶a̶s̶s̶L̶i̶s̶t̶ https://github.com/yola/classlist-polyfill sorry, my bad. – ippi Jun 27 '18 at 01:35
  • 2
    @Arthur you are compeltely right... I though they did fix it already, forgot that I use a fork... Included it in the Answer – Kaiido Jun 27 '18 at 01:35
  • @ippi and SVG2... `d` attribute can't be set from CSS in SVG1.1 – Kaiido Jun 27 '18 at 01:36
  • @Kaiido, I do not quite understand your last comment. What exactly is not possible? – Air Jun 27 '18 at 05:43
  • @Air To set the `d` attribute of a `` through CSS (required in your case to make the morph anim through CSS). This has only been added in SVG2, and this part of SVG2 is currently only implemented in Chrome. – Kaiido Jun 27 '18 at 05:45
  • @Kaiido, Thank you. I did not know. I missed this important moment – Air Jun 27 '18 at 05:49

1 Answers1

2

This morphing can't be done with only SVG1.1 (still the only version supported by most of browsers) and CSS. You need either SMIL or a complex javascript library that will implement it.

I am reluctant to link you to a js lib that would do it (partly because I don't know these libs well), but SMIL seems indeed the best way.

Since you are wanting to call SVGAnimateElement.beginElement, I'll guess you are displaying your svg in a place where javascript can execute, and this means that you can polyfill SMIL for IE browsers.

With such a polyfill, your animation should run in any browser that do support svg (IE9+).

Here I will use FakeSmile polyfill*, but there are others available on the Internets.

var wrapper_svg_1 = document.getElementById("wrapper_svg_1"),
  close = document.getElementById('close'),
  open = document.getElementById("open");

let flag = true;

wrapper_svg_1.addEventListener('click', function() {
  if (flag == true) {
    close.beginElement();
    flag = false;
  } else {
    open.beginElement();
    flag = true;
  }
});
* {
  margin: 0;
  padding: 0;
}

html,
body {
  width: 100vw;
  height: 100vh;
  background: #272727;
  font-size: 20px;
}

#wrapper {
  width: 100vw;
  height: 100vh;
  background: transparent;
}
<!-- include polyfill for IE -->
<script src="https://cdn.jsdelivr.net/gh/Kaiido/FakeSmile@1e50d675df616a8e784e0e6e931b3f0d595367d4/smil.user.js"></script>
<div id="wrapper">
<svg id="wrapper_svg_1" viewBox="0 0 301 301" width="301" height="301">
    <path fill="none" id="icon-active" stroke="white" stroke-width="5" d="M100 65, 160 5, 195 40, 135 100, 195 160, 160 195, 100 135, 40 195, 5 160,  65 100, 5 40, 40 5z">
        <animate id="close" begin="indefinite" fill="freeze" attributeName="d" dur="0.2s" to="M5 5, 195 5, 195 195, 145 195, 145 40, 125 40, 125 195, 75 195, 75 40, 55 40, 55 195, 5 195z"></animate>
        <animate id="open" begin="indefinite" fill="freeze" attributeName="d" dur="0.2s" to="M100 65, 160 5, 195 40, 135 100, 195 160, 160 195, 100 135, 40 195, 5 160,  65 100, 5 40, 40 5z"></animate>
    </path>
</svg>

</div>

*Actually this demo uses a Fork of said library which has a long standing bug failing to detect MS Edge does not support SMIL...

Kaiido
  • 123,334
  • 13
  • 219
  • 285