Русский
Русский
English
Статистика
Реклама

Создание квадратизированной галереи проектов на JS v 2.0

Под квадратизированной галереей подразумевается галерея такого типаПод квадратизированной галереей подразумевается галерея такого типа

Это моя вторая статья на тему создания адаптивной галереи проектов на JS. На основе замечаний и комментариев к первой я постарался исправить некоторые ошибки и поработал над логикой и структурой кода. Для удобства добавил возможность просмотра галереи и полного кода в песочнице.

Цели и задачи

  • Создать js-класс ImgComponent, описывающий компонент картинки галереи и принимающий следующие аргументы: тип картинки - широкая, высокая, стандартная, ссылка на изображение, ссылка на проект.

  • Генерировать галерею в html.

  • Реализовать механизм показа/скрытия частей галереи. После полного показа галереи - кнопка должна скрываться.

  • При наведении на картинку поверх изображения должна накладываться подсказка - заголовок проекта и прочая информация.

  • По class.elem должен быть доступен корневой DOM элемент картинки.

В статье пошагово описываю все свои действия по каждому пункту. Для создания данной галереи вам понадобится базовое знание ООП в JS и grid в CSS.

Приступим к созданию

1.Создадим HTML-контейнер для галереи:

<div class="gallery"><!--Сюда будут интерпретироваться картинки--></div>

2. Пропишем CSS для галереи и картинок:

Стили для высокой, широкой и стандартной картинки:

