Как реализовать увеличение картинки при наведении курсора CSS

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

В этой статье рассказывается о том как реализовать увеличение картинки при наведении курсора CSS и JavaScript без использования библиотеки jQuery.

HTML

<div class="container-fluid">
	<div class="row">
		<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12" id="samples">
			<img id="zoom1" src="pic1.jpg" width="100px" height="250px">
			<img id="zoom2" src="pic2.jpg" width="100px" height="250px">
		</div>
		<div class="col-lg-9 col-md-9 col-sm-9 col-xs-12">
			<div id="preview"></div>
		</div>
	</div>
</div>

HTML-код довольно простой: строка разделена на два столбца. Первый из них содержит два изображения, превью которых будет выводиться. Второй содержит div с идентификатором 'preview', который будет отображать превью. Оба изображения имеют одинаковую ширину и высоту.

CSS

Для preview div него задан определенный размер, границы и отступы. Свойство background-repeat: no-repeat гарантирует, что фоновое изображение не будет повторяться. margin-left: auto и margin-right: auto выравнивают этот div по центру относительно родительского элемента.

CSS

#preview{
	margin-top: 10px;
	border:1px solid black;
	width:350px;
	height:500px;
	background-repeat: no-repeat;
	margin-left: auto;
	margin-right: auto;
}

Для изображений задано свойство display: block, чтобы они не выводились рядом друг с другом. Для родительского div задано свойство text-align: center, чтобы выровнять изображения по центру. При наведении на изображения курсор мыши меняется на иконку лупы с минусом.

В медиа запросе я задал значение display: inline-block, чтобы отображать оба изображения в одной строке, если ширина экрана меньше или равна 767 пикселям.

CSS

#preview{
	margin-top: 10px;
	border:1px solid black;
	width:350px;
	height:500px;
	background-repeat: no-repeat;
	margin-left: auto;
	margin-right: auto;
}
#samples{
	text-align: center;
}
#samples img {	
	margin: 10px;
	display: block;
	 border: 2px solid #6A6462;
}
#samples img:hover {
	 cursor: zoom-in;
	 border: 0;
	 -moz-box-shadow:2px 2px 7px 2px rgba(130,130,130,1),-1px -1px 7px 2px rgba(130,130,130,1);
	-webkit-box-shadow: 2px 2px 7px 2px rgba(130,130,130,.7),-1px -1px 7px 2px rgba(130,130,130,1);
	box-shadow: 2px 2px 7px 2px rgba(130,130,130,.7),-2px -2px 7px 2px rgba(130,130,130,1);
}
@media screen and (max-width: 767px){
	#samples img {
		display: inline-block;
	}
}

JavaScript

С помощью JavaScript реализован ключевой код, благодаря которому работает превью. Разделим его написание на шаги.

Шаг 1

Сначала используются функции 'zoomIn' и 'zoomOut', чтобы увеличивать и уменьшать изображения. Данные функции определены в JavaScript. Я подключил к этим двум функциям два события – onmousemove и onmouseout соответственно.

HTML

<div class="container-fluid">
	<div class="row">
		<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12" id="samples">
			<img id="zoom1" width="100px" height="250px" onmousemove="zoomIn(event)" onmouseout="zoomOut()" src="pic1.jpg">
			<img id="zoom2" width="100px" height="250px" onmousemove="zoomIn(event)" onmouseout="zoomOut()" src="pic2.jpg">
		</div>
		<div class="col-lg-9 col-md-9 col-sm-9 col-xs-12">
			<div id="preview" onmousemove="zoomIn(event)"></div>
		</div>
	</div>
</div>

Шаг 2

Начнем с функции zoomOut. Я записал div с id 'preview' в переменную pre и установил visibility hidden.

Шаг 3

В функции zoomIn задано visibility visible. Всякий раз, когда курсор мыши перемещается по изображениям, будет виден div с превью. В остальных случаях он будет скрыт.

Условие $('#zoom1').is(':hover') проверяет, находится ли курсор мыши над первым изображением (с идентификатором 'zoom1'). Если условие истинно (true), то первое изображение устанавливается в качестве фонового изображения для div с id preview. Таким образом, каждый раз, когда вы наводите курсор мыши на первое изображение, div становится видимым с первым изображением в качестве фона. То же самое относится и ко второму изображению.

