Эффект маски для изображений
Эффекты, реализованные на базе CSS трансформаций.
Структура
HTML структура будет состоять из списка <section>
, обёрнутого в элемент .cd-image-mask-effect
. Каждый контейнер <section>
содержит div.featured-image
(изображение), div.mask
(маску) и div.cd-project-info
(контент).
<section class="project-1 cd-project-mask"> <h1>Project Name</h1> <div class="featured-image"></div> <div class="mask"> <img src="img/mask-01.png" alt="mask"> <span class="mask-border mask-border-top"></span> <span class="mask-border mask-border-bottom"></span> <span class="mask-border mask-border-left"></span> <span class="mask-border mask-border-right"></span> </div> <a href="#0" class="project-trigger">Explore Project</a> <a href="#0" class="cd-scroll cd-img-replace">Scroll down</a> <div class="cd-project-info" data-url="project-1"> <!-- content loaded using js --> </div> <a href="#0" class="project-close cd-img-replace">Close Project</a> </section> <!-- .cd-project-mask --> <section class="project-2 cd-project-mask"> <!-- content here --> </section> <!-- other sections here -->
Сам контент будет подгружаться через JavaScript.
Стили
Высота каждого элемента .cd-project-mask
равна 100vh, ширина 100%; изображение установлено как фон элемента .featured-image
, а маска помещена в элемент .mask
.
.cd-project-mask { position: relative; height: 100vh; width: 100%; overflow: hidden; } .cd-project-mask .featured-image { /* project intro image */ position: absolute; left: 50%; top: 50%; bottom: auto; right: auto; transform: translateX(-50%) translateY(-50%); height: 100%; width: 100%; background: url(../img/img-01.jpg) no-repeat center center; background-size: cover; } .cd-project-mask .mask { position: absolute; left: 50%; top: 50%; bottom: auto; right: auto; transform: translateX(-50%) translateY(-50%); width: 300px; height: 300px; } .cd-project-mask .mask .mask-border { /* this is used to create a frame around the mask */ position: absolute; } .cd-project-mask .mask .mask-border-top, .cd-project-mask .mask .mask-border-bottom { /* this is used to create a frame around the mask */ height: calc(50vh - 150px + 10px); width: 100vw; left: 50%; right: auto; transform: translateX(-50%); } .cd-project-mask .mask .mask-border-top { bottom: calc(100% - 10px); } .cd-project-mask .mask .mask-border-bottom { top: calc(100% - 10px); } .cd-project-mask .mask .mask-border-left, .cd-project-mask .mask .mask-border-right { /* this is used to create a frame around the mask */ height: 100vh; width: calc(50vw - 150px + 10px); top: 50%; bottom: auto; transform: translateY(-50%); } .cd-project-mask .mask .mask-border-left { left: calc(100% - 10px); } .cd-project-mask .mask .mask-border-right { right: calc(100% - 10px); }
При выборе проекта будет добавлен класс .project-view
(к элементу с классом .cd-image-mask-effect
).
.project-view .cd-project-mask:not(.project-selected) { /* the project-view class is added to the .cd-image-mask-effect element when a project is selected - hide all not selected projects */ position: absolute; top: 0; left: 0; opacity: 0; visibility: hidden; }
Обработка событий
Сам эффект реализован в объекте ProjectMask
. В методе initProject
прописываем обработчики прослушиваемых событий.
function ProjectMask( element ) { this.element = element; this.projectTrigger = this.element.find('.project-trigger'); this.projectClose = this.element.find('.project-close'); this.projectTitle = this.element.find('h1'); this.projectMask = this.element.find('.mask'); //... this.initProject(); } var revealingProjects = $('.cd-project-mask'); var objProjectMasks = []; if( revealingProjects.length > 0 ) { revealingProjects.each(function(){ //create ProjectMask objects objProjectMasks.push(new ProjectMask($(this))); }); }
При выборе проекта, вызов метода revealProject
увеличит маску изображения, а вызов метода uploadContent
загрузит нужный контент.
ProjectMask.prototype.initProject = function() { var self = this; //open the project this.projectTrigger.on('click', function(event){ event.preventDefault(); if( !self.animating ) { self.animating = true; //upload project content self.uploadContent(); //show project content and scale up mask self.revealProject(); } }); //... }; ProjectMask.prototype.revealProject = function() { var self = this; //get mask scale value self.updateMaskScale(); //scale up mask and animate project title self.projectTitle.attr('style', 'opacity: 0;'); self.projectMask.css('transform', 'translateX(-50%) translateY(-50%) scale('+self.maskScaleValue+')').one(transitionEnd, function(){ self.element.addClass('center-title'); self.projectTitle.attr('style', ''); self.animating = false; }); //hide the other sections self.element.addClass('project-selected content-visible').parent('.cd-image-mask-effect').addClass('project-view'); } ProjectMask.prototype.uploadContent = function(){ var self = this; //if content has not been loaded -> load it if( self.projectContent.find('.content-wrapper').length == 0 ) self.projectContent.load(self.projectContentUrl+'.html .cd-project-info > *'); if( self.projectContentUrl+'.html'!=window.location ){ //add the new page to the window.history window.history.pushState({path: self.projectContentUrl+'.html'},'',self.projectContentUrl+'.html'); } }
Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: https://codyhouse.co/gem/image-mask-effect/
Перевел: Станислав Протасевич
Урок создан: 8 Марта 2017
Просмотров: 5308
Правила перепечатки
5 последних уроков рубрики "CSS"
-
Забавные эффекты для букв
Небольшой эффект с интерактивной анимацией букв.
-
Реализация забавных подсказок
Небольшой концепт забавных подсказок, которые реализованы на SVG и anime.js. Помимо особого стиля в примере реализована анимация и трансформация графических объектов.
-
Анимированные буквы
Эксперимент: анимированные SVG буквы на базе библиотеки anime.js.
-
Солнцезащитные очки от первого лица
Прикольный эксперимент веб страницы отображение которой осуществляется “от первого лица” через солнцезащитные очки.
-
Раскрывающаяся навигация
Экспериментальный скрипт раскрывающейся навигации.