PageSourceSearch

https://yarplaneta.ru/local/templates/yarplaneta/scripts/_polygon.js?8848682131

js yarplaneta.ru collected 2026-09-25 20:37:19 UTC 10,498 bytes, 196 lines download raw bytes

1$(document).ready(drawPolygons);
2$(window).on('resize', function (){
3	drawPolygons(); /* По ходу ресайза сразу применяем полигон. Сработает в большинстве кейсов. */
4	setTimeout(drawPolygons, 1500); /* Сработает в каруселях, которые пересоздаются через 1000ms. */
5});
6
7function drawPolygons() {
8
9	const userScreen = window.matchMedia('(min-width: 1500px)').matches ? 'monitor' : window.matchMedia('(max-width: 739px)').matches ? 'smartphone' : 'notebook';
10
11	$('.polygon').each(function () {
12
13		const $this = $(this);
14
15		/* 1) Ширина/высота всегда по размерам родителя. Неизменна. */
16		const width = $this.outerWidth();
17		const height = $this.outerHeight();
18
19
20		/* 2) Оригинальный, стилевой border-radius нужен на кнопке, чтобы задать фон. Он там остаётся.
21		 * SVG рисующая контур внутри напрямую зависит от этого border-radius, забираем его.
22		 */
23		const radius = parseInt($this.css('border-bottom-left-radius'));
24		/* Возможно правильным вариантом будет:
25		 * const radius = parseInt($this.css('border-bottom-left-radius')) - stroke / 2;
26		 * но зависит от ситуации. Если, например, stroke будет как inner в фигме, но сейчас не так.
27		 */
28
29
30		/* 3) Параметрические значения -- для каждой фигуры свои.
31		 * stroke (толщина бордюра), по-идее, надо бы извелкать из box-shadow в стилях,
32		 * но парсить его сложно и ненадёжно. Теоретически там может быть несколько box-shadow.
33		 */
34		let angleWidth = 0;
35		let angleHeight = 0;
36		let stroke = 0;
37
38
39		if ($this.hasClass('session__info')) {
40			angleWidth = (userScreen === 'smartphone') ? 38 : (userScreen === 'monitor') ? 54 : 47; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
41			angleHeight = (userScreen === 'smartphone') ? 32 : (userScreen === 'monitor') ? 44 : 38; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
42			stroke = 2;
43		}
44
45		if ($this.hasClass('docs__link')) {
46			angleWidth = (userScreen === 'smartphone') ? 22 : (userScreen === 'monitor') ? 54 : 47; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
47			angleHeight = (userScreen === 'smartphone') ? 34 : (userScreen === 'monitor') ? 44 : 38; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
48			stroke = 2;
49		}
50
51		if ($this.hasClass('pagination__item')) {
52			angleWidth = (userScreen === 'smartphone') ? 11 : (userScreen === 'monitor') ? 12 : 11; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
53			angleHeight = (userScreen === 'smartphone') ? 16 : (userScreen === 'monitor') ? 14 : 13; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
54			stroke = 1;
55		}
56
57		if ($this.hasClass('sub-nav__link')) {
58			angleWidth = (userScreen === 'smartphone') ? 15 : (userScreen === 'monitor') ? 17 : 16; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
59			angleHeight = (userScreen === 'smartphone') ? 15 : (userScreen === 'monitor') ? 17 : 16; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
60			stroke = 2;
61		}
62
63		if ($this.hasClass('button')) {
64			angleWidth = (userScreen === 'smartphone') ? 16 : (userScreen === 'monitor') ? 22 : 19; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
65			angleHeight = (userScreen === 'smartphone') ? 20 : (userScreen === 'monitor') ? 26 : 23; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
66			stroke = 0;
67		}
68
69		if ($this.hasClass('button--outline')) {
70			stroke = 1;
71		}
72
73		if ($this.hasClass('slideshow__control')) {
74			angleWidth = (userScreen === 'smartphone') ? 11 : (userScreen === 'monitor') ? 12 : 11; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
75			angleHeight = (userScreen === 'smartphone') ? 14 : (userScreen === 'monitor') ? 15 : 14; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
76			stroke = 1;
77		}
78
79		if ($this.hasClass('swiper__control')) {
80			angleWidth = (userScreen === 'smartphone') ? 11 : (userScreen === 'monitor') ? 12 : 11; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
81			angleHeight = (userScreen === 'smartphone') ? 14 : (userScreen === 'monitor') ? 15 : 14; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
82			stroke = 1;
83		}
84
85		if ($this.hasClass('day')) {
86			angleWidth = (userScreen === 'smartphone') ? 15 : (userScreen === 'monitor') ? 17 : 15; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
87			angleHeight = (userScreen === 'smartphone') ? 12 : (userScreen === 'monitor') ? 14 : 12; /* Читать справа-налево, чтобы было laptop first (как в стилях) */
88			stroke = 1;
89		}
90
91
92		if ($this.hasClass('panel__body')) {
93
94			/* Отступы между карточкой и кнопкой: */
95			const topPadding = (userScreen === 'smartphone') ? 10 : (userScreen === 'monitor') ? 12 : 11; /* Читать справа-налево, чтобы было laptop first (как в стилях) */;
96			const leftPadding = (userScreen === 'smartphone') ? 8 : (userScreen === 'monitor') ? 10 : 9; /* Читать справа-налево, чтобы было laptop first (как в стилях) */;
97
98			/* Размеры кнопки + отступы: */
99			angleWidth = parseInt($this.parents('.panel').find('.panel__action').outerWidth(), 10) + topPadding;
100			angleHeight = parseInt($this.parents('.panel').find('.panel__action').outerHeight(), 10) + leftPadding;
101			stroke = 2;
102		}
103
104
105		/* Линия, по которой будет обрезаться полигон и рисоваться бордюр */
106
107		let path = '';
108
109		// M 0,7.5
110		// C0 3.35787 3.35786,0 7.5,0
111		// L115.43,0
112		// C117.955,0 120.311,1.27115 121.698,3.38199
113		// L132.768,20.2331
114		// C133.572,21.4562 134,22.8876 134,24.3511
115		// L134,46.5
116		// C134,50.6421 130.642,54 126.5,54
117		// L7.5,54
118		// C3.35786,54 0,50.6421 0,46.5
119		// L0,39.375
120		// L0,7.5
121		// Z
122
123
124		/*
125		  В коде ниже, две строчки помеченные "→" -- слабое место. Здесь скругление углов как бы захардкожено цифрами 1,2,3,6::
126		  M ${0} ${radius}
127		  C ${0} ${radius / 2}   ${radius / 2} ${0}   ${radius} ${0}
128		  L ${width - angleWidth} ${0}
129	   →  C ${width - angleWidth + 3}  ${0}   ${width - angleWidth + 5}  ${1} ${width - angleWidth + 6} ${2}
130		  L ${width - 1.25}  ${angleHeight - 5}
131	   →  C ${width - 0.5}  ${angleHeight - 3}      ${width}  ${angleHeight - 1.5}      ${width}   ${angleHeight}
132		  L ${width} ${height - radius}
133		  C ${width} ${height - radius / 2}
133   ${width - radius / 2} ${height}   ${width - radius} ${height}
134		  L ${radius} ${height}
135		  C ${radius / 2} ${height}    ${0} ${height - radius / 2}    ${0} ${height - radius}
136		  L ${0} ${radius}
137		*/
138		if ($this.hasClass('polygon--trapezoid')) {
139			path = `
140				M ${0} ${radius}
141				C ${0} ${radius / 2}   ${radius / 2} ${0}   ${radius} ${0}
142				L ${width - angleWidth} ${0}
143				C ${width - angleWidth + 3}  ${0}   ${width - angleWidth + 5}  ${1} ${width - angleWidth + 6} ${2}
144				L ${width - 1.25}  ${angleHeight - 5}
145				C ${width - 0.5}  ${angleHeight - 3}      ${width}  ${angleHeight - 1.5}      ${width}   ${angleHeight}
146				L ${width} ${height - radius}
147				C ${width} ${height - radius / 2}   ${width - radius / 2} ${height}   ${width - radius} ${height}
148				L ${radius} ${height}
149				C ${radius / 2} ${height}    ${0} ${height - radius / 2}    ${0} ${height - radius}
150				L ${0} ${radius}
151				Z
152			`;
153		}
154
155		if ($this.hasClass('polygon--card')) {
156			path = `
157				M ${radius} ${0}
158				L ${width - radius} ${0}
159				C ${width - radius / 2} ${0}   ${width} ${radius / 2}     ${width} ${radius}
160				L ${width} ${height - angleHeight - radius}
161				C ${width} ${height - angleHeight - radius / 2}    ${width - radius / 2} ${height - angleHeight}    ${width - radius} ${height - angleHeight}
162				L ${width - angleWidth + radius} ${height - angleHeight}
163				C ${width - angleWidth + radius / 2} ${height - angleHeight}    ${width - angleWidth} ${height - angleHeight + radius / 2}    ${width - angleWidth} ${height - angleHeight + radius}
164				L ${width - angleWidth} ${height - radius}
165				C ${width - angleWidth} ${height - radius / 2}   ${width - angleWidth - radius / 2} ${height}   ${width - angleWidth - radius} ${height}
166				L ${radius} ${height}
167				C ${radius / 2}  ${height}     ${0} ${height - radius / 2}     ${0} ${height - radius}
168				L ${0} ${radius}
169				C ${0} ${radius / 2}    ${radius / 2} ${0}    ${radius} ${0}
170				Z
171			`;
172		}
173
174		/* Удаляем форматирование (переносы строки и табуляции) */
175		path = path.replace(/\s\s+/g, ' ');
176
177		/* Вырезаем нужную форму: */
178		$this.attr('style', `clip-path: path('${path}')`);
179
180		/* Опциональный контур в виде такой же формы: */
181		if (stroke) {
182
183			$this.find('.polygon__border').remove(); /* Если с прошлого раза остался .polygon__border (например при перерисовки, при ресайзе) */
184
185			$this.prepend(`
186				<svg class="polygon__border" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
187					<path id="polygon__path" stroke-width="${stroke * 2}" d="${path}" fill="none"/>
188				</svg>
189			`);
190		}
191
192		/* Даём стилям понять, что алгоритм отработан и новый контур отрисован (чтобы они выключили старый) */
193		$this.addClass('polygon--applied');
194
195	});
196}

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.