Как изображение увеличивается в div preview?

Я установил для изображения ширину и высоту 100px и 250px. Но его реальные размеры гораздо больше. Так как я не установил это же ограничение размера для фонового изображения div preview, то оно принимает его полную ширину и высоту. Ширина и высота этого блока меньше ширины фонового изображения. Поэтому оно не полностью покрывает весь div и создает ощущение, будто изображение увеличивается.

JavaScript

function zoomIn(event) {
  var pre = document.getElementById("preview");
  pre.style.visibility = "visible";
  if ($('#zoom1').is(':hover')) {
        var img = document.getElementById("zoom1");
		pre.style.backgroundImage = "url('pic1.jpg')";
    }
  if ($('#zoom2').is(':hover')){
		var img = document.getElementById("zoom2");
		pre.style.backgroundImage = "url('pic2.jpg')";
  } 

}

function zoomOut() {
  var pre = document.getElementById("preview");
  pre.style.visibility = "hidden";
}

Шаг 4

Оператор var posX = event.offsetX присваивает значение координаты X позиции курсора мыши относительно изображения, на котором мышь перемещается в var posX. Аналогично, posY сохраняет значение координаты Y.

Положение фонового изображения div с id= preview определяется оператором pre.style.backgroundPosition=(-posX*2.5)+"px "+(-posY*5.5)+"px".

Я использовал отрицательные значения posX и posY, чтобы фон изображения превью перемещался в направлении, противоположном движению курсора мыши.

Кроме этого, некоторые числа умножаются на posX и posY, чтобы можно было видеть изображение превью полностью при движении курсора.

Ниже представлена полная версия исходного кода анимации.

HTML

<div class="container-fluid">
	<div class="row">
		<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12" id="samples">
			<img id="zoom1" width="100px" height="250px" onmousemove="zoomIn(event)" onmouseout="zoomOut()" src="pic1.jpg">
			<img id="zoom2" width="100px" height="250px" onmousemove="zoomIn(event)" onmouseout="zoomOut()" src="pic2.jpg">
		</div>
		<div class="col-lg-9 col-md-9 col-sm-9 col-xs-12">
			<div id="preview" onmousemove="zoomIn(event)"></div>
		</div>
	</div>
</div>

CSS

#preview{
	margin-top: 10px;
	border:1px solid black;
	width:350px;
	height:500px;
	background-repeat: no-repeat;
	margin-left: auto;
	margin-right: auto;
}
#samples{
	text-align: center;
}
#samples img {	
	margin: 10px;
	display: block;
	 border: 2px solid #6A6462;
}
#samples img:hover {
	 cursor: zoom-in;
	 border: 0;
	 -moz-box-shadow:2px 2px 7px 2px rgba(130,130,130,1),-1px -1px 7px 2px rgba(130,130,130,1);
	-webkit-box-shadow: 2px 2px 7px 2px rgba(130,130,130,.7),-1px -1px 7px 2px rgba(130,130,130,1);
	box-shadow: 2px 2px 7px 2px rgba(130,130,130,.7),-2px -2px 7px 2px rgba(130,130,130,1);
}
@media screen and (max-width: 767px){
	#samples img {
		display: inline-block;
	}
}

JavaScript

function zoomIn(event) {
  var pre = document.getElementById("preview");
  pre.style.visibility = "visible";
  if ($('#zoom1').is(':hover')) {
        var img = document.getElementById("zoom1");
		pre.style.backgroundImage = "url('pic1.jpg')";
    }
  if ($('#zoom2').is(':hover')){
		var img = document.getElementById("zoom2");
		pre.style.backgroundImage = "url('pic2.jpg')";
  } 
  var posX = event.offsetX;
  var posY = event.offsetY;
  pre.style.backgroundPosition=(-posX*2.5)+"px "+(-posY*5.5)+"px";

}

function zoomOut() {
  var pre = document.getElementById("preview");
  pre.style.visibility = "hidden";
}

Ангелина Писанюкавтор-переводчик статьи «Mouse Rollover Zoom Effect on Images»