jQuery - Bodymovin JSON not loading
Asked Answered
C

3

14

The slider and shuffle lottie animations are supposed to run from 0 to 100 and then back to 0 when toggled; like the box animation.

However you can see that the slider animation disappears in the final frame and the shuffle animation seems to only go a part of the way through its animation before it stops.

How do I get the slider and shuffle animations to run in the same way as the box where they run from 0 -> 100 and then back again?

Note that slider and box have additional code where only one can have the open state at a time.

const anim1 = lottie.loadAnimation({
  container: document.getElementById("box"),
  renderer: "svg",
  loop: false,
  autoplay: false,
  path:
    "https://cdn.statically.io/gist/moofawsaw/b8abeafe008f8b9ef040199c60a15162/raw/296dde84544ed1b41d5acfa303cca21c3ceee70f/lottie_box.json"
});
anim1.setSpeed(5);

const anim2 = lottie.loadAnimation({
  container: document.getElementById("slider"),
  renderer: "svg",
  loop: false,
  autoplay: false,
  path:
    "https://gist.githubusercontent.com/moofawsaw/de2c253620930f2d582daceebff72665/raw/c5d7f528325aed481e6479da1c6921e62066de0b/lottie_sliders.json"
});
anim2.setSpeed(16);

const anim3 = lottie.loadAnimation({
  container: document.getElementById("shuffle"),
  renderer: "svg",
  loop: false,
  autoplay: false,
  path:
    "https://cdn.statically.io/gist/moofawsaw/d009a2a791b03fbf37bca60de465e29c/raw/a87e77ea3362ba6f42cf65f86f0edbc37cb9f15b/lottie_shuffle.json"
});
anim3.setSpeed(12);

function toggle($el, anim) {
  $el.toggleClass("active");
  const open = $el.hasClass("active");
  $el
    .closest(".button")
    .find(".state")
    .text(open ? "open" : "closed");
  const start = open ? 0 : 100;
  anim.playSegments([start, 100 - start], true);
}

