Skip to content

Commit

Permalink
Merge pull request #9 from dennyhappysomuch/module12-task2
Browse files Browse the repository at this point in the history
Module12 task2
  • Loading branch information
kvakazyambra authored Dec 26, 2024
2 parents 51f7a3b + 821c2ce commit c5bd48a
Show file tree
Hide file tree
Showing 20 changed files with 796 additions and 301 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.pdf
*.psd
*.sublime*
js1-kekstagram-e2e/
build/
node_modules/
npm-debug.log*
Expand Down
27 changes: 11 additions & 16 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
<link rel="stylesheet" href="vendor/nouislider/nouislider.css">
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">
<title>Кекстаграм</title>
</head>
Expand All @@ -17,9 +18,9 @@
<section class="img-filters img-filters--inactive container">
<h2 class="img-filters__title visually-hidden">Фильтр фотографий</h2>
<form class="img-filters__form" action="index.html" method="get" autocomplete="off">
<button type=button class="img-filters__button img-filters__button--active" id="filter-default">По умолчанию</button>
<button type=button class="img-filters__button" id="filter-random">Случайные</button>
<button type=button class="img-filters__button" id="filter-discussed">Обсуждаемые</button>
<button type="button" class="img-filters__button img-filters__button--active" id="filter-default">По умолчанию</button>
<button type="button" class="img-filters__button" id="filter-random">Случайные</button>
<button type="button" class="img-filters__button" id="filter-discussed">Обсуждаемые</button>
</form>
</section>

Expand All @@ -31,11 +32,11 @@ <h2 class="pictures__title visually-hidden">Фотографии других
<section class="img-upload">
<div class="img-upload__wrapper">
<h2 class="img-upload__title visually-hidden">Загрузка фотографии</h2>
<form class="img-upload__form" id="upload-select-image" autocomplete="off">
<form class="img-upload__form" id="upload-select-image" autocomplete="off" method="post" enctype="multipart/form-data" action="https://32.javascript.htmlacademy.pro/kekstagram">

<!-- Изначальное состояние поля для загрузки изображения -->
<fieldset class="img-upload__start">
<input type="file" id="upload-file" class="img-upload__input visually-hidden" name="filename" required>
<input type="file" id="upload-file" class="img-upload__input visually-hidden" name="filename" accept="image/png, image/jpeg" required>
<label for="upload-file" class="img-upload__label img-upload__control">Загрузить</label>
</fieldset>

Expand Down Expand Up @@ -114,7 +115,7 @@ <h2 class="img-upload__title visually-hidden">Загрузка фотограф
</ul>
</fieldset>

<!-- Добавление хэштегов и комментария к изображению -->
<!-- Добавление хэш-тегов и комментария к изображению -->
<fieldset class="img-upload__text text">
<div class="img-upload__field-wrapper">
<input class="text__hashtags" name="hashtags" placeholder="#ХэшТег">
Expand Down Expand Up @@ -200,22 +201,14 @@ <h2 class="big-picture__title visually-hidden">Просмотр фотогра
<!-- Шаблон изображения случайного пользователя -->
<template id="picture">
<a href="#" class="picture">
<img class="picture__img" src="" width="182" height="182" alt="Случайная фотография">
<img class="picture__img" src="#" width="182" height="182" alt="Случайная фотография">
<p class="picture__info">
<span class="picture__comments"></span>
<span class="picture__likes"></span>
</p>
</a>
</template>

<!-- Шаблон комментария -->
<template id="comment">
<li class="social__comment">
<img class="social__picture" src="" alt="" width="35" height="35">
<p class="social__text"></p>
</li>
</template>

<!-- Сообщение с ошибкой загрузки изображения -->
<template id="error">
<section class="error">
Expand Down Expand Up @@ -243,7 +236,9 @@ <h2 class="data-error__title">Не удалось загрузить данны
</section>
</template>

<script type="module" src="js/main.js"></script>
<script src="vendor/pristine/pristine.min.js"></script>
<script src="vendor/nouislider/nouislider.js"></script>
<script src="js/main.js" type="module"></script>
</body>

</html>
19 changes: 19 additions & 0 deletions js/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { BASE_URL, ROUTE, METHOD, ERROR_TEXT } from './init.js';

const load = (route, errorText, method = METHOD.GET, body = null) =>
fetch(`${BASE_URL}${route}`, {method, body})
.then((response) => {
if (!response.ok) {
throw new Error();
}
return response.json();
})
.catch(() => {
throw new Error(errorText);
});

const getData = () => load(ROUTE.GET_DATA, ERROR_TEXT.GET_DATA);

const sendData = (body) => load(ROUTE.SEND_DATA, ERROR_TEXT.SEND_DATA, METHOD.POST, body);

export {getData, sendData};
62 changes: 0 additions & 62 deletions js/data.js

This file was deleted.

16 changes: 16 additions & 0 deletions js/file-validation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FILE_TYPES } from './init.js';

const uploadFormElement = document.querySelector('.img-upload__form');
const uploadFileElement = uploadFormElement.querySelector('#upload-file');

const isValidType = (file) => {
const fileName = file.name.toLowerCase();
return FILE_TYPES.some((item) => fileName.endsWith(item));
};

const isFileValid = () => {
const file = uploadFileElement.files[0];
return file && isValidType(file);
};

export { isFileValid };
56 changes: 56 additions & 0 deletions js/form-control.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { closeUploadForm } from './form.js';
import { isEscapeKey } from './utils.js';
import { removePopup } from './popup.js';

const uploadFormElement = document.querySelector('.img-upload__form');
const formOverlayElement = uploadFormElement.querySelector('.img-upload__overlay');
const closeButtonElement = uploadFormElement.querySelector('#upload-cancel');

const onFormOverlayClick = (evt) => {
if (evt.target.classList.contains('img-upload__overlay')) {
closeUploadForm();
}
};

const onFormCloseClick = (evt) => {
if (evt.target.id === 'upload-cancel') {
closeUploadForm();
}
};

const onFormEscapeDown = (evt) => {
if ((isEscapeKey(evt)
&& !evt.target.classList.contains('text__hashtags')
&& !evt.target.classList.contains('text__description')
&& !document.querySelector('.error'))) {
closeUploadForm();
}
};

const setFormCloseFormEvent = () => {
formOverlayElement.addEventListener('click', onFormOverlayClick);
closeButtonElement.addEventListener('click', onFormCloseClick);
document.addEventListener('keydown', onFormEscapeDown);
};

const removeFormCloseEvent = () => {
formOverlayElement.removeEventListener('click', onFormOverlayClick);
closeButtonElement.removeEventListener('click', onFormCloseClick);
document.removeEventListener('keydown', onFormEscapeDown);
};

const onPopupEscapeDown = (evt) => {
if (isEscapeKey(evt)) {
removePopup();
}
};

const setPopupEscapeControl = () => {
document.addEventListener('keydown', onPopupEscapeDown);
};

const removePopupEscapeControl = () => {
document.removeEventListener('keydown', onPopupEscapeDown);
};

export { setFormCloseFormEvent, removeFormCloseEvent, setPopupEscapeControl, removePopupEscapeControl };
88 changes: 88 additions & 0 deletions js/form-filters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { EFFECT_DEFAULT, EFFECTS } from './init.js';

const sliderContainerElement = document.querySelector('.img-upload__effect-level');
const sliderElement = sliderContainerElement.querySelector('.effect-level__slider');
const sliderInputElement = sliderContainerElement.querySelector('.effect-level__value');
const effectListElement = document.querySelector('.effects__list');
const effectItemElements = document.querySelectorAll('.effects__item');
const previewImageElement = document.querySelector('.img-upload__preview img');

