анимация чисел в зоне видимости гистограмма 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> |
рони,
мне в этом варианте не нравится, что скрипт с анимацией каждый раз заново запускается при прокрутке "вверх-вниз"...мне бы хотелось что бы один раз после попадания в зону видимости сработала анимация и все... или я может недопонимаю чего-то опять |
Цитата:
<!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> |
рони,
благодарю, именно так и хотел ) |
рони,
блин, только я хочу еще что бы полоски с задержкой анимировались (т.е. первая полоска сразу, вторая через 0.2s, третья через 0.4s и т.д.)... в прошлом варианте я через css это смог сделать (transition-delay)... А здесь как? |
Цитата:
}).delay(indx * 200).animate({ |
супер! спасибо
|
Часовой пояс GMT +3, время: 10:51. |