Знакомство с Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»ΡΡŽΡ‰ΠΈΠΌΠΈ возмоТностями SVG-Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ: пишСм Π½Π΅Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ ΠΈΠ³Ρ€Ρƒ

ОблоТка: Знакомство с Π²ΠΏΠ΅Ρ‡Π°Ρ‚Π»ΡΡŽΡ‰ΠΈΠΌΠΈ возмоТностями SVG-Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΉ: пишСм Π½Π΅Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ ΠΈΠ³Ρ€Ρƒ

РассказываСт Грэг Π₯ованСсян 

ИдСя ΠΈΠ³Ρ€Ρ‹

Π― ΡƒΠΆΠ΅ достаточно Π΄Π°Π²Π½ΠΎ Π·Π½Π°ΠΊΠΎΠΌ с SVG-анимациями ΠΈ Ρ…ΠΎΡ€ΠΎΡˆΠΎ понимаю, ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡ… ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для создания Π°Π½ΠΈΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… спрайтов ΠΈΠ»ΠΈ Π΄ΠΈΠ·Π°ΠΉΠ½Π° Π²Π΅Π±-страниц. Π’Π°ΠΊΠΎΠ΅ сочСтаниС, ΠΊΠ°ΠΊΒ GreenSock ΠΈ Π½Π°Ρ‚ΠΈΠ²Π½Ρ‹ΠΉ CSS, Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΎ прСкрасно. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ я ΠΏΠΎΠ΄ΡƒΠΌΠ°Π» ΠΈ Ρ€Π΅ΡˆΠΈΠ» ΠΏΠΎΠΉΡ‚ΠΈ Π΄Π°Π»ΡŒΡˆΠ΅Β β€” ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ с ΠΈΡ… ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π½Π΅Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ ΠΈΠ³Ρ€Ρƒ. РазумССтся, с ΠΎΡ‚Π»ΠΈΡ‡Π½ΠΎ ΠΏΡ€ΠΎΡ€Π°Π±ΠΎΡ‚Π°Π½Π½Ρ‹ΠΌ, Π°Π½ΠΈΠΌΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΌ Π΄ΠΈΠ·Π°ΠΉΠ½ΠΎΠΌ. Π˜Ρ‚Π°ΠΊ, ΠΎΠ΄Π½Π°ΠΆΠ΄Ρ‹ Π½ΠΎΡ‡ΡŒΡŽ ΠΊΠΎ ΠΌΠ½Π΅ ΠΏΡ€ΠΈΡˆΠ»Π° идСя ΠΈΠ³Ρ€Ρ‹, я сдСлал ΠΏΠ°Ρ€Ρƒ набросков ΠΈ ΠΏΠΎΠΊΠ°Π·Π°Π» ΠΈΡ… Π±Ρ€Π°Ρ‚Ρƒ β€” ΠΏΡ€ΠΎΡ„Π΅ΡΡΠΈΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΌΡƒ Π΄ΠΈΠ·Π°ΠΉΠ½Π΅Ρ€Ρƒ. ΠœΡ‹ обсудили всС Π΄Π΅Ρ‚Π°Π»ΠΈ, ΠΈ я приступил ΠΊ Ρ€Π°Π±ΠΎΡ‚Π΅.Β 

Как ΠΈΠ³Ρ€Π°Ρ‚ΡŒ:Β ΠŸΡ€Ρ‹Π³Π°ΡŽΡ‰ΠΈΠΉ мяч мСняСт Ρ†Π²Π΅Ρ‚. ΠΌΡ‹ Π΄ΠΎΠ»ΠΆΠ½Ρ‹ ΡΠ»Π΅Π΄ΠΈΡ‚ΡŒ Π·Π° Π΅Π³ΠΎ Ρ†Π²Π΅Ρ‚ΠΎΠΌ ΠΈ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ Ρ†Π²Π΅Ρ‚ ΠΊΠΎΠ»ΠΎΠ½Π½, Π½Π° ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠ½ ΠΏΠ°Π΄Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ†Π²Π΅Ρ‚Π° совпадали. Одно Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ Π½Π° ΠΊΠΎΠ»ΠΎΠ½Π½Ρƒ Π΄Π΅Π»Π°Π΅Ρ‚ Π΅Ρ‘ красной, Π΄Π²Π° β€” ΠΆΡ‘Π»Ρ‚ΠΎΠΉ, Ρ‚Ρ€ΠΈ β€” Ρ„ΠΈΠΎΠ»Π΅Ρ‚ΠΎΠ²ΠΎΠΉ.

