Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to start and stop execution of a JavaScript script with two buttons?

I am animating an element in SVG so that it travels around a circular track. It runs around the track 3x and stops. I am using the GSAP MotionPath plugin to do the animation. I want to control the motion with start and stop buttons. The stop button can either pause the motion or stop it completely and have the element return to its place – whichever involves the simpler method.

I managed to get the animation to start by clicking the "START" button. But I can’t get it to stop by clicking the "STOP" button.

I show below the animation with the start button.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

function myFunction(){
     gsap.registerPlugin(MotionPathPlugin);
     gsap.to("#comet-horizontal", {
        duration: 5, 
        repeat: 2,
        repeatDelay: 0,
        yoyo: false,
        ease: "none",
        motionPath:{
             path: "#racetrack",
             align: "#racetrack",
             autoRotate: true,
             alignOrigin: [0.5, 0.5]
        }
     });
}
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
body {
  /*background-color: black;*/
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
svg {
  overflow: visible;
  height: 100%;
  background-color: orange;
  /* Fix Safari rendering bug */
  transform: translateZ(0);
}
circle {
  fill: pink;
}
#button{
 width: 60px;
 height: 30px; 
 background-color: orange;
 position: relative;
margin-top: 5px;
margin-bottom:  5px;
}
#button2{
 width: 60px;
 height: 30px; 
 background-color: yellow; 
 position: relative;
margin-top: 5px;
margin-bottom:  5px;
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.3/gsap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.3/MotionPathPlugin.min.js"></script>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
        <script src="snap.svg-min.js"></script>
</head>
<body>
<button id="button" onclick="myFunction()">START</button>
<button id="button2">STOP</button>
<svg
   width="100%"
   height="100%"
   viewBox="0 0 338.66667 190.5">
    <path
       id="racetrack"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffaaaa;stroke-width:2.32673;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;stop-color:#000000;stop-opacity:1"
       d="M 184.04496,79.375006 A 51.753304,51.753307 0 0 1 132.29166,131.1283 51.753304,51.753307 0 0 1 80.538365,79.375006 51.753304,51.753307 0 0 1 132.29166,27.621698 a 51.753304,51.753307 0 0 1 51.7533,51.753308 z" />   
    <path
       id="comet-horizontal"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#00d3ff;fill-opacity:1;fill-rule:evenodd;stroke-width:2.82278;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000;stop-opacity:1"
       d="m 241.75652,61.794127 v 2.645839 l -13.22916,-0.661459 v -0.66146 -0.66146 z"
       sodipodi:nodetypes="cccccc" />
</svg>
</body>

I browsed StackOverflow but could not find the answer. For example, How to control the execution of javascript functions? is a similar question to mine but the asker wants a new function to start after the first one is stopped.

I cannot use typical animation functions such as animation-play-state since the animation is using a GreenSock script.

I also tried out the top solution from How to stop a function during its execution – JavaScript but it didn’t work for me (maybe because I implemented it wrongly). I am having trouble writing the "if" condition for when the Stop button is clicked. I tried if(document.getElementById('button').clicked == true) but it didn’t work.

Below is the solution mentioned above in the last link.

function foo1(){
  console.log("Foo started...");
  if(prompt("Type 1 to terminate right now or anything else to continue...") == "1"){
    return;  // Function will terminate here if this is encountered
  }
  console.log("Foo ending...");  // This will only be run if something other than 1 was entered
}

foo1();

I would prefer to stick with vanilla JS solutions if possible rather than JQuery because I am not familiar with JQuery, but if a JQuery solution is the easiest way of doing it, I am open to it.

This is the attempt to implement the "foo1" solution that failed:

     function myFunction(){
     gsap.registerPlugin(MotionPathPlugin);
     gsap.to("#comet-horizontal", {
        duration: 5, 
        repeat: 2,
        repeatDelay: 0,
        yoyo: false,
        ease: "none",
        motionPath:{
             path: "#racetrack",
             align: "#racetrack",
             autoRotate: true,
             alignOrigin: [0.5, 0.5]
        }
     });
    if (document.getElementById("button2").clicked == true)
            return;
}
myFunction();

>Solution :

The gsap.to method returns a Tween object with which you can control the anumation. It has pause, resume, restart and several other useful methods.

Here I adapted your script:

  • Renamed the HTML buttons with more telling names.
  • Attached the click handlers in code, not via HTML attribute
  • Added a global variable to allow each event handler to access the above mentioned object
  • Added the logic to pause and resume the animation
let tween; // global so both handlers can access it

document.getElementById("buttonStart").addEventListener("click", function () {
    if (tween) { // Not first time:
        tween.resume(); // Continue from where it was paused
        return;
    }
    gsap.registerPlugin(MotionPathPlugin);
    tween = gsap.to("#comet-horizontal", {
        duration: 5, 
        repeat: 2,
        repeatDelay: 0,
        yoyo: false,
        ease: "none",
        motionPath:{
             path: "#racetrack",
             align: "#racetrack",
             autoRotate: true,
             alignOrigin: [0.5, 0.5]
        }
    });
});

document.getElementById("buttonStop").addEventListener("click", function () {
    tween?.pause();
});
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}
body {
  /*background-color: black;*/
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
}
svg {
  overflow: visible;
  height: 100%;
  background-color: orange;
  /* Fix Safari rendering bug */
  transform: translateZ(0);
}
circle {
  fill: pink;
}
#button{
 width: 60px;
 height: 30px; 
 background-color: orange;
 position: relative;
margin-top: 5px;
margin-bottom:  5px;
}
#button2{
 width: 60px;
 height: 30px; 
 background-color: yellow; 
 position: relative;
margin-top: 5px;
margin-bottom:  5px;
}
<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.3/gsap.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.3/MotionPathPlugin.min.js"></script>
  <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
  <script src="snap.svg-min.js"></script>
</head>
<body>
<button id="buttonStart">START</button>
<button id="buttonStop">STOP</button>
<svg
   width="100%"
   height="100%"
   viewBox="0 0 338.66667 190.5">
    <path
       id="racetrack"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffaaaa;stroke-width:2.32673;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;stop-color:#000000;stop-opacity:1"
       d="M 184.04496,79.375006 A 51.753304,51.753307 0 0 1 132.29166,131.1283 51.753304,51.753307 0 0 1 80.538365,79.375006 51.753304,51.753307 0 0 1 132.29166,27.621698 a 51.753304,51.753307 0 0 1 51.7533,51.753308 z" />   
    <path
       id="comet-horizontal"
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#00d3ff;fill-opacity:1;fill-rule:evenodd;stroke-width:2.82278;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000;stop-opacity:1"
       d="m 241.75652,61.794127 v 2.645839 l -13.22916,-0.661459 v -0.66146 -0.66146 z"
       sodipodi:nodetypes="cccccc" />
</svg>
</body>
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading