Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ <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" action="https://32.javascript.htmlacademy.pro/kekstagram" method="post" enctype="multipart/form-data">

<!-- Изначальное состояние поля для загрузки изображения -->
<fieldset class="img-upload__start">
Expand Down Expand Up @@ -119,7 +119,7 @@ <h2 class="img-upload__title visually-hidden">Загрузка фотограф
<input class="text__hashtags" name="hashtags" placeholder="#ХэшТег">
</div>
<div class="img-upload__field-wrapper">
<textarea class="text__description" name="description" placeholder="Ваш комментарий..."></textarea>
<textarea class="text__description" name="description" placeholder="Ваш комментарий..." maxlength="140"></textarea>
</div>
</fieldset>

Expand Down Expand Up @@ -235,5 +235,7 @@ <h2 class="data-error__title">Не удалось загрузить данны
</template>
<script src="functions.js"></script>
<script type="module" src="js/main.js"></script>
<script src="vendor/pristine/pristine.min.js"></script>
<script src="./vendor/nouislider/nouislider.js"></script>
</body>
</html>
46 changes: 46 additions & 0 deletions js/dataEffects.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const styleEffects = {
'none': {
min: 0,
max: 100,
step: 1
},
'chrome': {
style: 'grayscale',
unit: '',
min: 0,
max: 1,
step: 0.1
},
'sepia': {
style: 'sepia',
unit: '',
min: 0,
max: 1,
step: 0.1
},
'marvin': {
style: 'invert',
unit: '%',
min: 0,
max: 100,
step: 1
},
'phobos': {
style: 'blur',
unit: 'px',
min: 0,
max: 3,
step: 0.1
},
'heat': {
style: 'brightness',
unit: '',
min: 1,
max: 3,
step: 0.1
}
};

export {
styleEffects
};
94 changes: 94 additions & 0 deletions js/effectsStyle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
styleEffects
} from './dataEffects.js';

let currentEffect = 'none';

const imgUploadPreview = document.querySelector('.img-upload__preview img');
const effectLevelSlider = document.querySelector('.effect-level__slider');
const effectsList = document.querySelector('.effects__list');
const effectLevelValue = document.querySelector('.effect-level__value');
const effectLevel = document.querySelector('.effect-level');

const setImageStyle = () => {
if (currentEffect === 'none') {
imgUploadPreview.style.filter = null;
return;
}

const value = effectLevelValue.value;
const unit = styleEffects[currentEffect].unit;
const style = styleEffects[currentEffect].style;
imgUploadPreview.style.filter = `${style}(${value}${unit})`;
};

const onSliderUpdate = () => {
effectLevelValue.value = effectLevelSlider.noUiSlider.get();
setImageStyle();
};

const createSlider = () => {
noUiSlider.create(effectLevelSlider, {
range: {
min: 0,
max: 1
},
step: 0.1,
start: 1,
connect: 'lower',
format: {
to: (value) => Number(value),
from: (value) => Number(value)
}
});

effectLevelValue.value = effectLevelSlider.noUiSlider.get();
effectLevelSlider.noUiSlider.on('update', onSliderUpdate);
};

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

effectLevelValue.value = effectLevelSlider.noUiSlider.get();
};

const pictureEffectReset = () => {
effectLevel.classList.add('hidden');
imgUploadPreview.style.filter = null;
effectLevelSlider.value = null;
};

effectsList.addEventListener('change', (evt) => {
currentEffect = evt.target.value;

if (currentEffect === 'none') {
pictureEffectReset();
effectLevel.classList.add('hidden');
effectLevelSlider.value = null;
} else {
effectLevel.classList.remove('hidden');
effectLevelSlider.value = currentEffect;
updateSlider(styleEffects[currentEffect]);
setImageStyle();
}
});

const pictureEffectInit = () => {
createSlider(styleEffects[currentEffect]);
};

export {
pictureEffectInit,
pictureEffectReset
};
80 changes: 80 additions & 0 deletions js/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const MAX_HASHTAG_COUNT = 5;
const MAX_HASHTAG_LENGTH = 20;
const MAX_COMMENTS_LENGTH = 140;

const uploadFormImg = document.querySelector('.img-upload__form');
const textDescription = document.querySelector('.text__description');
const textHashtag = document.querySelector('.text__hashtags');

const options = {
classTo: 'img-upload__field-wrapper',
errorTextParent: 'img-upload__field-wrapper',
errorTextClass: 'img-upload__field-wrapper--error'
};

const errorMessage = {
hashtag: 'Поле заполнено некорректно.',
description: `длина комментария не может составлять больше ${MAX_COMMENTS_LENGTH} символов`
};

const isErrorDescription = (value) => {
let isValid = true;

if (value.length > MAX_COMMENTS_LENGTH) {
isValid = false;
}

return isValid;
};

const isErrorHashtag = (value) => {
value = value.replace(/\s+/g, ' ').trim().split(' ');
let isValid = true;
const validHachtag = /^#[А-яЁёA-z0-9]{1,19}$/i;

if (value.length > MAX_HASHTAG_COUNT) {
errorMessage.hashtag = `Может быть не более ${MAX_HASHTAG_COUNT} хэштегов.`;
isValid = false;
return isValid;
}

const setHashtag = new Set(value);
if (setHashtag.size !== value.length) {
errorMessage.hashtag = 'Один и тот же хэштег не может быть использован дважды.';
isValid = false;
return isValid;
}

value.forEach((currentHachtag) => {
if (!validHachtag.test(currentHachtag)) {
errorMessage.hashtag = 'Хэштег должен начинаться с "#" и может состоять только из букв и чисел.';
isValid = false;
}

if (currentHachtag.length > MAX_HASHTAG_LENGTH) {
errorMessage.hashtag = `Максимальная длина одного хэштега ${MAX_HASHTAG_LENGTH} символов, включая решётку.`;
isValid = false;
}
});
return isValid;
};

const getHashtagErrorMessage = () => errorMessage.hashtag;

const pristine = new Pristine(uploadFormImg, options, true);

const form = () => {

pristine.addValidator(textDescription, isErrorDescription, errorMessage.description);
pristine.addValidator(textHashtag, isErrorHashtag, getHashtagErrorMessage);
};

const clearValidator = () => {
pristine.reset();
pristine.destroy();
};

export {
form,
clearValidator
};
3 changes: 3 additions & 0 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import {pictures} from './createThumbnail.js';
import {openPicture} from './openBigPhotoShow.js';
import { uploadImageModal } from './upload.js';

pictures.addEventListener('click', (evt) => {
const currentPicture = evt.target.closest('.picture');
if (currentPicture) {
openPicture(currentPicture.dataset.pictureId);
}
});

uploadImageModal();
2 changes: 0 additions & 2 deletions js/openBigPhotoShow.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ const caption = pictureBig.querySelector('.social__caption');
const pictureBigcloseButton = document.querySelector('#picture-cancel');
const body = document.body;

// Убедитесь, что модальное окно скрыто при загрузке
pictureBig.classList.add('hidden');

// / создаю функцию где добавляю класс хидден, чтоб показать фотку
const hidePictureBig = () => {
// Закрываем модальное окно
pictureBig.classList.add('hidden');
Expand Down
33 changes: 33 additions & 0 deletions js/scalePictures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
const scaleControlSmaller = document.querySelector('.scale__control--smaller');
const scaleControlValue = document.querySelector('.scale__control--value');
const scaleControlBigger = document.querySelector('.scale__control--bigger');
const bigImages = document.querySelector('.img-upload__preview img');

const MAX_CONTROL = 100;
const MIN_CONTROL = 25;
const DEFAULT_CONTROL = 100;
const STEP = 25;

const upValue = () => Math.min(MAX_CONTROL, (parseInt(scaleControlValue.value, 10) + STEP));
const endValue = () => Math.max(MIN_CONTROL, (parseInt(scaleControlValue.value, 10) - STEP));
const updateScale = (value) => {
scaleControlValue.value = `${value}%`;
bigImages.style.transform = `scale(${value / 100})`;
};

const pictureScale = () => {
scaleControlSmaller.addEventListener('click', () => {
updateScale(endValue());
});

scaleControlBigger.addEventListener('click', () => {
updateScale(upValue());
});
};

const pictureScaleDefault = () => updateScale(DEFAULT_CONTROL);

export {
pictureScale,
pictureScaleDefault
};
50 changes: 50 additions & 0 deletions js/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { isEscapeKey } from './util.js';
import { clearValidator } from './form';

import { form } from './form.js';
import { pictureEffectInit, pictureEffectReset } from './effectsStyle.js';
import { pictureScale, pictureScaleDefault } from './scalePictures.js';

form();
pictureEffectInit();
pictureScale();

const uploadImageModal = () => {
const imgUploadInput = document.querySelector('.img-upload__input');
const imgUploadOverlay = document.querySelector('.img-upload__overlay');
const imgUploadCancel = document.querySelector('.img-upload__cancel');

const onFormKeydown = (evt) => {
if (document.activeElement.name === 'hashtags' || document.activeElement.name === 'description') {
return;
}

if (isEscapeKey(evt)) {
closeModal();
}
};

imgUploadInput.addEventListener('input', () => {
imgUploadOverlay.classList.remove('hidden');
document.body.classList.add('modal-open');
pictureEffectReset();

document.addEventListener('keydown', onFormKeydown);
imgUploadCancel.addEventListener('click', closeModal);
});

function closeModal() {
imgUploadOverlay.classList.add('hidden');
document.body.classList.remove('modal-open');

document.removeEventListener('keydown', onFormKeydown);
imgUploadCancel.removeEventListener('click', closeModal);
document.querySelector('.img-upload__form').reset();
clearValidator();
pictureScaleDefault();
}
};

export {
uploadImageModal
};
Loading