ΠŸΡ€ΠΎΡ†Π΅ΡΡ создания

Π’ΠΎ врСмя Ρ€Π°Π±ΠΎΡ‚Ρ‹ Π½Π°Π΄ ΠΈΠ³Ρ€ΠΎΠΉ я сталкивался с Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹ΠΌΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ. Π‘Π°ΠΌΡ‹ΠΌ слоТным Π±Ρ‹Π»ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ‚Π°ΠΊ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΈΠ³Ρ€Π° выглядСла ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²ΠΎ Ρ…ΠΎΡ€ΠΎΡˆΠΎ Π½Π° всСх экранах. ПослС Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… ΠΏΠΎΠΏΡ‹Ρ‚ΠΎΠΊ стало ясно, Ρ‡Ρ‚ΠΎ классичСскиС Ρ‚Π΅Ρ…Π½ΠΈΠΊΠΈ использования мСдиазапросов Π½Π΅ ΡΡ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‚.

Π­Ρ‚ΠΎ Π½Π΅ руководство, поэтому я Π½Π΅ Π±ΡƒΠ΄Ρƒ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½ΠΎ ΠΎΠ±ΡŠΡΡΠ½ΡΡ‚ΡŒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ строчку ΠΊΠΎΠ΄Π°. Но я ΠΏΠΎΠΊΠ°ΠΆΡƒ Π²Π°ΠΌ нСсколько классных ΠΏΡ€ΠΈΡ‘ΠΌΠΎΠ², Π° Π²Ρ‹ смоТСтС ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒΡΡ с ΠΊΠΎΠ΄ΠΎΠΌ Π½Π°Β CodePen. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, я подСлюсь с Π²Π°ΠΌΠΈ нСскольким ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ΠΌΠΈ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Π°ΠΌΠΈ. Код Ρ‚Π°ΠΊΠΆΠ΅ сопровоТдаСтся коммСнтариями.

GSAPΒ β€” это ΠΎΡ‡Π΅Π½ΡŒ ΠΌΠΎΡ‰Π½Ρ‹ΠΉ инструмСнт, поэтому Π½Π΅ΡƒΠ΄ΠΈΠ²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ, Ρ‡Ρ‚ΠΎ я ΠΈΠΌ пользовался. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, Ρƒ CodePen Π΅ΡΡ‚ΡŒ встроСнный компилятор Babel, поэтому я ΠΌΠΎΠ³Ρƒ ΠΏΠΈΡΠ°Ρ‚ΡŒ Ρ‚Π°ΠΌ ES6-ΠΊΠΎΠ΄, Ρƒ ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ Π΅ΡΡ‚ΡŒ ΠΊΡƒΡ‡Π° возмоТностСй: синтаксис классов, стрСлочныС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ Ρ‚.Π΄. ΠŸΠΎΠ΄Ρ€ΠΎΠ±Π½Π΅Π΅ ΠΎΠ± этом ΠΌΠΎΠΆΠ½ΠΎ ΡƒΠ·Π½Π°Ρ‚ΡŒ здСсь.

Π― Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€Π΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΡŽ, Ρ‡Ρ‚ΠΎ Π²Ρ‹ ΡƒΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌΡ‹ с GSAP, Π½ΠΎ Ссли это Π½Π΅ Ρ‚Π°ΠΊ, Ρ‚ΠΎ Π²ΠΎΡ‚ ΠΎΡ‚Π»ΠΈΡ‡Π½Ρ‹ΠΉ курс для изучСния.

Ѐоновая анимация

