diff --git a/index.html b/index.html index 6f36e31..238761a 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ + Кекстаграм @@ -235,6 +236,7 @@

Не удалось загрузить данны + diff --git a/js/src/postAdd/addPostForm.js b/js/src/postAdd/addPostForm.js index 0da0e7d..ca6230a 100644 --- a/js/src/postAdd/addPostForm.js +++ b/js/src/postAdd/addPostForm.js @@ -1,4 +1,6 @@ -import formSubmit from './sendValidate'; +import formSubmit, {createPristine, destroyPristine} from './sendValidate'; +import { initEffectSlider, effectChangeHandler } from './effects'; +import { handleScaleControlSmallerClick, handleScaleControlBiggerClick } from './scale'; const body = document.querySelector('body'); const uploadForm = document.querySelector('.img-upload__form'); @@ -6,6 +8,17 @@ const uploadFileControl = uploadForm.querySelector('#upload-file'); const photoEditorForm = uploadForm.querySelector('.img-upload__overlay'); const photoEditorResetBtn = photoEditorForm.querySelector('#upload-cancel'); const textInputs = [uploadForm.querySelector('.text__hashtags'), uploadForm.querySelector('.text__description')]; +const effectPreview = photoEditorForm.querySelectorAll('.effects__preview'); +const previewImage = photoEditorForm.querySelector('.img-upload__preview img'); +const effectItems = photoEditorForm.querySelectorAll('.effects__radio'); +const effectLevel = photoEditorForm.querySelector('.effect-level'); +const effectLevelSlider = photoEditorForm.querySelector('.effect-level__slider'); +const effectLevelValue = photoEditorForm.querySelector('.effect-level__value'); +const scaleControl = photoEditorForm.querySelector('.scale__control--value'); +const scaleControlSmaller = photoEditorForm.querySelector('.scale__control--smaller'); +const scaleControlBigger = photoEditorForm.querySelector('.scale__control--bigger'); +let scale = 100; + const handleDocumentKeydown = (event) => { if (event.key === 'Escape') { @@ -28,13 +41,29 @@ export const uploadImage = () => { uploadFileControl.addEventListener('change', () => { photoEditorForm.classList.remove('hidden'); body.classList.add('modal-open'); + + createPristine(uploadForm); + + previewImage.src = URL.createObjectURL(uploadFileControl.files[0]); + effectPreview.forEach((preview) => (preview.style.backgroundImage = `url(${previewImage.src})`)); + + initEffectSlider(); + + scaleControlSmaller.addEventListener('click', handleScaleControlSmallerClick); + scaleControlBigger.addEventListener('click', handleScaleControlBiggerClick); + + effectLevel.classList.add('hidden'); + effectItems.forEach((item) => { + item.addEventListener('change', effectChangeHandler); + }); + photoEditorResetBtn.addEventListener('click', onPhotoEditorResetBtnClick); document.addEventListener('keydown', handleDocumentKeydown); }); - uploadForm.addEventListener('submit', (event) => { + uploadForm.addEventListener('submit', async (event) => { event.preventDefault(); - formSubmit(event, onSuccessfulSubmit); + await formSubmit(event, onSuccessfulSubmit); }); }; @@ -42,6 +71,27 @@ export function closeEditor(isSuccessfulSubmit = false) { photoEditorForm.classList.add('hidden'); body.classList.remove('modal-open'); uploadForm.removeEventListener('submit', formSubmit); + scale = 100; + previewImage.style.transform = `scale(${scale / 100})`; + scaleControl.value = `${scale}%`; + effectLevelValue.value = 100; + effectLevelSlider.noUiSlider.set(100); + effectLevelSlider.noUiSlider.destroy(); + effectItems.forEach((item) => { + if (item.value === 'none') { + item.checked = true; + } else { + item.checked = false; + } + }); + previewImage.style.filter = ''; + previewImage.className = ''; + previewImage.classList.add('effects__preview--none'); + effectLevel.classList.add('hidden'); + effectItems.forEach((item) => item.removeEventListener('change', effectChangeHandler)); + + scaleControlSmaller.removeEventListener('click', handleScaleControlSmallerClick); + scaleControlBigger.removeEventListener('click', handleScaleControlBiggerClick); if (!isSuccessfulSubmit) { document.removeEventListener('keydown', handleDocumentKeydown); @@ -51,8 +101,11 @@ export function closeEditor(isSuccessfulSubmit = false) { uploadFileControl.value = ''; textInputs.forEach((input) => (input.value = '')); document.removeEventListener('keydown', handleDocumentKeydown); + uploadForm.reset(); + destroyPristine(); } + function onPhotoEditorResetBtnClick() { closeEditor(); } diff --git a/js/src/postAdd/effects.js b/js/src/postAdd/effects.js new file mode 100644 index 0000000..a59e51d --- /dev/null +++ b/js/src/postAdd/effects.js @@ -0,0 +1,116 @@ +const uploadForm = document.querySelector('.img-upload__form'); +const photoEditorForm = uploadForm.querySelector('.img-upload__overlay'); +const previewImage = photoEditorForm.querySelector('.img-upload__preview img'); +const effectLevel = photoEditorForm.querySelector('.effect-level'); +const effectLevelValue = photoEditorForm.querySelector('.effect-level__value'); + + +let effectLevelSlider; + +function initEffectSlider() { + effectLevelSlider = document.querySelector('.effect-level__slider'); + + noUiSlider.create(effectLevelSlider, { + range: { + min: 0, + max: 100, + }, + start: 100, + step: 1, + connect: 'lower', + format: { + to: function (value) { + if (Number.isInteger(value)) { + return value.toFixed(0); + } + return value.toFixed(1); + }, + from: function (value) { + return parseFloat(value); + } + } + }); + + effectLevelSlider.noUiSlider.on('update', (values, handle) => { + effectLevelValue.value = values[handle]; + + if (previewImage.classList.contains('effects__preview--chrome')) { + previewImage.style.filter = `grayscale(${values[handle]})`; + } else if (previewImage.classList.contains('effects__preview--sepia')) { + previewImage.style.filter = `sepia(${values[handle]})`; + } else if (previewImage.classList.contains('effects__preview--marvin')) { + previewImage.style.filter = `invert(${values[handle]}%)`; + } else if (previewImage.classList.contains('effects__preview--phobos')) { + previewImage.style.filter = `blur(${values[handle]}px)`; + } else if (previewImage.classList.contains('effects__preview--heat')) { + previewImage.style.filter = `brightness(${parseFloat(values[handle]) + 1})`; + } else { + previewImage.style.filter = ''; + } + }); +} + +function effectChangeHandler(event) { + previewImage.className = ''; + previewImage.classList.add(`effects__preview--${event.target.value}`); + + effectLevel.classList.toggle('hidden', event.target.value === 'none'); + + if (event.target.value === 'chrome') { + effectLevelSlider.noUiSlider.updateOptions({ + range: { + min: 0, + max: 1, + }, + start: 1, + step: 0.1, + }); + } else if (event.target.value === 'sepia') { + effectLevelSlider.noUiSlider.updateOptions({ + range: { + min: 0, + max: 1, + }, + start: 1, + step: 0.1, + }); + } else if (event.target.value === 'marvin') { + effectLevelSlider.noUiSlider.updateOptions({ + range: { + min: 0, + max: 100, + }, + start: 100, + step: 1, + }); + } else if (event.target.value === 'phobos') { + effectLevelSlider.noUiSlider.updateOptions({ + range: { + min: 0, + max: 3, + }, + start: 3, + step: 0.1, + }); + } else if (event.target.value === 'heat') { + effectLevelSlider.noUiSlider.updateOptions({ + range: { + min: 1, + max: 3, + }, + start: 3, + step: 0.1, + }); + } else { + effectLevelSlider.noUiSlider.updateOptions({ + range: { + min: 0, + max: 100, + }, + start: 100, + step: 1, + }); + } +} + +export { initEffectSlider, effectChangeHandler }; diff --git a/js/src/postAdd/scale.js b/js/src/postAdd/scale.js new file mode 100644 index 0000000..71554bd --- /dev/null +++ b/js/src/postAdd/scale.js @@ -0,0 +1,26 @@ +const uploadForm = document.querySelector('.img-upload__form'); +const photoEditorForm = uploadForm.querySelector('.img-upload__overlay'); +const scaleControl = photoEditorForm.querySelector('.scale__control--value'); +const previewImage = photoEditorForm.querySelector('.img-upload__preview img'); + +let scale = 100; + +function handleScaleControlSmallerClick() { + scale -= 25; + if (scale < 25) { + scale = 25; + } + scaleControl.value = `${scale}%`; + previewImage.style.transform = `scale(${scale / 100})`; +} + +function handleScaleControlBiggerClick() { + scale += 25; + if (scale > 100) { + scale = 100; + } + scaleControl.value = `${scale}%`; + previewImage.style.transform = `scale(${scale / 100})`; +} + +export { handleScaleControlSmallerClick, handleScaleControlBiggerClick }; diff --git a/js/src/postAdd/sendValidate.js b/js/src/postAdd/sendValidate.js index de3fb27..49d185a 100644 --- a/js/src/postAdd/sendValidate.js +++ b/js/src/postAdd/sendValidate.js @@ -1,46 +1,21 @@ import {closeEditor} from './addPostForm'; import displayMessage from './displayMessage'; +const uploadImageForm = document.querySelector('.img-upload__form'); +const submitButton = uploadImageForm.querySelector('.img-upload__submit'); +const successTemplate = document.querySelector('#success'); +const errorTemplate = document.querySelector('#error'); +const modal = document.querySelector('.img-upload__overlay'); const MAX_COMMENT_LENGTH = 140; const MAX_HASHTAG_COUNT = 5; const MAX_HASHTAG_LENGTH = 20; const ERROR_MESSAGE_FOR_COMMENTS = 'Длина комментария больше 140 символов.'; -const uploadImageForm = document.querySelector('.img-upload__form'); const hashtags = uploadImageForm.querySelector('.text__hashtags'); const descriptions = uploadImageForm.querySelector('.text__description'); -const submitButton = uploadImageForm.querySelector('.img-upload__submit'); -const successTemplate = document.querySelector('#success'); -const errorTemplate = document.querySelector('#error'); -const modal = document.querySelector('.img-upload__overlay'); - -const hideMessage = (messageSelector) => { - const messageElement = document.querySelector(messageSelector); - if (messageElement) { - messageElement.remove(); - } -}; - -const sendImage = async (post) => { - if (post.checkValidity()) { - submitButton.disabled = true; - displayMessage(successTemplate); - post.reset(); - modal.classList.remove('show'); - closeEditor(true); - submitButton.disabled = false; - } -}; - let errorMessage = ''; -const pristineConfig = new Pristine(uploadImageForm, { - classTo: 'img-upload__field-wrapper', - errorTextParent: 'img-upload__field-wrapper', - errorTextClass: 'img-upload__field-wrapper--error', - errorTextTag: 'div', -}); const error = () => errorMessage; @@ -96,24 +71,46 @@ const isHashtagsValid = (value) => { }; const isCommentValid = (value) => value.length <= MAX_COMMENT_LENGTH; +let pristineConfig = null; -pristineConfig.addValidator(hashtags, isHashtagsValid, error); -pristineConfig.addValidator(descriptions, isCommentValid, ERROR_MESSAGE_FOR_COMMENTS); +export const destroyPristine = () => { + if (pristineConfig) { + pristineConfig.reset(); + pristineConfig.destroy(); + pristineConfig = null; + } +}; +export const createPristine = (form) => { + if (!pristineConfig){ + + pristineConfig = new Pristine(form, { + classTo: 'img-upload__field-wrapper', + errorTextParent: 'img-upload__field-wrapper', + errorTextClass: 'img-upload__field-wrapper--error', + errorTextTag: 'div', + }); + + pristineConfig.addValidator(hashtags, isHashtagsValid, error); + pristineConfig.addValidator(descriptions, isCommentValid, ERROR_MESSAGE_FOR_COMMENTS); + } else{ + destroyPristine(); + } +}; -const hideDataError = () => { - const errorElement = document.querySelector('.data-error'); - if (errorElement) { - errorElement.remove(); +const sendImage = async (post) => { + if (post.checkValidity()) { + submitButton.disabled = true; + displayMessage(successTemplate); + post.reset(); + modal.classList.remove('show'); + closeEditor(true); + submitButton.disabled = false; } }; const formSubmit = async (event) => { event.preventDefault(); - hideDataError(); - hideMessage(document.querySelector('.success')); - hideMessage(document.querySelector('.error')); - const isValid = pristineConfig.validate(); if (isValid) { diff --git a/js/src/postAdd/validation.js b/js/src/postAdd/validation.js new file mode 100644 index 0000000..e69de29