Кнопка в виде ЛОДКИ

Кнопка в виде ЛОДКИ

Просто дурь на CSS. Разок можно.

Сегодня мы абсолютно низачем сделаем кнопку, которая при нажатии превращается в лодку и уплывает. 

Зачем? Да низачем. Просто так.

Кнопка в виде ЛОДКИ

Готовим страницу

Логика проекта будет такой:

  1. Создаём страницу и подключаем к ней скрипт и CSS-стили.
  2. На этой странице делаем общий контейнер, куда сложим всю будущую анимацию и кнопку.
  3. В этот контейнер кладём все детали корабля, пока невидимые.

При загрузке страницы кнопка отрисуется так, как будет написано у нас в стилях. Потом, при нажатии, мы трансформируем кнопку в корабль с помощью скрипта, а потом отправим её уплывать за границу экрана.

Запишем всё это в виде кода.

<!DOCTYPE html>
<html lang="ru" >
<head>
  <meta charset="UTF-8">
  <title>Кнопка-путешественник</title>
  <!-- подключаем стили -->
  <link rel="stylesheet" href="style.css">
</head>
<body>
	<!-- основной контейнер -->
	<div id="container">
		<!-- блок с будущим корабликом -->
		<!-- сначала идёт мачта -->
		<div id="mast">
			<!-- паруса, которые на старте лежат в сложенном виде -->
			<div id="sail-1"></div>
			<div id="sail-2"></div>
		</div>
		<!-- кнопка, на которую нажимаем -->
		<button type="button" id="buttoun">Подтвердите заказ</button>
	</div>

	<!-- рабочий скрипт -->
  <script  src="./script.js"></script>
</body>
</html>

Задаём стили

В стилях будет хитрость: мы заранее нарисуем все элементы лодки, но они все будут спрятаны за нарисованной кнопкой. В нужный момент мы просто добавим свойство трансформации к мачте, парусам и самой кнопке, чтобы превратить всё в корабль.

Единственное новое свойство, которое мы будем здесь использовать — transform: translate. Оно трансформирует элемент так, как прописано в параметрах — поворачивает, уменьшает масштаб и так далее. Мы сразу рисуем элементы на своих местах, как они должны быть, а потом трансформируем, чтобы они спрятались за кнопку.

/* общие настройки для всей страницы */
body,
html {
	height: 100%;
	width: 100%;
	overflow: hidden;
	display: grid;
	background: rgb(238, 174, 202);
	background: linear-gradient(
		30deg,
		rgba(238, 174, 202, 1) 0%,
		rgba(148, 187, 233, 1) 100%
	);
}

/* настройки основного блока */
#container {
	width: 300px;
	height: 300px;
	margin: 0 auto;
	display: flex;
	transform: translatex(0px);
	transition: all 4.5s;
}

/* настоящая кнопка, которую мы нажимаем */
button {
	justify-self: center;
	align-self: flex-end;
}

/* убираем внешнюю границу настоящей кнопки, когда она в фокусе */
button:focus {
	outline: none;
}

/* как бы кнопка, которая будет превращаться в корабль */
/* за этой нарисованной поверх всего кнопкой и будет прятаться остальное */
#buttoun {
	width: 300px;
	height: 100px;
	border-radius: 10px 10px 10px 10px;
	border: none;
	background-color: rgb(100, 100, 200);
	z-index: 1;
	transition: all 1s;
	font-size: 19px;
	color: white;

}

/* мачта */
#mast {
	width: 12px;
	height: 160px;
	transform-origin: bottom;
	transform: translate(170px, 48px) rotatez(-90deg);
	background-color: rgb(100, 100, 200);
	transition: all 1s;
}

/* парус */
#sail-1 {
	width: 0;
	height: 0;
	border-bottom: 145px solid white;
	border-right: 60px solid transparent;
	transform-origin: bottom;
	transform: translatex(16px) scaley(0.001);
	transition: all 1s;
}

/* второй парус */
#sail-2 {
	width: 0;
	height: 0;
	border-bottom: 145px solid white;
	border-left: 100px solid transparent;
	transform-origin: bottom;
	transform: translate(-104px, -145px) scaley(0.001);
	transition: all 1s;
}

Пишем скрипт

