PageSourceSearch

https://baofeng.ru/bitrix/js/main/core/core_fx.js

js baofeng.ru collected 2026-10-07 11:43:02 UTC 16,887 bytes, 705 lines download raw bytes

1;(function(window){
2var defaultOptions = {
3	time: 1.0,
4	step: 0.05,
5	type: 'linear',
6
7	allowFloat: false
8}
9
10/*
11options: {
12	start: start value or {param: value, param: value}
13	finish: finish value or {param: value, param: value}
14	time: time to transform in seconds
15	type: linear|accelerated|decelerated|custom func name
16	callback,
17	callback_start,
18	callback_complete,
19
20	step: time between steps in seconds
21	allowFloat: false|true
22}
23*/
24BX.fx = function(options)
25{
26	this.options = options;
27
28	if (null != this.options.time)
29		this.options.originalTime = this.options.time;
30	if (null != this.options.step)
31		this.options.originalStep = this.options.step;
32
33	if (!this.__checkOptions())
34		return false;
35
36	this.__go = BX.delegate(this.go, this);
37
38	this.PARAMS = {};
39}
40
41BX.fx.prototype.__checkOptions = function()
42{
43	if (typeof this.options.start != typeof this.options.finish)
44		return false;
45
46	if (null == this.options.time) this.options.time = defaultOptions.time;
47	if (null == this.options.step) this.options.step = defaultOptions.step;
48	if (null == this.options.type) this.options.type = defaultOptions.type;
49	if (null == this.options.allowFloat) this.options.allowFloat = defaultOptions.allowFloat;
50
51	this.options.time *= 1000;
52	this.options.step *= 1000;
53
54	if (typeof this.options.start != 'object')
55	{
56		this.options.start = {_param: this.options.start};
57		this.options.finish = {_param: this.options.finish};
58	}
59
60	var i;
61	for (i in this.options.start)
62	{
63		if (null == this.options.finish[i])
64		{
65			this.options.start[i] = null;
66			delete this.options.start[i];
67		}
68	}
69
70	if (!BX.type.isFunction(this.options.type))
71	{
72		if (BX.type.isFunction(window[this.options.type]))
73			this.options.type = window[this.options.type];
74		else if (BX.type.isFunction(BX.fx.RULES[this.options.type]))
75			this.options.type = BX.fx.RULES[this.options.type];
76		else
77			this.options.type = BX.fx.RULES[defaultOptions.type];
78	}
79
80	return true;
81}
82
83BX.fx.prototype.go = function()
84{
85	var timeCurrent = new Date().valueOf();
86	if (timeCurrent < this.PARAMS.timeFinish)
87	{
88		for (var i in this.PARAMS.current)
89		{
90			this.PARAMS.current[i][0] = this.options.type.apply(this, [{
91				start_value: this.PARAMS.start[i][0],
92				finish_value: this.PARAMS.finish[i][0],
93				current_value: this.PARAMS.current[i][0],
94				current_time: timeCurrent - this.PARAMS.timeStart,
95				total_time: this.options.time
96			}]);
97		}
98
99		this._callback(this.options.callback);
100
101		if (!this.paused)
102			this.PARAMS.timer = setTimeout(this.__go, this.options.step);
103	}
104	else
105	{
106		this.stop();
107	}
108}
109
110BX.fx.prototype._callback = function(cb)
111{
112	var tmp = {};
113
114	cb = cb || this.options.callback;
115
116	for (var i in this.PARAMS.current)
117	{
118		tmp[i] = (this.options.allowFloat ? this.PARAMS.current[i][0] : Math.round(this.PARAMS.current[i][0])) + this.PARAMS.current[i][1];
119	}
120
121	return cb.apply(this, [null != tmp['_param'] ? tmp._param : tmp]);
122}
123
124BX.fx.prototype.start = function()
125{
126	var i,value, unit;
127
128	this.PARAMS.start = {};
129	this.PARAMS.current = {};
130	this.PARAMS.finish = {};
131
132	for (i in this.options.start)
133	{
134		value = +this.options.start[i];
135		unit = (this.options.start[i]+'').substring((value+'').length);
136		this.PARAMS.start[i] = [value, unit];
137		this.PARAMS.current[i] = [value, unit];
138		this.PARAMS.finish[i] = [+this.options.finish[i], unit];
139	}
140
141	this._callback(this.options.callback_start);
142	this._callback(this.options.callback);
143
144	this.PARAMS.timeStart = new Date().valueOf();
145	this.PARAMS.timeFinish = this.PARAMS.timeStart + this.options.time;
146	this.PARAMS.timer = setTimeout(BX.delegate(this.go, this), this.options.step);
147
148	return this;
149}
150
151BX.fx.prototype.pause = function()
152{
153	if (this.paused)
154	{
155		this.PARAMS.timer = setTimeout(this.__go, this.options.step);
156		this.paused = false;
157	}
158	else
159	{
160		clearTimeout(this.PARAMS.timer);
161		this.paused = true;
162	}
163}
164
165BX.fx.prototype.stop = function(silent)
166{
167	silent = !!silent;
168	if (this.PARAMS.timer)
169		clearTimeout(this.PARAMS.timer);
170
171	if (null != this.options.originalTime)
172		this.options.time = this.options.originalTime;
173	if (null != this.options.originalStep)
174		this.options.step = this.options.originalStep;
175
176	this.PARAMS.current = this.PARAMS.finish;
177	if (!silent) {
178		this._callback(this.options.callback);
179		this._callback(this.options.callback_complete);
180	}
181}
182
183/*
184type rules of animation
185 - linear - simple linear animation
186 - accelerated
187 - decelerated
188*/
189
190/*
191	params: {
192		start_value, finish_value, current_time, total_time
193	}
194*/
195BX.fx.RULES =
196{
197	linear: function(params)
198	{
199		return params.start_value + (params.current_time/params.total_time) * (params.finish_value - params.start_value);
200	},
201
202	decelerated: function(params)
203	{
204		return params.start_value + Math.sqrt(params.current_time/params.total_time) * (params.finish_value - params.start_value);
205	},
206
207	accelerated: function(params)
208	{
209		var q = params.current_time/params.total_time;
210		return params.start_value + q * q * (params.finish_value - params.start_value);
211	}
212}
213
214/****************** effects realizaion ************************/
215
216/*
217	type = 'fade' || 'scroll' || 'scale' || 'fold'
218*/
219
220BX.fx.hide = function(el, type, opts)
221{
222	el = BX(el);
223
224	if (typeof type == 'object' && null == opts)
225	{
226		opts = type;
227		type = opts.type
228	}
229
230	if (!opts) opts = {};
231
232	if (!BX.type.isNotEmptyString(type))
233	{
234		el.style.display = 'none';
235		return;
236	}
237
238	var fxOptions = BX.fx.EFFECTS[type](el, opts, 0);
239	fxOptions.callback_complete = function () {
240		if (opts.hide !== false)
241			el.style.display = 'none';
242
243		if (opts.callback_complete)
244			opts.callback_complete.apply(this, arguments);
245	}
246
247	return (new BX.fx(fxOptions)).start();
248}
249
250BX.fx.show = function(el, type, opts)
251{
252	el = BX(el);
253
254	if (typeof type == 'object' && null == opts)
255	{
256		opts = type;
257		type = opts.type
258	}
259
260	if (!opts) opts = {};
261
262	if (!BX.type.isNotEmptyString(type))
263	{
264		el.style.display = 'block';
265		return;
266	}
267
268	var fxOptions = BX.fx.EFFECTS[type](el, opts, 1);
269
270	fxOptions.callback_complete = function () {
271		if (opts.show !== false)
272			el.style.display = 'block';
273
274		if (opts.callback_complete)
275			opts.callback_complete.apply(this, arguments);
276	}
277
278	return (new BX.fx(fxOptions)).start();
279}
280
281BX.fx.EFFECTS = {
282	scroll: function(el, opts, action)
283	{
284		if (!opts.direction) opts.direction = 'vertical';
285
286		var param = opts.direction == 'horizontal' ? 'width' : 'height';
287
288		var val = parseInt(BX.style(el, param));
289		if (isNaN(val))
290		{
291			val = BX.pos(el)[param];
292		}
293
294		if (action == 0)
295			var start = val, finish = opts.min_height ? parseInt(opts.min_height) : 0;
296		else
297			var finish = val, start = opts.min_height ? parseInt(opts.min_height) : 0;
298
299		return {
300			'start': start,
301			'finish': finish,
302			'time': opts.time || defaultOptions.time,
303			'type': 'linear',
304			callback_start: function () {
305				if (BX.style(el, 'position') == 'static')
306					el.style.position = 'relative';
307
308				el.style.overflow = 'hidden';
309				el.style[param] = start + 'px';
310				el.style.display = 'block';
311			},
312			callback: function (val) {el.style[param] = val + 'px';}
313		}
314	},
315
316	fade: function(el, opts, action)
317	{
318		var fadeOpts = {
319			'time': opts.time || defaultOptions.time,
320			'type': action == 0 ? 'decelerated' : 'linear',
321			'start': action == 0 ? 1 : 0,
322			'finish': action == 0 ? 0 : 1,
323			'allowFloat': true
324		};
325
326		if (BX.browser.IsIE() && !BX.browser.IsIE9())
327		{
328			fadeOpts.start *= 100; fadeOpts.finish *= 100; fadeOpts.allowFloat = false;
329
330			fadeOpts.callback_start = function() {
331				el.style.display = 'block';
332				el.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity=" + fadeOpts.start + ")";
333			};
334
335			fadeOpts.callback = function (val) {
336				(el.filters['DXImageTransform.Microsoft.alpha']||el.filters.alpha).opacity = val;
337			}
338		}
339		else
340		{
341			fadeOpts.callback_start = function () {
342				el.style.display = 'block';
343			}
344
345			fadeOpts.callback = function (val) {
346				el.style.opacity = el.style.KhtmlOpacity = el.style.MozOpacity = val;
347			};
348		}
349
350		return fadeOpts;
351	},
352
353	fold: function (el, opts, action) // 'fold' is a combination of two consequential 'scroll' hidings.
354	{
355		if (action != 0) return;
356
357		var pos = BX.pos(el);
358		var coef = pos.height / (pos.width + pos.height);
359		var old_opts = {time: opts.time || defaultOptions.time, callback_complete: opts.callback_complete, hide: opts.hide};
360
361		opts.type = 'scroll';
362		opts.direction = 'vertical';
363		opts.min_height = opts.min_height || 10;
364		opts.hide = false;
365		opts.time = coef * old_opts.time;
366		opts.callback_complete = function()
367		{
368			el.style.whiteSpace = 'nowrap';
369
370			opts.direction = 'horizontal';
371			opts.min_height = null;
372
373			opts.time = old_opts.time - opts.time;
374			opts.hide = old_opts.hide;
375			opts.callback_complete = old_opts.callback_complete;
376
377			BX.fx.hide(el, opts);
378		}
379
380		return BX.fx.EFFECTS.scroll(el, opts, action);
381	},
382
383	scale: function (el, opts, action)
384	{
385		var val = {width: parseInt(BX.style(el, 'width')), height: parseInt(BX.style(el, 'height'))};
386		if (isNaN(val.width) || isNaN(val.height))
387		{
388			var pos = BX.pos(el)
389			val = {width: pos.width, height: pos.height};
390		}
391
392		if (action == 0)
393			var start = val, finish = {width: 0, height: 0};
394		else
395			var finish = val, start = {width: 0, height: 0};
396
397		return {
398			'start': start,
399			'finish': finish,
400			'time': opts.time || defaultOptions.time,
401			'type': 'linear',
402			callback_start: function () {
403				el.style.position = 'relative';
404				el.style.overflow = 'hidden';
405				el.style.display = 'block';
406				el.style.height = start.height + 'px';
407				el.style.width = start.width + 'px';
408			},
409			callback: function (val) {
410				el.style.height = val.height + 'px';
411				el.style.width = val.width + 'px';
412			}
413		}
414	}
415}
416
417// Color animation
418//
419// Set animation rule
420// BX.fx.colorAnimate.addRule('animationRule1',"#FFF","#faeeb4", "background-color", 100, 1, true);
421// BX.fx.colorAnimate.addRule('animationRule2',"#fc8282","#ff0000", "color", 100, 1, true);
422// Params: 1 - animation name, 2 - start color, 3 - end color, 4 - count step, 5 - delay each step, 6 - return color on end animation
423//
424// Animate color for element
425// BX.fx.colorAnimate(BX('element'), 'animationRule1,animationRule2');
426
427var defaultOptionsColorAnimation = {
428	arStack: {},
429	arRules: {},
430	globalAnimationId: 0
431}
432
433BX.fx.colorAnimate = function(element, rule, back)
434{
435	if (element == null)
436		return;
437
438	animationId = element.getAttribute('data-animation-id');
439	if (animationId == null)
440	{
441		animationId = defaultOptionsColorAnimation.globalAnimationId;
442		element.setAttribute('data-animation-id', defaultOptionsColorAnimation.globalAnimationId++);
443	}
444	var aRuleList = rule.split(/\s*,\s*/);
445
446	for (var j	= 0; j < aRuleList.length; j++)
447	{
448		rule = aRuleList[j];
449
450		if (!defaultOptionsColorAnimation.arRules[rule]) continue;
451
452		var i=0;
453
454		if (!defaultOptionsColorAnimation.arStack[animationId])
455		{
456			defaultOptionsColorAnimation.arStack[animationId] = {};
457		}
458		else if (defaultOptionsColorAnimation.arStack[animationId][rule])
459		{
460			i = defaultOptionsColorAnimation.arStack[animationId][rule].i;
461			clearInterval(defaultOptionsColorAnimation.arStack[animationId][rule].tId);
462		}
463
464		if ((i==0 && back) || (i==defaultOptionsColorAnimation.arRules[rule][3] && !back)) continue;
465
466		defaultOptionsColorAnimation.arStack[animationId][rule] = {'i':i, 'element': element, 'tId':setInterval('BX.fx.colorAnimate.run("'+animationId+'","'+rule+'")', defaultOptionsColorAnimation.arRules[rule][4]),'back':Boolean(back)};
467	}
468}
469
470BX.fx.colorAnimate.addRule = function (rule, startColor, finishColor, cssProp, step, delay, back)
471{
472	defaultOptionsColorAnimation.arRules[rule] = [
473		BX.util.hex2rgb(startColor),
474		BX.util.hex2rgb(finishColor),
475		cssProp.replace(/\-(.)/g,function(){return arguments[1].toUpperCase();}),
476		step,
477		delay || 1,
478		back || false
479	];
480};
481
482BX.fx.colorAnimate.run = function(animationId, rule)
483{
484	element = defaultOptionsColorAnimation.arStack[animationId][rule].element;
485
486    defaultOptionsColorAnimation.arStack[animationId][rule].i += defaultOptionsColorAnimation.arStack[animationId][rule].back?-1:1;
487 	var finishPercent = defaultOptionsColorAnimation.arStack[animationId][rule].i/defaultOptionsColorAnimation.arRules[rule][3];
488	var startPercent = 1 - finishPercent;
489
490	var aRGBStart = defaultOptionsColorAnimation.arRules[rule][0];
491	var aRGBFinish = defaultOptionsColorAnimation.arRules[rule][1];
492
493	element.style[defaultOptionsColorAnimation.arRules[rule][2]] = 'rgb('+
494	Math.floor( aRGBStart['r'] * startPercent + aRGBFinish['r'] * finishPercent ) + ','+
495	Math.floor( aRGBStart['g'] * startPercent + aRGBFinish['g'] * finishPercent ) + ','+
496	Math.floor( aRGBStart['b'] * startPercent + aRGBFinish['b'] * finishPercent ) +')';
497
498	if ( defaultOptionsColorAnimation.arStack[animationId][rule].i == defaultOptionsColorAnimation.arRules[rule][3] || defaultOptionsColorAnimation.arStack[animationId][rule].i ==0)
499	{
500		clearInterval(defaultOptionsColorAnimation.arStack[animationId][rule].tId);
501		if (defaultOptionsColorAnimation.arRules[rule][5])
502			BX.fx.colorAnimate(defaultOptionsColorAnimation.arStack[animationId][rule].element, rule, true);
503	}
504}
505
506
507/*
508options = {
509	delay: 100,
510	duration : 3000,
511	start : { scroll : document.body.scrollTop, left : 0, opacity :  100 },
512	finish : { scroll : document.body.scrollHeight, left : 500, opacity : 10 },
513	transition : BitrixAnimation.makeEaseOut(BitrixAnimation.transitions.quart),
514
515	step : function(state)
516	{
517		document.body.scrollTop = state.scroll;
518		button.style.left =  state.left + "px";
519		button.style.opacity =  state.opacity / 100;
520	},
521	complete : function()
522	{
523		button.style.background = "green";
524	}
525}
526
527options =
528{
529	delay : 20,
530	duration : 4000,
531	transition : BXAnimation.makeEaseOut(BXAnimation.transitions.quart),
532	progress : function(progress)
533	{
534		document.body.scrollTop = Math.round(topMax * progress);
535		button.style.left =  Math.round(leftMax * progress) + "px";
536		button.style.opacity =  (100 + Math.round((opacityMin - 100) * progress)) / 100;
537
538	},
539	complete : function()
540	{
541		button.style.background = "green";
542	}
543}
544*/
545
546BX.easing = function(options)
547{
548	this.options = options;
549	this.timer = null;
550};
551
552BX.easing.prototype.animate = function()
553{
554	if (!this.options || !this.options.start || !this.options.finish ||
555		typeof(this.options.start) != "object" || typeof(this.options.finish) != "object"
556		)
557		return null;
558
559	for (var propName in this.options.start)
560	{
561		if (typeof(this.options.finish[propName]) == "undefined")
562		{
563			delete this.options.start[propName];
564		}
565	}
566
567	this.options.progress = function(progress) {
568		var state = {};
569		for (var propName in this.start)
570			state[propName] = Math.round(this.start[propName] + (this.finish[propName] - this.start[propName]) * progress);
571
572		if (this.step)
573		{
574			this.step(state);
575		}
576	};
577
578	this.animateProgress();
579};
580
581BX.easing.prototype.stop = function(completed)
582{
583	if (this.timer)
584	{
585		cancelAnimationFrame(this.timer);
586		this.timer = null;
587		if (completed)
588		{
589			this.options.complete && this.options.complete();
590		}
591	}
592};
593
594BX.easing.prototype.animateProgress = function()
595{
596	if (!window.requestAnimationFrame)
597	{
598		//For old browsers we skip animation
599		this.options.progress(1);
600		this.options.complete && this.options.complete();
601		return;
602	}
603
604	var start = null;
605	var delta = this.options.transition || BX.easing.transitions.linear;
606	var duration = this.options.duration || 1000;
607	var animation = BX.proxy(function(time) {
608
609		if (start === null)
610		{
611			start = time;
612		}
613
614		var progress = (time - start) / duration;
615		if (progress > 1)
616		{
617			progress = 1;
618		}
619
620		this.options.progress(delta(progress));
621
622		if (progress == 1)
623		{
624			this.stop(true);
625		}
626		else
627		{
628			this.timer = requestAnimationFrame(animation);
629		}
630
631	}, this);
632
633	this.timer = requestAnimationFrame(animation);
634};
635
636BX.easing.makeEaseInOut = function(delta)
637{
638	return function(progress) {
639		if (progress < 0.5)
640			return delta( 2 * progress ) / 2;
641		else
642			return (2 - delta( 2 * (1-progress) ) ) / 2;
643	}
644};
645
646BX.easing.makeEaseOut = function(delta)
647{
648	return function(progress) {
649		return 1 - delta(1 - progress);
650	};
651};
652
653BX.easing.transitions = {
654
655	linear : function(progress)
656	{
657		return progress;
658	},
659
660	quad : function(progress)
661	{
662		return Math.pow(progress, 2);
663	},
664
665	cubic : function(progress) {
666		return Math.pow(progress, 3);
667	},
668
669	quart : function(progress)
670	{
671		return Math.pow(progress, 4);
672	},
673
674	quint : function(progress)
675	{
676		return Math.pow(progress, 5);
677	},
678
679	circ : function(progress)
680	{
681		return 1 - Math.sin(Math.acos(progress));
682	},
683
684	back : function(progress)
685	{
686		return Math.pow(progress, 2) * ((1.5 + 1) * progress - 1.5);
687	},
688
689	elastic: function(progress)
690	{
691		return Math.pow(2, 10 * (progress-1)) * Math.cos(20 * Math.PI * 1.5/3 * progress);
692	},
693
694	bounce : function(progress)
695	{
696		for(var a = 0, b = 1; 1; a += b, b /= 2) {
697			if (progress >= (7 - 4 * a) / 11) {
698				return -Math.pow((11 - 6 * a - 11 * progress) / 4, 2) + Math.pow(b, 2);
699			}
700		}
701	}};
702
703
704})(window);
705

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.