$(".lottie--box").on("click", function () {
  var lottie = $(this).find("#box");
  toggle(lottie, anim1);
  if (lottie.hasClass("active") && $("#slider").hasClass("active"))
    toggle($("#slider"), anim2);
});
$(".lottie--slider").on("click", function () {
  var lottie = $(this).find("#slider");
  toggle(lottie, anim2);
  if (lottie.hasClass("active") && $("#box").hasClass("active"))
    toggle($("#box"), anim1);
});
$(".lottie--shuffle").on("click", function () {
  var lottie = $(this).find("#shuffle");
  toggle(lottie, anim3);
});
.wrap {
  height: 32px;
  width: 32px;
  border: 2px solid white;
}
.button {
  display: flex;
  color: white;
  align-items: center;
  cursor: pointer;
  height: 46px;
  max-width: 270px;
  min-width: 270px;
  margin-top: 9px;
  margin-right: 0.5rem;
  margin-bottom: 6px;
  border-style: none;
  border-radius: 6px;
  background-color: #4aabf0;
  font-size: 16px;
}
.lottie--slider {
  background-color: #756fe4;
}
.lottie--shuffle {
  background-color: #fff;
  border: 2px solid blue;
}
#slider {
  width: 200px;
}
#box path,
#slider path {
  fill: white;
  stroke: white;
}
#box svg {
  min-height: 32px;
  max-height: 32px;
}
#slider svg {
  max-height: 26px;
}
#shuffle svg {
  max-height: 62px;
}
#shuffle svg,
#box svg,
#slider svg {
  transition: 0.2s cubic-bezier(0.45, 0, 0.55, 1);
}
#box.active > svg {
  transform: scale(0.9) translatey(3px) !important;
  transform-origin: center;
  transition: 0.2s cubic-bezier(0.45, 0, 0.55, 1);
}
.container {
  margin: 0px auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  align-content: center;
}
.state {
  min-width: 90px;
  margin-left: 0.9rem;
}
.lottie--shuffle {
  color: blue
}
@keyframes pulse {
  0% {
    transform: scale(0.6);
  }

  50% {
    transform: scale(1.1);
  }

  100% {
    transform: scale(1);
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.7.0/lottie.min.js"></script>
<div class="container">
  <div class="button lottie--box">
    <div id="box"></div>
    <div class="state">closed</div>
  </div>
  <div class="button lottie--slider">
    <div id="slider"></div>
    <div class="state">closed</div>
  </div>
  <div class="button lottie--shuffle">
    <div id="shuffle"></div>
    <div class="state">closed</div>
  </div>
</div>
Clemmy answered 8/6, 2020 at 4:20 Comment(0)
P
2

This did the trick... So i created a new function for each button.

study the code snippet below(the javascript code)

const anim1 = lottie.loadAnimation({
    container: document.getElementById("box"),
    renderer: "svg",
    loop: false,
    autoplay: false,
    path:
      "https://cdn.statically.io/gist/moofawsaw/b8abeafe008f8b9ef040199c60a15162/raw/296dde84544ed1b41d5acfa303cca21c3ceee70f/lottie_box.json"
  });
  anim1.setSpeed(5);
  
  const anim2 = lottie.loadAnimation({
    container: document.getElementById("slider"),
    renderer: "svg",
    loop: false,
    autoplay: false,

    path:
      "https://gist.githubusercontent.com/moofawsaw/de2c253620930f2d582daceebff72665/raw/c5d7f528325aed481e6479da1c6921e62066de0b/lottie_sliders.json"
  });
  anim2.setSpeed(1);
  
  const anim3 = lottie.loadAnimation({
    container: document.getElementById("shuffle"),
    renderer: "svg",
    loop: false,
    autoplay: false,
    path:
      "https://cdn.statically.io/gist/moofawsaw/d009a2a791b03fbf37bca60de465e29c/raw/a87e77ea3362ba6f42cf65f86f0edbc37cb9f15b/lottie_shuffle.json"
  });
  anim3.setSpeed(12);
  
  function toggle($el, anim) {
    $el.toggleClass("active");
    const open = $el.hasClass("active");
    $el
      .closest(".button")
      .find(".state")
      .text(open ? "open" : "closed");
    const start = open ? 0 : 100;
    anim.playSegments([start, 100 - start], true);
  }

  function toggle_for_shuffler($el, anim) {
    $el.toggleClass("active");
    const open = $el.hasClass("active");
    $el
      .closest(".button")
      .find(".state")
      .text(open ? "open" : "closed");
    const start = open ? 0 : 120;
    anim.playSegments([start, 120 - start], true);
  }
  let slider_direction = 1;

  function toggle_slider($el, anim) {
    $el.toggleClass("active");
    const open = $el.hasClass("active");
    $el
      .closest(".button")
      .find(".state")
      .text(open ? "open" : "closed");
    const direction = open ? slider_direction : -slider_direction;  
    // The so-called “conditional” or “question mark” operator lets us do
    //  that in a shorter and simpler way.
    // The operator is represented by a question mark ?.
    //  Sometimes it’s called “ternary”, because the operator 
    //  has three operands. It is actually the one and only operator
    //   in JavaScript which has that many.
    // let result = condition ? value1 : value2;
    anim.setDirection(direction);
    anim.play();
  }



   $(".lottie--box").on("click", function () {
    var lottie = $(this).find("#box");
    toggle(lottie, anim1);
    if (lottie.hasClass("active") && $("#slider").hasClass("active"))
      toggle_slider($("#slider"), anim2);
  });
  $(".lottie--slider").on("click", function () {

    var lottie = $(this).find("#slider");
    toggle_slider(lottie, anim2);
    if (lottie.hasClass("active") && $("#box").hasClass("active"))
      toggle($("#box"), anim1);
  });
  $(".lottie--shuffle").on("click", function () {
    var lottie = $(this).find("#shuffle");
    toggle_for_shuffler(lottie, anim3);
  });
  
.wrap {
    height: 32px;
    width: 32px;
    border: 2px solid white;
  }
  .button {
    display: flex;
    color: white;
    align-items: center;
    cursor: pointer;
    height: 46px;
    max-width: 270px;
    min-width: 270px;
    margin-top: 9px;
    margin-right: 0.5rem;
    margin-bottom: 6px;
    border-style: none;
    border-radius: 6px;
    background-color: #4aabf0;
    font-size: 16px;
  }
  .lottie--slider {
    background-color: #756fe4;
  }
  .lottie--shuffle {
    background-color: #fff;
    border: 2px solid blue;
  }
  #slider {
    width: 200px;
  }
  #box path,
  #slider path {
    fill: white;
    stroke: white;
  }
  #box svg {
    min-height: 32px;
    max-height: 32px;
  }
  #slider svg {
    max-height: 26px;
  }
  #shuffle svg {
    max-height: 62px;
  }
  #shuffle svg,
  #box svg,
  #slider svg {
    transition: 0.2s cubic-bezier(0.45, 0, 0.55, 1);
  }
  #box.active > svg {
    transform: scale(0.9) translatey(3px) !important;
    transform-origin: center;
    transition: 0.2s cubic-bezier(0.45, 0, 0.55, 1);
  }
  .container {
    margin: 0px auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    align-content: center;
  }
  .state {
    min-width: 90px;
    margin-left: 0.9rem;
  }
  .lottie--shuffle {
    color: blue
  }
  @keyframes pulse {
    0% {
      transform: scale(0.6);
    }
  
    50% {
      transform: scale(1.1);
    }
  
    100% {
      transform: scale(1);
    }
  }
  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.6.10/lottie.min.js" integrity="sha256-/56Y/jYu6730zlN8iulnNWn2IcVa4wK/ogwk7n9p2JY=" crossorigin="anonymous"></script>
