Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Гмстограмма с анимацией (https://javascript.ru/forum/dom-window/75226-gmstogramma-s-animaciejj.html)

рони 16.09.2018 13:41

анимация чисел в зоне видимости гистограмма jquery
 
<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .meter {
      width: 100%;
      height: 8px;
      color: #fff ;
      text-align: center;
      margin: 30px 0;
      position: relative;
  }
  .meter:after {
      font-size: 18px;
      content: attr(data-max);
      color: #000;
      position: absolute;
      right: 5px;
      top: -20px;
  }
  .meter:before {
      font-size: 18px;
      content: attr(data-title);
      color: #000;
      position: absolute;
      left: 5px;
      top: -20px;
  }
  p {
      height: 2000px;
  }
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    jQuery.easing.easeOutQuart =  function(x, t, b, c, d) {
				return -c * (t /= d) * (t - 2) + b
			};
    var num = $(".meter");
    var duration = 1200;
    num.each(function(indx, el) {
        var max = $(el).data("max");
        var color = $(el).data("color");
        var visibility = checkViewport(el);
        $(el).on("animeNum", function() {
            $({
                n: 0
            }).animate({
                n: max
            }, {
                easing: "easeOutQuart",
                duration: duration,
                step: function(now, fx) {
                    now |= 0;
                    now += "%";
                    var gradient = "linear-gradient(to right, " + color + " , " + color + "  " + now + ", #FFFFFF " + now + ")";
                    $(el).attr("data-max", now).css({
                        "backgroundImage": gradient
                    })
                }
            })
        }).data("visibility", visibility);
        visibility && $(el).trigger("animeNum")
    });

    function checkViewport(elem) {
        var rect = elem.getBoundingClientRect();
        var y = rect.bottom / (innerHeight + rect.bottom - rect.top);
        var isInView = y > 0 && y < 1;
        return isInView
    }
    jQuery.fn.scrollComplete = function(fn, ms) {
        var timer = null;
        this.scroll(function() {
            if (timer) clearTimeout(timer);
            timer = setTimeout(fn, ms)
        })
    };
    $(window).scrollComplete(function() {
            num.each(function(indx, el) {
                var visibility = checkViewport(el);
                el = $(el);
                var old = el.data("visibility");
                old != visibility && el.data("visibility", visibility) && !old && el.trigger("animeNum")
            })
        },
        100)
});
  </script>
</head>

<body>
<p></p>
<div class="meter" data-max="98" data-title="Оптимизация" data-color="#464c5c"></div>
<div class="meter" data-max="100" data-title="Кроссплатформенность" data-color="#6d747a"></div>
<div class="meter" data-max="99" data-title="Удобство" data-color="#8c8274"></div>
<div class="meter" data-max="99" data-title="Дизайн" data-color="#d2c6b4"></div>
<p></p>
</body>
</html>

Igorsrt 16.09.2018 15:12

рони,
мне в этом варианте не нравится, что скрипт с анимацией каждый раз заново запускается при прокрутке "вверх-вниз"...мне бы хотелось что бы один раз после попадания в зону видимости сработала анимация и все... или я может недопонимаю чего-то опять

рони 16.09.2018 15:38

Цитата:

Сообщение от Igorsrt
один раз после попадания в зону видимости сработала анимация и все...

<!DOCTYPE html>

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
  .meter {
      width: 100%;
      height: 8px;
      color: #fff ;
      text-align: center;
      margin: 30px 0;
      position: relative;
  }
  .meter:after {
      font-size: 18px;
      content: attr(data-max);
      color: #000;
      position: absolute;
      right: 5px;
      top: -20px;
  }
  .meter:before {
      font-size: 18px;
      content: attr(data-title);
      color: #000;
      position: absolute;
      left: 5px;
      top: -20px;
  }
  p {
      height: 2000px;
  }
  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    jQuery.easing.easeOutQuart =  function(x, t, b, c, d) {
				return -c * (t /= d) * (t - 2) + b
			};
    var num = $(".meter");
    var duration = 1200;
    num.each(function(indx, el) {
        var max = $(el).data("max");
        var color = $(el).data("color");

        $(el).on("animeNum", function() {
            $({
                n: 0
            }).delay(indx * 200).animate({
                n: max
            }, {
                easing: "easeOutQuart",
                duration: duration,
                step: function(now, fx) {
                    now |= 0;
                    now += "%";
                    var gradient = "linear-gradient(to right, " + color + " , " + color + "  " + now + ", #FFFFFF " + now + ")";
                    $(el).attr("data-max", now).css({
                        "backgroundImage": gradient
                    })
                }
            })
        })

    });

    function checkViewport(elem) {
        var rect = elem.getBoundingClientRect();
        var y = rect.bottom / (innerHeight + rect.bottom - rect.top);
        var isInView = y > 0 && y < 1;
        return isInView
    }

    function visibility()
    {
      return $.makeArray(num).some(checkViewport)
    }

    visibility() ?  num.trigger("animeNum") :

    $(window).scroll(function anime() {
            visibility() &&  num.trigger("animeNum")  &&  $(window).off("scroll", anime)
        })
});
  </script>
</head>

<body>
<p></p>
<div class="meter" data-max="98" data-title="Оптимизация" data-color="#464c5c"></div>
<div class="meter" data-max="100" data-title="Кроссплатформенность" data-color="#6d747a"></div>
<div class="meter" data-max="99" data-title="Удобство" data-color="#8c8274"></div>
<div class="meter" data-max="99" data-title="Дизайн" data-color="#d2c6b4"></div>
<p></p>
</body>
</html>

Igorsrt 16.09.2018 15:51

рони,
благодарю, именно так и хотел )

Igorsrt 16.09.2018 16:38

рони,
блин, только я хочу еще что бы полоски с задержкой анимировались (т.е. первая полоска сразу, вторая через 0.2s, третья через 0.4s и т.д.)... в прошлом варианте я через css это смог сделать (transition-delay)... А здесь как?

рони 16.09.2018 16:48

Цитата:

Сообщение от Igorsrt
А здесь как?

строка 52
}).delay(indx * 200).animate({

Igorsrt 16.09.2018 17:49

супер! спасибо


Часовой пояс GMT +3, время: 10:51.