Всё, Ρ‡Ρ‚ΠΎ Π²Ρ‹ Π²ΠΈΠ΄ΠΈΡ‚Π΅ Π½Π° Ρ„ΠΎΠ½Π΅ β€” это SVG. КаТдая Π²ΠΎΠ»Π½Π°, ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ слой Π³ΠΎΡ€ ΠΈ ΠΎΠ±Π»Π°ΠΊΠ° β€” это ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ div’ы. Π”Π° ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ Π±Ρ‹ ΡΠΎΠ·Π΄Π°Ρ‚ΡŒ Ρ„ΠΎΠ½ лишь ΠΎΠ΄Π½ΠΈΠΌ SVG, ΠΈ Π°Π½ΠΈΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π΄ΠΎΡ‡Π΅Ρ€Π½ΠΈΠ΅ элСмСнты β€” Greensock это ΠΌΠΎΠΆΠ΅Ρ‚, достаточно Π·Π°Π΄Π°Ρ‚ΡŒ ΠΈΠΌ ID. Π”Π΅Π»ΠΎ Π² Ρ‚ΠΎΠΌ, Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠ³Π΄Π° анимация Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π½Π° ΠΌΠΎΠ±ΠΈΠ»ΡŒΠ½Ρ‹Ρ… устройствах.

			var wave1 = TweenMax.to('.wave1', 0.7, {backgroundPositionX: '-=54px', repeat: -1, ease: Power0.easeNone});
		

Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ инструмСнт TweenMax для сдвига Ρ„ΠΎΠ½Π° Π½Π° 54 пиксСля с постоянной ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒΡŽ. Π’ΠΎ ΠΆΠ΅ самоС ΠΌΡ‹ Π΄Π΅Π»Π°Π΅ΠΌ ΠΈ с Π³ΠΎΡ€Π°ΠΌΠΈ ΠΈ ΠΎΠ±Π»Π°ΠΊΠ°ΠΌΠΈ. Задавая ΠΊΠ°ΠΆΠ΄ΠΎΠΌΡƒ элСмСнту ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ, ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅ΠΌ Π½Π΅ΠΏΠ»ΠΎΡ…ΠΎ выглядящий эффСкт параллакса.

Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π²Π΅Π·Π΄Π΅ парят малСнькиС частицы. Π― Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΡŽ ΠΈΡ… случайным ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΈ Π°Π½ΠΈΠΌΠΈΡ€ΡƒΡŽ Ρ†ΠΈΠΊΠ»ΠΈΡ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ:

			{rotation: 360, transformOrigin: "-"+radius+"px -"+radius+"px", ...}
		

Они всС ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ, ΠΈ это выглядит Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ Ρ…Π°ΠΎΡ‚ΠΈΡ‡Π½ΠΎ.

Анимация ΠΊΠΎΠ»ΠΎΠ½Π½

Π’ ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠ»ΠΎΠ½Π½Π΅ Π΅ΡΡ‚ΡŒ малСнькиС двиТущиСся элСмСнты. Π˜Ρ… я создал просто срСдствами HTML/CSS. SCSS сэкономил ΠΎΠ³Ρ€ΠΎΠΌΠ½ΠΎΠ΅ количСство Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΈ строк ΠΊΠΎΠ΄Π°. Π― создал ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ миксины для ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ»ΠΎΠ½Π½Ρ‹. ВзглянСм Π½Π° эффСкт для ΠΏΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠΎΠ². ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΊΡ€ΡƒΠ³ ΠΈΠΌΠ΅Π΅Ρ‚ Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎΠ΅ ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΎΠ½ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, Π° Π΅Π³ΠΎ ΡΡ‚ΠΈΠ»ΡŒ задаётся миксином. Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΎΠ² Π² CSS Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ Π΅Ρ‰Ρ‘ большС строк ΠΊΠΎΠ΄Π°, поэтому миксины выглядят Π΅Ρ‰Ρ‘ Π²Ρ‹Π³ΠΎΠ΄Π½Π΅Π΅.

ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π½Π° ΠΊΡ€Π°ΡΠ½ΡƒΡŽ ΠΊΠΎΠ»ΠΎΠ½Π½Ρƒ с ΠΏΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ°ΠΌΠΈ.

			@mixin bubble ($size, $top, $left) {
    height: $size;
    width: $size;
    top: $top;
    left: $left;
}