Скрипт будет состоять из трёх частей:

  1. Получаем доступ ко всем элементам страницы по их ID — благодаря этому мы сможем менять их свойства и добавлять новые CSS-команды.
  2. Добавляем обработчик нажатия на кнопку.
  3. При нажатии последовательно поднимаем мачту, паруса, а затем отплываем.

👉 Чтобы добавить элементу новый CSS-стиль, используем свойство объекта .style.setProperty, в котором прописываем сначала название свойства, а потом его значение. Как только у элемента появляется свойство, которое меняет его внешний вид, оно меняется не мгновенно, а с заранее заданной скоростью анимации. Это и даёт картинке плавный и красивый эффект.

// получаем доступ ко всем элементам внутри страницы по их ID
const container = document.getElementById("container");
const buttoun = document.getElementById("buttoun");
const mast = document.getElementById("mast");
const sail1 = document.getElementById("sail-1");
const sail2 = document.getElementById("sail-2");

// отслеживаем нажатие на кнопку
// при нажатии запустится функция sail()
buttoun.addEventListener("click", sail);

// подготовка к отплытию — функция, которая сработает по нажатию кнопки
function sail() {
	// выводим надпись
	buttoun.innerText = 'Счастливого пути!'
	// превращаем кнопку в лодку
	buttoun.style.setProperty("border-radius", "10px 10px 100px 100px");
	// поднимаем мачту
	mast.style.setProperty("transform", " translate(170px, 48px) rotatez(-0deg)");
	// отдаём команду «Поднять паруса»
	setTimeout(hoist, 500);
}

// Поднимаем паруса
function hoist() {
	// поднимаем паруса
	sail1.style.setProperty("transform", "translatex(16px) scaley(1)");
	sail2.style.setProperty("transform", "translate(-104px, -145px) scaley(1)");
	// отдаём команду на отплытие
	setTimeout(sailaway, 1000);
}

// уплываем за экран
function sailaway() {
	// движемся на 150 пикселей правее правой границы экрана
	container.style.setProperty("transform", "translatex(calc(100vw - 150px)");
}

Что дальше

В следующий раз используем команду transform поплотнее — сделаем проект, в котором можно управлять с помощью стрелок клавиатуры любым элементом на странице на чистом CSS. Подпишитесь, чтобы не пропустить новые проекты.

Текст:

Михаил Полянин

Редактура:

Максим Ильяхов

Художник:

Даня Берковский

Корректор:

Ирина Михеева

Вёрстка:

Мария Дронова

Соцсети:

Олег Вешкурцев

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства и компенсация, если вы пойдёте работать в «Яндекс».
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Делаем своё расширение для браузера за 10 минут
Делаем своё расширение для браузера за 10 минут

Cнова запускаем снежинки.

Как подключить фотогалерею к сайту
Как подключить фотогалерею к сайту

Рецепт на 6 минут.

ООП: атрибуты и методы
ООП: атрибуты и методы

Два главных слова любого программиста в ООП. Знай их, люби их, говори правильно.

Шифр Вернама на JavaScript
Шифр Вернама на JavaScript

Невзламываемый шифр за 4 строчки кода.

Добавляем секретный уровень в пинг-понг на JavaScript
Добавляем секретный уровень в пинг-понг на JavaScript

Мини-проект для тех, кому всё ещё просто.

$ is not defined в jQuery: что это значит и что делать
Убираем спагетти-код

Два подхода к упорядочиванию хаоса.

Что означает ошибка SyntaxError: missing : after property id
Что означает ошибка SyntaxError: missing : after property id

Используйте двоеточие, если хотите обратиться к свойству объекта.

Пианино на JavaScript для Chrome
Пианино на JavaScript для Chrome

Не «Мир Дикого запада», но тоже сгодится.

Ещё больше полезных CSS-команд
Ещё больше полезных CSS-команд

Короткие и мощные.

Пишем код: как поменять местами значения переменных
Пишем код: как поменять местами значения переменных

Что делать, если третью переменную использовать нельзя.

Делаем страницу «О себе» на Бутстрапе

Если ты можешь сделать страницу о себе, ты можешь сделать всё.

Что означает ошибка IndexError: list index out of range
Что означает ошибка IndexError: list index out of range

Многогранная ошибка с коварным поведением.

easy