.short_box {  width: 383px;  height: 337px;  background: #ffffff;}.high_box {  width: 383px;  height: 692px;  background: #ffffff;}.long_box {  width: 795px;  height: 337px;  background: #ffffff;  grid-column: 1/2;}

Стили для всех картинок:

.gallery > div {  border: 4px solid #BB70B3;  z-index: 10;  position: relative;  overflow: hidden;  cursor: pointer;}.gallery > div img {  z-index: -5;  width: 100%;  height: auto;  position: absolute;  left: 50%;   top: 50%;  transform: translate(-50%, -50%);}

Стили для контейнера галереи:

.gallery {  width: 805px;  display: grid;  grid-template-columns: repeat(2, 390px);  grid-gap: 20px;  margin: 0 auto;  justify-content: center;  margin-top: 50px;  margin-bottom: 50px;}

Стили для кнопки прокрутки:

.scroll_button {  width: 200%;  cursor: pointer;  grid-column: 1/2;  padding: 0 10px 0 10px;  position: relative;}

Стили для анимации при наведении на кнопку:

@keyframes scroll_move {  0% {    top: 0;  }  100% {    top: 12px;  }}  .scroll_button:hover {  animation-name: scroll_move;  animation-duration: 0.5s;  animation-iteration-count: infinite;  animation-timing-function: ease-out;  animation-direction: alternate;}

Стили для анимации подсказки при наведении на картинку - маска, заголовок, текст

.mask {  width: 100%;  height: 100%;  background: rgba(176, 155, 174, 0.92);  position: absolute;  display: none;}.descr {  position: absolute;  top: 35%;  display: none;  margin-left: 26px;}.gallery > div:hover .mask {  display: block;}.gallery > div:hover .descr {  display: block;  top: 50%;  transform: translate(0%, -50%);}.gallery h2 {  font-family: Nunito;  font-style: normal;  font-weight: normal;  font-size: 24px;  line-height: 33px;  letter-spacing: 0.2em;  color: #FFFFFF;}.gallery p {  font-family: Nunito;  font-style: normal;  font-weight: normal;  font-size: 11px;  line-height: 15px;  letter-spacing: 0.2em;  color: #F3F3F3;  padding-top: 7px;}

Дополнительные стили для адаптивности галереи:

@media screen and (max-width: 795px) {  .gallery {    width: 595px;    grid-template-columns: 1fr;  }  .short_box {    width: 283px;    height: 237px;    background: #ffffff;  }  .high_box {    width: 283px;    height: 490px;    background: #ffffff;  }  .long_box {    width: 595px;    height: 237px;    background: #ffffff;  }  .high_box, .long_box, .short_box {    grid-column: 1!important;    grid-row: auto!important;    justify-self: center;  }  .scroll_button {    grid-column: 1;    width: 100%;    padding: 0;  }}@media screen and (max-width: 595px) {  .gallery {    width: 100%;  }  .long_box {    width: 100%;    height: 237px;  }}

3. Пишем JS-класс для создания компонентов:

Создадим класс, в котором будем создавать DOM-элемент и повесим на него событие onclick для перехода по нужной ссылке. Для будущего механизма показа/скрытия частей галереи передадим аргумент groupImg, в который впоследствии будет передаваться группа с принадлежащим ей изображением. Благодаря этому мы сможем скрывать и показывать нужные нам группы изображений.

В аргумент descrip передаем объект с двумя свойствами: header - заголовок, text - текст подсказки.

class ImgComponent {    constructor(groupImg, srcImg, srcToProject, row, column, size, descrip) { // передаем аргументы: группа изображений, ссылка на изображение, ссылка на проект, значение свойства row, значение свойства column, размер картинки по заранее созданным типам(short, long, high), объект подсказки        this.render(); //создаем корневой DOM элемент        this.elem.className = `img_gallery ${size}_box`; // присваиваем классы для картинок, и также класс описывающий его тип        this.elem.dataset.group = `${groupImg}`; // Присваиваем data-атрибут         this.elem.href = `./articles/${srcToProject}`; // Присваиваем ссылку на проект, на который ведет картинка        this.elem.style.cssText = `            grid-row: ${size === 'high' ? row + '/' + ++row : row};            grid-column: ${size === 'long' ? '1/2' : column + '/' + column};        `; // Присваиваем все нужные свойства.        this.elem.innerHTML = `            <div class="mask"></div>            <img src="img/${srcImg}" alt="gallery_img">            <div class="descr">                <h2>${descrip.header}</h2>                <p>${descrip.text}</p>            </div>        `; // Вкладываем внутрь элемента картинку, маску и подсказку        this.appendElem(); // Добавляем элемент на страницу        this.onClick(); // Добавляем на элемент событие onclick    }     render = () => {         this.elem = document.createElement('div'); //создаем метод, создающий корневой DOM элемент нашей картинки.    }    appendElem = () => { // Создаем метод, для добавления элемента на страницу        document.querySelector('.gallery').append(this.elem);    }    onClick = () => { // Создаем метод для прослушки события onclick элемента, для перехода по ссылке.        this.elem.addEventListener('click', () => {            window.open(this.elem.href);        })    }}

Класс для генерации галереи готов, теперь можем создавать на основе него нужные нам компоненты (картинки).

new ImgComponent(1, 'img_1.jpg', 'article1.html', 1, 1, 'short', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_1.jpg', 'article1.html', 1, 2, 'short', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_3.jpg', 'article1.html', 2, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_2.jpg', 'article1.html', 3, 1, 'high', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_2.jpg', 'article1.html', 3, 2, 'high', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(2, 'img_3.jpg', 'article1.html', 4, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(2, 'img_3.jpg', 'article1.html', 5, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(3, 'img_3.jpg', 'article1.html', 6, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(3, 'img_3.jpg', 'article1.html', 7, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});

Далее создадим объект, на основе которого будет создаваться элемент нашей кнопки, и все необходимые методы.

let scrollButton = {    elem: document.createElement('img'), // Создаем корневой DOM элемент кнопки    groupNum: 1, // Создаем свойство, которая будет считать прогресс показа картинок    hiddenImg() {  // Создаем метод скрытия для первоначального всех изображений        let array = document.querySelectorAll('.img_gallery'); // Выделяем все изображения внутри галлереи        let arrayShow = document.querySelectorAll(`.img_gallery[data-group="${this.groupNum}"]`); // выделяем первую группу изображений по атрибута data-group для показа        for(let i = 0; i < array.length; i++) { // Скрываем все изображения            array[i].style.display = 'none';        }        for(let i = 0; i < arrayShow.length; i++) { // Показ первой группы изображений            arrayShow[i].style.display = '';            if(i === arrayShow.length - 1) { // Вставка элементов после первой группе изображений                arrayShow[i].insertAdjacentElement('afterEnd', this.elem);            }        }    },    showImg() { // Создаем метод показа следующей группы изображений        let array = document.querySelectorAll('.img_gallery'); // Выделяем все изображения внутри галлереи        let arrayShow = document.querySelectorAll(`.img_gallery[data-group="${this.groupNum}"]`); // выделяем следующую группу изображений по атрибута data-group для показа        for(let i = 0; i < arrayShow.length; i++) { // Перебор массива изображений которые нужно показать            arrayShow[i].style.display = ''; // показываем все изображения из нашего массива             if(arrayShow[i] !== array[array.length - 1]) { // Проверка - на то является ли группа картинок последней                arrayShow[i].insertAdjacentElement('afterEnd', this.elem); // Если нет, то вставляем кнопку после следующей группы картинок            } else {                this.elem.style.display = 'none'; // Если условие не проходит, скрываем кнопку со страницы            }        }    },    render() {        this.elem.src = './img/scroll.svg'; // Прописываем путь до кнопки показа        this.elem.className = 'scroll_button'; // Присваивает класс, для последующего приминения CSS стилей        this.hiddenImg(); // Скрытие всех изображений на странице, кроме первой группы        this.elem.addEventListener('click', () => { // Вешаем событие на кнопку - показ группы изображений и увелечение переменной хранящей в себе прогресс показа изображений            this.groupNum++;            this.showImg();        })    }}

Завершающий штрих! Вызовем метод render() для активации механизма.

scrollButton.render();
Полный JS код
class ImgComponent {    constructor(groupImg, srcImg, srcToProject, row, column, size, descrip) {        this.render();        this.elem.className = `img_gallery ${size}_box`;        this.elem.dataset.group = `${groupImg}`;        this.elem.href = `./articles/${srcToProject}`;        this.elem.style.cssText = `            grid-row: ${size === 'high' ? row + '/' + ++row : row};            grid-column: ${size === 'long' ? '1/2' : column + '/' + column};        `;        this.elem.innerHTML = `            <div class="mask"></div>            <img src="img/${srcImg}" alt="gallery_img">            <div class="descr">                <h2>${descrip.header}</h2>                <p>${descrip.text}</p>            </div>        `;        this.appendElem();        this.onClick();    }     render = () => {         this.elem = document.createElement('div');    }    appendElem = () => {         document.querySelector('.gallery').append(this.elem);    }    onClick = () => {         this.elem.addEventListener('click', () => {            window.open(this.elem.href);        })    }}new ImgComponent(1, 'img_1.jpg', 'article1.html', 1, 1, 'short', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_1.jpg', 'article1.html', 1, 2, 'short', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_3.jpg', 'article1.html', 2, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_2.jpg', 'article1.html', 3, 1, 'high', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(1, 'img_2.jpg', 'article1.html', 3, 2, 'high', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(2, 'img_3.jpg', 'article1.html', 4, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(2, 'img_3.jpg', 'article1.html', 5, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(3, 'img_3.jpg', 'article1.html', 6, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});new ImgComponent(3, 'img_3.jpg', 'article1.html', 7, 1, 'long', {'header': 'Head', 'text': 'Test text test text test text'});let scrollButton = {    elem: document.createElement('img'),    groupNum: 1,    hiddenImg() {        let array = document.querySelectorAll('.img_gallery');        let arrayShow = document.querySelectorAll(`.img_gallery[data-group="${this.groupNum}"]`);        for(let i = 0; i < array.length; i++) {            array[i].style.display = 'none';        }        for(let i = 0; i < arrayShow.length; i++) {            arrayShow[i].style.display = '';            if(i === arrayShow.length - 1) {                arrayShow[i].insertAdjacentElement('afterEnd', this.elem);            }        }    },    showImg() {        let array = document.querySelectorAll('.img_gallery');        let arrayShow = document.querySelectorAll(`.img_gallery[data-group="${this.groupNum}"]`);        for(let i = 0; i < arrayShow.length; i++) {            arrayShow[i].style.display = '';            if(arrayShow[i] !== array[array.length - 1]) {                arrayShow[i].insertAdjacentElement('afterEnd', this.elem);            } else {                this.elem.style.display = 'none';            }        }    },    render() {        this.elem.src = './img/scroll.svg';        this.elem.className = 'scroll_button';        this.hiddenImg();        this.elem.addEventListener('click', () => {            this.groupNum++;            this.showImg();        })    }}scrollButton.render();
Полный CSS код
@keyframes scroll_move {  0% {    top: 0;  }  100% {    top: 12px;  }}  .short_box {  width: 383px;  height: 337px;  background: #ffffff;}.high_box {  width: 383px;  height: 692px;  background: #ffffff;}.long_box {  width: 795px;  height: 337px;  background: #ffffff;  grid-column: 1/2;}.gallery > div {  border: 4px solid #BB70B3;  z-index: 10;  position: relative;  overflow: hidden;  cursor: pointer;}.gallery > div img {  z-index: -5;  width: 100%;  height: auto;  position: absolute;  left: 50%;   top: 50%;  transform: translate(-50%, -50%);}.gallery {  width: 805px;  display: grid;  grid-template-columns: repeat(2, 390px);  grid-gap: 20px;  margin: 0 auto;  justify-content: center;  margin-top: 50px;  margin-bottom: 50px;}.scroll_button {  width: 200%;  cursor: pointer;  grid-column: 1/2;  padding: 0 10px 0 10px;  position: relative;}.scroll_button:hover {  animation-name: scroll_move;  animation-duration: 0.5s;  animation-iteration-count: infinite;  animation-timing-function: ease-out;  animation-direction: alternate;}.mask {  width: 100%;  height: 100%;  background: rgba(176, 155, 174, 0.92);  position: absolute;  display: none;}.descr {  position: absolute;  top: 35%;  display: none;  margin-left: 26px;}.gallery > div:hover .mask {  display: block;}.gallery > div:hover .descr {  display: block;  top: 50%;  transform: translate(0%, -50%);}.gallery h2 {  font-family: Nunito;  font-style: normal;  font-weight: normal;  font-size: 24px;  line-height: 33px;  letter-spacing: 0.2em;  color: #FFFFFF;}.gallery p {  font-family: Nunito;  font-style: normal;  font-weight: normal;  font-size: 11px;  line-height: 15px;  letter-spacing: 0.2em;  color: #F3F3F3;  padding-top: 7px;}@media screen and (max-width: 795px) {  .gallery {    width: 595px;    grid-template-columns: 1fr;  }  .short_box {    width: 283px;    height: 237px;    background: #ffffff;  }  .high_box {    width: 283px;    height: 490px;    background: #ffffff;  }  .long_box {    width: 595px;    height: 237px;    background: #ffffff;  }  .high_box, .long_box, .short_box {    grid-column: 1!important;    grid-row: auto!important;    justify-self: center;  }  .scroll_button {    grid-column: 1;    width: 100%;    padding: 0;  }}@media screen and (max-width: 595px) {  .gallery {    width: 100%;  }  .long_box {    width: 100%;    height: 237px;  }}

Полный код галереи в песочнице - песочница

P.S. Если у вас есть идеи для дополнения или улучшения моей галереи, пишите в комментариях, я обязательно это реализую.

Источник: habr.com
К списку статей
Опубликовано: 24.02.2021 08:04:01
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Javascript

Ооп

Ооп js

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru