Чтобы привлечь внимание пользователей к определенным элементам сайта разработчики используют различные интерактивные эффекты. В этом уроке создадим многослойный баннер с параллакс эффектом. В последнее время такие баннеры стали весьма популярны, так как они взаимодействуют с пользователем. Для создания такого баннера не требуется владение технологией flash разработки. Для реализации нам потребуется подключить две js библиотеки, написать html разметку и добавить css стили. Кроме того необходимо подготовить изображения для баннера. Этого будет достаточно для создания эффекта параллакс, чтобы получить отзывчивый и анимированный баннер.
Наш баннер будет иметь несколько слоев с изображениями. Каждый слой будет реагировать на движение мыши, и создавать эффект 3D параллакса.
Для начала подключим к проекту библиотеки jQuery и Knockout:
<script src="/article/19/resources/js/jquery-3.3.1.min.js"></script>
<script src="/article/19/resources/js/knockout-min.js"></script>
Затем необходимо подготовить нужные изображения, которые будут распределены по слоям. Следует выбирать изображения в формате png с прозрачным фоном. Наш баннер на тему Star Wars будет иметь 12 изображений. Для этих изображений зададим html разметку:
<div class="banner">
<div id="parallxWrapper">
<div class="parallxBackground" data-bind="attr: { style:'-webkit-transform:perspective(1000px) rotateY(' + relativeMouse.x() + 'deg) rotateX(' + relativeMouse.y() + 'deg);transform:perspective(1000px) rotateY(' + relativeMouse.x() + 'deg) rotateX(' + relativeMouse.y() + 'deg)' }">
<div class="parallxLayerKreiser"></div>
<div class="parallxLayerJedi"></div>
<div class="parallxLayerKylo"></div>
<div class="parallxLayerStorm"></div>
<div class="parallxLayerFire1"></div>
<div class="parallxLayerFire2"></div>
<div class="parallxLayerDron"></div>
<div class="parallxLayerClone1"></div>
<div class="parallxLayerClone2"></div>
<div class="parallxLayerIoda"></div>
<div class="parallxLayerR2d2"></div>
<div class="parallxLayerStarWars"></div>
</div>
</div>
</div>
С помощью css стилей зададим параметры наложения изображений для каждого слоя. За это отвечает параметр transform: translateZ(50px), который будет позиционировать изображения по разным слоям. Параметры top и left будут позиционировать изображения от края баннера.
#parallxWrapper {
margin: auto;
height: 540px;
width: 1000px;
}
.parallxBackground {
height: 100%;
background-image: url("fon.png");
border-radius: 10px 0px 0px 0px;
padding: 10px;
-webkit-transform-style: preserve-3d;
transform-style: preserve-3d;
}
.parallxLayerJedi {
width: 460px;
height: 439px;
background-image: url("jedi.png");
background-repeat: no-repeat;
top: 210px;
left: 410px;
position: absolute;
-webkit-transform: translateZ(90px);
-webkit-transition: all 0.2s;
transform: translateZ(90px);
transition: all 0.2s;
}
.parallxLayer:hover {
-webkit-transform: scale(1.05);
-webkit-transform: translateZ(30px);
transform: scale(1.05);
transform: translateZ(30px);
cursor: pointer;
}
.parallxLayerKreiser {
width: 1010px;
height: 620px;
top: -2px;
left: -3px;
float: right;
border-radius: 0px 10px 0px 0px;
background-image: url("kreiser.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(20px);
transform: translateZ(20px);
}
.parallxLayerClone1 {
width: 150px;
height: 150px;
left: 148px;
top: 430px;
float: right;
background-image: url("clone1.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(38px);
transform: translateZ(38px);
}
.parallxLayerClone2 {
width: 124px;
height: 200px;
left: 26px;
top: 428px;
float: right;
background-image: url("clone2.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(38px);
transform: translateZ(38px);
}
.parallxLayerKylo {
width: 1024px;
height: 245px;
float: right;
top: 374px;
left: -10px;
border-radius: 0px 0px 10px 10px;
background-image: url("kylo.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(38px);
transform: translateZ(38px);
}
.parallxLayerStorm {
width: 180px;
height: 111px;
top: 40px;
float: right;
left: 720px;
background-image: url("storm.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(38px);
transform: translateZ(38px);
}
.parallxLayerFire1 {
width: 120px;
height: 120px;
margin-left: 0px;
margin-top: 100px;
float: right;
left: 600px;
background-image: url("fire.png");
background-size: contain;
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(38px);
transform: translateZ(38px);
}
.parallxLayerFire2 {
width: 180px;
height: 180px;
margin-left: 0px;
margin-top: 300px;
float: right;
left: 580px;
background-image: url("fire.png");
background-size: contain;
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(38px);
transform: translateZ(38px);
}
.parallxLayerDron {
width: 55px;
height: 80px;
left: 880px;
top: 300px;
float: right;
background-image: url("dron.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(30px);
transform: translateZ(30px);
}
.parallxLayerIoda {
width: 300px;
height: 300px;
float: right;
top: 150px;
left: 240px;
background-image: url("ioda.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(50px);
transform: translateZ(50px);
}
.parallxLayerR2d2 {
width: 144px;
height: 190px;
float: right;
top: 440px;
left: 290px;
background-image: url("r2d2.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(50px);
transform: translateZ(50px);
}
.parallxLayerStarWars {
width: 260px;
height: 118px;
float: right;
top: 40px;
left: 380px;
background-image: url("star_wars.png");
background-repeat: no-repeat;
position: absolute;
-webkit-transform: translateZ(60px);
transform: translateZ(60px);
}
Далее подготовим JavaScript код, в котором установим скорость в миллисекундах для каждого слоя, чтобы одни слои двигались быстрее, а другие медленнее. Также повесим событие на движение курсора:
var parallx = null;
var demoCount = 0;
function Parallx(){
var self = this;
$("body").mousemove(function(e){
parallax.mouseX(e.pageX);
parallax.mouseY(e.pageY);
});
self.sensitivityMultiplier = ko.observable(0.03);
self.wrapperOffset = $('#parallxWrapper').offset();
self.wrapperCenter = {
x:ko.computed(function(){ return self.wrapperOffset.left + ($('#parallxWrapper').width()/2) }, this),
y:ko.computed(function(){ return self.wrapperOffset.top + ($('#parallxWrapper').height()/2) }, this)
};
self.mouseX = ko.observable(0);
self.mouseY = ko.observable(0);
self.relativeMouse = {
x:ko.computed(function(){ return (self.mouseX() - self.wrapperCenter.x()) * self.sensitivityMultiplier() }, this),
y:ko.computed(function(){ return ((self.mouseY() - self.wrapperCenter.y()) * -1) * self.sensitivityMultiplier()}, this)
};
self.origin = {
x:ko.computed(function(){ return ((self.mouseX())/$(window).width()) * 100 }, this),
y:ko.computed(function(){ return ((self.mouseY())/$(window).height()) * 100 }, this)
};
};
$(document).ready(function(){
parallax = new Parallx();
ko.applyBindings(parallax);
setInterval(function(){
if(demoCount < 130){
parallax.mouseX(parallax.mouseX() + 10);
demoCount+=1;
}
}, 40);
});
Интерактивный баннер готов!