PageSourceSearch

https://akademia-excel.ru/nassets/c727a27/js/block-animation.js?v=1765633901

js akademia-excel.ru collected 2026-09-30 11:25:49 UTC 5,209 bytes, 111 lines download raw bytes

1jQuery.widget('gc.animatedBlock', {
2	// минимальное время между обработками события scroll
3	SCROLL_HANDLE_TIMEOUT: 400,
4	// Данное значение уменьшает координату нижней границы screen зоны (если в зоне, то запускается анимация)
5	SCREEN_BOTTOM_GAP: 50,
6	// Задержка между запуском анимации элементов при порядке анимации "по очереди" (и перед первым запуском)
7	ANIMATION_DELAY: 300,
8
9	ANIMATION_ORDER_IN_TURN: 'in-turn',
10	ANIMATION_ORDER_AT_ONCE: 'at-once',
11
12	ANIMATION_MODE_APPEAR: 'appear',
13	ANIMATION_MODE_INCREASE: 'increase',
14	ANIMATION_MODE_SLIDE_FROM_LEFT: 'slide-from-left',
15	ANIMATION_MODE_SLIDE_FROM_RIGHT: 'slide-from-right',
16	ANIMATION_MODE_SLIDE_FROM_TOP: 'slide-from-top',
17	ANIMATION_MODE_SLIDE_FROM_BOTTOM: 'slide-from-bottom',
18
19	// Таймер для блокировки обработки скролла, чтобы ограничить частоту обработки
20	timerId: null,
21	// Таймер для фантомной обработки скролла. Из-за ограничения частоты обработки мы пропускаем события, потому
22	// когда события перестали поступать, нужно для верности обработку вызвать
23	phantomTimerId: null,
24	_create: function () {
25		var self = this;
26
27		if ($(window).width() < 1024) {
28			// Если ширина меньше 1024, то сразу все показать без анимации
29			self.element.find('.animated-element').removeClass('animated-element');
30		} else {
31			self.setScrollHandler();
32
33			// После загрузки в первый раз сразу инициируем событие для пересчета анимации
34			setTimeout(function () {
35				$(window).scroll();
36			}, self.ANIMATION_DELAY);
37		}
38	},
39	setScrollHandler: function() {
40		var self = this;
41
42		$(window).scroll(function(event) {
43			if (!self.timerId) {
44				// Сбрасываем таймер фантомной обработки
45				clearTimeout(self.phantomTimerId);
46				self.phantomTimerId = null;
47
48				// Блокируем обработку скролла на некоторое время, чтобы слишком часто не обрабатывать событие
49				self.timerId = setTimeout(function() {
50					self.timerId = null;
51				}, self.SCROLL_HANDLE_TIMEOUT);
52
53				self.recalculateAnimation();
54			} else {
55				// Смотри коммент к объявлению переменной phantomTimerId
56				if (!self.phantomTimerId) {
57					self.phantomTimerId = setTimeout(function () {
58						self.phantomTimerId = null;
59						self.recalculateAnimation();
60					}, self.SCROLL_HANDLE_TIMEOUT);
61				}
62			}
63		});
64	},
65	animateElement: function($element) {
66		// Да, все так просто. Все через css делается.
67		$element.removeClass('before-animation');
68
69		// Теперь сразу после окончания анимации уберем класс со всеми стилями для нее, потому что стиль transform
70		// ведет к тому, что слой просвечивает через вышележащие, а в редактировании блоков есть всплывашка с параметрами
71		var animationDuration = parseFloat($element.css('transition-duration')) * 1000;
72		setTimeout(function() {
73			$element.removeClass('animated-element');
74		}, animationDuration);
75	},
76	recalculateAnimation: function() {
77		var self = this;
78		var screenTop = $(window).scrollTop();
79		var screenBottom = screenTop + $(window).height() - self.SCREEN_BOTTOM_GAP;
80		var animationOrder = self.element.data('animation-order');
81
82		var nextElementTimeout = 0;
83		// Выбираем элементы, для которых еще не сработала анимация. Исключаем те, на которые уже повешен таймер на запуск анимации
84		self.element.find('.animated-element.before-animation').not('.animation-will-start-soon').each(function() {
85			var $el = $(this);
86			if (self.isOnScreen($el, screenTop, screenBottom)) {
87				if (animationOrder === self.ANIMATION_ORDER_AT_ONCE) {
88					self.animateElement($el);
89				} else {
90					$el.addClass('animation-will-start-soon');
91					setTimeout(function () {
92						$el.removeClass('animation-will-start-soon');
93						self.animateElement($el);
94					}, nextElementTimeout);
95					nextElementTimeout += self.ANIMATION_DELAY;
96				}
97			}
98		});
99
100	},
101	isOnScreen: function($el, screenTop, screenBottom) {
102		var elPull = parseInt($el.css('transform').split(',')[5]);
103		if (elPull !== 0) {
104			// Делаем коррекцию на существующий сдвиг элемента по оси y (сделан в css в качестве начальной позиции перед анимацией)
105			screenBottom += elPull;
106		}
107		var elTop = $el.offset().top;
108		var elBottom = elTop + $el.height();
109		return elBottom > screenTop && elTop < screenBottom;
110	}
111});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.