<script src="lottie.js"></script>
<div class="container">
  <div class="button lottie--box">
    <div id="box"></div>
    <div class="state">closed</div>
  </div>
  <div class="button lottie--slider">
    <div id="slider"></div>
    <div class="state">closed</div>
  </div>
  <div class="button lottie--shuffle">
    <div id="shuffle"></div>
    <div class="state">closed</div>
  </div>
</div>
<script src="script.js"></script>
</body>

</html>
Proconsul answered 13/7, 2020 at 2:46 Comment(0)
H
8

You seems to use an older version of the library, I just replace it with v5.6.10 and it worked fine, this is the first time I use this library, so I had to use a selector to force the display:block for <g> tags inside the second button to make sure that we have the icon animation (I'm sure there is a better way to make it work for the second icon).


Note: I changed bodymovin.loadAnimation to lottie.loadAnimation, here is a working snippet:

var animData1 = {
  container: document.getElementById("toggle"),
  renderer: "svg",
  loop: false,
  autoplay: false,
  path:
    "https://cdn.statically.io/gist/moofawsaw/b8abeafe008f8b9ef040199c60a15162/raw/296dde84544ed1b41d5acfa303cca21c3ceee70f/lottie_box.json",
};
var animData2 = {
  container: document.getElementById("slider"),
  renderer: "svg",
  loop: false,
  autoplay: false, path:"https://gist.githubusercontent.com/moofawsaw/de2c253620930f2d582daceebff72665/raw/c5d7f528325aed481e6479da1c6921e62066de0b/lottie_sliders.json",
};
var anim1 = lottie.loadAnimation(animData1);
var anim2 = lottie.loadAnimation(animData2);

$("#toggle").on("click", function () {
  anim1.setSpeed(5);
  if ($("#toggle").hasClass("active")) {
    anim1.playSegments([100, 0], true);
    $("#toggle").removeClass("active");
  } else {
    anim1.playSegments([0, 100], true);
    $("#toggle").addClass("active");
  }
});
$("#slider").on("click", function () {
  anim2.setSpeed(5);
  if ($("#slider").hasClass("active")) {
    anim2.playSegments([100, 0], true);
    $("#slider").removeClass("active");
  } else {
    anim2.playSegments([0, 100], true);
    $("#slider").addClass("active");
  }
});
#toggle,
#slider {
  display: flex;
  align-items: center;
  cursor: pointer;
  height: 46px;
  min-width: 270px;
  margin-top: 9px;
  margin-right: 0.5rem;
  margin-bottom: 6px;
  border-style: none;
  border-radius: 6px;
  background-color: #4aabf0;
  font-size: 16px;
}

g[clip-path="url(#__lottie_element_48)"] g {
  display: block !important;
}

#toggle path,
#slider path {
  fill: white;
  stroke: white;
}

#toggle svg,
#slider svg {
  max-height: 32px;
  transition: 100ms;
}

#toggle.active>svg {
  transform: scale(0.9) translate(0px, 2px);
  transform-origin: center;
  transition: 0.2s;
}

