Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Анимация чисел при прокрутке страницы (https://javascript.ru/forum/misc/60390-animaciya-chisel-pri-prokrutke-stranicy.html)

Ingener 26.12.2015 12:17

Анимация чисел при прокрутке страницы
 
Здравствуйте, очень нужен небольшой скрипт анимации чисел при прокрутке страницы, ну например от 0 до 300.

Но при этом хотелось бы чтобы сама цифра ДО которой идет отсчет вводилась в html, а не в скрипте.

Во нашел что то подобное, но там финальное число вводится в сам скрипт, а не в html

http://jsfiddle.net/f48ZD/183/

ruslan_mart 26.12.2015 13:02

https://jsfiddle.net/3tfd4z4n/

Ingener 26.12.2015 13:13

Спасибо, но это не то, надо чтобы как в моем примере, человек прокручивает страницу до определенного дива и появляется число, которое быстро увеличивается (как в лендингах).

а в вашем оно просто увеличивается при прокрутке

Ingener 26.12.2015 13:14

http://demo.icetheme.com/?template=it_studio

вот например

Ingener 26.12.2015 14:39

https://jsfiddle.net/Homelux/8jkr53n6/

вот сделал чтото похожее - но если несколько цифр на странице с одним классом, как тут

http://demo.icetheme.com/?template=it_studio

то СЧИАТЕТ БЕСКОНЕЧНО

как поправить это можно?

ruslan_mart 26.12.2015 23:35

https://jsfiddle.net/3tfd4z4n/1/

Ingener 27.12.2015 08:42

Да, то что надо

Но при этом хотелось бы чтобы сама цифра ДО которой идет отсчет вводилась в html, а не в скрипте.

Можно сделать чтобы в эту строку вместо нуля?

<div class="number">0</div>

ruslan_mart 27.12.2015 09:43

https://jsfiddle.net/3tfd4z4n/2/

antonenkoab 02.01.2017 17:10

А как быть, если нужно увеличить одновременно 3 разных числа?
Например, изменив предыдущий пример таким образом:

HTML:
<div class="number" data-max="3">0</div>
<div class="number" data-max="40">0</div>
<div class="number" data-max="400">0</div>

Malleys 02.01.2017 20:18

<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<title>Document</title>
		<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
	</head>
	<body>
		<div class="scrolling">
			<p>Крути вниз!</p>
			<div class="number" data-max="30"></div>
			<div class="number" data-max="450"></div>
			<div class="number" data-max="7500"></div>
			<div class="number" data-max="1000000"></div>
		</div>

		<style>
			
html {
	text-align: center;
	--angle: 5deg;
	background: linear-gradient(calc(180deg + var(--angle)), transparent 47%, #f5f5f5 50%, transparent 0) 0 0,
				linear-gradient(calc(180deg - var(--angle)), transparent 47%, #f5f5f5 50%, transparent 0) 100% 0;
	background-size: 50% 8em;
	background-repeat: repeat-y;
}

body {
	margin: 0;
}

.scrolling {
	overflow: auto;
	height: 100vh;
}

.number {
	font: 3em sans-serif;
	margin: 25em auto;
}

.number::after {
	background: rebeccapurple;
	color: white;
	border-radius: 50%;
	padding: 2em;
	counter-reset: number var(--value);
	content: counter(number);
}
			
		</style>
		<script>
			
{
	let inTheView = Symbol.for("inTheView");
	let multiplier = Symbol.for("multiplier");
	
	// Создадим новое событие, которое выстреливает, когда счётчик становится видимым
	
	for(let element of document.querySelectorAll(".scrolling")) {
		element.addEventListener("scroll", event => {
			for(let numberElement of element.querySelectorAll(".number")) {
				let y = (element.scrollTop - numberElement.offsetTop + element.offsetHeight) / (element.offsetHeight);
				let isInTheView = y > 0 && y < 1;
				
				if(numberElement[inTheView] !== isInTheView) {
					numberElement[inTheView] = isInTheView;
					
					if(isInTheView)
						numberElement.dispatchEvent(new Event("number:visible", { bubbles: true }));
				}
			}
		});
	}
	
	// обработка нового события
	addEventListener("number:visible", event => {
		loop.call(event.target);
		console.log(event.target[inTheView]);
	});
	
	// анимация цифр запускается, когда срабатывает новое событие
	function loop() {
		if(this[multiplier] === 1) {
			this[multiplier] = null;
			return;
		};
		
		if(typeof this[multiplier] !== "number") {
			this[multiplier] = 0;
			this["dateStart"] = performance.now();
		}
		
		this[multiplier] = Math.min((performance.now() - this.dateStart) / 750, 1);
		this.style.setProperty("--value", (this[multiplier] * this.getAttribute("data-max") | 0));
		
		requestAnimationFrame(loop.bind(this));
	}
};
		</script>
	</body>
</html>

antonenkoab 04.01.2017 20:56

Спасибо за ответ и интересное решение!:thanks:
Но, нельзя ли даную задачу выполнить иначе, а именно изменив лишь код javascript?
А с помощью css, может, только задать числам горизонтальное расположение, а не вертикальное как сейчас, то есть расположить их в одну строку.

рони 04.01.2017 22:17

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

<html>
<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
   .number{
    float:  left;
    width: 100px;
    font-size: 22px;
    line-height: 44px;
    color: #FFFFFF;
    background-color: #8B4513;
    text-align: center;
    margin-right: 30px;
   }
  p{
    height: 2000px;
  }

  </style>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

  <script>
$(function() {
    var num = $(".number");
    num.each(function(indx, el) {
        var max = $(el).data("max");
        var duration = 5000;
        var visibility = checkViewport(el);
        $(el).on("animeNum", function() {
            $({n: 0}).animate({n: max}, {
                easing: "linear",
                duration: duration,
                step: function(now, fx) {
                    $(el).html(now | 0)
                }
            })
        }).data("visibility", visibility);
        visibility && $(el).trigger("animeNum")
    });

    function checkViewport(el) {
    var H = document.documentElement.clientHeight,
        h = el.scrollHeight,
        pos = el.getBoundingClientRect();
        return pos.top + h > 0 && pos.bottom - h < H
    }
    $(window).scroll(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")
        })
    })
});
  </script>
</head>

<body>
<p></p>
<div class="number" data-max="3">0</div>
<div class="number" data-max="40">0</div>
<div class="number" data-max="400">0</div>
<p></p>
</body>
</html>

antonenkoab 05.01.2017 10:54

Здорово! Спасибо! :thanks: Наверное таки следует изучать jquery :) .
А, все-таки, для приверженцев писать код на чистом javascript, как такое повторить без использования библиотек на подобие jquery?

рони 05.01.2017 11:08

Цитата:

Сообщение от antonenkoab
А, все-таки, для приверженцев писать код на чистом javascript, как такое повторить без использования библиотек на подобие jquery?

вы наверно пост №10 не заметили :-/

antonenkoab 05.01.2017 11:20

Заметил. Я на пост №10 тоже писал комментарий. Извините, я наверное многого хочу.

рони 05.01.2017 12:00

antonenkoab,
чем пост №10 не устроил?

antonenkoab 05.01.2017 13:17

Цитата:

Сообщение от рони (Сообщение 439749)
antonenkoab,
чем пост №10 не устроил?

У меня никак не получается переделать код из поста №10 так, чтобы получился результат как в посте №12. Знаний и ума тут у меня не хватает, вот и надеюсь на доброго человека.


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