Алло! Ваш дизайнер ещё на месте? Нужно на нашем сайте сделать фон зеркальным, чтобы пользователь заходил и видел своё отражение


Если вы видели этот мем, то наверняка посмеялись над странными идеями заказчиков, и быть может, заинтересовались темой зеркального фона.
В принципе, зеркальный фон не так сложно реализовать, как может показаться. Давайте разбираться! Нам нужно:
Я не буду приводить весь код, опишу только важные моменты. Для начала возьмём два контейнера: первый будет зеркальным фоном, второй — телом документа.
<div class="video">
<video id="video" autoplay="autoplay" width="1920" height="1080"></video>
</div>
<div class="body">
<div class="body-content">
<h1>Сайт с зеркальным фоном</h1>
<p>Чтобы фон на сайте стал зеркальным, нам необходимо получить доступ к вашей веб-камере. Нажмите на кнопку в браузере, чтобы разрешить доступ.</p>
</div>
</div><div class="video"> будет у нас в качестве фона, а <div class="body"> — телом документа. Также мы добавляем тег <video> для загрузки самого видео и <div class="body-content"> в качестве контейнера содержимого сайта. Итак, HTML-разметка у нас есть. Возьмёмся за CSS.
<style>
body > div {
position: absolute;
width: 100%;
height: 100%;
}
.video {
z-index: 1;
}
.body {
z-index: 2;
}
video {
position: absolute;
width: 100%;
height: 100%;
}
</style>Что мы сделали? Во-первых, мы спозиционировали два родительских контейнера абсолютно и задали им стопроцентные ширину и высоту, чтобы оба контейнера занимали всё пространство документа. Далее мы выставили им очерёдность, контейнер с видео отправили назад, а тело документа — вперёд.
<script>
window.onload = function() {
var video = document.getElementById( 'video' );
var videoStreamUrl = false;
//navigator.getUserMedia (Для каждого браузера определяем правильный метод)
navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
//window.URL.createObjectURL (Для каждого браузера определяем правильный метод)
window.URL.createObjectURL = window.URL.createObjectURL || window.URL.webkitCreateObjectURL || window.URL.mozCreateObjectURL || window.URL.msCreateObjectURL;
//Запрашиваем разрешение на доступ к видео-потоку
navigator.getUserMedia( {
video : {
width : { ideal : window.width },
height : { ideal : window.height },
facingMode: "user"
}
}, function( stream ) {
//Разрешение от пользователя получено
//Получаем url поточного видео
videoStreamUrl = window.URL.createObjectURL( stream );
// устанавливаем как источник для video
video.src = videoStreamUrl;
}, function() {
console.log( 'Что-то не так с видео-потоком или пользователь запретил его использовать!' );
} );
};
</script>При загрузке страницы мы находим элемент video и записываем его в переменную. Далее необходимо получить метод getUserMedia объекта navigator — navigator.getUserMedia. Этот метод и делает всю работу за нас: просит у пользователя разрешение на использование веб-камеры, инциализирует её, управляет видео-потоком, и так далее. Мы всего лишь настраиваем его на вывод видео-потока в нужном месте.
На вход метод принимает объект MediaStreamConstraints, в котором есть всего два свойства: video и audio. Эти свойства принимают значения типа boolean или MediaStreamConstraints. Мы используем снова MediaStreamConstraints. Но на этот раз мы укажем уже необходимые параметры видео-потока. Нам нужны только ширина width : { ideal : window.width } — указываем идеальную ширину, равную ширине экрана, высота height : { ideal : window.height } — указываем идеальную высоту, равную высоте экрана, и facingMode: "user" на случай, если у пользователя 2 камеры — передняя и задняя (используем переднюю).
Второй параметр — это функция, в которой мы получаем объект видео-потока stream, который можем использовать в своих целях. Нам необходимо получить URL. Делаем это с помощью метода window.URL.createObjectURL( stream ) и передаём полученный URL-адрес в атрибут src нашего элемента video. Вот и всё! Больше нам ничего не нужно.
Если вы уже опробовали этот код в действии, то, наверняка, заметили, что фон получился не полностью зеркальный, а, скорее, анти-зеркальный — мы видим обратное отражение. Чтобы получить полное зеркало, нужно применить небольшую трансформацию… Добавим в CSS-стиль элемента video следующее свойство:
<style>
video {
transform: scale(-1, 1);
}
</style>Первый параметр отвечает за масштабирование по горизонтали, а второй — по вертикали. Таким образом мы отразим элемент по горизонтали и получим «настоящее зеркало».
Также вы могли заметить, что на некоторых устройствах наше «зеркало» занимает не весь экран, по сторонам видны пустые полосы. Это происходит из-за того, что веб-камера отдаёт видео-поток не в том разрешении, в котором мы видим окно браузера, а в том, в котором она способна его отдавать. А браузер, в свою очередь, пытается уместить в окне весь видео-поток. Давайте исправим эту ситуацию с помощью той же трансформации. Изменим свойство transform на следующее:
<style>
video {
transform: scale(-1.6, 1.6);
}
</style>Увеличив оба коэффициента, мы увеличим видео в браузере, и оно займёт больше места, чем занимало изначально. Вы можете «поиграться» с коэффициентами и выбрать подходящие для вашего конкретного случая.
Посмотреть на всё это вживую можно по этой ссылке.
На нашем сайте используются файлы cookies, которые делают его более удобным для каждого пользователя. Оставаясь на сайте, вы соглашаетесь с использованием файлов cookies. Некоторые файлы вы можете отключить в настройках своего браузера. Узнать, для чего именно необходимы файлы cookies, вы можете ознакомившись с политикой конфиденциальности.