let filterActive = EFFECT_DEFAULT;

const isDefault = () => filterActive === EFFECT_DEFAULT;

const showSlider = () => {
sliderContainerElement.classList.remove('hidden');
};

const hideSlider = () => {
sliderContainerElement.classList.add('hidden');
};

const setImageStyles = () => {
if (isDefault()) {
previewImageElement.style.filter = null;
return;
}
const { value } = sliderInputElement;
const { name, units } = EFFECTS[filterActive];
previewImageElement.style.filter = `${name}(${value}${units})`;
};

const sliderUpdateHandler = () => {
sliderInputElement.value = sliderElement.noUiSlider.get();
setImageStyles();
};

const createSlider = ({ min, max, step }) => {
noUiSlider.create(sliderElement, {
range: {
min: min,
max: max,
},
start: max,
step: step,
connect: 'lower',
format: {
to: (value) => Number(value),
from: (value) => Number(value),
}
});
sliderElement.noUiSlider.on('update', sliderUpdateHandler);
hideSlider();
};

const updateSlider = ({ min, max, step }) => {
sliderElement.noUiSlider.updateOptions({
step: step,
range: { min: min, max: max },
start: max,
});
};

const setSlider = () => {
updateSlider(EFFECTS[filterActive].config);
showSlider();
if (isDefault()) {
hideSlider();
}
};

const startFilterHandler = (evt) => {
filterActive = evt.target.value;
setSlider();
setImageStyles();
};

const setFilters = () => {
createSlider(EFFECTS[EFFECT_DEFAULT].config);
effectListElement.addEventListener('change', startFilterHandler);
};

const removeFilters = () => {
effectItemElements[0].children[0].checked = true;
effectListElement.removeEventListener('change', startFilterHandler);
sliderElement.noUiSlider?.destroy();
};

export { setFilters, removeFilters };
52 changes: 52 additions & 0 deletions js/form-scale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { SCALE_DEFAULT, SCALE_STEP, SCALE_MAX, SCALE_MIN, SCALE_RATIO } from './init.js';

const state = {
scale: SCALE_DEFAULT,
};

const buttonUpElement = document.querySelector('.scale__control--bigger');
const buttonDownElement = document.querySelector('.scale__control--smaller');
const currentScaleElement = document.querySelector('.scale__control--value');
const previewImageElement = document.querySelector('.img-upload__preview img');

const renderImage = () => {
previewImageElement.style.transform = `scale(${state.scale * SCALE_RATIO})`;
currentScaleElement.attributes.value.textContent = `${state.scale}%`;
currentScaleElement.value = `${state.scale}%`;
};

const onButtonUpClick = () => {
if (state.scale + SCALE_STEP <= SCALE_MAX) {
state.scale += SCALE_STEP;
}
renderImage();
};

const onButtonDownClick = () => {
if (state.scale - SCALE_STEP >= SCALE_MIN) {
state.scale -= SCALE_STEP;
}
renderImage();
};

const setScaleDefault = () => {
state.scale = SCALE_DEFAULT;
previewImageElement.style.transform = `scale(${SCALE_DEFAULT * SCALE_RATIO})`;
currentScaleElement.value = `${SCALE_DEFAULT}%`;
};

const setScale = () => {
setScaleDefault();
buttonUpElement.addEventListener('click', onButtonUpClick);
buttonDownElement.addEventListener('click', onButtonDownClick);
};

const removeScale = () => {
state.scale = SCALE_DEFAULT;
previewImageElement.style.transform = `scale(${SCALE_DEFAULT * SCALE_RATIO})`;
currentScaleElement.value = `${SCALE_DEFAULT}%`;
buttonUpElement.removeEventListener('click', onButtonUpClick);
buttonDownElement.removeEventListener('click', onButtonDownClick);
};

export { setScale, removeScale };
Loading

0 comments on commit c5bd48a

Please sign in to comment.