.container {
  margin: 0px auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  align-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.6.10/lottie.min.js" integrity="sha256-/56Y/jYu6730zlN8iulnNWn2IcVa4wK/ogwk7n9p2JY=" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div id="toggle"></div>
  <div id="slider"></div>
</div>
Helbonnas answered 10/6, 2020 at 5:21 Comment(3)
Forcing the display disrupts the performance of the animation. As you can see the slider's animation here: useanimations.comClemmy
let me find the alternate to using cssForspent
Were you able to find a solution? The slider animation is disappearing at the final frameClemmy
F
4

Just change this line

<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.6.10/lottie.min.js" integrity="sha256-/56Y/jYu6730zlN8iulnNWn2IcVa4wK/ogwk7n9p2JY=" crossorigin="anonymous"></script>

It is just the json you have does not work with old version of library.

var animData1 = {
  container: document.getElementById("toggle"),
  renderer: "svg",
  loop: false,
  autoplay: false,
  path: "https://cdn.statically.io/gist/moofawsaw/b8abeafe008f8b9ef040199c60a15162/raw/296dde84544ed1b41d5acfa303cca21c3ceee70f/lottie_box.json"
};
var animData2 = {
  container: document.getElementById("slider"),
  renderer: "svg",
  loop: false,
  autoplay: false,
  path: "https://cdn.statically.io/gist/moofawsaw/de2c253620930f2d582daceebff72665/raw/c5d7f528325aed481e6479da1c6921e62066de0b/lottie_sliders.json"
};
var anim1;
var anim2;

anim1 = bodymovin.loadAnimation(animData1);
anim2 = bodymovin.loadAnimation(animData2);

$("#toggle").on("click", function() {
  anim1.setSpeed(5);
  if ($("#toggle").hasClass("active")) {
    anim1.playSegments([100, 0], true);
    $("#toggle").removeClass("active");
  } else {
    anim1.playSegments([0, 100], true);
    $("#toggle").addClass("active");
  }
});
$("#slider").on("click", function() {
  anim2.setSpeed(5);
  if ($("#slider").hasClass("active")) {
    anim2.playSegments([100, 0], true);
    $("#slider").removeClass("active");
  } else {
    anim2.playSegments([0, 100], true);
    $("#slider").addClass("active");
  }
});
g[clip-path="url(#__lottie_element_48)"] g {
  display: block !important;
}
#toggle,
#slider {
  display: flex;
  align-items: center;
  cursor: pointer;
  height: 46px;
  max-width: 270px;
  margin-top: 9px;
  margin-right: 0.5rem;
  margin-bottom: 6px;
  border-style: none;
  border-radius: 6px;
  background-color: #4aabf0;
  font-size: 16px;
}

#toggle path,
#slider path {
  fill: white;
  stroke: white;
}

#toggle svg,
#slider svg {
  max-height: 32px;
  transition: 100ms;
}

#toggle.active>svg {
  transform: scale(0.9) translate(0px, 2px);
  transform-origin: center;
  transition: 0.2s;
}

.container {
  margin: 0px auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  align-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.6.10/lottie.min.js" integrity="sha256-/56Y/jYu6730zlN8iulnNWn2IcVa4wK/ogwk7n9p2JY=" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="container">
  <div id="toggle"></div>
  <div id="slider" class='settings-V2'></div>
</div>
Forspent answered 16/6, 2020 at 11:37 Comment(9)
Why does the icon disappear in the final frame?Clemmy
css issue as explained by my friend below g[clip-path="url(#__lottie_element_48)"] g { display: block !important; }Forspent
Forcing the display disrupts the animation. You can see the intended animation here: useanimations.comClemmy
the file cdn.statically.io/gist/moofawsaw/… is working good this file cdn.statically.io/gist/moofawsaw/… has some issueForspent
The CDN used in the question for the slider should have no issues.Clemmy
It is not cdn issue it is JSON issue use same JSON in both slider and toggle they work greatForspent
check these lottie sliders and dpwnload the son I think that's what you need lottiefiles.com/tag/sliderForspent
Thanks for the link but I need that JSON file specifically. That is why I posted the question as I don't know why the JSON was executing at useanimations.com and not in the snippet.Clemmy
were you able to find the solution without using CSS?Clemmy
P
2

This did the trick... So i created a new function for each button.

study the code snippet below(the javascript code)

const anim1 = lottie.loadAnimation({
    container: document.getElementById("box"),
    renderer: "svg",
    loop: false,
    autoplay: false,
    path:
      "https://cdn.statically.io/gist/moofawsaw/b8abeafe008f8b9ef040199c60a15162/raw/296dde84544ed1b41d5acfa303cca21c3ceee70f/lottie_box.json"
  });
  anim1.setSpeed(5);
  
  const anim2 = lottie.loadAnimation({
    container: document.getElementById("slider"),
    renderer: "svg",
    loop: false,
    autoplay: false,

    path:
      "https://gist.githubusercontent.com/moofawsaw/de2c253620930f2d582daceebff72665/raw/c5d7f528325aed481e6479da1c6921e62066de0b/lottie_sliders.json"
  });
  anim2.setSpeed(1);
  
  const anim3 = lottie.loadAnimation({
    container: document.getElementById("shuffle"),
    renderer: "svg",
    loop: false,
    autoplay: false,
    path:
      "https://cdn.statically.io/gist/moofawsaw/d009a2a791b03fbf37bca60de465e29c/raw/a87e77ea3362ba6f42cf65f86f0edbc37cb9f15b/lottie_shuffle.json"
  });
  anim3.setSpeed(12);
  
  function toggle($el, anim) {
    $el.toggleClass("active");
    const open = $el.hasClass("active");
    $el
      .closest(".button")
      .find(".state")
      .text(open ? "open" : "closed");
    const start = open ? 0 : 100;
    anim.playSegments([start, 100 - start], true);
  }

  function toggle_for_shuffler($el, anim) {
    $el.toggleClass("active");
    const open = $el.hasClass("active");
    $el
      .closest(".button")
      .find(".state")
      .text(open ? "open" : "closed");
    const start = open ? 0 : 120;
    anim.playSegments([start, 120 - start], true);
  }
  let slider_direction = 1;

  function toggle_slider($el, anim) {
    $el.toggleClass("active");
    const open = $el.hasClass("active");
    $el
      .closest(".button")
      .find(".state")
      .text(open ? "open" : "closed");
    const direction = open ? slider_direction : -slider_direction;  
    // The so-called “conditional” or “question mark” operator lets us do
    //  that in a shorter and simpler way.
    // The operator is represented by a question mark ?.
    //  Sometimes it’s called “ternary”, because the operator 
    //  has three operands. It is actually the one and only operator
    //   in JavaScript which has that many.
    // let result = condition ? value1 : value2;
    anim.setDirection(direction);
    anim.play();
  }



   $(".lottie--box").on("click", function () {
    var lottie = $(this).find("#box");
    toggle(lottie, anim1);
    if (lottie.hasClass("active") && $("#slider").hasClass("active"))
      toggle_slider($("#slider"), anim2);
  });
  $(".lottie--slider").on("click", function () {

    var lottie = $(this).find("#slider");
    toggle_slider(lottie, anim2);
    if (lottie.hasClass("active") && $("#box").hasClass("active"))
      toggle($("#box"), anim1);
  });
  $(".lottie--shuffle").on("click", function () {
    var lottie = $(this).find("#shuffle");
    toggle_for_shuffler(lottie, anim3);
  });
  
.wrap {
    height: 32px;
    width: 32px;
    border: 2px solid white;
  }
  .button {
    display: flex;
    color: white;
    align-items: center;
    cursor: pointer;
    height: 46px;
    max-width: 270px;
    min-width: 270px;
    margin-top: 9px;
    margin-right: 0.5rem;
    margin-bottom: 6px;
    border-style: none;
    border-radius: 6px;
    background-color: #4aabf0;
    font-size: 16px;
  }
  .lottie--slider {
    background-color: #756fe4;
  }
  .lottie--shuffle {
    background-color: #fff;
    border: 2px solid blue;
  }
  #slider {
    width: 200px;
  }
  #box path,
  #slider path {
    fill: white;
    stroke: white;
  }
  #box svg {
    min-height: 32px;
    max-height: 32px;
  }
  #slider svg {
    max-height: 26px;
  }
  #shuffle svg {
    max-height: 62px;
  }
  #shuffle svg,
  #box svg,
  #slider svg {
    transition: 0.2s cubic-bezier(0.45, 0, 0.55, 1);
  }
  #box.active > svg {
    transform: scale(0.9) translatey(3px) !important;
    transform-origin: center;
    transition: 0.2s cubic-bezier(0.45, 0, 0.55, 1);
  }
  .container {
    margin: 0px auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    align-content: center;
  }
  .state {
    min-width: 90px;
    margin-left: 0.9rem;
  }
  .lottie--shuffle {
    color: blue
  }
  @keyframes pulse {
    0% {
      transform: scale(0.6);
    }
  
    50% {
      transform: scale(1.1);
    }
  
    100% {
      transform: scale(1);
    }
  }
  
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <link rel="stylesheet" href="style.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.6.10/lottie.min.js" integrity="sha256-/56Y/jYu6730zlN8iulnNWn2IcVa4wK/ogwk7n9p2JY=" crossorigin="anonymous"></script>
<script src="lottie.js"></script>
<div class="container">
  <div class="button lottie--box">
    <div id="box"></div>
    <div class="state">closed</div>
  </div>
  <div class="button lottie--slider">
    <div id="slider"></div>
    <div class="state">closed</div>
  </div>
  <div class="button lottie--shuffle">
    <div id="shuffle"></div>
    <div class="state">closed</div>
  </div>
</div>
<script src="script.js"></script>
</body>

</html>
Proconsul answered 13/7, 2020 at 2:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.