Показать сообщение отдельно
  #10 (permalink)  
Старый 02.01.2017, 20:18
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

<!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>
Ответить с цитированием