@mixin bubble_hollow ($size, $top, $left) {
    @include bubble ($size, $top, $left);
    background-color: transparent;
    border-style: solid;
}
		

Π’Π°ΠΊΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ, Ссли я Ρ…ΠΎΡ‡Ρƒ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΡƒΠ·Ρ‹Ρ€Ρ‘ΠΊ, я просто Π²Ρ‹Π·Ρ‹Π²Π°ΡŽ Π½ΡƒΠΆΠ½Ρ‹ΠΉ миксин, указывая располоТСниС ΠΏΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠ° Π² ΠΊΠΎΠ»ΠΎΠ½Π½Π΅.

			.bubble-4 {
    @include bubble(15px, 98px, 37px);
}
.bubble-5 {
    @include bubble_hollow(5px, 116px, 20px);
}
		

Анимация ΠΏΡƒΠ·Ρ‹Ρ€ΡŒΠΊΠΎΠ²

Для Ρ‚Π°ΠΊΠΎΠ³ΠΎ эффСкта я использовал ΠΎΡ‚Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Π΅ Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΠΈ. Они Π·Π°Ρ‚Ρ€Π°Π³ΠΈΠ²Π°ΡŽΡ‚ всС элСмСнты Π²Π½ΡƒΡ‚Ρ€ΠΈ ΠΊΠΎΠ»ΠΎΠ½Π½Ρ‹, Π½ΠΎ Π΄Π²ΠΈΠ³Π°Ρ‚ΡŒΡΡ ΠΎΠ½ΠΈ Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‚ с нСольшими Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ°ΠΌΠΈ. Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΎΠ± этом ΠΏΡ€ΠΈΡ‘ΠΌΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ здСсь.

Анимация Ρ‚Ρ€Π΅ΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΎΠ²

Π’ ΠΆΡ‘Π»Ρ‚ΠΎΠΉ ΠΊΠΎΠ»ΠΎΠ½Π½Π΅ я Π΄ΠΎΠ±Π°Π²ΠΈΠ» эффСкт ΠΏΠ΅Ρ€Π΅Π²ΠΎΡ€ΠΎΡ‚Π°. Π—Π°ΠΌΠ΅Ρ‚ΡŒΡ‚Π΅, Ρ‡Ρ‚ΠΎ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· элСмСнтов Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ Π²ΠΎΠΊΡ€ΡƒΠ³ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½ΠΎΠΉ оси, Π° Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ β€” Π²ΠΎΠΊΡ€ΡƒΠ³ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Π°Π»ΡŒΠ½ΠΎΠΉ. Π—Π΄Π΅ΡΡŒ я ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ свойство cycle:

			var triangle = new TimelineMax({delay: 0.5});
triangle
        .staggerTo(el.find('.triangle'), 1.5, {
            cycle:{
                rotationY: [0, 360],
                rotationX: [360, 0],
            },
            repeat: -1,
            repeatDelay: 0.1
        }, 0.1);
		

Анимация Π±Π»ΠΎΠΊΠΎΠ²

Π’ΠΎ ΠΆΠ΅ самоС я ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽ ΠΈ Π² Ρ‚Ρ€Π΅Ρ‚ΡŒΠ΅ΠΉ ΠΊΠΎΠ»ΠΎΠ½Π½Π΅: Ρ‡Π°ΡΡ‚ΡŒ элСмСнтов двиТСтся Π½Π°Π»Π΅Π²ΠΎ, Ρ‡Π°ΡΡ‚ΡŒ β€” Π½Π°ΠΏΡ€Π°Π²ΠΎ.

Анимация ΠΎΠΊΠ½Π° с Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Π°ΠΌΠΈ

НаТмитС Rerun, Ρ‡Ρ‚ΠΎΠ±Ρ‹ воспроизвСсти Π°Π½ΠΈΠΌΠ°Ρ†ΠΈΡŽ.

Π― Ρ…ΠΎΡ‚Π΅Π» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ для этого ΠΎΠΊΠ½Π° эффСкт ΠΆΠ΅Π»Π΅, ΠΈ ΠΎΠ½ занял лишь нСсколько строк:

			var resultTimeline = new TimelineMax();
resultTimeline
      .fromTo('.stop-game .score-container', 0.7, { opacity: 0, scale: 0.3 }, { opacity: 1, scale: 1, ease: Elastic.easeOut.config(1.25, 0.5)})
      .fromTo('.stop-game .final-score', 2, { scale: 0.5 }, { scale: 1, ease: Elastic.easeOut.config(2, 0.5)}, 0)
      .fromTo('.stop-game .result', 1, { scale: 0.5 }, { scale: 1, ease: Elastic.easeOut.config(1.5, 0.5)}, 0.3)
      ;
		

Для создания Ρ‚Π°ΠΊΠΎΠ³ΠΎ эластичного эффСкта Π½ΡƒΠΆΠ½ΠΎ всСго лишь Π·Π°Π΄Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ ΠΏΠ»Π°Π²Π½ΠΎΡΡ‚ΡŒ. Π§Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΡΡ‰ΡƒΡŽ ΠΏΠ»Π°Π²Π½ΠΎΡΡ‚ΡŒ, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ этим инструмСнтом: Π²Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅Β Elastic ΠΈ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚Π΅ΡΡŒ с ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Π°ΠΌΠΈ.

Flexbox

ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ ΠΆΠ΅, я использовал Flexbox. (ΠšΡΡ‚Π°Ρ‚ΠΈ, совсСм Π½Π΅Π΄Π°Π²Π½ΠΎ Π΅Π³ΠΎ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ стал ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ Bootstrap.) Для Ρ‚Π΅Ρ…, ΠΊΡ‚ΠΎ Π½Π΅ Π·Π½Π°ΠΊΠΎΠΌ с Π½ΠΈΠΌ, Π΅ΡΡ‚ΡŒ отличная вводная ΡΡ‚Π°Ρ‚ΡŒΡ. Как Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π²Ρ‹ Π½Π°Ρ‡Π½Ρ‘Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Flexbox, Π²Ρ‹ Π½Π΅ смоТСтС ΠΆΠΈΡ‚ΡŒ Π±Π΅Π· Π½Π΅Π³ΠΎ. Π˜Ρ‚Π°ΠΊ, взглянСм Π½Π° экран Π³Π»Π°Π²Π½ΠΎΠ³ΠΎ мСню ΠΈ самой ΠΈΠ³Ρ€Ρ‹.

ΠšΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ β€œStart Game” задаётся ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΊΠΎΠ΄ΠΎΠΌ:

			{
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
}
		

flex-direction: columnΒ Π·Π°Π΄Π°Ρ‘Ρ‚ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ элСмСнты Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‚ΡΡ Π² ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π΅. Π—Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ (row) размСстил Π±Ρ‹ ΠΈΡ… Π² ряд слСва Π½Π°ΠΏΡ€Π°Π²ΠΎ. Π—Π°Ρ‚Π΅ΠΌ ΠΈΠ΄Ρ‘Ρ‚Β justify-content. Он распрСдСляСт свободноС мСсто, ΠΈ ΠΌΡ‹ ΠΌΠΎΠΆΠ΅ΠΌ Π²Ρ‹Π±Ρ€Π°Ρ‚ΡŒ, Ρ…ΠΎΡ‚ΠΈΠΌ Π»ΠΈ ΠΌΡ‹ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠΈ слСва, справа ΠΈΠ»ΠΈ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π²ΠΎΠΊΡ€ΡƒΠ³ всСго элСмСнта. ΠœΡ‹ устанавливаСм Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅Β space-between, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ΄Π½ΠΈΠΌΠ°Π΅Ρ‚ β€œTop” Π½Π°Π²Π΅Ρ€Ρ…, β€œHow to Play” Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°Π΅Ρ‚ Π²Π½ΠΈΠ·Ρƒ, Π° β€œLogo Holder” β€” Π² Ρ†Π΅Π½Ρ‚Ρ€Π΅ (всё свободноС пространство располоТСно ΠΌΠ΅ΠΆΠ΄Ρƒ этими элСмСнтами).Β align-items: centerΒ Ρ†Π΅Π½Ρ‚Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ элСмСнты ΠΎΡ‚Π½ΠΎΡΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π³ΠΎΡ€ΠΈΠ·ΠΎΠ½Ρ‚Π°Π»ΡŒΠ½ΠΎΠΉ оси.

β€œHow to Play” β€” это Π³ΠΈΠ±ΠΊΠΈΠΉ элСмСнт:

			{
    display: flex;
    width: 100%;
}
		

ΠœΡ‹ Π½Π΅ Π·Π°Π΄Π°Ρ‘ΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅, поэтому Ρ‚Ρ€ΠΈ сСкции Ρ€Π°Π·ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π² ΠΎΠ΄ΠΈΠ½ ряд. Π£ сСкций 1 ΠΈ 3 ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ β€œflex” установлСн Π² 1, поэтому ΠΎΠ½ΠΈ Π·Π°Π½ΠΈΠΌΠ°ΡŽΡ‚ всё свободноС мСсто. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ Π±Ρ‹Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΒ justify-content: space-aroundΒ Π² элСмСнтС β€œHow to Play”, Π½ΠΎ я Ρ…ΠΎΡ‚Π΅Π», Ρ‡Ρ‚ΠΎΠ±Ρ‹ сСкция 2 Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°Π»Π°ΡΡŒ строго ΠΏΠΎ Ρ†Π΅Π½Ρ‚Ρ€Ρƒ.

Π­Ρ‚ΠΎ сцСна ΠΈΠ³Ρ€Ρ‹, со свойством display: flex. Π’ Π½Π΅ΠΉ Π΅ΡΡ‚ΡŒ Π΄Π²Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°. Π― Π½Π΅ Ρ…ΠΎΡ‚Π΅Π» Π΄Π΅Π»Π°Ρ‚ΡŒ располоТСниС мяча Π°Π±ΡΠΎΠ»ΡŽΡ‚Π½Ρ‹ΠΌ, я Ρ…ΠΎΡ‚Π΅Π», Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π±Ρ‹Π» Ρ€ΠΎΠ²Π½ΠΎ Π½Π°Π΄ ΠΊΠΎΠ»ΠΎΠ½Π½Π°ΠΌΠΈ, ΠΈ я стрСмился ΠΏΡ€ΠΈΠ΄ΡƒΠΌΠ°Ρ‚ΡŒ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π½Π° CSS, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Π»ΠΎ, Π΄Π°ΠΆΠ΅ Ссли я помСняю высоту ΠΊΠΎΠ»ΠΎΠ½Π½. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ свойство flex-direction ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° Ρ€Π°Π²Π½ΠΎ column, ΠΈ это ΠΈΠΌΠ΅Π½Π½ΠΎ Ρ‚ΠΎ, Ρ‡Ρ‚ΠΎ Π½ΡƒΠΆΠ½ΠΎ. justify-content: space-betweenΒ ΠΏΠΎΠ΄Π½ΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ с мячом Π½Π°Π²Π΅Ρ€Ρ…, Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ с ΠΊΠΎΠ»ΠΎΠ½Π½Π°ΠΌΠΈ закрСпляСт Π²Π½ΠΈΠ·Ρƒ. Π’Π΅ΠΏΠ΅Ρ€ΡŒ ΠΏΡ€ΠΈΠΌΠ΅Π½ΠΈΠΌ ΠΊ Π²Π΅Ρ€Ρ…Π½Π΅ΠΌΡƒ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Ρƒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ свойства:

			{
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
		

Он Ρ‚ΠΎΠΆΠ΅ становится Π³ΠΈΠ±ΠΊΠΈΠΌ, ΠΌΡ‹ Π΄Π΅Π»Π°Π΅ΠΌ Π²Π΅Ρ€Ρ‚ΠΈΠΊΠ°Π»ΡŒΠ½ΡƒΡŽ ось Π³Π»Π°Π²Π½ΠΎΠΉ ΠΈ Π·Π°Ρ‚Π΅ΠΌ Π΄Π²ΠΈΠ³Π°Π΅ΠΌ содСрТимоС ΠΊ ΠΊΠΎΠ½Ρ†Ρƒ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈΒ justify-content: flex-end, поэтому мяч опускаСтся Π²Π½ΠΈΠ·.

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅ сСбС Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ всСго этого Π±Π΅Π· Flexbox ?

Π”Π΅Π»Π°Π΅ΠΌ ΠΈΠ³Ρ€Ρƒ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΠΉ

Π’ΠΎΡ‚ Ρ‡Ρ‚ΠΎ Π±Ρ‹Π»ΠΎ ΠΏΠΎ-настоящСму слоТным. ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅, ΠΊΠ°ΠΊ Ρ…ΠΎΡ€ΠΎΡˆΠΎ ΠΈΠ³Ρ€Π° смотрится Π½Π° экранах с Ρ€Π°Π·Π½Ρ‹ΠΌ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ΠΌ. Для Π΅Π³ΠΎ я просто использовал CSS-трансформации. ПолоТим Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ Ρ€Π°Π²Π½Ρ‹ΠΌ 1200x800px. Π—Π°Ρ‚Π΅ΠΌ, Ссли ваш экран отличаСтся ΠΏΠΎ Ρ€Π°Π·Ρ€Π΅ΡˆΠ΅Π½ΠΈΡŽ, ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ ΠΈΠ³Ρ€Ρ‹ Π½ΡƒΠΆΠ½ΠΎ ΠΎΡ‚ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΈ ΠΏΠΎΠΌΠΎΡ‰ΠΈ коэффициСнта screenHeight / 800. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, Π½ΡƒΠΆΠ½ΠΎ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ΠΈ ΠΏΠΎΡ€Ρ‚Ρ€Π΅Ρ‚Π½ΠΎΠ΅ располоТСниС устройства. Π’ΠΎΡ‚ Π½ΡƒΠΆΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄:

			var scale = (screenWidth > screenHeight) ? screenHeight/800 : screenWidth/1200;
		

Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, выглядит это ΠΏΠΎΠΊΠ° Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΎΡ‡Π΅Π½ΡŒ. ΠžΠΊΠ½ΠΎΒ Π²Ρ‹Π³Π»ΡΠ΄ΠΈΡ‚ ΠΎΡ‡Π΅Π½ΡŒ малСньким.

ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Π½Π° Ρ‚Π°ΠΊΠΎΠΉ ΠΆΠ΅ коэффициСнт, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ½ Π·Π°Π½ΠΈΠΌΠ°Π» вСсь экран. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ, Ссли ΠΌΡ‹ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠΌΒ Π΅Π³ΠΎ Π² Π΄Π²Π° Ρ€Π°Π·Π°, Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΡ‚ΡŒ Π² Π΄Π²Π° Ρ€Π°Π·Π° Π΅Π³ΠΎ исходный Ρ€Π°Π·ΠΌΠ΅Ρ€, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ стал стал Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒ вСсь экран. А ΠΌΠΎΠΆΠ΅Ρ‚, экран слишком Π²Π΅Π»ΠΈΠΊ, ΠΈ Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΡƒΠΌΠ΅Π½ΡŒΡˆΠΈΡ‚ΡŒ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π² 1.2 Ρ€Π°Π·Π°. Π’ ΠΎΠ±Ρ‰Π΅ΠΌ, Π²ΠΎΡ‚ Π½ΡƒΠΆΠ½Ρ‹ΠΉ ΠΊΠΎΠ΄:

			$('.container')
        .css('transform', 'scale(' + this.scale + ')')
        .css('height', height/this.scale)
        .css('width', width/this.scale)
        .css('transformOrigin', 'left top');
		
Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡƒΠ΅ΠΌ